watir 6.16.2 → 6.18.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (108) hide show
  1. checksums.yaml +5 -5
  2. data/.github/actions/enable-safari/action.yml +11 -0
  3. data/.github/actions/install-chrome/action.yml +11 -0
  4. data/.github/workflows/linux.yml +61 -0
  5. data/.github/workflows/mac.yml +55 -0
  6. data/.github/workflows/unit.yml +31 -0
  7. data/.github/workflows/windows.yml +39 -0
  8. data/.rubocop.yml +32 -107
  9. data/.rubocop_todo.yml +36 -0
  10. data/CHANGES.md +42 -0
  11. data/Gemfile +3 -1
  12. data/LICENSE +2 -2
  13. data/README.md +9 -10
  14. data/Rakefile +4 -4
  15. data/lib/watir-webdriver.rb +1 -1
  16. data/lib/watir.rb +1 -1
  17. data/lib/watir/adjacent.rb +8 -10
  18. data/lib/watir/after_hooks.rb +4 -4
  19. data/lib/watir/alert.rb +1 -0
  20. data/lib/watir/attribute_helper.rb +2 -0
  21. data/lib/watir/browser.rb +7 -3
  22. data/lib/watir/capabilities.rb +9 -6
  23. data/lib/watir/cookies.rb +3 -1
  24. data/lib/watir/element_collection.rb +21 -6
  25. data/lib/watir/elements/element.rb +66 -53
  26. data/lib/watir/elements/file_field.rb +1 -0
  27. data/lib/watir/elements/html_elements.rb +0 -1
  28. data/lib/watir/elements/iframe.rb +4 -3
  29. data/lib/watir/elements/link.rb +0 -9
  30. data/lib/watir/elements/radio.rb +1 -1
  31. data/lib/watir/elements/select.rb +22 -7
  32. data/lib/watir/generator/base/spec_extractor.rb +4 -4
  33. data/lib/watir/generator/html/generator.rb +1 -1
  34. data/lib/watir/has_window.rb +17 -15
  35. data/lib/watir/js_execution.rb +3 -3
  36. data/lib/watir/js_snippets.rb +2 -2
  37. data/lib/watir/legacy_wait.rb +1 -1
  38. data/lib/watir/locators.rb +1 -3
  39. data/lib/watir/locators/element/locator.rb +22 -12
  40. data/lib/watir/locators/element/selector_builder.rb +12 -13
  41. data/lib/watir/locators/element/selector_builder/xpath.rb +40 -13
  42. data/lib/watir/locators/text_field/matcher.rb +1 -1
  43. data/lib/watir/locators/text_field/selector_builder/xpath.rb +3 -1
  44. data/lib/watir/logger.rb +7 -20
  45. data/lib/watir/radio_set.rb +2 -2
  46. data/lib/watir/user_editable.rb +6 -2
  47. data/lib/watir/version.rb +1 -1
  48. data/lib/watir/wait.rb +2 -0
  49. data/lib/watir/wait/timer.rb +1 -1
  50. data/lib/watir/window.rb +8 -4
  51. data/lib/watir/window_collection.rb +105 -0
  52. data/lib/watirspec.rb +2 -1
  53. data/lib/watirspec/guards.rb +1 -1
  54. data/lib/watirspec/implementation.rb +3 -5
  55. data/lib/watirspec/rake_tasks.rb +2 -0
  56. data/lib/watirspec/runner.rb +5 -1
  57. data/lib/watirspec/server.rb +1 -1
  58. data/spec/spec_helper.rb +2 -7
  59. data/spec/unit/container_spec.rb +1 -1
  60. data/spec/unit/logger_spec.rb +5 -7
  61. data/spec/unit/match_elements/element_spec.rb +17 -15
  62. data/spec/unit/selector_builder/button_spec.rb +16 -15
  63. data/spec/unit/selector_builder/element_spec.rb +58 -9
  64. data/spec/unit/selector_builder/text_field_spec.rb +14 -14
  65. data/spec/unit/unit_helper.rb +2 -4
  66. data/spec/watirspec/after_hooks_spec.rb +58 -68
  67. data/spec/watirspec/alert_spec.rb +69 -79
  68. data/spec/watirspec/browser_spec.rb +51 -48
  69. data/spec/watirspec/cookies_spec.rb +52 -37
  70. data/spec/watirspec/drag_and_drop_spec.rb +14 -38
  71. data/spec/watirspec/elements/button_spec.rb +2 -0
  72. data/spec/watirspec/elements/buttons_spec.rb +1 -1
  73. data/spec/watirspec/elements/checkbox_spec.rb +8 -4
  74. data/spec/watirspec/elements/date_field_spec.rb +18 -9
  75. data/spec/watirspec/elements/date_time_field_spec.rb +3 -4
  76. data/spec/watirspec/elements/div_spec.rb +62 -54
  77. data/spec/watirspec/elements/element_spec.rb +73 -88
  78. data/spec/watirspec/elements/elements_spec.rb +12 -3
  79. data/spec/watirspec/elements/filefield_spec.rb +25 -50
  80. data/spec/watirspec/elements/form_spec.rb +6 -8
  81. data/spec/watirspec/elements/frame_spec.rb +10 -13
  82. data/spec/watirspec/elements/iframe_spec.rb +12 -9
  83. data/spec/watirspec/elements/iframes_spec.rb +2 -2
  84. data/spec/watirspec/elements/link_spec.rb +23 -12
  85. data/spec/watirspec/elements/links_spec.rb +11 -3
  86. data/spec/watirspec/elements/option_spec.rb +15 -17
  87. data/spec/watirspec/elements/select_list_spec.rb +222 -117
  88. data/spec/watirspec/elements/text_field_spec.rb +8 -4
  89. data/spec/watirspec/elements/tr_spec.rb +0 -9
  90. data/spec/watirspec/html/forms_with_input_elements.html +1 -0
  91. data/spec/watirspec/html/iframes.html +3 -0
  92. data/spec/watirspec/html/non_control_elements.html +4 -4
  93. data/spec/watirspec/html/right_click.html +12 -0
  94. data/spec/watirspec/html/wait.html +6 -6
  95. data/spec/watirspec/html/window_switching.html +10 -0
  96. data/spec/watirspec/legacy_wait_spec.rb +216 -0
  97. data/spec/watirspec/support/rspec_matchers.rb +17 -13
  98. data/spec/watirspec/user_editable_spec.rb +1 -1
  99. data/spec/watirspec/wait_spec.rb +257 -305
  100. data/spec/watirspec/window_switching_spec.rb +332 -211
  101. data/spec/watirspec_helper.rb +16 -19
  102. data/support/doctest_helper.rb +0 -2
  103. data/watir.gemspec +6 -7
  104. metadata +36 -26
  105. data/.travis.yml +0 -84
  106. data/appveyor.yml +0 -12
  107. data/lib/watir/elements/area.rb +0 -10
  108. data/spec/watirspec/relaxed_locate_spec.rb +0 -113
