watir 6.19.1 → 7.0.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/.github/actions/install-chrome/action.yml +1 -0
  3. data/.github/actions/setup-linux/action.yml +8 -0
  4. data/.github/workflows/tests.yml +100 -0
  5. data/CHANGES.md +7 -0
  6. data/README.md +1 -4
  7. data/Rakefile +1 -1
  8. data/lib/watir.rb +1 -45
  9. data/lib/watir/alert.rb +3 -8
  10. data/lib/watir/capabilities.rb +54 -230
  11. data/lib/watir/cell_container.rb +4 -4
  12. data/lib/watir/container.rb +4 -26
  13. data/lib/watir/elements/checkbox.rb +4 -4
  14. data/lib/watir/elements/date_field.rb +4 -4
  15. data/lib/watir/elements/date_time_field.rb +4 -4
  16. data/lib/watir/elements/element.rb +12 -49
  17. data/lib/watir/elements/file_field.rb +4 -4
  18. data/lib/watir/elements/font.rb +4 -4
  19. data/lib/watir/elements/hidden.rb +4 -4
  20. data/lib/watir/elements/html_elements.rb +444 -445
  21. data/lib/watir/elements/iframe.rb +4 -4
  22. data/lib/watir/elements/radio.rb +4 -4
  23. data/lib/watir/elements/select.rb +12 -78
  24. data/lib/watir/elements/svg_elements.rb +96 -96
  25. data/lib/watir/elements/text_field.rb +4 -4
  26. data/lib/watir/generator/base/generator.rb +4 -4
  27. data/lib/watir/generator/base/visitor.rb +0 -29
  28. data/lib/watir/generator/html/generator.rb +2 -1
  29. data/lib/watir/has_window.rb +4 -4
  30. data/lib/watir/http_client.rb +0 -8
  31. data/lib/watir/locators.rb +1 -5
  32. data/lib/watir/locators/button/matcher.rb +0 -23
  33. data/lib/watir/locators/button/selector_builder/xpath.rb +4 -15
  34. data/lib/watir/locators/element/matcher.rb +4 -19
  35. data/lib/watir/locators/element/selector_builder.rb +2 -37
  36. data/lib/watir/locators/element/selector_builder/xpath.rb +26 -41
  37. data/lib/watir/radio_set.rb +2 -2
  38. data/lib/watir/row_container.rb +4 -4
  39. data/lib/watir/version.rb +1 -1
  40. data/lib/watir/wait.rb +4 -74
  41. data/lib/watir/window.rb +6 -22
  42. data/lib/watir/window_collection.rb +5 -49
  43. data/lib/watirspec/implementation.rb +4 -0
  44. data/spec/spec_helper.rb +2 -7
  45. data/spec/unit/capabilities_spec.rb +196 -929
  46. data/spec/unit/match_elements/button_spec.rb +0 -13
  47. data/spec/unit/match_elements/element_spec.rb +38 -47
  48. data/spec/unit/match_elements/text_field_spec.rb +6 -6
  49. data/spec/unit/selector_builder/element_spec.rb +6 -23
  50. data/spec/unit/selector_builder/text_field_spec.rb +6 -7
  51. data/spec/watirspec/alert_spec.rb +4 -21
  52. data/spec/watirspec/browser_spec.rb +2 -2
  53. data/spec/watirspec/cookies_spec.rb +1 -1
  54. data/spec/watirspec/elements/button_spec.rb +0 -10
  55. data/spec/watirspec/elements/checkbox_spec.rb +10 -22
  56. data/spec/watirspec/elements/div_spec.rb +4 -34
  57. data/spec/watirspec/elements/divs_spec.rb +2 -2
  58. data/spec/watirspec/elements/element_spec.rb +38 -84
  59. data/spec/watirspec/elements/form_spec.rb +2 -4
  60. data/spec/watirspec/elements/links_spec.rb +4 -4
  61. data/spec/watirspec/elements/select_list_spec.rb +7 -108
  62. data/spec/watirspec/elements/span_spec.rb +2 -2
  63. data/spec/watirspec/elements/spans_spec.rb +1 -1
  64. data/spec/watirspec/elements/strong_spec.rb +1 -1
  65. data/spec/watirspec/html/non_control_elements.html +8 -3
  66. data/spec/watirspec/support/rspec_matchers.rb +1 -32
  67. data/spec/watirspec/window_switching_spec.rb +2 -49
  68. data/spec/watirspec_helper.rb +6 -1
  69. data/watir.gemspec +3 -4
  70. metadata +11 -32
  71. data/.github/workflows/linux.yml +0 -61
  72. data/.github/workflows/mac.yml +0 -55
  73. data/.github/workflows/unit.yml +0 -37
  74. data/.github/workflows/windows.yml +0 -39
  75. data/lib/watir/legacy_wait.rb +0 -123
  76. data/spec/unit/container_spec.rb +0 -35
  77. data/spec/watirspec/legacy_wait_spec.rb +0 -216
