watir 7.2.0 → 7.3.0

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 (149) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/chrome.yml +9 -1
  3. data/.github/workflows/edge.yml +10 -2
  4. data/.github/workflows/firefox.yml +10 -2
  5. data/.github/workflows/ie.yml +1 -1
  6. data/.github/workflows/safari.yml +1 -1
  7. data/.github/workflows/unit.yml +3 -3
  8. data/.rubocop.yml +36 -14
  9. data/.rubocop_todo.yml +8 -1
  10. data/CHANGES.md +17 -1
  11. data/LICENSE +2 -2
  12. data/lib/watir/capabilities.rb +2 -12
  13. data/lib/watir/cookies.rb +7 -2
  14. data/lib/watir/elements/date_field.rb +2 -2
  15. data/lib/watir/elements/date_time_field.rb +2 -2
  16. data/lib/watir/elements/select.rb +3 -3
  17. data/lib/watir/locators/anchor/selector_builder.rb +3 -0
  18. data/lib/watir/locators/element/matcher.rb +2 -1
  19. data/lib/watir/locators/element/selector_builder/regexp_disassembler.rb +2 -1
  20. data/lib/watir/locators/element/selector_builder.rb +1 -1
  21. data/lib/watir/locators/text_field/matcher.rb +1 -5
  22. data/lib/watir/version.rb +1 -1
  23. data/lib/watir.rb +1 -0
  24. data/lib/watirspec/implementation.rb +1 -1
  25. data/lib/watirspec.rb +1 -1
  26. data/spec/locator_spec_helper.rb +3 -15
  27. data/spec/unit/capabilities_spec.rb +552 -561
  28. data/spec/unit/element_locator_spec.rb +89 -78
  29. data/spec/unit/match_elements/button_spec.rb +69 -62
  30. data/spec/unit/match_elements/element_spec.rb +303 -309
  31. data/spec/unit/match_elements/text_field_spec.rb +76 -73
  32. data/spec/unit/selector_builder/anchor_spec.rb +39 -33
  33. data/spec/unit/selector_builder/button_spec.rb +209 -202
  34. data/spec/unit/selector_builder/cell_spec.rb +48 -42
  35. data/spec/unit/selector_builder/element_spec.rb +632 -627
  36. data/spec/unit/selector_builder/row_spec.rb +119 -113
  37. data/spec/unit/selector_builder/text_field_spec.rb +195 -188
  38. data/spec/unit/selector_builder/textarea_spec.rb +22 -14
  39. data/spec/unit/wait_spec.rb +85 -81
  40. data/spec/watirspec/adjacent_spec.rb +249 -247
  41. data/spec/watirspec/after_hooks_spec.rb +161 -159
  42. data/spec/watirspec/alert_spec.rb +61 -58
  43. data/spec/watirspec/browser_spec.rb +411 -409
  44. data/spec/watirspec/capabilities_spec.rb +99 -112
  45. data/spec/watirspec/cookies_spec.rb +144 -115
  46. data/spec/watirspec/drag_and_drop_spec.rb +26 -24
  47. data/spec/watirspec/element_hidden_spec.rb +66 -60
  48. data/spec/watirspec/elements/area_spec.rb +49 -47
  49. data/spec/watirspec/elements/areas_spec.rb +27 -25
  50. data/spec/watirspec/elements/button_spec.rb +253 -251
  51. data/spec/watirspec/elements/buttons_spec.rb +36 -34
  52. data/spec/watirspec/elements/checkbox_spec.rb +48 -36
  53. data/spec/watirspec/elements/checkboxes_spec.rb +29 -27
  54. data/spec/watirspec/elements/collections_spec.rb +126 -119
  55. data/spec/watirspec/elements/date_field_spec.rb +202 -183
  56. data/spec/watirspec/elements/date_fields_spec.rb +29 -27
  57. data/spec/watirspec/elements/date_time_field_spec.rb +216 -195
  58. data/spec/watirspec/elements/date_time_fields_spec.rb +30 -28
  59. data/spec/watirspec/elements/dd_spec.rb +87 -85
  60. data/spec/watirspec/elements/dds_spec.rb +27 -25
  61. data/spec/watirspec/elements/del_spec.rb +106 -104
  62. data/spec/watirspec/elements/dels_spec.rb +26 -24
  63. data/spec/watirspec/elements/div_spec.rb +225 -221
  64. data/spec/watirspec/elements/divs_spec.rb +37 -35
  65. data/spec/watirspec/elements/dl_spec.rb +110 -108
  66. data/spec/watirspec/elements/dls_spec.rb +28 -26
  67. data/spec/watirspec/elements/dt_spec.rb +86 -84
  68. data/spec/watirspec/elements/dts_spec.rb +27 -25
  69. data/spec/watirspec/elements/element_spec.rb +794 -775
  70. data/spec/watirspec/elements/elements_spec.rb +40 -38
  71. data/spec/watirspec/elements/em_spec.rb +62 -60
  72. data/spec/watirspec/elements/ems_spec.rb +28 -26
  73. data/spec/watirspec/elements/filefield_spec.rb +116 -114
  74. data/spec/watirspec/elements/filefields_spec.rb +28 -26
  75. data/spec/watirspec/elements/font_spec.rb +20 -18
  76. data/spec/watirspec/elements/form_spec.rb +51 -49
  77. data/spec/watirspec/elements/forms_spec.rb +29 -27
  78. data/spec/watirspec/elements/frame_spec.rb +89 -87
  79. data/spec/watirspec/elements/frames_spec.rb +27 -25
  80. data/spec/watirspec/elements/hidden_spec.rb +81 -79
  81. data/spec/watirspec/elements/hiddens_spec.rb +28 -26
  82. data/spec/watirspec/elements/hn_spec.rb +59 -57
  83. data/spec/watirspec/elements/hns_spec.rb +26 -24
  84. data/spec/watirspec/elements/iframe_spec.rb +195 -191
  85. data/spec/watirspec/elements/iframes_spec.rb +31 -29
  86. data/spec/watirspec/elements/image_spec.rb +148 -146
  87. data/spec/watirspec/elements/images_spec.rb +26 -24
  88. data/spec/watirspec/elements/input_spec.rb +9 -7
  89. data/spec/watirspec/elements/ins_spec.rb +106 -104
  90. data/spec/watirspec/elements/inses_spec.rb +26 -24
  91. data/spec/watirspec/elements/label_spec.rb +56 -54
  92. data/spec/watirspec/elements/labels_spec.rb +26 -24
  93. data/spec/watirspec/elements/li_spec.rb +76 -74
  94. data/spec/watirspec/elements/link_spec.rb +173 -177
  95. data/spec/watirspec/elements/links_spec.rb +45 -43
  96. data/spec/watirspec/elements/lis_spec.rb +27 -25
  97. data/spec/watirspec/elements/list_spec.rb +44 -42
  98. data/spec/watirspec/elements/map_spec.rb +57 -55
  99. data/spec/watirspec/elements/maps_spec.rb +27 -25
  100. data/spec/watirspec/elements/meta_spec.rb +16 -14
  101. data/spec/watirspec/elements/metas_spec.rb +26 -24
  102. data/spec/watirspec/elements/ol_spec.rb +56 -65
  103. data/spec/watirspec/elements/ols_spec.rb +26 -24
  104. data/spec/watirspec/elements/option_spec.rb +91 -89
  105. data/spec/watirspec/elements/p_spec.rb +81 -79
  106. data/spec/watirspec/elements/pre_spec.rb +77 -75
  107. data/spec/watirspec/elements/pres_spec.rb +26 -24
  108. data/spec/watirspec/elements/ps_spec.rb +26 -24
  109. data/spec/watirspec/elements/radio_spec.rb +251 -249
  110. data/spec/watirspec/elements/radios_spec.rb +28 -26
  111. data/spec/watirspec/elements/select_list_spec.rb +537 -526
  112. data/spec/watirspec/elements/select_lists_spec.rb +32 -30
  113. data/spec/watirspec/elements/span_spec.rb +112 -110
  114. data/spec/watirspec/elements/spans_spec.rb +26 -24
  115. data/spec/watirspec/elements/strong_spec.rb +58 -58
  116. data/spec/watirspec/elements/strongs_spec.rb +28 -26
  117. data/spec/watirspec/elements/table_spec.rb +192 -139
  118. data/spec/watirspec/elements/tables_spec.rb +28 -26
  119. data/spec/watirspec/elements/tbody_spec.rb +74 -72
  120. data/spec/watirspec/elements/tbodys_spec.rb +40 -38
  121. data/spec/watirspec/elements/td_spec.rb +66 -64
  122. data/spec/watirspec/elements/tds_spec.rb +41 -39
  123. data/spec/watirspec/elements/text_field_spec.rb +206 -204
  124. data/spec/watirspec/elements/text_fields_spec.rb +30 -28
  125. data/spec/watirspec/elements/textarea_spec.rb +20 -18
  126. data/spec/watirspec/elements/textareas_spec.rb +18 -16
  127. data/spec/watirspec/elements/tfoot_spec.rb +65 -63
  128. data/spec/watirspec/elements/tfoots_spec.rb +42 -40
  129. data/spec/watirspec/elements/thead_spec.rb +65 -63
  130. data/spec/watirspec/elements/theads_spec.rb +42 -40
  131. data/spec/watirspec/elements/tr_spec.rb +48 -46
  132. data/spec/watirspec/elements/trs_spec.rb +42 -40
  133. data/spec/watirspec/elements/ul_spec.rb +56 -54
  134. data/spec/watirspec/elements/uls_spec.rb +26 -24
  135. data/spec/watirspec/radio_set_spec.rb +269 -267
  136. data/spec/watirspec/screenshot_spec.rb +20 -18
  137. data/spec/watirspec/scroll_spec.rb +152 -148
  138. data/spec/watirspec/shadow_root_spec.rb +88 -83
  139. data/spec/watirspec/support/rspec_matchers.rb +34 -25
  140. data/spec/watirspec/user_editable_spec.rb +200 -198
  141. data/spec/watirspec/wait_spec.rb +289 -295
  142. data/spec/watirspec/window_switching_spec.rb +423 -434
  143. data/spec/watirspec_helper.rb +1 -23
  144. data/watir.gemspec +6 -5
  145. metadata +47 -37
  146. data/spec/watirspec/attributes_spec.rb +0 -18
  147. data/spec/watirspec/elements/table_nesting_spec.rb +0 -51
  148. data/spec/watirspec/special_chars_spec.rb +0 -23
  149. data/support/travis.sh +0 -15
