1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
# frozen_string_literal: true
require 'rspec'
require 'rspec/expectations'
require 'capybara'
require 'capybara/rspec' # Required here instead of in rspec_spec to avoid RSpec deprecation warning
require 'capybara/spec/test_app'
require 'nokogiri'
Capybara.save_path = File.join(Dir.pwd, 'save_path_tmp')
module Capybara
module SpecHelper
class << self
def configure(config)
config.filter_run_excluding requires: method(:filter).to_proc
config.before { Capybara::SpecHelper.reset! }
config.after { Capybara::SpecHelper.reset! }
config.shared_context_metadata_behavior = :apply_to_host_groups
end
def reset!
Capybara.app = TestApp
Capybara.app_host = nil
Capybara.default_selector = :xpath
Capybara.default_max_wait_time = 1
Capybara.default_retry_interval = 0.01
Capybara.ignore_hidden_elements = true
Capybara.exact = false
Capybara.raise_server_errors = true
Capybara.visible_text_only = false
Capybara.match = :smart
Capybara.enable_aria_label = false
Capybara.enable_aria_role = false
Capybara.default_set_options = {}
Capybara.disable_animation = false
Capybara.test_id = nil
Capybara.predicates_wait = true
Capybara.default_normalize_ws = false
Capybara.use_html5_parsing = !ENV['HTML5_PARSING'].nil?
Capybara.w3c_click_offset = true
reset_threadsafe
end
def filter(requires, metadata)
if requires && metadata[:capybara_skip]
requires.any? do |require|
metadata[:capybara_skip].include?(require)
end
else
false
end
end
def spec(name, *options, &block)
@specs ||= []
@specs << [name, options, block]
end
def run_specs(session, name, **options, &filter_block)
specs = @specs
RSpec.describe Capybara::Session, name, options do
include Capybara::SpecHelper
include Capybara::RSpecMatchers
before do |example|
@session = session
instance_exec(example, &filter_block) if filter_block
end
after do
session.reset_session!
end
before :each, :psc do
SpecHelper.reset_threadsafe(bool: true, session: session)
end
after psc: true do
SpecHelper.reset_threadsafe(session: session)
end
before :each, :exact_false do
Capybara.exact = false
end
specs.each do |spec_name, spec_options, block|
describe spec_name, *spec_options do
class_eval(&block)
end
end
end
end
def reset_threadsafe(bool: false, session: nil)
# Work around limit on when threadsafe can be changed
Capybara::Session.class_variable_set(:@@instance_created, false) # rubocop:disable Style/ClassVars
Capybara.threadsafe = bool
session = session.current_session if session.respond_to?(:current_session)
session&.instance_variable_set(:@config, nil)
end
end
def silence_stream(stream)
old_stream = stream.dup
stream.reopen(RbConfig::CONFIG['host_os'].match?(/rmswin|mingw/) ? 'NUL:' : '/dev/null')
stream.sync = true
yield
ensure
stream.reopen(old_stream)
end
def quietly(&block)
silence_stream($stdout) do
silence_stream($stderr, &block)
end
end
def extract_results(session)
expect(session).to have_xpath("//pre[@id='results']")
perms = [(::Sinatra::IndifferentHash if defined? ::Sinatra::IndifferentHash)].compact
results = Capybara::HTML(session.body).xpath("//pre[@id='results']").first.inner_html.lstrip
YAML.safe_load results, permitted_classes: perms
end
def extract_content_type(session)
expect(session).to have_xpath("//pre[@id='content_type']")
Capybara::HTML(session.body).xpath("//pre[@id='content_type']").first.text
end
def be_an_invalid_element_error(session)
satisfy { |error| session.driver.invalid_element_errors.any? { |e| error.is_a? e } }
end
def with_os_path_separators(path)
Gem.win_platform? ? path.to_s.tr('/', '\\') : path.to_s
end
end
end
Dir["#{File.dirname(__FILE__)}/session/**/*.rb"].each { |file| require_relative file }
|