@@ -1,11 +1,10 @@
1
1
  require 'watirspec_helper'
2
2
 
3
- describe 'Browser' do
3
+ describe Watir::Browser do
4
4
  before do
5
- url = WatirSpec.url_for('window_switching.html')
6
- browser.goto url
5
+ browser.goto WatirSpec.url_for('window_switching.html')
7
6
  browser.a(id: 'open').click
8
- Watir::Wait.until { browser.windows.size == 2 }
7
+ browser.windows.wait_until(size: 2)
9
8
  end
10
9
 
11
10
  after do
@@ -14,14 +13,15 @@ describe 'Browser' do
14
13
  end
15
14
 
16
15
  describe '#windows' do
17
- it 'returns an array of window handles' do
18
- wins = browser.windows
19
- expect(wins).to_not be_empty
20
- wins.each { |win| expect(win).to be_kind_of(Watir::Window) }
16
+ it 'returns a WindowCollection' do
17
+ expect(browser.windows).to be_a(Watir::WindowCollection)
21
18
  end
22
19
 
23
- it 'only returns windows matching the given selector' do
24
- browser.wait_until { |b| b.window(title: 'closeable window').exists? }
20
+ it 'stores Window instances' do
21
+ expect(browser.windows(title: 'closeable window')).to all(be_a(Watir::Window))
22
+ end
23
+
24
+ it 'filters windows to match the given selector' do
25
25
  expect(browser.windows(title: 'closeable window').size).to eq 1
26
26
  end
27
27
 
@@ -30,24 +30,31 @@ describe 'Browser' do
30
30
  end
31
31
 
32
32
  it 'returns an empty array if no window matches the selector' do
33
- expect(browser.windows(title: 'noop')).to eq []
33
+ expect(browser.windows(title: 'noop')).to be_empty
34
34
  end
35
35
  end
36
36
 
37
37
  describe '#window' do
38
38
  it 'finds window by :url' do
39
- w = browser.window(url: /closeable\.html/).use
40
- expect(w).to be_kind_of(Watir::Window)
39
+ expect(browser.window(url: /closeable\.html/).use).to be_a(Watir::Window)
41
40
  end
42
41
 
43
42
  it 'finds window by :title' do