@@ -2,590 +2,579 @@
2
2
 
3
3
  require 'watirspec_helper'
4
4
 
5
- describe Watir::Browser do
6
- before do
7
- browser.goto WatirSpec.url_for('window_switching.html')
8
- browser.a(id: 'open').click
9
- browser.windows.wait_until(size: 2)
10
- end
11
-
12
- after do
13
- browser.windows.restore!
14
- end
15
-
16
- describe '#windows' do
17
- it 'returns a WindowCollection' do
18
- expect(browser.windows).to be_a(Watir::WindowCollection)
5
+ module Watir
6
+ describe Browser, exclude: {browser: :ie, reason: 'Cannot call #restore!'} do
7
+ before do
8
+ browser.goto WatirSpec.url_for('window_switching.html')
9
+ browser.a(id: 'open').click
10
+ browser.windows.wait_until(size: 2)
19
11
  end
20
12
 
21
- it 'stores Window instances' do
22
- expect(browser.windows(title: 'closeable window')).to all(be_a(Watir::Window))
13
+ after do
14
+ browser.windows.restore!
23
15
  end
24
16
 
25
- it 'filters windows to match the given selector' do
26
- expect(browser.windows(title: 'closeable window').size).to eq 1
27
- end
17
+ describe '#windows' do
18
+ it 'returns a WindowCollection' do
19
+ expect(browser.windows).to be_a(WindowCollection)
20
+ end
28
21
 
29
- it 'raises ArgumentError if the selector is invalid' do
30
- expect { browser.windows(name: 'foo') }.to raise_error(ArgumentError)
31
- end
22
+ it 'stores Window instances' do
23
+ expect(browser.windows(title: 'closeable window')).to all(be_a(Window))
24
+ end
32
25
 
33
- it 'returns an empty array if no window matches the selector' do
34
- expect(browser.windows(title: 'noop')).to be_empty
35
- end
36
- end
26
+ it 'filters windows to match the given selector' do
27
+ expect(browser.windows(title: 'closeable window').size).to eq 1
28
+ end
37
29
 