@@ -1,37 +0,0 @@
1
- name: Unit Tests
2
-
3
- on:
4
- - push
5
- - pull_request
6
-
7
- jobs:
8
- unit-test:
9
- name: Unit Tests
10
- runs-on: ubuntu-latest
11
- strategy:
12
- fail-fast: false
13
- matrix:
14
- ruby: ['2.5', '2.6', '2.7', '3.0']
15
- steps:
16
- - uses: actions/checkout@v2
17
- - uses: ruby/setup-ruby@v1
18
- with:
19
- ruby-version: ${{ matrix.ruby }}
20
- - run: bundle install
21
- - uses: ./.github/actions/install-chrome
22
- - run: Xvfb :99 &
23
- - run: |
24
- bundle exec rake spec:unit
25
- env:
26
- DISPLAY: :99
27
-
28
- linter-test:
29
- name: Rubocop Tests
30
- runs-on: ubuntu-latest
31
- steps:
32
- - uses: actions/checkout@v2
33
- - uses: ruby/setup-ruby@v1
34
- with:
35
- ruby-version: 2.5
36
- - run: bundle install
37
- - run: bundle exec rubocop
@@ -1,39 +0,0 @@
1
- name: Windows Tests
2
-
3
- on:
4
- - push
5
- - pull_request
6
-
7
- jobs:
8
- chrome-test:
9
- name: Chrome Test
10
- runs-on: windows-latest
11
- strategy:
12
- fail-fast: false
13
- matrix:
14
- task: [ 'chrome' ]
15
- steps:
16
- - uses: actions/checkout@v2
17
- - uses: ruby/setup-ruby@v1
18
- with:
19
- ruby-version: 2.5
20
- - run: bundle install
21
- - run: |
22
- bundle exec rake spec:${{ matrix.task }}
23
- firefox-test:
24
- name: Firefox Test
25
- runs-on: windows-latest
26
- strategy:
27
- fail-fast: false
28
- matrix:
29
- task: [ 'firefox' ]
30
- steps:
31
- - uses: actions/checkout@v2
32
- - uses: ruby/setup-ruby@v1
33
- with:
34
- ruby-version: 2.5
35
- - run: bundle install
36
- - run: |
37
- bundle exec rake spec:${{ matrix.task }}
38
-
39
-
@@ -1,123 +0,0 @@
1
- require 'forwardable'
2
-
3
- # TODO: - remove this file for future release
4
- module Watir
5
- class BaseDecorator
6
- def initialize(element, timeout, message = nil)
7
- @element = element
8
- @timeout = timeout
9
- @message = message
10
- end
11
-
12
- def respond_to_missing?(*args)
13
- @element.respond_to?(*args) || super
14
- end
15
-
16
- def method_missing(method, *args, &block)
17
- return super unless @element.respond_to?(method)
18
-
19
- Wait.until(@timeout, @message) { wait_until }
20
-
21
- @element.__send__(method, *args, &block)
22
- end
23
- end
24
-
25
- #
26
- # Wraps an Element so that any subsequent method calls are
27
- # put on hold until the element is present (exists and is visible) on the page.
28
- #
29
-
30
- class WhenPresentDecorator < BaseDecorator
31
- def present?
32
- Wait.until(@timeout, @message) { wait_until }
33
- true
34
- rescue Wait::TimeoutError
35
- false
36
- end
37
-
38
- private
39
-
40
- def wait_until
41
- @element.present?
42
- end
43
- end # WhenPresentDecorator
44
-
45
- #
46
- # Wraps an Element so that any subsequent method calls are
47
- # put on hold until the element is enabled (exists and is enabled) on the page.
48
- #
49
-
50
- class WhenEnabledDecorator < BaseDecorator
51
- private
52
-
53
- def wait_until
54
- @element.enabled?
55
- end
56
- end # WhenEnabledDecorator
57
-
58
- #
59
- # Convenience methods for things that eventually become present.
60
- #
61
- # Includers should implement a public #present? and a (possibly private) #selector_string method.
62
- #
63
-
64
- module EventuallyPresent
65
- #
66
- # Waits until the element is present.
67
- #
68
- # @example
69
- # browser.text_field(name: "new_user_first_name").when_present.click
70
- # browser.text_field(name: "new_user_first_name").when_present { |field| field.set "Watir" }
71
- # browser.text_field(name: "new_user_first_name").when_present(60).text
72
- #
73
- # @param [Integer] timeout seconds to wait before timing out
74
- #
75
- # @see Watir::Wait
76
- # @see Watir::Element#present?
77
- #
78
-
79
- def when_present(timeout = nil)
80
- msg = '#when_present'
81
- repl_msg = '#wait_until_present if a wait is still needed'
82
- Watir.logger.deprecate msg, repl_msg, ids: [:when_present]
83
-
84
- timeout ||= Watir.default_timeout
85
- message = "waiting for #{selector_string} to become present"
86
-
87
- if block_given?
88
- Wait.until(timeout, message) { present? }
89
- yield self
90
- else
91
- WhenPresentDecorator.new(self, timeout, message)
92
- end
93
- end
94
-
95
- #
96
- # Waits until the element is enabled.
97
- #
98
- # @example
99
- # browser.button(name: "new_user_button_2").when_enabled.click
100
- #
101
- # @param [Integer] timeout seconds to wait before timing out
102
- #
103
- # @see Watir::Wait
104
- # @see Watir::Element#enabled?
105
- #
106
-
107
- def when_enabled(timeout = nil)
108
- msg = '#when_enabled'
109
- repl_msg = 'wait_until(&:enabled?)'
110
- Watir.logger.deprecate msg, repl_msg, ids: [:when_enabled]
111
-
112
- timeout ||= Watir.default_timeout
113
- message = "waiting for #{selector_string} to become enabled"
114
-
115
- if block_given?
116
- Wait.until(timeout, message) { enabled? }
117
- yield self
118
- else
119
- WhenEnabledDecorator.new(self, timeout, message)
120
- end
121
- end
122
- end # EventuallyPresent
123
- end # Watir
@@ -1,35 +0,0 @@
1
- require_relative 'unit_helper'
2
-
3
- describe Watir::Container do
4
- before { @container = Object.new.extend(Watir::Container) }
5
-
6
- describe '#extract_selector' do
7
- before do
8
- def @container.public_extract_selector(*args)
9
- extract_selector(*args)
10
- end
11
- end
12
-
13
- it 'converts 2-arg selector into a hash' do
14
- expect {
15
- expect(@container.public_extract_selector([:how, 'what'])).to eq Hash[how: 'what']
16
- }.to have_deprecated_selector_parameters
17
- end
18
-
19
- it 'returns the hash given' do
20
- expect(@container.public_extract_selector([{how: 'what'}])).to eq Hash[how: 'what']
21
- end
22
-
23
- it 'returns an empty hash if given no args' do
24
- expect(@container.public_extract_selector([])).to eq Hash[]
25
- end
26
-
27
- it 'raises ArgumentError if given 1 arg which is not a Hash' do
28
- expect { @container.public_extract_selector([:how]) }.to raise_error(ArgumentError)
29
- end
30
-
31
- it 'raises ArgumentError if given > 2 args' do
32
- expect { @container.public_extract_selector([:how, 'what', 'value']) }.to raise_error(ArgumentError)
33
- end
34
- end
35
- end
@@ -1,216 +0,0 @@
1
- require 'watirspec_helper'
2
-
3
- describe Watir::Element do
4
- before do
5
- browser.goto WatirSpec.url_for('wait.html')
6
- end
7
-
8
- compliant_on :relaxed_locate do
9
- describe '#wait_until_present' do
10
- it 'waits until the element appears' do
11
- browser.a(id: 'show_bar').click
12
- expect {
13
- expect { browser.div(id: 'bar').wait_until_present(timeout: 5) }.to_not raise_exception
14
- }.to have_deprecated_wait_until_present
15
- end
16
-
17
- bug 'Safari does not recognize date type', :safari do
18
- it 'waits until the element re-appears' do
19
- browser.link(id: 'readd_bar').click
20
- expect {
21
- expect { browser.div(id: 'bar').wait_until_present }.to_not raise_exception
22
- }.to have_deprecated_wait_until_present
23
- end
24
- end
25
-
26
- it "times out if the element doesn't appear" do
27
- inspected = '#<Watir::Div: located: true; {:id=>"bar", :tag_name=>"div"}>'
28
- error = Watir::Wait::TimeoutError
29
- message = "timed out after 1 seconds, waiting for #{inspected} to become present"
30
-
31
- expect {
32
- expect { browser.div(id: 'bar').wait_until_present(timeout: 1) }.to raise_error(error, message)
33
- }.to have_deprecated_wait_until_present
34
- end
35
-
36
- it 'uses provided interval' do
37
- element = browser.div(id: 'bar')
38
- expect(element).to receive(:present?).twice
39
-
40
- expect {
41
- expect { element.wait_until_present(timeout: 0.4, interval: 0.2) }.to raise_timeout_exception
42
- }.to have_deprecated_wait_until_present
43
- end
44
- end
45
-
46
- describe '#wait_while_present' do
47
- it 'waits until the element disappears' do
48
- browser.a(id: 'hide_foo').click
49
- expect {
50
- expect { browser.div(id: 'foo').wait_while_present(timeout: 2) }.to_not raise_exception
51
- }.to have_deprecated_wait_while_present
52
- end
53
-
54
- it "times out if the element doesn't disappear" do
55
- error = Watir::Wait::TimeoutError
56
- inspected = '#<Watir::Div: located: true; {:id=>"foo", :tag_name=>"div"}>'
57
- message = "timed out after 1 seconds, waiting for #{inspected} not to be present"
58
- expect {
59
- expect { browser.div(id: 'foo').wait_while_present(timeout: 1) }.to raise_error(error, message)
60
- }.to have_deprecated_wait_while_present
61
- end
62
-
63
- it 'uses provided interval' do
64
- error = Watir::Wait::TimeoutError
65
- element = browser.div(id: 'foo')
66
- expect(element).to receive(:present?).and_return(true).twice
67
-
68
- expect {
69
- expect { element.wait_while_present(timeout: 0.4, interval: 0.2) }.to raise_error(error)
70
- }.to have_deprecated_wait_while_present
71
- end
72
-
73
- it 'does not error when element goes stale' do
74
- element = browser.div(id: 'foo').locate
75
-
76
- allow(element).to receive(:stale?).and_return(false, true)
77
-
78
- browser.a(id: 'hide_foo').click
79
- expect {
80
- expect { element.wait_while_present(timeout: 2) }.to_not raise_exception
81
- }.to have_deprecated_wait_while_present
82
- end
83
-
84
- it 'waits until the selector no longer matches' do
85
- element = browser.link(name: 'add_select').wait_until(&:exists?)
86
- browser.link(id: 'change_select').click
87
- expect {
88
- expect { element.wait_while_present }.not_to raise_error
89
- }.to have_deprecated_wait_while_present
90
- end
91
- end
92
- end
93
-
94
- not_compliant_on :relaxed_locate do
95
- describe '#when_present' do
96
- it 'invokes subsequent method calls when the element becomes present' do
97
- browser.a(id: 'show_bar').click
98
-
99
- bar = browser.div(id: 'bar')
100
- bar.when_present(2).click
101
- expect(bar.text).to eq 'changed'
102
- end
103
-
104
- it 'times out when given a block' do
105
- expect { browser.div(id: 'bar').when_present(1) {} }.to raise_error(Watir::Wait::TimeoutError)
106
- end
107
-
108
- it 'times out when not given a block' do
109
- locator = '(\{:id=>"bar", :tag_name=>"div"\}|\{:tag_name=>"div", :id=>"bar"\})'
110
- msg = /^timed out after 1 seconds, waiting for #{locator} to become present$/
111
- expect { browser.div(id: 'bar').when_present(1).click }.to raise_error(Watir::Wait::TimeoutError, msg)
112
- end
113
-
114
- it 'responds to Element methods' do
115
- decorator = browser.div.when_present
116
-
117
- expect(decorator).to respond_to(:exist?)
118
- expect(decorator).to respond_to(:present?)
119
- expect(decorator).to respond_to(:click)
120
- end
121
-
122
- it 'delegates present? to element' do
123
- Object.class_eval do
124
- def present?
125
- false
126
- end
127
- end
128
- element = browser.a(id: 'show_bar').when_present(1)
129
- expect(element).to be_present
130
- end
131
-
132
- it 'processes before calling present?' do
133
- browser.a(id: 'show_bar').click
134
- expect(browser.div(id: 'bar').when_present.present?).to be true
135
- end
136
- end
137
-
138
- describe '#wait_until &:enabled?' do
139
- it 'invokes subsequent method calls when the element becomes enabled' do
140
- browser.a(id: 'enable_btn').click
141
-
142
- btn = browser.button(id: 'btn')
143
- btn.wait_until(timeout: 2, &:enabled?).click
144
- Watir::Wait.while { btn.enabled? }
145
- expect(btn.disabled?).to be true
146
- end
147
-
148
- it 'times out' do
149
- error = Watir::Wait::TimeoutError
150
- inspected = '#<Watir::Button: located: true; {:id=>"btn", :tag_name=>"button"}>'
151
- message = "timed out after 1 seconds, waiting for true condition on #{inspected}"
152
- element = browser.button(id: 'btn')
153
- expect { element.wait_until(timeout: 1, &:enabled?).click }.to raise_error(error, message)
154
- end
155
-
156
- it 'responds to Element methods' do
157
- element = browser.button.wait_until { true }
158
-
159
- expect(element).to respond_to(:exist?)
160
- expect(element).to respond_to(:present?)
161
- expect(element).to respond_to(:click)
162
- end
163
-
164
- it 'can be chained with #wait_until &:present?' do
165
- browser.a(id: 'show_and_enable_btn').click
166
- browser.button(id: 'btn2').wait_until(&:present?).wait_until(&:enabled?).click
167
-
168
- expect(browser.button(id: 'btn2')).to exist
169
- expect(browser.button(id: 'btn2')).to be_enabled
170
- end
171
- end
172
-
173
- context 'when acting on an element that is never present' do
174
- it 'raises exception immediately' do
175
- element = browser.link(id: 'not_there')
176
- start_time = ::Time.now
177
- expect { element.click }.to raise_exception(Watir::Exception::UnknownObjectException)
178
- expect(::Time.now - start_time).to be < 1
179
- end
180
- end
181
-
182
- context 'when acting on an element that eventually becomes present' do
183
- it 'raises exception immediately' do
184
- start_time = ::Time.now
185
- browser.a(id: 'show_bar').click
186
-
187
- expect { browser.div(id: 'bar').click }.to raise_unknown_object_exception
188
-
189
- expect(::Time.now - start_time).to be < 1
190
- end
191
- end
192
- end
193
- end
194
-
195
- describe Watir::Window do
196
- not_compliant_on :relaxed_locate do
197
- describe '#wait_until &:present?' do
198
- before do
199
- browser.goto WatirSpec.url_for('window_switching.html')
200
- browser.a(id: 'open').click
201
- Watir::Wait.until { browser.windows.size == 2 }
202
- end
203
-
204
- after do
205
- browser.original_window.use
206
- browser.windows.reject(&:current?).each(&:close)
207
- end
208
-
209
- it 'times out waiting for a non-present window' do
210
- expect {
211
- browser.window(title: 'noop').wait_until(timeout: 0.5, &:present?)
212
- }.to raise_error(Watir::Wait::TimeoutError)
213
- end
214
- end
215
- end
216
- end