44
- w = browser.window(title: 'closeable window').use
45
- expect(w).to be_kind_of(Watir::Window)
43
+ expect(browser.window(title: 'closeable window').use).to be_a(Watir::Window)
46
44
  end
47
45
 
48
46
  it 'finds window by :index' do
49
- w = browser.window(index: 1).use
50
- expect(w).to be_kind_of(Watir::Window)
47
+ expect {
48
+ expect(browser.window(index: 1).use).to be_a(Watir::Window)
49
+ }.to have_deprecated_window_index
50
+ end
51
+
52
+ it 'finds window by :element' do
53
+ expect(browser.window(element: browser.a(id: 'close')).use).to be_a(Watir::Window)
54
+ end
55
+
56
+ it 'finds window by multiple values' do
57
+ expect(browser.window(title: 'closeable window', url: /closeable\.html/).use).to be_a(Watir::Window)
51
58
  end
52
59
 
53
60
  it 'should not find incorrect handle' do
@@ -60,21 +67,19 @@ describe 'Browser' do
60
67
 
61
68
  it 'stores the reference to a window when no argument is given' do
62
69
  original_window = browser.window
63
- browser.window(index: 1).use
70
+ browser.window(title: 'closeable window').use
64
71
  expect(original_window.url).to match(/window_switching\.html/)
65
72
  end
66
73
 
67
- bug 'https://bugzilla.mozilla.org/show_bug.cgi?id=1223277', :firefox do
68
- not_compliant_on :headless do
69
- it 'it executes the given block in the window' do
70
- browser.window(title: 'closeable window') {
71
- link = browser.a(id: 'close')
72
- expect(link).to exist
73
- link.click
74
- }.wait_while(&:present?)
75
-
76
- expect(browser.windows.size).to eq 1
74
+ bug 'Clicking an Element that Closes a Window is returning NoMatchingWindowFoundException', :safari do
75
+ it 'it executes the given block in the window' do
76
+ browser.window(title: 'closeable window') do
77
+ link = browser.a(id: 'close')
78
+ expect(link).to exist
79
+ link.click
77
80
  end
81
+
82
+ expect { browser.windows.wait_until(size: 1) }.to_not raise_error
78
83
  end
79
84
  end
80
85
 
@@ -87,21 +92,57 @@ describe 'Browser' do
87
92
  end
88
93
 
89
94
  it "raises a NoMatchingWindowFoundException error if there's no window at the given index" do
90
- expect { browser.window(index: 100).use }.to raise_no_matching_window_exception
95
+ expect {
96
+ expect { browser.window(index: 100).use }.to raise_no_matching_window_exception
97
+ }.to have_deprecated_window_index
91
98
  end
92
99
 
93
100
  it 'raises NoMatchingWindowFoundException error when attempting to use a window with an incorrect handle' do
94
101
  expect { browser.window(handle: 'bar').use }.to raise_no_matching_window_exception
95
102
  end
96
103
  end
104
+
105
+ describe '#switch_window' do
106
+ it 'switches to second window' do
107
+ original_window = browser.window
108
+ browser.switch_window
109
+ new_window = browser.window
110
+
111
+ expect(original_window).to_not eq new_window
112
+ expect(browser.windows).to include(original_window, new_window)
113
+ end
114
+
115
+ it 'returns an instance of Window' do
116
+ expect(browser.switch_window).to be_a(Watir::Window)
117
+ end
118
+
119
+ it 'times out if there is no second window' do
120
+ browser.windows.reject(&:current?).each(&:close)
121
+ message = /waiting for true condition on (.*) title="window switching">$/
122
+ expect { browser.switch_window }.to raise_timeout_exception(message)
123
+ end
124
+
125
+ it 'provides previous window value to #original_window' do
126
+ browser.switch_window
127
+ expect(browser.original_window).to_not be_nil
128
+ end
129
+
130
+ it 'waits for second window' do
131
+ browser.windows.reject(&:current?).each(&:close)
132
+ expect {
133
+ browser.a(id: 'delayed').click
134
+ browser.switch_window
135
+ }.to execute_when_satisfied(min: 1)
136
+ end
137
+ end
97
138
  end
98
139
 
99
- describe 'Window' do
140
+ describe Watir::Window do
100
141
  context 'multiple windows' do
101
142
  before do
102
143
  browser.goto WatirSpec.url_for('window_switching.html')
103
144
  browser.a(id: 'open').click
104
- Watir::Wait.until { browser.windows.size == 2 }
145
+ browser.windows.wait_until(size: 2)
105
146
  end
106
147
 
107
148
  after do
@@ -109,198 +150,194 @@ describe 'Window' do
109
150
  browser.windows.reject(&:current?).each(&:close)
110
151
  end
111
152
 