38
- describe '#window' do
39
- it 'finds window by :url' do
40
- expect(browser.window(url: /closeable\.html/).use).to be_a(Watir::Window)
41
- end
30
+ it 'raises ArgumentError if the selector is invalid' do
31
+ expect { browser.windows(name: 'foo') }.to raise_error(ArgumentError)
32
+ end
42
33
 
43
- it 'finds window by :title' do
44
- expect(browser.window(title: 'closeable window').use).to be_a(Watir::Window)
34
+ it 'returns an empty array if no window matches the selector' do
35
+ expect(browser.windows(title: 'noop')).to be_empty
36
+ end
45
37
  end
46
38
 
47
- it 'finds window by :element' do
48
- expect(browser.window(element: browser.a(id: 'close')).use).to be_a(Watir::Window)
49
- end
39
+ describe '#window' do
40
+ it 'finds window by :url' do
41
+ expect(browser.window(url: /closeable\.html/).use).to be_a(Window)
42
+ end
50
43
 
51
- it 'finds window by multiple values' do
52
- expect(browser.window(title: 'closeable window', url: /closeable\.html/).use).to be_a(Watir::Window)
53
- end
44
+ it 'finds window by :title' do
45
+ expect(browser.window(title: 'closeable window').use).to be_a(Window)
46
+ end
54
47
 
55
- it 'should not find incorrect handle' do
56
- expect(browser.window(handle: 'bar')).to_not be_present
57
- end
48
+ it 'finds window by :element' do
49
+ expect(browser.window(element: browser.a(id: 'close')).use).to be_a(Window)
50
+ end
58
51
 
59
- it 'returns the current window if no argument is given' do
60
- expect(browser.window.url).to match(/window_switching\.html/)
61
- end
52
+ it 'finds window by multiple values' do
53
+ expect(browser.window(title: 'closeable window', url: /closeable\.html/).use).to be_a(Window)
54
+ end
62
55
 
63
- it 'stores the reference to a window when no argument is given' do
64
- original_window = browser.window
65
- browser.window(title: 'closeable window').use
66
- expect(original_window.url).to match(/window_switching\.html/)
67
- end
56
+ it 'does not find incorrect handle' do
57
+ expect(browser.window(handle: 'bar')).not_to be_present
58
+ end
68
59
 
69
- it 'it executes the given block in the window',
70
- except: {browser: :safari,
71
- reason: 'Clicking an Element that Closes a Window is returning NoMatchingWindowFoundException'} do
72
- browser.window(title: 'closeable window') do
73
- link = browser.a(id: 'close')
74
- expect(link).to exist
75
- link.click
60
+ it 'returns the current window if no argument is given' do
61
+ expect(browser.window.url).to match(/window_switching\.html/)
76
62
  end
77
63
 
78
- expect { browser.windows.wait_until(size: 1) }.to_not raise_error
79
- end
64
+ it 'stores the reference to a window when no argument is given' do
65
+ original_window = browser.window
66
+ browser.window(title: 'closeable window').use
67
+ expect(original_window.url).to match(/window_switching\.html/)
68
+ end
80
69
 
81
- it 'raises ArgumentError if the selector is invalid' do
82
- expect { browser.window(name: 'foo') }.to raise_error(ArgumentError)
83
- end
70
+ it 'executes the given block in the window',
71
+ except: {browser: :safari,
72
+ reason: 'Clicking an Element that Closes a Window is returning NoMatchingWindowFoundException'} do
73
+ browser.window(title: 'closeable window') do
74
+ link = browser.a(id: 'close')
75
+ expect(link).to exist
76
+ link.click
77
+ end
84
78
 
85
- it 'raises a NoMatchingWindowFoundException error if no window matches the selector' do
86
- expect { browser.window(title: 'noop').use }.to raise_no_matching_window_exception
87
- end
79
+ expect { browser.windows.wait_until(size: 1) }.not_to raise_error
80
+ end
88
81
 
89
- it 'raises NoMatchingWindowFoundException error when attempting to use a window with an incorrect handle' do
90
- expect { browser.window(handle: 'bar').use }.to raise_no_matching_window_exception
91
- end
92
- end
82
+ it 'raises ArgumentError if the selector is invalid' do
83
+ expect { browser.window(name: 'foo') }.to raise_error(ArgumentError)
84
+ end
93
85
 
94
- describe '#switch_window' do
95
- it 'stays on the same window when matches single window' do
96
- browser.switch_window
97
- browser.window.close
98
- browser.original_window.use
86
+ it 'raises a NoMatchingWindowFoundException error if no window matches the selector' do
87
+ expect { browser.window(title: 'noop').use }.to raise_no_matching_window_exception
88
+ end
99
89
 
100
- title = browser.title
101
- expect { browser.window(title: title).use }.not_to raise_exception
90
+ it 'raises NoMatchingWindowFoundException error when attempting to use a window with an incorrect handle' do
91
+ expect { browser.window(handle: 'bar').use }.to raise_no_matching_window_exception
92
+ end
102
93
  end
103
94
 
104
- it 'switches to second window' do
105
- original_window = browser.window
106
- browser.switch_window
107
- new_window = browser.window
95
+ describe '#switch_window' do
96
+ it 'stays on the same window when matches single window' do
97
+ browser.switch_window
98
+ browser.window.close
99
+ browser.original_window.use
108
100
 
109
- expect(original_window).to_not eq new_window
110
- expect(browser.windows).to include(original_window, new_window)
111
- end
101
+ title = browser.title
102
+ expect { browser.window(title: title).use }.not_to raise_exception
103
+ end
112
104
 
113
- it 'returns an instance of Window' do
114
- expect(browser.switch_window).to be_a(Watir::Window)
115
- end
105
+ it 'switches to second window' do
106
+ original_window = browser.window
107
+ browser.switch_window
108
+ new_window = browser.window
116
109
 
117
- it 'times out if there is no second window' do
118
- browser.windows.restore!
119
- message = /waiting for true condition on (.*) title="window switching">$/
120
- expect { browser.switch_window }.to raise_timeout_exception(message)
121
- end
110
+ expect(original_window).not_to eq new_window
111
+ expect(browser.windows).to include(original_window, new_window)
112
+ end
122
113
 
123
- it 'provides previous window value to #original_window' do
124
- browser.switch_window
125
- expect(browser.original_window).to_not be_nil
126
- end
114
+ it 'returns an instance of Window' do
115
+ expect(browser.switch_window).to be_a(Window)
116
+ end
127
117
 
