File: spec_helper.rb

package info (click to toggle)
ruby-capybara 3.40.0%2Bds-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,368 kB
  • sloc: ruby: 23,988; javascript: 752; makefile: 11
file content (141 lines) | stat: -rw-r--r-- 4,447 bytes parent folder | download
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 }