112
- not_compliant_on :safari, %i[firefox linux] do
153
+ bug 'Focus is on newly opened window instead of the first', :safari do
154
+ it 'allows actions on first window after opening second' do
155
+ browser.a(id: 'open').click
156
+
157
+ expect { browser.windows.wait_until(size: 3) }.to_not raise_timeout_exception
158
+ end
159
+ end
160
+
161
+ not_compliant_on %i[firefox linux] do
113
162
  describe '#close' do
114
163
  it 'closes a window' do
164
+ browser.window(title: 'window switching').use
115
165
  browser.a(id: 'open').click
116
- Watir::Wait.until { browser.windows.size == 3 }
166
+ browser.windows.wait_until(size: 3)
167
+
168
+ Watir::Window.new(browser, title: 'closeable window').close
117
169
 
118
- browser.window(title: 'closeable window').close
119
- expect(browser.windows.size).to eq 2
170
+ expect { browser.windows.wait_until(size: 2) }.to_not raise_timeout_exception
120
171
  end
121
- end
122
172
 
123
- it 'closes the current window' do
124
- browser.a(id: 'open').click
125
- Watir::Wait.until { browser.windows.size == 3 }
173
+ bug 'Focus is on newly opened window instead of the first', :safari do
174
+ it 'closes the current window' do
175
+ browser.a(id: 'open').click
176
+ browser.windows.wait_until(size: 3)
126
177
 
127
- window = browser.window(title: 'closeable window').use
128
- window.close
129
- expect(browser.windows.size).to eq 2
178
+ Watir::Window.new(browser, title: 'closeable window').use.close
179
+
180
+ expect { browser.windows.wait_until(size: 2) }.to_not raise_timeout_exception
181
+ end
182
+ end
130
183
  end
131
184
  end
132
185
 
133
186
  describe '#use' do
134
187
  it 'switches to the window' do
135
- browser.window(title: 'closeable window').use
188
+ Watir::Window.new(browser, title: 'closeable window').use
136
189
  expect(browser.title).to eq 'closeable window'
137
190
  end
138
191
  end
139
192
 
140
193
  describe '#current?' do
141
194
  it 'returns true if it is the current window' do
142
- expect(browser.window(title: browser.title)).to be_current
195
+ expect(Watir::Window.new(browser, title: browser.title)).to be_current
143
196
  end
144
197
 
145
198
  it 'returns false if it is not the current window' do
146
- expect(browser.window(title: 'closeable window')).to_not be_current
199
+ expect(Watir::Window.new(browser, title: 'closeable window')).to_not be_current
147
200
  end
148
201
  end
149
202
 
150
203
  describe '#title' do
151
204
  it 'returns the title of the window' do
152
205
  titles = browser.windows.map(&:title)
153
- expect(titles.size).to eq 2
154
206
 
155
- expect(titles.sort).to eq ['window switching', 'closeable window'].sort
156
- end
157
-
158
- it 'does not change the current window' do
159
- expect(browser.title).to eq 'window switching'
160
- expect(browser.windows.find { |w| w.title == 'closeable window' }).to_not be_nil
161
- expect(browser.title).to eq 'window switching'
207
+ expect(titles.size).to eq 2
208
+ expect(titles).to include 'window switching', 'closeable window'
162
209
  end
163
210
  end
164
211
 
165
212
  describe '#url' do
166
213
  it 'returns the url of the window' do
167
- expect(browser.windows.select { |w| w.url =~ /window_switching\.html/ }.size).to eq 1
168
- expect(browser.windows.select { |w| w.url =~ /closeable\.html$/ }.size).to eq 1
169
- end
214
+ urls = browser.windows.map(&:url)
170
215
 
171
- it 'does not change the current window' do
172
- expect(browser.url).to match(/window_switching\.html/)
173
- expect(browser.windows.find { |w| w.url =~ /closeable\.html/ }).to_not be_nil
174
- expect(browser.url).to match(/window_switching/)
216
+ expect(urls.size).to eq 2
217
+ expect(urls).to(include(/window_switching\.html/, /closeable\.html$/))
175
218
  end
176
219
  end
177
220
 
178
221
  describe '#eql?' do
179
222
  it 'knows when two windows are equal' do
180
- expect(browser.window).to eq browser.window(index: 0)
223
+ win1 = Watir::Window.new browser, {}
224
+ win2 = Watir::Window.new browser, title: 'window switching'
225
+
226
+ expect(win1).to eq win2
181
227
  end
182
228
 
183
229
  it 'knows when two windows are not equal' do
184
- win1 = browser.window(index: 0)
185
- win2 = browser.window(index: 1)
230
+ win1 = Watir::Window.new browser, title: 'closeable window'
231
+ win2 = Watir::Window.new browser, title: 'window switching'
186
232
 