128
- it 'waits for second window', except: {browser: :ie} do
129
- browser.windows.restore!
130
- expect {
131
- browser.a(id: 'delayed').click
132
- browser.switch_window
133
- }.to execute_when_satisfied(min: 1)
134
- end
135
- end
136
- end
118
+ it 'times out if there is no second window' do
119
+ browser.windows.restore!
120
+ message = /waiting for true condition on (.*) title="window switching">$/
121
+ expect { browser.switch_window }.to raise_timeout_exception(message)
122
+ end
137
123
 
138
- describe Watir::Window do
139
- after do
140
- browser.windows.restore!
141
- end
124
+ it 'provides previous window value to #original_window' do
125
+ browser.switch_window
126
+ expect(browser.original_window).not_to be_nil
127
+ end
142
128
 
143
- context 'multiple windows' do
144
- before do
145
- browser.goto WatirSpec.url_for('window_switching.html')
146
- browser.a(id: 'open').click
147
- browser.windows.wait_until(size: 2)
129
+ it 'waits for second window' do
130
+ browser.windows.restore!
131
+ expect {
132
+ browser.a(id: 'delayed').click
133
+ browser.switch_window
134
+ }.to execute_when_satisfied(min: 1)
135
+ end
148
136
  end
137
+ end
149
138
 
150
- it 'allows actions on first window after opening second',
151
- except: {browser: %i[ie safari]}, reason: 'Focus is on newly opened window instead of the first' do
152
- browser.a(id: 'open').click
153
-
154
- expect { browser.windows.wait_until(size: 3) }.to_not raise_timeout_exception
139
+ describe Window, exclude: {browser: :ie, reason: 'Cannot call #restore!'} do
140
+ after do
141
+ browser.windows.restore!
155
142
  end
156
143
 
157
- describe '#close', except: {browser: :ie, reason: 'Click is not opening window'} do
158
- it 'closes a window' do
159
- browser.window(title: 'window switching').use
144
+ context 'when using multiple windows' do
145
+ before do
146
+ browser.goto WatirSpec.url_for('window_switching.html')
160
147
  browser.a(id: 'open').click
161
- browser.windows.wait_until(size: 3)
148
+ browser.windows.wait_until(size: 2)
149
+ browser.wait_until { |b| !b.window(title: 'about:blank').exist? }
150
+ end
162
151
 
163
- Watir::Window.new(browser, title: 'closeable window').close
152
+ it 'allows actions on first window after opening second',
153
+ except: {browser: :safari, reason: 'Focus is on newly opened window instead of the first'} do
154
+ browser.a(id: 'open').click
164
155
 
165
- expect { browser.windows.wait_until(size: 2) }.to_not raise_timeout_exception
156
+ expect { browser.windows.wait_until(size: 3) }.not_to raise_timeout_exception
166
157
  end
167
158
 
168
- it 'closes the current window',
169
- except: {browser: %i[ie safari]},
170
- reason: 'Focus is on newly opened window instead of the first' do
171
- browser.a(id: 'open').click
172
- browser.windows.wait_until(size: 3)
159
+ describe '#close' do
160
+ it 'closes a window' do
161
+ browser.window(title: 'window switching').use
162
+ browser.a(id: 'open').click
163
+ browser.windows.wait_until(size: 3)
173
164
 
174
- Watir::Window.new(browser, title: 'closeable window').use.close
165
+ described_class.new(browser, title: 'closeable window').close
175
166
 
176
- expect { browser.windows.wait_until(size: 2) }.to_not raise_timeout_exception
177
- end
178
- end
167
+ expect { browser.windows.wait_until(size: 2) }.not_to raise_timeout_exception
168
+ end
179
169
 
180
- describe '#use' do
181
- it 'switches to the window' do
182
- Watir::Window.new(browser, title: 'closeable window').use
183
- expect(browser.title).to eq 'closeable window'
184
- end
185
- end
170
+ it 'closes the current window',
171
+ except: {browser: :safari},
172
+ reason: 'Focus is on newly opened window instead of the first' do
173
+ browser.a(id: 'open').click
174
+ browser.windows.wait_until(size: 3)
186
175
 
187
- describe '#current?' do
188
- it 'returns true if it is the current window' do
189
- expect(Watir::Window.new(browser, title: browser.title)).to be_current
190
- end
176
+ described_class.new(browser, title: 'closeable window').use.close
191
177
 
192
- it 'returns false if it is not the current window' do
193
- expect(Watir::Window.new(browser, title: 'closeable window')).to_not be_current
178
+ expect { browser.windows.wait_until(size: 2) }.not_to raise_timeout_exception
179
+ end
194
180
  end
195
- end
196
-
197
- describe '#title' do
198
- it 'returns the title of the window' do
199
- browser.wait_while { |b| b.window(title: /^$/).exists? }
200
- titles = browser.windows.map(&:title)
201
181
 
202
- expect(titles).to include 'window switching', 'closeable window'
182
+ describe '#use' do
183
+ it 'switches to the window' do
184
+ described_class.new(browser, title: 'closeable window').use
185
+ expect(browser.title).to eq 'closeable window'
186
+ end
203
187
  end
204
- end
205
188
 
206
- describe '#url' do
207
- it 'returns the url of the window' do
208
- urls = browser.windows.map(&:url)
189
+ describe '#current?' do
190
+ it 'returns true if it is the current window' do
191
+ expect(described_class.new(browser, title: browser.title)).to be_current
192
+ end
209
193
 
210
- expect(urls).to(include(/window_switching\.html/, /closeable\.html$/))
194
+ it 'returns false if it is not the current window' do
195
+ expect(described_class.new(browser, title: 'closeable window')).not_to be_current
196
+ end
211
197
  end
212
- end
213
198
 
214
- describe '#eql?' do
215
- it 'knows when two windows are equal' do
216
- win1 = Watir::Window.new browser, {}
217
- win2 = Watir::Window.new browser, title: 'window switching'
199
+ describe '#title' do
200
+ it 'returns the title of the window' do
201
+ browser.wait_while { |b| b.window(title: /^$/).exists? }
202
+ titles = browser.windows.map(&:title)
218
203
 
219
- expect(win1).to eq win2
204
+ expect(titles).to include 'window switching', 'closeable window'
205
+ end
220
206
  end
