watir 6.19.1 → 7.0.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
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