187
233
  expect(win1).to_not eq win2
188
234
  end
189
235
  end
190
236
 
191
- not_compliant_on :relaxed_locate do
192
- describe '#wait_until &:present?' do
193
- it 'times out waiting for a non-present window' do
194
- expect {
195
- browser.window(title: 'noop').wait_until(timeout: 0.5, &:present?)
196
- }.to raise_error(Watir::Wait::TimeoutError)
197
- end
237
+ describe '#handle' do
238
+ it 'does not find if not matching' do
239
+ expect(browser.window(title: 'noop').handle).to be_nil
198
240
  end
199
- end
200
- end
201
241
 
202
- context 'with a closed window' do
203
- before do
204
- browser.goto WatirSpec.url_for('window_switching.html')
205
- browser.a(id: 'open').click
206
- Watir::Wait.until { browser.windows.size == 2 }
207
- end
242
+ it 'finds window by :url' do
243
+ expect(browser.window(url: /closeable\.html/).handle).to_not be_nil
244
+ end
208
245
 
209
- after do
210
- browser.original_window.use
211
- browser.windows.reject(&:current?).each(&:close)
246
+ it 'finds window by :title' do
247
+ expect(browser.window(title: 'closeable window').handle).to_not be_nil
248
+ end
249
+
250
+ it 'finds window by :index' do
251
+ expect {
252
+ expect(browser.window(index: 1).handle).to_not be_nil
253
+ }.to have_deprecated_window_index
254
+ end
255
+
256
+ it 'finds window by :element' do
257
+ expect(browser.window(element: browser.a(id: 'close')).handle).to_not be_nil
258
+ end
259
+
260
+ it 'finds window by multiple values' do
261
+ expect(browser.window(url: /closeable\.html/, title: 'closeable window').handle).to_not be_nil
262
+ end
212
263
  end
264
+ end
213
265
 
214
- bug 'https://bugzilla.mozilla.org/show_bug.cgi?id=1223277', :firefox do
215
- not_compliant_on :headless do
216
- describe '#exists?' do
217
- it 'returns false if previously referenced window is closed' do
218
- window = browser.window(title: 'closeable window')
219
- window.use
220
- browser.a(id: 'close').click
221
- Watir::Wait.until { browser.windows.size == 1 }
222
- expect(window).to_not be_present
223
- end
266
+ bug 'Clicking an Element that Closes a Window is returning NoMatchingWindowFoundException', :safari do
267
+ context 'with a closed window' do
268
+ before do
269
+ @original_window = browser.window
270
+ browser.goto WatirSpec.url_for('window_switching.html')
271
+ browser.a(id: 'open').click
272
+ browser.windows.wait_until(size: 2)
273
+ @handles = browser.driver.window_handles
274
+ @closed_window = browser.window(title: 'closeable window').use
275
+ browser.a(id: 'close').click
276
+ browser.windows.wait_until(size: 1)
277
+ end
224
278
 
225
- it 'returns false if closed window is referenced' do
226
- browser.window(title: 'closeable window').use
227
- browser.a(id: 'close').click
228
- Watir::Wait.until { browser.windows.size == 1 }
229
- expect(browser.window).to_not exist
230
- end
279
+ after do
280
+ browser.original_window.use
281
+ browser.windows.reject(&:current?).each(&:close)
282
+ end
231
283
 
232
- it 'returns false if window closes during iteration' do
233
- browser.window(title: 'closeable window').use
234
- original_handle = browser.original_window.instance_variable_get('@handle')
235
- handles = browser.windows.map { |w| w.instance_variable_get('@handle') }
284
+ describe '#exists?' do
285
+ it 'returns false if previously referenced window is closed' do
286
+ expect(@closed_window).to_not be_present
287
+ end
236
288
 
237
- browser.a(id: 'close').click
238
- Watir::Wait.until { browser.windows.size == 1 }
239
- allow(browser.wd).to receive(:window_handles).and_return(handles, [original_handle])
240
- expect(browser.window(title: 'closeable window')).to_not exist
241
- end
289
+ it 'returns false if closed window is referenced' do
290
+ expect(browser.window).to_not exist
242
291
  end
243
292
  end
244
- end
245
293
 
246
- describe '#current?' do
247
- it 'returns false if the referenced window is closed' do
248
- original_window = browser.window
249
- browser.window(title: 'closeable window').use
250
- original_window.close
251
- expect(original_window).to_not be_current
294
+ describe '#current?' do
295
+ it 'returns false if the referenced window is closed' do
296
+ expect(@original_window).to_not be_current
297
+ end
252
298
  end