221
207
 
222
- it 'knows when two windows are not equal' do
223
- win1 = Watir::Window.new browser, title: 'closeable window'
224
- win2 = Watir::Window.new browser, title: 'window switching'
208
+ describe '#url' do
209
+ it 'returns the url of the window' do
210
+ urls = browser.windows.map(&:url)
225
211
 
226
- expect(win1).to_not eq win2
212
+ expect(urls).to(include(/window_switching\.html/, /closeable\.html$/))
213
+ end
227
214
  end
228
- end
229
215
 
230
- describe '#handle' do
231
- it 'does not find if not matching' do
232
- expect(browser.window(title: 'noop').handle).to be_nil
233
- end
216
+ describe '#eql?' do
217
+ it 'knows when two windows are equal' do
218
+ win1 = described_class.new browser, {}
219
+ win2 = described_class.new browser, title: 'window switching'
234
220
 
235
- it 'finds window by :url' do
236
- expect(browser.window(url: /closeable\.html/).handle).to_not be_nil
237
- end
221
+ expect(win1).to eq win2
222
+ end
238
223
 
239
- it 'finds window by :title' do
240
- expect(browser.window(title: 'closeable window').handle).to_not be_nil
241
- end
224
+ it 'knows when two windows are not equal' do
225
+ win1 = described_class.new browser, title: 'closeable window'
226
+ win2 = described_class.new browser, title: 'window switching'
242
227
 
243
- it 'finds window by :element' do
244
- expect(browser.window(element: browser.a(id: 'close')).handle).to_not be_nil
228
+ expect(win1).not_to eq win2
229
+ end
245
230
  end
246
231
 
247
- it 'finds window by multiple values' do
248
- expect(browser.window(url: /closeable\.html/, title: 'closeable window').handle).to_not be_nil
249
- end
250
- end
251
- end
232
+ describe '#handle' do
233
+ it 'does not find if not matching' do
234
+ expect(browser.window(title: 'noop').handle).to be_nil
235
+ end
252
236
 
253
- context 'with a closed window',
254
- except: {browser: :safari,
255
- reason: 'Clicking an Element that Closes a Window is returning NoMatchingWindowFoundException'} do
256
- before do
257
- @original_window = browser.window
258
- browser.goto WatirSpec.url_for('window_switching.html')
259
- browser.a(id: 'open').click
260
- browser.windows.wait_until(size: 2)
261
- @handles = browser.driver.window_handles
262
- @closed_window = browser.window(title: 'closeable window').use
263
- browser.a(id: 'close').click
264
- browser.windows.wait_until(size: 1)
265
- end
237
+ it 'finds window by :url' do
238
+ expect(browser.window(url: /closeable\.html/).handle).not_to be_nil
239
+ end
266
240
 
267
- describe '#exists?' do
268
- it 'returns false if previously referenced window is closed' do
269
- expect(@closed_window).to_not be_present
270
- end
241
+ it 'finds window by :title' do
242
+ expect(browser.window(title: 'closeable window').handle).not_to be_nil
243
+ end
271
244
 
272
- it 'returns false if closed window is referenced' do
273
- expect(browser.window).to_not exist
274
- end
275
- end
245
+ it 'finds window by :element' do
246
+ expect(browser.window(element: browser.a(id: 'close')).handle).not_to be_nil
247
+ end
276
248
 
277
- describe '#current?' do
278
- it 'returns false if the referenced window is closed' do
279
- expect(@original_window).to_not be_current
249
+ it 'finds window by multiple values' do
250
+ expect(browser.window(url: /closeable\.html/, title: 'closeable window').handle).not_to be_nil
251
+ end
280
252
  end
281
253
  end
282
254
 
283
- describe '#eql?' do
284
- it 'should return false when checking equivalence to a closed window' do
285
- expect(browser.window).not_to eq @closed_widow
255
+ context 'with a closed window',
256
+ except: {browser: :safari,
257
+ reason: 'Clicking an Element that Closes a Window is returning NoMatchingWindowFoundException'} do
258
+ before do
259
+ @original_window = browser.window
260
+ browser.goto WatirSpec.url_for('window_switching.html')
261
+ browser.a(id: 'open').click
262
+ browser.windows.wait_until(size: 2)
263
+ @handles = browser.driver.window_handles
264
+ @closed_window = browser.window(title: 'closeable window').use
265
+ browser.a(id: 'close').click
266
+ browser.windows.wait_until(size: 1)
286
267
  end
287
- end
288
268
 
289
- describe '#use' do
290
- it 'raises NoMatchingWindowFoundException error when attempting to use a referenced window that is closed' do
291
- expect { @closed_window.use }.to raise_no_matching_window_exception
292
- end
269
+ describe '#exists?' do
270
+ it 'returns false if previously referenced window is closed' do
271
+ expect(@closed_window).not_to be_present
272
+ end
293
273
 
294
- it 'raises NoMatchingWindowFoundException error when attempting to use the current window if it is closed' do
295
- expect { browser.window.use }.to raise_no_matching_window_exception
274
+ it 'returns false if closed window is referenced' do
275
+ expect(browser.window).not_to exist
276
+ end
296
277
  end
297
- end
298
278
 
299
- it 'raises an exception when using an element on a closed window',
300
- exclude: {browser: :firefox,
301
- platform: :windows,
302
- reason: 'https://github.com/mozilla/geckodriver/issues/1847'} do
303
- msg = 'browser window was closed'
304
- expect { browser.a.text }.to raise_exception(Watir::Exception::NoMatchingWindowFoundException, msg)
305
- end
279
+ describe '#current?' do
280
+ it 'returns false if the referenced window is closed' do
281
+ expect(@original_window).not_to be_current
282
+ end
283
+ end
306
284
 
307
- it 'raises an exception when locating a closed window' do
308
- expect { browser.window(title: 'closeable window').use }.to raise_no_matching_window_exception
309
- end
310
- end
285
+ describe '#eql?' do
286
+ it 'returns false when checking equivalence to a closed window' do
287
+ expect(browser.window).not_to eq @closed_widow
288
+ end
289
+ end
311
290
 
