watir 7.2.0 → 7.2.1
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.
- checksums.yaml +4 -4
- data/.github/workflows/chrome.yml +1 -1
- data/.github/workflows/edge.yml +1 -1
- data/.github/workflows/firefox.yml +1 -1
- data/.github/workflows/ie.yml +1 -1
- data/.github/workflows/safari.yml +1 -1
- data/.github/workflows/unit.yml +1 -1
- data/.rubocop.yml +25 -12
- data/.rubocop_todo.yml +8 -1
- data/CHANGES.md +6 -1
- data/LICENSE +2 -2
- data/lib/watir/capabilities.rb +1 -1
- data/lib/watir/locators/anchor/selector_builder.rb +3 -0
- data/lib/watir/locators/element/matcher.rb +2 -1
- data/lib/watir/locators/element/selector_builder/regexp_disassembler.rb +2 -1
- data/lib/watir/locators/text_field/matcher.rb +0 -4
- data/lib/watir/version.rb +1 -1
- data/spec/locator_spec_helper.rb +0 -8
- data/spec/unit/capabilities_spec.rb +553 -561
- data/spec/unit/element_locator_spec.rb +89 -78
- data/spec/unit/match_elements/button_spec.rb +69 -62
- data/spec/unit/match_elements/element_spec.rb +303 -309
- data/spec/unit/match_elements/text_field_spec.rb +76 -73
- data/spec/unit/selector_builder/anchor_spec.rb +39 -33
- data/spec/unit/selector_builder/button_spec.rb +209 -202
- data/spec/unit/selector_builder/cell_spec.rb +48 -42
- data/spec/unit/selector_builder/element_spec.rb +634 -627
- data/spec/unit/selector_builder/row_spec.rb +119 -113
- data/spec/unit/selector_builder/text_field_spec.rb +195 -188
- data/spec/unit/selector_builder/textarea_spec.rb +22 -14
- data/spec/unit/wait_spec.rb +85 -81
- data/spec/watirspec/adjacent_spec.rb +249 -247
- data/spec/watirspec/after_hooks_spec.rb +161 -159
- data/spec/watirspec/alert_spec.rb +61 -58
- data/spec/watirspec/browser_spec.rb +409 -409
- data/spec/watirspec/capabilities_spec.rb +89 -99
- data/spec/watirspec/cookies_spec.rb +120 -118
- data/spec/watirspec/drag_and_drop_spec.rb +26 -24
- data/spec/watirspec/element_hidden_spec.rb +66 -60
- data/spec/watirspec/elements/area_spec.rb +49 -47
- data/spec/watirspec/elements/areas_spec.rb +27 -25
- data/spec/watirspec/elements/button_spec.rb +253 -251
- data/spec/watirspec/elements/buttons_spec.rb +36 -34
- data/spec/watirspec/elements/checkbox_spec.rb +48 -36
- data/spec/watirspec/elements/checkboxes_spec.rb +29 -27
- data/spec/watirspec/elements/collections_spec.rb +126 -119
- data/spec/watirspec/elements/date_field_spec.rb +185 -183
- data/spec/watirspec/elements/date_fields_spec.rb +29 -27
- data/spec/watirspec/elements/date_time_field_spec.rb +197 -195
- data/spec/watirspec/elements/date_time_fields_spec.rb +30 -28
- data/spec/watirspec/elements/dd_spec.rb +87 -85
- data/spec/watirspec/elements/dds_spec.rb +27 -25
- data/spec/watirspec/elements/del_spec.rb +106 -104
- data/spec/watirspec/elements/dels_spec.rb +26 -24
- data/spec/watirspec/elements/div_spec.rb +225 -221
- data/spec/watirspec/elements/divs_spec.rb +37 -35
- data/spec/watirspec/elements/dl_spec.rb +110 -108
- data/spec/watirspec/elements/dls_spec.rb +28 -26
- data/spec/watirspec/elements/dt_spec.rb +86 -84
- data/spec/watirspec/elements/dts_spec.rb +27 -25
- data/spec/watirspec/elements/element_spec.rb +794 -775
- data/spec/watirspec/elements/elements_spec.rb +40 -38
- data/spec/watirspec/elements/em_spec.rb +62 -60
- data/spec/watirspec/elements/ems_spec.rb +28 -26
- data/spec/watirspec/elements/filefield_spec.rb +116 -114
- data/spec/watirspec/elements/filefields_spec.rb +28 -26
- data/spec/watirspec/elements/font_spec.rb +20 -18
- data/spec/watirspec/elements/form_spec.rb +51 -49
- data/spec/watirspec/elements/forms_spec.rb +29 -27
- data/spec/watirspec/elements/frame_spec.rb +89 -87
- data/spec/watirspec/elements/frames_spec.rb +27 -25
- data/spec/watirspec/elements/hidden_spec.rb +81 -79
- data/spec/watirspec/elements/hiddens_spec.rb +28 -26
- data/spec/watirspec/elements/hn_spec.rb +59 -57
- data/spec/watirspec/elements/hns_spec.rb +26 -24
- data/spec/watirspec/elements/iframe_spec.rb +195 -191
- data/spec/watirspec/elements/iframes_spec.rb +31 -29
- data/spec/watirspec/elements/image_spec.rb +148 -146
- data/spec/watirspec/elements/images_spec.rb +26 -24
- data/spec/watirspec/elements/input_spec.rb +9 -7
- data/spec/watirspec/elements/ins_spec.rb +106 -104
- data/spec/watirspec/elements/inses_spec.rb +26 -24
- data/spec/watirspec/elements/label_spec.rb +56 -54
- data/spec/watirspec/elements/labels_spec.rb +26 -24
- data/spec/watirspec/elements/li_spec.rb +76 -74
- data/spec/watirspec/elements/link_spec.rb +173 -177
- data/spec/watirspec/elements/links_spec.rb +45 -43
- data/spec/watirspec/elements/lis_spec.rb +27 -25
- data/spec/watirspec/elements/list_spec.rb +44 -42
- data/spec/watirspec/elements/map_spec.rb +57 -55
- data/spec/watirspec/elements/maps_spec.rb +27 -25
- data/spec/watirspec/elements/meta_spec.rb +16 -14
- data/spec/watirspec/elements/metas_spec.rb +26 -24
- data/spec/watirspec/elements/ol_spec.rb +56 -65
- data/spec/watirspec/elements/ols_spec.rb +26 -24
- data/spec/watirspec/elements/option_spec.rb +91 -89
- data/spec/watirspec/elements/p_spec.rb +81 -79
- data/spec/watirspec/elements/pre_spec.rb +77 -75
- data/spec/watirspec/elements/pres_spec.rb +26 -24
- data/spec/watirspec/elements/ps_spec.rb +26 -24
- data/spec/watirspec/elements/radio_spec.rb +251 -249
- data/spec/watirspec/elements/radios_spec.rb +28 -26
- data/spec/watirspec/elements/select_list_spec.rb +537 -526
- data/spec/watirspec/elements/select_lists_spec.rb +32 -30
- data/spec/watirspec/elements/span_spec.rb +112 -110
- data/spec/watirspec/elements/spans_spec.rb +26 -24
- data/spec/watirspec/elements/strong_spec.rb +58 -58
- data/spec/watirspec/elements/strongs_spec.rb +28 -26
- data/spec/watirspec/elements/table_spec.rb +192 -139
- data/spec/watirspec/elements/tables_spec.rb +28 -26
- data/spec/watirspec/elements/tbody_spec.rb +74 -72
- data/spec/watirspec/elements/tbodys_spec.rb +40 -38
- data/spec/watirspec/elements/td_spec.rb +66 -64
- data/spec/watirspec/elements/tds_spec.rb +41 -39
- data/spec/watirspec/elements/text_field_spec.rb +206 -204
- data/spec/watirspec/elements/text_fields_spec.rb +30 -28
- data/spec/watirspec/elements/textarea_spec.rb +20 -18
- data/spec/watirspec/elements/textareas_spec.rb +18 -16
- data/spec/watirspec/elements/tfoot_spec.rb +65 -63
- data/spec/watirspec/elements/tfoots_spec.rb +42 -40
- data/spec/watirspec/elements/thead_spec.rb +65 -63
- data/spec/watirspec/elements/theads_spec.rb +42 -40
- data/spec/watirspec/elements/tr_spec.rb +48 -46
- data/spec/watirspec/elements/trs_spec.rb +42 -40
- data/spec/watirspec/elements/ul_spec.rb +56 -54
- data/spec/watirspec/elements/uls_spec.rb +26 -24
- data/spec/watirspec/radio_set_spec.rb +269 -267
- data/spec/watirspec/screenshot_spec.rb +20 -18
- data/spec/watirspec/scroll_spec.rb +152 -148
- data/spec/watirspec/shadow_root_spec.rb +86 -83
- data/spec/watirspec/user_editable_spec.rb +200 -198
- data/spec/watirspec/wait_spec.rb +289 -295
- data/spec/watirspec/window_switching_spec.rb +422 -434
- data/spec/watirspec_helper.rb +1 -23
- data/watir.gemspec +5 -4
- metadata +44 -33
- data/spec/watirspec/attributes_spec.rb +0 -18
- data/spec/watirspec/elements/table_nesting_spec.rb +0 -51
- data/spec/watirspec/special_chars_spec.rb +0 -23
|
@@ -3,29 +3,31 @@
|
|
|
3
3
|
require 'base64'
|
|
4
4
|
require 'watirspec_helper'
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
6
|
+
module Watir
|
|
7
|
+
describe Screenshot do
|
|
8
|
+
let(:png_header) { (+"\211PNG").force_encoding('ASCII-8BIT') }
|
|
8
9
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
describe '#png' do
|
|
11
|
+
it 'gets png representation of screenshot' do
|
|
12
|
+
expect(browser.screenshot.png[0..3]).to eq png_header
|
|
13
|
+
end
|
|
12
14
|
end
|
|
13
|
-
end
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
describe '#base64' do
|
|
17
|
+
it 'gets base64 representation of screenshot' do
|
|
18
|
+
image = browser.screenshot.base64
|
|
19
|
+
expect(Base64.decode64(image)[0..3]).to eq png_header
|
|
20
|
+
end
|
|
19
21
|
end
|
|
20
|
-
end
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
describe '#save' do
|
|
24
|
+
it 'saves screenshot to given file' do
|
|
25
|
+
path = "#{Dir.tmpdir}/test#{::Time.now.to_i}.png"
|
|
26
|
+
expect(File).not_to exist(path)
|
|
27
|
+
browser.screenshot.save(path)
|
|
28
|
+
expect(File).to exist(path)
|
|
29
|
+
expect(File.binread(path)[0..3]).to eq png_header
|
|
30
|
+
end
|
|
29
31
|
end
|
|
30
32
|
end
|
|
31
33
|
end
|
|
@@ -2,203 +2,207 @@
|
|
|
2
2
|
|
|
3
3
|
require 'watirspec_helper'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
module Watir
|
|
6
|
+
describe Scrolling do
|
|
7
|
+
before do
|
|
8
|
+
browser.goto(WatirSpec.url_for('scroll.html'))
|
|
9
|
+
pause
|
|
10
|
+
end
|
|
10
11
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
def top_centered_viewport
|
|
13
|
+
browser.execute_script('return (window.innerHeight - document.body.scrollHeight)/2;')
|
|
14
|
+
end
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
def current_top
|
|
17
|
+
browser.execute_script('return document.body.getBoundingClientRect().top;')
|
|
18
|
+
end
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
context 'when scrolling Browser' do
|
|
21
|
+
describe '#to' do
|
|
22
|
+
it 'scrolls to the top of the page' do
|
|
23
|
+
browser.scroll.to :bottom
|
|
24
|
+
expect(browser.div(id: 'top')).not_to be_in_viewport
|
|
25
|
+
browser.scroll.to :top
|
|
26
|
+
expect(browser.div(id: 'top')).to be_in_viewport
|
|
27
|
+
end
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
29
|
+
it 'scrolls to the center of the page' do
|
|
30
|
+
browser.scroll.to :center
|
|
31
|
+
viewport_top = browser.execute_script('return document.body.getBoundingClientRect().top;')
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
33
|
+
expect(viewport_top).to be_within(1).of(top_centered_viewport)
|
|
34
|
+
end
|
|
34
35
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
36
|
+
it 'scrolls to the bottom of the page' do
|
|
37
|
+
expect(browser.div(id: 'bottom')).not_to be_in_viewport
|
|
38
|
+
browser.scroll.to :bottom
|
|
39
|
+
expect(browser.div(id: 'bottom')).to be_in_viewport
|
|
40
|
+
end
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
it 'scrolls to coordinates' do
|
|
43
|
+
element = browser.div(id: 'center')
|
|
44
|
+
location = element.location
|
|
45
|
+
browser.scroll.to [location.x, location.y]
|
|
46
|
+
expect(element).to be_in_viewport
|
|
47
|
+
end
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
it 'raises error when scroll point is not valid' do
|
|
50
|
+
expect { browser.scroll.to(:blah) }.to raise_error(ArgumentError)
|
|
51
|
+
end
|
|
50
52
|
end
|
|
51
|
-
end
|
|
52
53
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
describe '#by' do
|
|
55
|
+
before do
|
|
56
|
+
browser.scroll.to :top
|
|
57
|
+
pause
|
|
58
|
+
end
|
|
58
59
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
60
|
+
it 'offset from top' do
|
|
61
|
+
initial_top = current_top
|
|
62
|
+
scroll_by = top_centered_viewport.round
|
|
63
|
+
browser.scroll.by(0, -scroll_by)
|
|
64
|
+
pause
|
|
65
|
+
puts "scroll by #{scroll_by}"
|
|
66
|
+
puts "initial top #{initial_top}"
|
|
67
|
+
puts "current top #{current_top}"
|
|
68
|
+
expect(current_top).to be_within(1).of(scroll_by + initial_top)
|
|
69
|
+
end
|
|
69
70
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
it 'offset from bottom' do
|
|
72
|
+
initial_top = current_top
|
|
73
|
+
browser.scroll.to :bottom
|
|
74
|
+
scroll_by = top_centered_viewport
|
|
75
|
+
browser.scroll.by(0, scroll_by)
|
|
76
|
+
pause
|
|
77
|
+
expect(current_top).to be_within(1).of(scroll_by + initial_top)
|
|
78
|
+
end
|
|
77
79
|
end
|
|
78
|
-
end
|
|
79
80
|
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
81
|
+
describe '#from' do
|
|
82
|
+
it 'scrolls by given amount with offset', except: {browser: :ie, reason: 'Not implemented'} do
|
|
83
|
+
browser.goto(WatirSpec.url_for('scroll_nested.html'))
|
|
83
84
|
|
|
84
|
-
|
|
85
|
+
browser.scroll.from(10, 10).by(0, 225)
|
|
85
86
|
|
|
86
|
-
|
|
87
|
+
expect(in_viewport?(browser.iframe.checkbox(name: 'scroll_checkbox'))).to be true
|
|
88
|
+
end
|
|
87
89
|
end
|
|
88
90
|
end
|
|
89
|
-
end
|
|
90
91
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
92
|
+
context 'when scrolling Element' do
|
|
93
|
+
describe '#to' do
|
|
94
|
+
it 'scrolls element into view (viewport)',
|
|
95
|
+
except: [{browser: %i[firefox safari], reason: 'incorrect MoveTargetOutOfBoundsError'},
|
|
96
|
+
{browser: :ie, reason: 'Not implemented'}] do
|
|
97
|
+
browser.goto(WatirSpec.url_for('scroll_nested_offscreen.html'))
|
|
98
|
+
iframe = browser.iframe
|
|
97
99
|
|
|
98
|
-
|
|
100
|
+
expect(in_viewport?(iframe)).to be false
|
|
99
101
|
|
|
100
|
-
|
|
102
|
+
iframe.scroll.to(:viewport)
|
|
101
103
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
+
expect(in_viewport?(iframe)).to be true
|
|
105
|
+
end
|
|
104
106
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
107
|
+
it 'scrolls to element (top) by default' do
|
|
108
|
+
element = browser.div(id: 'center')
|
|
109
|
+
element.scroll.to
|
|
108
110
|
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
111
|
+
element_top = browser.execute_script('return arguments[0].getBoundingClientRect().top', element)
|
|
112
|
+
expect(element_top).to be_within(1).of(0)
|
|
113
|
+
end
|
|
112
114
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
115
|
+
it 'scrolls to element (center)' do
|
|
116
|
+
element = browser.div(id: 'center')
|
|
117
|
+
element.scroll.to :center
|
|
116
118
|
|
|
117
|
-
|
|
119
|
+
element_rect = browser.execute_script('return arguments[0].getBoundingClientRect()', element)
|
|
118
120
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
+
expect(element_rect['top']).to eq(element_rect['bottom'] - element_rect['height'])
|
|
122
|
+
end
|
|
121
123
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
124
|
+
it 'scrolls to element (bottom)' do
|
|
125
|
+
element = browser.div(id: 'center')
|
|
126
|
+
element.scroll.to :bottom
|
|
125
127
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
+
element_bottom = browser.execute_script('return arguments[0].getBoundingClientRect().bottom', element)
|
|
129
|
+
window_height = browser.execute_script('return window.innerHeight')
|
|
128
130
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
+
expect(element_bottom).to be_within(1).of(window_height)
|
|
132
|
+
end
|
|
131
133
|
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
134
|
+
it 'scrolls to element multiple times' do
|
|
135
|
+
2.times do
|
|
136
|
+
element = browser.div(id: 'center')
|
|
137
|
+
element.scroll.to(:center)
|
|
136
138
|
|
|
137
|
-
|
|
139
|
+
element_rect = browser.execute_script('return arguments[0].getBoundingClientRect()', element)
|
|
138
140
|
|
|
139
|
-
|
|
141
|
+
expect(element_rect['top']).to eq(element_rect['bottom'] - element_rect['height'])
|
|
142
|
+
end
|
|
140
143
|
end
|
|
141
|
-
end
|
|
142
144
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
+
it 'raises error when scroll param is not valid' do
|
|
146
|
+
expect { browser.div(id: 'top').scroll.to(:blah) }.to raise_error(ArgumentError)
|
|
147
|
+
end
|
|
145
148
|
end
|
|
146
|
-
end
|
|
147
149
|
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
150
|
+
describe '#by' do
|
|
151
|
+
it 'offset' do
|
|
152
|
+
browser.scroll.to :top
|
|
153
|
+
pause
|
|
154
|
+
initial_top = current_top
|
|
155
|
+
browser.scroll.to :bottom
|
|
156
|
+
pause
|
|
157
|
+
scroll_by = top_centered_viewport
|
|
158
|
+
|
|
159
|
+
element = browser.div(id: 'bottom')
|
|
160
|
+
element.scroll.by(0, scroll_by)
|
|
161
|
+
pause
|
|
162
|
+
expect(current_top).to be_within(1).of(scroll_by + initial_top)
|
|
163
|
+
end
|
|
161
164
|
end
|
|
162
|
-
end
|
|
163
165
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
166
|
+
describe '#from',
|
|
167
|
+
except: [{browser: %i[firefox safari], reason: 'incorrect MoveTargetOutOfBoundsError'},
|
|
168
|
+
{browser: :ie, reason: 'Not implemented'}] do
|
|
169
|
+
it 'scrolls from element by given amount' do
|
|
170
|
+
browser.goto(WatirSpec.url_for('scroll_nested_offscreen.html'))
|
|
171
|
+
iframe = browser.iframe
|
|
169
172
|
|
|
170
|
-
|
|
173
|
+
iframe.scroll.from.by(0, 200)
|
|
171
174
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
+
checkbox = iframe.checkbox(name: 'scroll_checkbox')
|
|
176
|
+
expect(in_viewport?(checkbox)).to be true
|
|
177
|
+
end
|
|
175
178
|
|
|
176
|
-
|
|
177
|
-
|
|
179
|
+
it 'scrolls from an element with an offset' do
|
|
180
|
+
browser.goto(WatirSpec.url_for('scroll_nested_offscreen.html'))
|
|
178
181
|
|
|
179
|
-
|
|
180
|
-
|
|
182
|
+
move_left = browser.execute_script('return arguments[0].getBoundingClientRect().width/2', browser.footer) -
|
|
183
|
+
browser.execute_script('return arguments[0].getBoundingClientRect().right/2', browser.iframe.we)
|
|
181
184
|
|
|
182
|
-
|
|
185
|
+
browser.footer.scroll.from(-move_left.round, -50).by(0, 200)
|
|
183
186
|
|
|
184
|
-
|
|
185
|
-
|
|
187
|
+
checkbox = browser.iframe.checkbox(name: 'scroll_checkbox')
|
|
188
|
+
expect(in_viewport?(checkbox)).to be true
|
|
189
|
+
end
|
|
186
190
|
end
|
|
187
191
|
end
|
|
188
|
-
end
|
|
189
192
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
193
|
+
def in_viewport?(element)
|
|
194
|
+
in_viewport = <<~IN_VIEWPORT
|
|
195
|
+
for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
|
|
196
|
+
e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
|
|
197
|
+
return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
|
|
198
|
+
window.pageYOffset&&t+o>window.pageXOffset
|
|
199
|
+
IN_VIEWPORT
|
|
197
200
|
|
|
198
|
-
|
|
199
|
-
|
|
201
|
+
element.browser.execute_script(in_viewport, element.we)
|
|
202
|
+
end
|
|
200
203
|
|
|
201
|
-
|
|
202
|
-
|
|
204
|
+
def pause
|
|
205
|
+
sleep 0.2
|
|
206
|
+
end
|
|
203
207
|
end
|
|
204
208
|
end
|
|
@@ -2,101 +2,104 @@
|
|
|
2
2
|
|
|
3
3
|
require 'watirspec_helper'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
context 'with errors' do
|
|
10
|
-
it 'returns false when element does not exist' do
|
|
11
|
-
missing_shadow_root = browser.div(id: 'does_not_exist').shadow_root
|
|
12
|
-
expect(missing_shadow_root).not_to exist
|
|
13
|
-
end
|
|
14
|
-
|
|
15
|
-
it 'raises ArgumentError when using :xpath to locate elements directly from the shadow root' do
|
|
16
|
-
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
17
|
-
expect { shadow_root.element(xpath: './/span').exists? }.to raise_exception(ArgumentError)
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
it 'returns false when locating element in shadow root that does not exist',
|
|
21
|
-
except: {browser: :safari, reason: 'shadow endpoint not recognized'} do
|
|
22
|
-
missing_shadow_root = browser.div(id: 'non_host').shadow_root
|
|
23
|
-
expect(missing_shadow_root.element).not_to exist
|
|
5
|
+
module Watir
|
|
6
|
+
describe ShadowRoot do
|
|
7
|
+
before do
|
|
8
|
+
browser.goto(WatirSpec.url_for('shadow_dom.html'))
|
|
24
9
|
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
context 'without errors', only: {browser: %i[firefox chrome edge]} do
|
|
28
|
-
describe '#exists?' do
|
|
29
|
-
it 'returns true when element has a shadow DOM' do
|
|
30
|
-
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
31
|
-
expect(shadow_root).to exist
|
|
32
|
-
end
|
|
33
10
|
|
|
34
|
-
|
|
35
|
-
|
|
11
|
+
context 'with errors' do
|
|
12
|
+
it 'returns false when element does not exist' do
|
|
13
|
+
missing_shadow_root = browser.div(id: 'does_not_exist').shadow_root
|
|
36
14
|
expect(missing_shadow_root).not_to exist
|
|
37
15
|
end
|
|
38
|
-
end
|
|
39
|
-
|
|
40
|
-
describe 'locating', except: {browser: :firefox, reason: 'location not supported yet'} do
|
|
41
|
-
it 'locates a nested element' do
|
|
42
|
-
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
43
|
-
expect(shadow_root.element.id).to eq('shadow_content')
|
|
44
|
-
expect(shadow_root.element(id: 'nested_shadow_host').id).to eq('nested_shadow_host')
|
|
45
|
-
expect(shadow_root.element(id: /nested_shadow_.+/).id).to eq('nested_shadow_host')
|
|
46
|
-
expect(shadow_root.element(css: 'div').id).to eq('nested_shadow_host')
|
|
47
|
-
expect(shadow_root.div.id).to eq('nested_shadow_host')
|
|
48
|
-
end
|
|
49
16
|
|
|
50
|
-
it '
|
|
17
|
+
it 'raises ArgumentError when using :xpath to locate elements directly from the shadow root' do
|
|
51
18
|
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
52
|
-
expect
|
|
53
|
-
expect(shadow_root.elements(id: 'nested_shadow_host').map(&:id)).to eq(['nested_shadow_host'])
|
|
54
|
-
expect(shadow_root.elements(id: /nested_shadow_.+/).map(&:id)).to eq(['nested_shadow_host'])
|
|
55
|
-
expect(shadow_root.elements(css: 'div').map(&:id)).to eq(%w[nested_shadow_host chrome_workaround])
|
|
56
|
-
expect(shadow_root.divs.map(&:id)).to eq(%w[nested_shadow_host chrome_workaround])
|
|
19
|
+
expect { shadow_root.element(xpath: './/span').exists? }.to raise_exception(ArgumentError)
|
|
57
20
|
end
|
|
58
21
|
|
|
59
|
-
it '
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
expect(
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
it 'locates a collection of nested elements within a nested shadow DOM' do
|
|
66
|
-
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
67
|
-
nested_shadow_root = shadow_root.element(id: 'nested_shadow_host').shadow_root
|
|
68
|
-
expect(nested_shadow_root.elements.count).to eq(2)
|
|
69
|
-
expect(nested_shadow_root.elements.map(&:id)).to include('nested_shadow_content')
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
it 'allows using :xpath to locate elements with an element of a shadow root' do
|
|
73
|
-
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
74
|
-
expect(shadow_root.span.element(xpath: './/span')).to exist
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
it 'click elements within the shadow dom' do
|
|
78
|
-
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
79
|
-
shadow_root.link.click
|
|
80
|
-
expect(browser.url).to include('scroll.html')
|
|
22
|
+
it 'returns false when locating element in shadow root that does not exist',
|
|
23
|
+
except: {browser: %i[ie safari], reason: 'shadow endpoint not recognized'} do
|
|
24
|
+
missing_shadow_root = browser.div(id: 'non_host').shadow_root
|
|
25
|
+
expect(missing_shadow_root.element).not_to exist
|
|
81
26
|
end
|
|
27
|
+
end
|
|
82
28
|
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
29
|
+
context 'without errors', only: {browser: %i[firefox chrome edge]} do
|
|
30
|
+
describe '#exists?' do
|
|
31
|
+
it 'returns true when element has a shadow DOM' do
|
|
32
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
33
|
+
expect(shadow_root).to exist
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
it 'returns false when element does not have a shadow DOM' do
|
|
37
|
+
missing_shadow_root = browser.div(id: 'non_host').shadow_root
|
|
38
|
+
expect(missing_shadow_root).not_to exist
|
|
39
|
+
end
|
|
87
40
|
end
|
|
88
41
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
42
|
+
describe 'locating', except: {browser: :firefox, reason: 'location not supported yet'} do
|
|
43
|
+
it 'locates a nested element' do
|
|
44
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
45
|
+
expect(shadow_root.element.id).to eq('shadow_content')
|
|
46
|
+
expect(shadow_root.element(id: 'nested_shadow_host').id).to eq('nested_shadow_host')
|
|
47
|
+
expect(shadow_root.element(id: /nested_shadow_.+/).id).to eq('nested_shadow_host')
|
|
48
|
+
expect(shadow_root.element(css: 'div').id).to eq('nested_shadow_host')
|
|
49
|
+
expect(shadow_root.div.id).to eq('nested_shadow_host')
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
it 'locates a collection of nested elements' do
|
|
53
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
54
|
+
expect(shadow_root.elements.count).to eq(8)
|
|
55
|
+
expect(shadow_root.elements(id: 'nested_shadow_host').map(&:id)).to eq(['nested_shadow_host'])
|
|
56
|
+
expect(shadow_root.elements(id: /nested_shadow_.+/).map(&:id)).to eq(['nested_shadow_host'])
|
|
57
|
+
expect(shadow_root.elements(css: 'div').map(&:id)).to eq(%w[nested_shadow_host chrome_workaround])
|
|
58
|
+
expect(shadow_root.divs.map(&:id)).to eq(%w[nested_shadow_host chrome_workaround])
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
it 'locates a nested element within a nested shadow DOM' do
|
|
62
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
63
|
+
nested_shadow_root = shadow_root.element(id: 'nested_shadow_host').shadow_root
|
|
64
|
+
expect(nested_shadow_root.element.id).to eq('nested_shadow_content')
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
it 'locates a collection of nested elements within a nested shadow DOM' do
|
|
68
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
69
|
+
nested_shadow_root = shadow_root.element(id: 'nested_shadow_host').shadow_root
|
|
70
|
+
expect(nested_shadow_root.elements.count).to eq(2)
|
|
71
|
+
expect(nested_shadow_root.elements.map(&:id)).to include('nested_shadow_content')
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
it 'allows using :xpath to locate elements with an element of a shadow root' do
|
|
75
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
76
|
+
expect(shadow_root.span.element(xpath: './/span')).to exist
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
it 'click elements within the shadow dom' do
|
|
80
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
81
|
+
shadow_root.link.click
|
|
82
|
+
expect(browser.url).to include('scroll.html')
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
it 'click! elements within the shadow dom' do
|
|
86
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
87
|
+
shadow_root.link.click!
|
|
88
|
+
expect(browser.url).to include('scroll.html')
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
it 'inputs form elements within the shadow dom' do
|
|
92
|
+
shadow_root = browser.div(id: 'shadow_host').shadow_root
|
|
93
|
+
|
|
94
|
+
shadow_root.text_field.set('abc')
|
|
95
|
+
expect(shadow_root.text_field.value).to eq('abc')
|
|
96
|
+
|
|
97
|
+
shadow_root.checkbox.set
|
|
98
|
+
expect(shadow_root.checkbox.set?).to be(true)
|
|
99
|
+
|
|
100
|
+
shadow_root.file_field.set(File.expand_path(__FILE__))
|
|
101
|
+
expect(shadow_root.file_field.value).to include('shadow_root_spec.rb')
|
|
102
|
+
end
|
|
100
103
|
end
|
|
101
104
|
end
|
|
102
105
|
end
|