253
- end
254
299
 
255
- not_compliant_on :safari, :headless do
256
300
  describe '#eql?' do
257
301
  it 'should return false when checking equivalence to a closed window' do
258
- original_window = browser.window
259
- other_window = browser.window(index: 1)
260
- other_window.use
261
- original_window.close
262
- expect(other_window == original_window).to be false
302
+ expect(browser.window).not_to eq @closed_widow
263
303
  end
264
304
  end
265
- end
266
305
 
267
- not_compliant_on :headless do
268
306
  describe '#use' do
269
307
  it 'raises NoMatchingWindowFoundException error when attempting to use a referenced window that is closed' do
270
- original_window = browser.window
271
- browser.window(index: 1).use
272
- original_window.close
273
- expect { original_window.use }.to raise_no_matching_window_exception
308
+ expect { @closed_window.use }.to raise_no_matching_window_exception
274
309
  end
275
310
 
276
- bug 'https://bugzilla.mozilla.org/show_bug.cgi?id=1223277', :firefox do
311
+ bug 'Clicking an Element that Closes a Window is returning NoMatchingWindowFoundException', :safari do
277
312
  it 'raises NoMatchingWindowFoundException error when attempting to use the current window if it is closed' do
278
- browser.window(title: 'closeable window').use
279
- browser.a(id: 'close').click
280
- Watir::Wait.until { browser.windows.size == 1 }
281
313
  expect { browser.window.use }.to raise_no_matching_window_exception
282
314
  end
283
315
  end
284
316
  end
285
- end
286
317
 
287
- it 'raises an exception when using an element on a closed window' do
288
- window = browser.window(title: 'closeable window')
289
- window.use
290
- browser.a(id: 'close').click
291
- msg = 'browser window was closed'
292
- expect { browser.a.text }.to raise_exception(Watir::Exception::NoMatchingWindowFoundException, msg)
318
+ bug 'https://github.com/mozilla/geckodriver/issues/1847', :firefox do
319
+ it 'raises an exception when using an element on a closed window' do
320
+ msg = 'browser window was closed'
321
+ expect { browser.a.text }.to raise_exception(Watir::Exception::NoMatchingWindowFoundException, msg)
322
+ end
323
+ end
324
+
325
+ it 'raises an exception when locating a closed window' do
326
+ expect { browser.window(title: 'closeable window').use }.to raise_no_matching_window_exception
327
+ end
293
328
  end
329
+ end
294
330
 
295
- it 'raises an exception when locating a closed window' do
296
- browser.window(title: 'closeable window').use
297
- handles = browser.windows.map(&:handle)
298
- browser.a(id: 'close').click
299
- allow(browser.wd).to receive(:window_handles).and_return(handles, [browser.original_window.handle])
300
- expect { browser.window(title: 'closeable window').use }.to raise_no_matching_window_exception
331
+ context 'with a closed window on a delay' do
332
+ after do
333
+ browser.original_window.use
334
+ browser.windows.reject(&:current?).each(&:close)
301
335
  end
302
336
 
303
337
  it 'raises an exception when locating a window closed during lookup' do
338
+ browser.goto WatirSpec.url_for('window_switching.html')
339
+ browser.a(id: 'open').click
340
+ browser.windows.wait_until(size: 2)
304
341
  browser.window(title: 'closeable window').use
305
342
  browser.a(id: 'close-delay').click
306
343
 
@@ -327,95 +364,109 @@ describe 'Window' do
327
364
  end
328
365
  end
329
366
 
330
- bug 'https://bugzilla.mozilla.org/show_bug.cgi?id=1223277', :firefox do
331
- not_compliant_on :headless do
332
- context 'with current window closed' do
333
- before do
334
- browser.goto WatirSpec.url_for('window_switching.html')
335
- browser.a(id: 'open').click
336
- Watir::Wait.until { browser.windows.size == 2 }
337
- browser.window(title: 'closeable window').use
338
- browser.a(id: 'close').click
339
- Watir::Wait.until { browser.windows.size == 1 }
367
+ bug 'Clicking an Element that Closes a Window is returning NoMatchingWindowFoundException', :safari do
368
+ context 'with current window closed' do
369
+ before do
370
+ browser.goto WatirSpec.url_for('window_switching.html')
371
+ browser.a(id: 'open').click
372
+ browser.windows.wait_until(size: 2)
373
+ browser.window(title: 'closeable window').use
374
+ browser.a(id: 'close').click
375
+ browser.windows.wait_until(size: 1)
376
+ end
377
+
378
+ after do
379
+ browser.original_window.use
380
+ browser.windows.reject(&:current?).each(&:close)
381
+ end
382
+
383
+ describe '#present?' do
384
+ it 'should find window by index' do
385
+ expect {
386
+ expect(browser.window(index: 0)).to be_present
387
+ }.to have_deprecated_window_index
340
388
  end