312
- context 'with a closed window on a delay' do
313
- it 'raises an exception when locating a window closed during lookup' do
314
- browser.goto WatirSpec.url_for('window_switching.html')
315
- browser.a(id: 'open').click
316
- browser.windows.wait_until(size: 2)
317
- browser.window(title: 'closeable window').use
318
- browser.a(id: 'close-delay').click
319
-
320
- begin
321
- module Watir
322
- class Browser
323
- alias title_old title
324
-
325
- def title
326
- sleep 0.5
327
- title_old
328
- end
329
- end
291
+ describe '#use' do
292
+ it 'raises NoMatchingWindowFoundException error when attempting to use a referenced window that is closed' do
293
+ expect { @closed_window.use }.to raise_no_matching_window_exception
330
294
  end
331
295
 
332
- expect { browser.window(title: 'closeable window').use }.to raise_no_matching_window_exception
333
- ensure
334
- module Watir
335
- class Browser
336
- alias title title_old
337
- end
296
+ it 'raises NoMatchingWindowFoundException error when attempting to use the current window if it is closed' do
297
+ expect { browser.window.use }.to raise_no_matching_window_exception
338
298
  end
339
299
  end
340
- end
341
- end
342
300
 
343
- context 'with current window closed',
344
- except: {browser: :safari,
345
- reason: 'Clicking an Element that Closes a Window is returning NoMatchingWindowFoundException'} do
346
- before do
347
- browser.goto WatirSpec.url_for('window_switching.html')
348
- browser.a(id: 'open').click
349
- browser.windows.wait_until(size: 2)
350
- browser.window(title: 'closeable window').use
351
- browser.a(id: 'close').click
352
- browser.windows.wait_until(size: 1)
353
- end
354
-
355
- describe '#present?' do
356
- it 'should find window by url' do
357
- expect(browser.window(url: /window_switching\.html/)).to be_present
301
+ it 'raises an exception when using an element on a closed window',
302
+ exclude: {browser: :firefox,
303
+ platform: :windows,
304
+ reason: 'https://github.com/mozilla/geckodriver/issues/1847'} do
305
+ msg = 'browser window was closed'
306
+ expect { browser.a.text }.to raise_exception(Exception::NoMatchingWindowFoundException, msg)
358
307
  end
359
308
 
360
- it 'should find window by title' do
361
- expect(browser.window(title: 'window switching')).to be_present
309
+ it 'raises an exception when locating a closed window' do
310
+ expect { browser.window(title: 'closeable window').use }.to raise_no_matching_window_exception
362
311
  end
312
+ end
363
313
 
364
- it 'should find window by element' do
365
- expect(browser.window(element: browser.link(id: 'open'))).to be_present
314
+ context 'with a closed window on a delay' do
315
+ it 'raises an exception when locating a window closed during lookup' do
316
+ browser.goto WatirSpec.url_for('window_switching.html')
317
+ browser.a(id: 'open').click
318
+ browser.windows.wait_until(size: 2)
319
+ browser.window(title: 'closeable window').use
320
+ browser.a(id: 'close-delay').click
321
+ allow(browser).to receive(:title).and_invoke(-> { sleep(0.5) && browser.wd.title })
322
+
323
+ expect { browser.window(title: 'closeable window').use }.to raise_no_matching_window_exception
366
324
  end
367
325
  end
368
326
 
369
- describe '#use' do
370
- context 'switching windows without blocks' do
371
- it 'by url' do
372
- browser.window(url: /window_switching\.html/).use
373
- expect(browser.title).to be == 'window switching'
327
+ context 'with current window closed',
328
+ except: {browser: :safari,
329
+ reason: 'Clicking an Element that Closes a Window is returning NoMatchingWindowFoundException'} do
330
+ before do
331
+ browser.goto WatirSpec.url_for('window_switching.html')
332
+ browser.a(id: 'open').click
333
+ browser.windows.wait_until(size: 2)
334
+ browser.window(title: 'closeable window').use
335
+ browser.a(id: 'close').click
336
+ browser.windows.wait_until(size: 1)
337
+ end
338
+
339
+ describe '#present?' do
340
+ it 'finds window by url' do
341
+ expect(browser.window(url: /window_switching\.html/)).to be_present
374
342
  end
375
343
 
376
- it 'by title' do
377
- browser.window(title: 'window switching').use
378
- expect(browser.url).to match(/window_switching\.html/)
344
+ it 'finds window by title' do
345
+ expect(browser.window(title: 'window switching')).to be_present
379
346
  end
380
347
 
381
- it 'by element' do
382
- browser.window(element: browser.link(id: 'open')).use
383
- expect(browser.url).to match(/window_switching\.html/)
348
+ it 'finds window by element' do
349
+ expect(browser.window(element: browser.link(id: 'open'))).to be_present
384
350
  end
385
351
  end
386
352
 
387
- context 'Switching windows with blocks' do
388
- it 'by url' do
389
- browser.window(url: /window_switching\.html/).use { expect(browser.title).to be == 'window switching' }
390
- end
353
+ describe '#use' do
354
+ context 'when switching windows without blocks' do
355
+ it 'by url' do
356
+ browser.window(url: /window_switching\.html/).use
357
+ expect(browser.title).to be == 'window switching'
358
+ end
359
+
360
+ it 'by title' do
361
+ browser.window(title: 'window switching').use
362
+ expect(browser.url).to match(/window_switching\.html/)
363
+ end
391
364
 
392
- it 'by title' do
393
- browser.window(title: 'window switching').use { expect(browser.url).to match(/window_switching\.html/) }
365
+ it 'by element' do
366
+ browser.window(element: browser.link(id: 'open')).use
367
+ expect(browser.url).to match(/window_switching\.html/)
368
+ end
394
369
  end
395
370
 
396
- it 'by element' do
397
- element = browser.link(id: 'open')
398
- browser.window(element: element).use { expect(browser.url).to match(/window_switching\.html/) }
371
+ context 'when switching windows with blocks' do
372
+ it 'by url' do
373
+ browser.window(url: /window_switching\.html/).use { expect(browser.title).to be == 'window switching' }
374
+ end
375
+
376
+ it 'by title' do
377
+ browser.window(title: 'window switching').use { expect(browser.url).to match(/window_switching\.html/) }
378
+ end
379
+
380
+ it 'by element' do
381
+ element = browser.link(id: 'open')
382
+ browser.window(element: element).use { expect(browser.url).to match(/window_switching\.html/) }
383
+ end
399
384
  end
400
385
  end
401
386
  end
402
- end
403
387
 