341
389
 
342
- after do
343
- browser.window(index: 0).use
344
- browser.windows[1..-1].each(&:close)
390
+ it 'should find window by url' do
391
+ expect(browser.window(url: /window_switching\.html/)).to be_present
345
392
  end
346
393
 
347
- describe '#present?' do
348
- it 'should find window by index' do
349
- expect(browser.window(index: 0)).to be_present
350
- end
394
+ it 'should find window by title' do
395
+ expect(browser.window(title: 'window switching')).to be_present
396
+ end
351
397
 
352
- it 'should find window by url' do
353
- expect(browser.window(url: /window_switching\.html/)).to be_present
354
- end
398
+ it 'should find window by element' do
399
+ expect(browser.window(element: browser.link(id: 'open'))).to be_present
400
+ end
401
+ end
355
402
 
356
- it 'should find window by title' do
357
- expect(browser.window(title: 'window switching')).to be_present
403
+ describe '#use' do
404
+ context 'switching windows without blocks' do
405
+ it 'by index' do
406
+ expect { browser.window(index: 0).use }.to have_deprecated_window_index
407
+ expect(browser.title).to be == 'window switching'
358
408
  end
359
- end
360
409
 
361
- describe '#use' do
362
- context 'switching windows without blocks' do
363
- it 'by index' do
364
- browser.window(index: 0).use
365
- expect(browser.title).to be == 'window switching'
366
- end
410
+ it 'by url' do
411
+ browser.window(url: /window_switching\.html/).use
412
+ expect(browser.title).to be == 'window switching'
413
+ end
367
414
 
368
- it 'by url' do
369
- browser.window(url: /window_switching\.html/).use
370
- expect(browser.title).to be == 'window switching'
371
- end
415
+ it 'by title' do
416
+ browser.window(title: 'window switching').use
417
+ expect(browser.url).to match(/window_switching\.html/)
418
+ end
372
419
 
373
- it 'by title' do
374
- browser.window(title: 'window switching').use
375
- expect(browser.url).to match(/window_switching\.html/)
376
- end
420
+ it 'by element' do
421
+ browser.window(element: browser.link(id: 'open')).use
422
+ expect(browser.url).to match(/window_switching\.html/)
377
423
  end
424
+ end
378
425
 
379
- context 'Switching windows with blocks' do
380
- it 'by index' do
426
+ context 'Switching windows with blocks' do
427
+ it 'by index' do
428
+ expect {
381
429
  browser.window(index: 0).use { expect(browser.title).to be == 'window switching' }
382
- end
430
+ }.to have_deprecated_window_index
431
+ end
383
432
 
384
- it 'by url' do
385
- browser.window(url: /window_switching\.html/).use { expect(browser.title).to be == 'window switching' }
386
- end
433
+ it 'by url' do
434
+ browser.window(url: /window_switching\.html/).use { expect(browser.title).to be == 'window switching' }
435
+ end
387
436
 
388
- it 'by title' do
389
- browser.window(title: 'window switching').use { expect(browser.url).to match(/window_switching\.html/) }
390
- end
437
+ it 'by title' do
438
+ browser.window(title: 'window switching').use { expect(browser.url).to match(/window_switching\.html/) }
439
+ end
440
+
441
+ it 'by element' do
442
+ element = browser.link(id: 'open')
443
+ browser.window(element: element).use { expect(browser.url).to match(/window_switching\.html/) }
391
444
  end
392
445
  end
393
446
  end
394
447
  end
395
448
  end
396
449
 
397
- context 'manipulating size and position' do
398
- before do
399
- browser.goto WatirSpec.url_for('window_switching.html')
400
- end
450
+ not_compliant_on :headless do
451
+ context 'manipulating size and position' do
452
+ before do
453
+ browser.goto WatirSpec.url_for('window_switching.html')
454
+ end
401
455
 
402
- not_compliant_on :headless do
403
456
  it 'should get the size of the current window' do
404
457
  size = browser.window.size
405
458
 
406
459
  expect(size.width).to eq browser.execute_script('return window.outerWidth;')
407
460
  expect(size.height).to eq browser.execute_script('return window.outerHeight;')
408
461
  end
409
- end
410
462
 
411
- it 'should get the position of the current window' do
412
- pos = browser.window.position
463
+ it 'should get the position of the current window' do
464
+ pos = browser.window.position
413
465
 