404
- context 'manipulating size and position', except: {headless: true} do
405
- before(:all) do
406
- maximized_size = browser.window.size
388
+ context 'when manipulating size and position', except: {headless: true} do
389
+ before(:all) do
390
+ maximized_size = browser.window.size
407
391
 
408
- browser.window.resize_to(
409
- maximized_size.width - 100,
410
- maximized_size.height - 100
411
- )
412
- browser.wait_until { |b| b.window.size != maximized_size }
392
+ browser.window.resize_to(
393
+ maximized_size.width - 100,
394
+ maximized_size.height - 100
395
+ )
396
+ browser.wait_until { |b| b.window.size != maximized_size }
413
397
 
414
- current_position = browser.window.position
398
+ current_position = browser.window.position
415
399
 
416
- browser.window.move_to(
417
- current_position.x + 40,
418
- current_position.y + 40
419
- )
420
- browser.wait_until { |b| b.window.position != current_position }
400
+ browser.window.move_to(
401
+ current_position.x + 40,
402
+ current_position.y + 40
403
+ )
404
+ browser.wait_until { |b| b.window.position != current_position }
421
405
 
422
- @initial_size = browser.window.size
423
- @initial_position = browser.window.position
424
- end
406
+ @initial_size = browser.window.size
407
+ @initial_position = browser.window.position
408
+ end
425
409
 
426
- before do
427
- browser.goto WatirSpec.url_for('window_switching.html')
428
- end
410
+ before do
411
+ browser.goto WatirSpec.url_for('window_switching.html')
412
+ end
429
413
 
430
- after do
431
- browser.window.resize_to @initial_size.width, @initial_size.height
432
- browser.window.move_to @initial_position.x, @initial_position.y
433
- end
414
+ after do
415
+ browser.window.resize_to @initial_size.width, @initial_size.height
416
+ browser.window.move_to @initial_position.x, @initial_position.y
417
+ end
434
418
 
435
- it 'should get the size of the current window' do
436
- expect(@initial_size.width).to eq browser.execute_script('return window.outerWidth;')
437
- expect(@initial_size.height).to eq browser.execute_script('return window.outerHeight;')
438
- end
419
+ it 'gets the size of the current window' do
420
+ expect(@initial_size.width).to eq browser.execute_script('return window.outerWidth;')
421
+ expect(@initial_size.height).to eq browser.execute_script('return window.outerHeight;')
422
+ end
439
423
 
440
- it 'should get the position of the current window' do
441
- expect(@initial_position.x).to eq browser.execute_script('return window.screenX;')
442
- expect(@initial_position.y).to eq browser.execute_script('return window.screenY;')
443
- end
424
+ it 'gets the position of the current window' do
425
+ expect(@initial_position.x).to eq browser.execute_script('return window.screenX;')
426
+ expect(@initial_position.y).to eq browser.execute_script('return window.screenY;')
427
+ end
444
428
 
445
- it 'should resize the window' do
446
- browser.window.resize_to(
447
- @initial_size.width - 20,
448
- @initial_size.height - 20
449
- )
429
+ it 'resizes the window' do
430
+ browser.window.resize_to(
431
+ @initial_size.width - 20,
432
+ @initial_size.height - 20
433
+ )
450
434
 
451
- browser.wait_until { |b| b.window.size != @initial_size }
435
+ browser.wait_until { |b| b.window.size != @initial_size }
452
436
 
453
- new_size = browser.window.size
454
- expect(new_size.width).to eq @initial_size.width - 20
455
- expect(new_size.height).to eq @initial_size.height - 20
456
- end
437
+ new_size = browser.window.size
438
+ expect(new_size.width).to eq @initial_size.width - 20
439
+ expect(new_size.height).to eq @initial_size.height - 20
440
+ end
457
441
 
458
- it 'should move the window' do
459
- browser.window.move_to(
460
- @initial_position.x + 5,
461
- @initial_position.y + 5
462
- )
442
+ it 'moves the window' do
443
+ browser.window.move_to(
444
+ @initial_position.x + 5,
445
+ @initial_position.y + 5
446
+ )
463
447
 
464
- browser.wait_until { |b| b.window.position != @initial_position }
448
+ browser.wait_until { |b| b.window.position != @initial_position }
465
449
 
466
- new_position = browser.window.position
467
- expect(new_position.x).to eq @initial_position.x + 5
468
- expect(new_position.y).to eq @initial_position.y + 5
469
- end
450
+ new_position = browser.window.position
451
+ expect(new_position.x).to eq @initial_position.x + 5
452
+ expect(new_position.y).to eq @initial_position.y + 5
453
+ end
470
454
 
471
- it 'should maximize the window' do
472
- browser.window.maximize
473
- browser.wait_until { |b| b.window.size != @initial_size }
455
+ it 'maximizes the window' do
456
+ browser.window.maximize
457
+ browser.wait_until { |b| b.window.size != @initial_size }
474
458
 
475
- new_size = browser.window.size
476
- expect(new_size.width).to be >= @initial_size.width
477
- expect(new_size.height).to be > @initial_size.height
478
- end
459
+ new_size = browser.window.size
460
+ expect(new_size.width).to be >= @initial_size.width
461
+ expect(new_size.height).to be > @initial_size.height
462
+ end
479
463
 
480
- it 'should make the window full screen' do
481
- browser.window.full_screen
482
- browser.wait_until { |b| b.window.size != @initial_size }
464
+ it 'makes the window full screen' do
465
+ browser.window.full_screen
466
+ browser.wait_until { |b| b.window.size != @initial_size }
483
467
 
484
- new_size = browser.window.size
485
- expect(new_size.width).to be >= @initial_size.width
486
- expect(new_size.height).to be > @initial_size.height
487
- end
468
+ new_size = browser.window.size
469
+ expect(new_size.width).to be >= @initial_size.width
470
+ expect(new_size.height).to be > @initial_size.height
471
+ end
488
472
 
489
- it 'should minimize the window' do
490
- expect(browser.execute_script('return document.visibilityState;')).to eq 'visible'
473
+ it 'minimizes the window' do
474
+ expect(browser.execute_script('return document.visibilityState;')).to eq 'visible'
491
475
 
492
- browser.window.minimize
476
+ browser.window.minimize
493
477
 
494
- browser.wait_until { |b| b.execute_script('return document.visibilityState;') != 'visible' }
478
+ browser.wait_until { |b| !%w[visible normal].include?(b.execute_script('return document.visibilityState;')) }
495
479
 
496
- expect(browser.execute_script('return document.visibilityState;')).to eq 'hidden'
497
- browser.window.maximize
480
+ expect(browser.execute_script('return document.visibilityState;')).to eq 'hidden'
481
+ browser.window.maximize
482
+ end
498
483
  end
499
484
  end
500
- end
501
485
 
502
- describe Watir::WindowCollection do
503
- before do
504
- browser.goto WatirSpec.url_for('window_switching.html')
505
- browser.a(id: 'open').click
506
- browser.windows.wait_until(size: 2)
507
- end
486
+ describe WindowCollection, exclude: {browser: :ie, reason: 'Cannot call #restore!'} do
487
+ before do
488
+ browser.goto WatirSpec.url_for('window_switching.html')
489
+ browser.a(id: 'open').click
490
+ browser.windows.wait_until(size: 2)
491
+ end
508
492
 
509
- after do
510
- browser.windows.restore!
511
- end
493
+ after do
494
+ browser.windows.restore!
495
+ end
512
496
 
513
- it '#to_a raises exception' do
514
- expect {
515
- Watir::WindowCollection.new(browser).to_a
516
- }.to raise_exception(NoMethodError, 'indexing not reliable on WindowCollection')
517
- end
497
+ describe '#to_a' do
498
+ it 'raises exception' do
499
+ expect {
500
+ described_class.new(browser).to_a
501
+ }.to raise_exception(NoMethodError, 'indexing not reliable on WindowCollection')
502
+ end
503
+ end
518
504
 
519
- describe '#new' do
520
- it 'returns all windows by default' do
521
- windows = Watir::WindowCollection.new(browser)
505
+ describe '#new' do
506
+ it 'returns all windows by default' do
507
+ windows = described_class.new(browser)
522
508
 
523
- expect(windows.size).to eq 2
524
- end
509
+ expect(windows.size).to eq 2
510
+ end
525
511
 
526
- it 'filters available windows by url' do
527
- windows = Watir::WindowCollection.new(browser, url: /closeable\.html/)
512
+ it 'filters available windows by url' do
513
+ windows = described_class.new(browser, url: /closeable\.html/)
528
514
 
529
- expect(windows.size).to eq 1
530
- end
515
+ expect(windows.size).to eq 1
516
+ end
531
517
 
532
- it 'filters available windows by title' do
533
- windows = Watir::WindowCollection.new(browser, title: /closeable/)
518
+ it 'filters available windows by title' do
519
+ windows = described_class.new(browser, title: /closeable/)
534
520
 
535
- expect(windows.size).to eq 1
536
- end
521
+ expect(windows.size).to eq 1
522
+ end
537
523
 
538
- it 'filters available windows by element' do
539
- windows = Watir::WindowCollection.new(browser, element: browser.element(id: 'close'))
524
+ it 'filters available windows by element' do
525
+ windows = described_class.new(browser, element: browser.element(id: 'close'))
540
526
 
541
- expect(windows.size).to eq 1
542
- end
527
+ expect(windows.size).to eq 1
528
+ end
543
529
 
544
- it 'raises ArgumentError if unrecognized locator' do
545
- expect {
546
- Watir::WindowCollection.new(browser, foo: /closeable/)
547
- }.to raise_error(ArgumentError)
530
+ it 'raises ArgumentError if unrecognized locator' do
531
+ expect {
532
+ described_class.new(browser, foo: /closeable/)
533
+ }.to raise_error(ArgumentError)
534
+ end
548
535
  end
549
- end
550
536
 
551
- describe '#size' do
552
- it 'counts the number of matching windows' do
553
- expect(Watir::WindowCollection.new(browser).size).to eq 2
537
+ describe '#size' do
538
+ it 'counts the number of matching windows' do
539
+ expect(described_class.new(browser).size).to eq 2
540
+ end
554
541
  end
555
- end
556
542
 
557
- describe '#eq?' do
558
- it 'compares the equivalence of window handles' do
559
- windows1 = Watir::WindowCollection.new(browser, title: //)
560
- windows2 = Watir::WindowCollection.new(browser, url: //)
543
+ describe '#eq?' do
544
+ it 'compares the equivalence of window handles' do
545
+ windows1 = described_class.new(browser, title: //)
546
+ windows2 = described_class.new(browser, url: //)
561
547
 
562
- expect(windows1).to eq windows2
548
+ expect(windows1).to eq windows2
549
+ end
563
550
  end
564
- end
565
551
 
566
- it '#reset!' do
567
- wins = browser.windows
568
- expect(wins.size).to eq 2
569
- wins.reset!
570
- expect(wins.instance_variable_get(:@window_list)).to be_nil
571
- end
552
+ describe '#reset!' do
553
+ it 'clears window list' do
554
+ wins = browser.windows
555
+ expect(wins.size).to eq 2
556
+ wins.reset!
557
+ expect(wins.instance_variable_get(:@window_list)).to be_nil
558
+ end
559
+ end
572
560
 
573
- describe '#restore!' do
574
- it 'when on other window',
575
- except: {browser: %i[ie safari], reason: 'Focus is on newly opened window instead of the first'} do
576
- browser.a(id: 'open').click
577
- browser.windows.wait_until(size: 3)
578
- browser.window(title: 'closeable window').use
561
+ describe '#restore!' do
562
+ it 'when on other window',
563
+ except: {browser: :safari, reason: 'Focus is on newly opened window instead of the first'} do
564
+ browser.a(id: 'open').click
565
+ browser.windows.wait_until(size: 3)
566
+ browser.window(title: 'closeable window').use
579
567
 
580
- browser.windows.restore!
581
- expect(browser.windows.size).to eq 1
582
- expect(browser.title).to eq 'window switching'
583
- end
568
+ browser.windows.restore!
569
+ expect(browser.windows.size).to eq 1
570
+ expect(browser.title).to eq 'window switching'
571
+ end
584
572
 
585
- it 'when browser closed does not raise exception' do
586
- browser.close
573
+ it 'when browser closed does not raise exception' do
574
+ browser.close
587
575
 
588
- expect { browser.windows.restore! }.not_to raise_exception
576
+ expect { browser.windows.restore! }.not_to raise_exception
577
+ end
589
578
  end
590
579
  end
591
580
  end