414
- expect(pos.x).to eq browser.execute_script('return window.screenX;')
415
- expect(pos.y).to eq browser.execute_script('return window.screenY;')
416
- end
466
+ expect(pos.x).to eq browser.execute_script('return window.screenX;')
467
+ expect(pos.y).to eq browser.execute_script('return window.screenY;')
468
+ end
417
469
 
418
- not_compliant_on :headless do
419
470
  it 'should resize the window' do
420
471
  initial_size = browser.window.size
421
472
  browser.window.resize_to(
@@ -428,9 +479,7 @@ describe 'Window' do
428
479
  expect(new_size.width).to eq initial_size.width - 20
429
480
  expect(new_size.height).to eq initial_size.height - 20
430
481
  end
431
- end
432
482
 
433
- not_compliant_on :headless, %i[remote firefox] do
434
483
  it 'should move the window' do
435
484
  initial_pos = browser.window.position
436
485
 
@@ -443,25 +492,97 @@ describe 'Window' do
443
492
  expect(new_pos.x).to eq initial_pos.x + 2
444
493
  expect(new_pos.y).to eq initial_pos.y + 2
445
494
  end
446
- end
447
495
 
448
- not_compliant_on :headless do
449
496
  compliant_on :window_manager do
450
497
  it 'should maximize the window' do
451
498
  initial_size = browser.window.size
452
499
  browser.window.resize_to(
453
- initial_size.width,
454
- initial_size.height - 20
500
+ initial_size.width - 40,
501
+ initial_size.height - 40
455
502
  )
503
+ browser.wait_until { |b| b.window.size != initial_size }
504
+ new_size = browser.window.size
456
505
 
457
506
  browser.window.maximize
458
- browser.wait_until { browser.window.size != initial_size }
507
+ browser.wait_until { |b| b.window.size != new_size }
459
508
 
460
- new_size = browser.window.size
461
- expect(new_size.width).to be >= initial_size.width
462
- expect(new_size.height).to be > (initial_size.height - 20)
509
+ final_size = browser.window.size
510
+ expect(final_size.width).to be >= new_size.width
511
+ expect(final_size.height).to be > (new_size.height)
463
512
  end
464
513
  end
465
514
  end
466
515
  end
467
516
  end
517
+
518
+ describe Watir::WindowCollection do
519
+ before do
520
+ browser.goto WatirSpec.url_for('window_switching.html')
521
+ browser.a(id: 'open').click
522
+ browser.windows.wait_until(size: 2)
523
+ end
524
+
525
+ after do
526
+ browser.original_window.use
527
+ browser.windows.reject(&:current?).each(&:close)
528
+ end
529
+
530
+ describe '#new' do
531
+ it 'returns all windows by default' do
532
+ windows = Watir::WindowCollection.new(browser)
533
+
534
+ expect(windows.size).to eq 2
535
+ end
536
+
537
+ it 'filters available windows by url' do
538
+ windows = Watir::WindowCollection.new(browser, url: /closeable\.html/)
539
+
540
+ expect(windows.size).to eq 1
541
+ end
542
+
543
+ it 'filters available windows by title' do
544
+ windows = Watir::WindowCollection.new(browser, title: /closeable/)
545
+
546
+ expect(windows.size).to eq 1
547
+ end
548
+
549
+ it 'filters available windows by element' do
550
+ windows = Watir::WindowCollection.new(browser, element: browser.element(id: 'close'))
551
+
552
+ expect(windows.size).to eq 1
553
+ end
554
+
555
+ it 'raises ArgumentError if unrecognized locator' do
556
+ expect {
557
+ Watir::WindowCollection.new(browser, foo: /closeable/)
558
+ }.to raise_error(ArgumentError)
559
+ end
560
+ end
561
+
562
+ describe '#size' do
563
+ it 'counts the number of matching windows' do
564
+ expect(Watir::WindowCollection.new(browser).size).to eq 2
565
+ end
566
+ end
567
+
568
+ describe '#[]' do
569
+ it 'returns window instance at provided index' do
570
+ windows = Watir::WindowCollection.new(browser)
571
+
572
+ expect {
573
+ expect(windows).to all(be_an(Watir::Window))
574
+ expect(windows.first).to_not eq windows.last
575
+ }.to have_deprecated_window_index
576
+ end
577
+ end
578
+
579
+ describe '#eq?' do
580
+ it 'compares the equivalence of window handles' do
581
+ windows1 = Watir::WindowCollection.new(browser, title: //)
582
+ windows2 = Watir::WindowCollection.new(browser, url: //)
583
+
584
+ expect(windows1).to eq windows2
585
+ expect(windows1.to_a.map(&:handle)).to eq windows2.to_a.map(&:handle)
586
+ end
587
+ end
588
+ end