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
|
@@ -2,1049 +2,1068 @@
|
|
|
2
2
|
|
|
3
3
|
require 'watirspec_helper'
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
describe '.new' do
|
|
12
|
-
it "finds elements matching the conditions when given a hash of :how => 'what' arguments" do
|
|
13
|
-
expect(browser.checkbox(name: 'new_user_interests', title: 'Dancing is fun!').value).to eq 'dancing'
|
|
14
|
-
expect(browser.text_field(class_name: 'name', index: 1).id).to eq 'new_user_last_name'
|
|
5
|
+
module Watir
|
|
6
|
+
describe Element do
|
|
7
|
+
before do
|
|
8
|
+
@c = Selenium::WebDriver::Platform.mac? ? :command : :control
|
|
9
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
15
10
|
end
|
|
16
11
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
describe '.new' do
|
|
13
|
+
it "finds elements matching the conditions when given a hash of :how => 'what' arguments" do
|
|
14
|
+
expect(browser.checkbox(name: 'new_user_interests', title: 'Dancing is fun!').value).to eq 'dancing'
|
|
15
|
+
expect(browser.text_field(class_name: 'name', index: 1).id).to eq 'new_user_last_name'
|
|
16
|
+
end
|
|
20
17
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
18
|
+
it "raises UnknownObjectException when given a hash of :how => 'what' arguments (non-existing object)" do
|
|
19
|
+
expect { browser.text_field(index: 100, name: 'foo').id }.to raise_unknown_object_exception
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
it 'raises ArgumentError if given the wrong number of arguments' do
|
|
23
|
+
expect { described_class.new(browser.wd, 'foo') }.to raise_error(ArgumentError)
|
|
24
|
+
end
|
|
25
25
|
end
|
|
26
|
-
end
|
|
27
26
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
describe '#element_call' do
|
|
28
|
+
it 'handles exceptions when taking an action on a stale element' do
|
|
29
|
+
browser.goto WatirSpec.url_for('removed_element.html')
|
|
31
30
|
|
|
32
|
-
|
|
31
|
+
element = browser.div(id: 'text').locate
|
|
33
32
|
|
|
34
|
-
|
|
33
|
+
browser.refresh
|
|
35
34
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
35
|
+
expect(element).to be_stale
|
|
36
|
+
expect { element.text }.not_to raise_error
|
|
37
|
+
end
|
|
39
38
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
it 'relocates stale element when taking an action on it' do
|
|
40
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
41
|
+
element = browser.text_field(id: 'new_user_first_name').locate
|
|
42
|
+
browser.refresh
|
|
43
|
+
expect { element.click }.not_to raise_exception
|
|
44
|
+
end
|
|
45
45
|
end
|
|
46
|
-
end
|
|
47
46
|
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
describe '#eq and #eql?' do
|
|
48
|
+
before { browser.goto WatirSpec.url_for('definition_lists.html') }
|
|
50
49
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
50
|
+
it 'returns true if the two elements point to the same DOM element' do
|
|
51
|
+
a = browser.dl(id: 'experience-list')
|
|
52
|
+
b = browser.dl
|
|
54
53
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
expect(a).to eq b
|
|
55
|
+
expect(a).to eql(b)
|
|
56
|
+
end
|
|
58
57
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
58
|
+
it 'returns false if the two elements are not the same' do
|
|
59
|
+
a = browser.dls[0]
|
|
60
|
+
b = browser.dls[1]
|
|
62
61
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
62
|
+
expect(a).not_to eq b
|
|
63
|
+
expect(a).not_to eql(b)
|
|
64
|
+
end
|
|
66
65
|
|
|
67
|
-
|
|
68
|
-
|
|
66
|
+
it 'returns false if the other object is not an Element' do
|
|
67
|
+
expect(browser.dl).not_to eq 1
|
|
68
|
+
end
|
|
69
69
|
end
|
|
70
|
-
end
|
|
71
70
|
|
|
72
|
-
|
|
73
|
-
|
|
71
|
+
describe 'data-* attributes' do
|
|
72
|
+
before { browser.goto WatirSpec.url_for('data_attributes.html') }
|
|
74
73
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
74
|
+
it 'finds elements by a data-* attribute' do
|
|
75
|
+
expect(browser.p(data_type: 'ruby-library')).to exist
|
|
76
|
+
end
|
|
78
77
|
|
|
79
|
-
|
|
80
|
-
|
|
78
|
+
it 'returns the value of a data-* attribute' do
|
|
79
|
+
expect(browser.p.data_type).to eq 'ruby-library'
|
|
80
|
+
end
|
|
81
81
|
end
|
|
82
|
-
end
|
|
83
82
|
|
|
84
|
-
|
|
85
|
-
|
|
83
|
+
describe 'aria-* attributes' do
|
|
84
|
+
before { browser.goto WatirSpec.url_for('aria_attributes.html') }
|
|
86
85
|
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
86
|
+
it 'finds elements by a aria-* attribute' do
|
|
87
|
+
expect(browser.p(aria_label: 'ruby-library')).to exist
|
|
88
|
+
end
|
|
90
89
|
|
|
91
|
-
|
|
92
|
-
|
|
90
|
+
it 'returns the value of a aria-* attribute' do
|
|
91
|
+
expect(browser.p.aria_label).to eq 'ruby-library'
|
|
92
|
+
end
|
|
93
93
|
end
|
|
94
|
-
end
|
|
95
94
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
describe 'visible text' do
|
|
96
|
+
it 'finds elements by visible text' do
|
|
97
|
+
browser.goto WatirSpec.url_for('non_control_elements.html')
|
|
99
98
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
99
|
+
expect(browser.element(visible_text: 'all visible')).to exist
|
|
100
|
+
expect(browser.element(visible_text: /all visible/)).to exist
|
|
101
|
+
expect(browser.element(visible_text: /some visible/)).to exist
|
|
102
|
+
expect(browser.element(visible_text: 'Link 2', class: 'external')).to exist
|
|
103
|
+
expect(browser.element(visible_text: /Link 2/, class: 'external')).to exist
|
|
104
|
+
end
|
|
106
105
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
it 'finds elements by visible text in spite of hidden text',
|
|
107
|
+
except: {browser: :safari, reason: 'Safari is not filtering out hidden text'} do
|
|
108
|
+
browser.goto WatirSpec.url_for('non_control_elements.html')
|
|
110
109
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
110
|
+
expect(browser.element(visible_text: 'some visible')).to exist
|
|
111
|
+
expect(browser.element(visible_text: 'none visible')).not_to exist
|
|
112
|
+
expect(browser.element(visible_text: /none visible/)).not_to exist
|
|
113
|
+
end
|
|
115
114
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
115
|
+
it 'raises exception unless value is a String or a RegExp' do
|
|
116
|
+
browser.goto WatirSpec.url_for('non_control_elements.html')
|
|
117
|
+
msg = /expected one of \[String, Regexp\], got 7:Integer/
|
|
118
|
+
expect { browser.element(visible_text: 7).exists? }.to raise_exception(TypeError, msg)
|
|
119
|
+
end
|
|
121
120
|
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
121
|
+
it 'raises exception unless key is valid' do
|
|
122
|
+
browser.goto WatirSpec.url_for('non_control_elements.html')
|
|
123
|
+
msg = /Unable to build XPath using 7:Integer/
|
|
124
|
+
expect { browser.element(7 => /foo/).exists? }.to raise_exception(Watir::Exception::Error, msg)
|
|
125
|
+
end
|
|
126
126
|
end
|
|
127
|
-
end
|
|
128
127
|
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
128
|
+
describe 'finding with unknown tag name' do
|
|
129
|
+
it 'finds an element without arguments' do
|
|
130
|
+
expect(browser.element).to exist
|
|
131
|
+
end
|
|
133
132
|
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
it 'finds an element by xpath' do
|
|
134
|
+
expect(browser.element(xpath: "//*[@for='new_user_first_name']")).to exist
|
|
135
|
+
end
|
|
137
136
|
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
137
|
+
it 'finds an element by arbitrary attribute' do
|
|
138
|
+
expect(browser.element(title: 'no title')).to exist
|
|
139
|
+
end
|
|
141
140
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
141
|
+
it 'finds several elements by xpath' do
|
|
142
|
+
expect(browser.elements(xpath: '//a').length).to eq 1
|
|
143
|
+
end
|
|
145
144
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
145
|
+
it 'finds several elements by arbitrary attribute' do
|
|
146
|
+
expect(browser.elements(id: /^new_user/).length).to eq 33
|
|
147
|
+
end
|
|
149
148
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
149
|
+
it "finds an element from an element's subtree" do
|
|
150
|
+
expect(browser.fieldset.element(id: 'first_label')).to exist
|
|
151
|
+
expect(browser.field_set.element(id: 'first_label')).to exist
|
|
152
|
+
end
|
|
154
153
|
|
|
155
|
-
|
|
156
|
-
|
|
154
|
+
it "finds several elements from an element's subtree" do
|
|
155
|
+
expect(browser.fieldset.elements(xpath: './/label').length).to eq 23
|
|
156
|
+
end
|
|
157
157
|
end
|
|
158
|
-
end
|
|
159
158
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
159
|
+
describe '#to_subtype' do
|
|
160
|
+
it 'returns a CheckBox instance' do
|
|
161
|
+
e = browser.input(xpath: "//input[@type='checkbox']").to_subtype
|
|
162
|
+
expect(e).to be_a(Watir::CheckBox)
|
|
163
|
+
end
|
|
165
164
|
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
165
|
+
it 'returns a Radio instance' do
|
|
166
|
+
e = browser.input(xpath: "//input[@type='radio']").to_subtype
|
|
167
|
+
expect(e).to be_a(Watir::Radio)
|
|
168
|
+
end
|
|
170
169
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
170
|
+
it 'returns a Button instance' do
|
|
171
|
+
es = [
|
|
172
|
+
browser.input(xpath: "//input[@type='button']").to_subtype,
|
|
173
|
+
browser.input(xpath: "//input[@type='submit']").to_subtype,
|
|
174
|
+
browser.input(xpath: "//input[@type='reset']").to_subtype,
|
|
175
|
+
browser.input(xpath: "//input[@type='image']").to_subtype
|
|
176
|
+
]
|
|
178
177
|
|
|
179
|
-
|
|
180
|
-
|
|
178
|
+
es.all? { |e| expect(e).to be_a(Watir::Button) }
|
|
179
|
+
end
|
|
181
180
|
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
181
|
+
it 'returns a TextField instance' do
|
|
182
|
+
e = browser.input(xpath: "//input[@type='text']").to_subtype
|
|
183
|
+
expect(e).to be_a(Watir::TextField)
|
|
184
|
+
end
|
|
186
185
|
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
186
|
+
it 'returns a FileField instance' do
|
|
187
|
+
e = browser.input(xpath: "//input[@type='file']").to_subtype
|
|
188
|
+
expect(e).to be_a(Watir::FileField)
|
|
189
|
+
end
|
|
191
190
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
191
|
+
it 'returns a Div instance' do
|
|
192
|
+
el = browser.element(xpath: "//*[@id='messages']").to_subtype
|
|
193
|
+
expect(el).to be_a(Watir::Div)
|
|
194
|
+
end
|
|
195
195
|
end
|
|
196
|
-
end
|
|
197
196
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
197
|
+
describe '#focus' do
|
|
198
|
+
it 'fires the onfocus event for the given element' do
|
|
199
|
+
tf = browser.text_field(id: 'new_user_occupation')
|
|
200
|
+
expect(tf.value).to eq 'Developer'
|
|
201
|
+
tf.focus
|
|
202
|
+
expect(browser.div(id: 'onfocus_test').text).to eq 'changed by onfocus event'
|
|
203
|
+
end
|
|
204
204
|
end
|
|
205
|
-
end
|
|
206
205
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
206
|
+
describe '#focused?',
|
|
207
|
+
except: {browser: :firefox,
|
|
208
|
+
driver: :remote_driver,
|
|
209
|
+
reason: 'https://github.com/SeleniumHQ/selenium/issues/2555'} do
|
|
210
|
+
it 'knows if the element is focused' do
|
|
211
|
+
expect(browser.element(id: 'new_user_first_name')).to be_focused
|
|
212
|
+
expect(browser.element(id: 'new_user_last_name')).not_to be_focused
|
|
213
|
+
end
|
|
214
214
|
end
|
|
215
|
-
end
|
|
216
215
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
216
|
+
describe '#fire_event' do
|
|
217
|
+
it 'fires the given event' do
|
|
218
|
+
expect(browser.div(id: 'onfocus_test').text).to be_empty
|
|
219
|
+
browser.text_field(id: 'new_user_occupation').fire_event('onfocus')
|
|
220
|
+
expect(browser.div(id: 'onfocus_test').text).to eq 'changed by onfocus event'
|
|
221
|
+
end
|
|
222
222
|
end
|
|
223
|
-
end
|
|
224
|
-
|
|
225
|
-
describe '#cache=' do
|
|
226
|
-
it 'bypasses selector location' do
|
|
227
|
-
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
228
223
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
224
|
+
describe '#cache=' do
|
|
225
|
+
it 'bypasses selector location' do
|
|
226
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
232
227
|
|
|
233
|
-
|
|
234
|
-
|
|
228
|
+
wd = browser.div.wd
|
|
229
|
+
element = described_class.new(browser, id: 'not_valid')
|
|
230
|
+
element.cache = wd
|
|
235
231
|
|
|
236
|
-
|
|
237
|
-
|
|
232
|
+
expect(element).to exist
|
|
233
|
+
end
|
|
238
234
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
element.cache = wd
|
|
235
|
+
it 'can be cleared' do
|
|
236
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
242
237
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
end
|
|
238
|
+
wd = browser.div.wd
|
|
239
|
+
element = described_class.new(browser, id: 'not_valid')
|
|
240
|
+
element.cache = wd
|
|
247
241
|
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
242
|
+
browser.refresh
|
|
243
|
+
expect(element).not_to exist
|
|
244
|
+
end
|
|
251
245
|
end
|
|
252
246
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
browser.refresh
|
|
258
|
-
|
|
259
|
-
expect(element).to be_stale
|
|
260
|
-
expect(element).to exist
|
|
261
|
-
end
|
|
247
|
+
describe '#exists?' do
|
|
248
|
+
before do
|
|
249
|
+
browser.goto WatirSpec.url_for('removed_element.html')
|
|
250
|
+
end
|
|
262
251
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
element = browser.element(element: div.wd)
|
|
252
|
+
it 'element from a collection is re-looked up after it becomes stale',
|
|
253
|
+
except: {browser: :ie, reason: 'throwing NoSuchElement instead'} do
|
|
254
|
+
element = browser.divs(id: 'text').first.locate
|
|
267
255
|
|
|
268
|
-
|
|
269
|
-
expect(element).to be_stale
|
|
256
|
+
browser.refresh
|
|
270
257
|
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
258
|
+
expect(element).to be_stale
|
|
259
|
+
expect(element).to exist
|
|
260
|
+
end
|
|
274
261
|
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
262
|
+
it 'element from a selenium element throws an exception when relocated',
|
|
263
|
+
except: {browser: :ie, reason: 'throwing NoSuchElement instead'} do
|
|
264
|
+
div = browser.div.locate
|
|
265
|
+
element = browser.element(element: div.wd)
|
|
278
266
|
|
|
279
|
-
|
|
267
|
+
browser.refresh
|
|
268
|
+
expect(element).to be_stale
|
|
280
269
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
270
|
+
msg = 'Can not relocate a Watir element initialized by a Selenium element'
|
|
271
|
+
expect { element.exists? }.to raise_exception(Watir::Exception::LocatorException, msg)
|
|
272
|
+
end
|
|
284
273
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
end
|
|
289
|
-
end
|
|
274
|
+
it 'element from a selenium element with other locators throws an exception' do
|
|
275
|
+
div = browser.div.locate
|
|
276
|
+
element = browser.element(element: div.wd, id: 'foo')
|
|
290
277
|
|
|
291
|
-
|
|
292
|
-
before do
|
|
293
|
-
browser.goto(WatirSpec.url_for('wait.html'))
|
|
294
|
-
end
|
|
278
|
+
browser.refresh
|
|
295
279
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
280
|
+
msg = 'Can not relocate a Watir element initialized by a Selenium element'
|
|
281
|
+
expect { element.exists? }.to raise_exception(Watir::Exception::LocatorException, msg)
|
|
282
|
+
end
|
|
299
283
|
|
|
300
|
-
|
|
301
|
-
|
|
284
|
+
it 'returns false when tag name does not match id' do
|
|
285
|
+
watir_element = browser.span(id: 'text')
|
|
286
|
+
expect(watir_element).not_to exist
|
|
287
|
+
end
|
|
302
288
|
end
|
|
303
289
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
290
|
+
describe '#present?' do
|
|
291
|
+
before do
|
|
292
|
+
browser.goto(WatirSpec.url_for('wait.html'))
|
|
293
|
+
end
|
|
307
294
|
|
|
308
|
-
|
|
309
|
-
|
|
295
|
+
it 'returns true if the element exists and is visible' do
|
|
296
|
+
expect(browser.div(id: 'foo')).to be_present
|
|
297
|
+
end
|
|
310
298
|
|
|
311
|
-
|
|
299
|
+
it 'returns false if the element exists but is not visible' do
|
|
300
|
+
expect(browser.div(id: 'bar')).not_to be_present
|
|
301
|
+
end
|
|
312
302
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
303
|
+
it 'returns false if the element does not exist' do
|
|
304
|
+
expect(browser.div(id: 'should-not-exist')).not_to be_present
|
|
305
|
+
end
|
|
316
306
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
320
|
-
end
|
|
307
|
+
it 'handles staleness' do
|
|
308
|
+
element = browser.div(id: 'foo').locate
|
|
321
309
|
|
|
322
|
-
|
|
323
|
-
expect(browser.button(name: 'new_user_submit')).to be_enabled
|
|
324
|
-
end
|
|
310
|
+
allow(element).to receive(:stale?).and_return(true)
|
|
325
311
|
|
|
326
|
-
|
|
327
|
-
|
|
312
|
+
expect(element).to be_present
|
|
313
|
+
end
|
|
328
314
|
end
|
|
329
315
|
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
316
|
+
describe '#enabled?' do
|
|
317
|
+
before do
|
|
318
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
319
|
+
end
|
|
334
320
|
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
321
|
+
it 'returns true if the element is enabled' do
|
|
322
|
+
expect(browser.button(name: 'new_user_submit')).to be_enabled
|
|
323
|
+
end
|
|
338
324
|
|
|
339
|
-
|
|
325
|
+
it 'returns false if the element is disabled' do
|
|
326
|
+
expect(browser.button(name: 'new_user_submit_disabled')).not_to be_enabled
|
|
327
|
+
end
|
|
340
328
|
|
|
341
|
-
|
|
329
|
+
it "raises UnknownObjectException if the element doesn't exist" do
|
|
330
|
+
expect { browser.button(name: 'no_such_name').enabled? }.to raise_unknown_object_exception
|
|
331
|
+
end
|
|
342
332
|
end
|
|
343
333
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
334
|
+
describe '#stale?' do
|
|
335
|
+
it 'returns true if the element is stale' do
|
|
336
|
+
element = browser.button(name: 'new_user_submit_disabled').locate
|
|
347
337
|
|
|
348
|
-
|
|
338
|
+
browser.refresh
|
|
349
339
|
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
end
|
|
340
|
+
expect(element).to be_stale
|
|
341
|
+
end
|
|
353
342
|
|
|
354
|
-
|
|
355
|
-
|
|
343
|
+
it 'returns true the second time if the element is stale',
|
|
344
|
+
except: {browser: :ie, reason: 'throwing NoSuchElement instead'} do
|
|
345
|
+
element = browser.div.locate
|
|
356
346
|
|
|
357
|
-
|
|
358
|
-
end
|
|
359
|
-
end
|
|
347
|
+
browser.refresh
|
|
360
348
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
before do
|
|
364
|
-
browser.goto(WatirSpec.url_for('class_locator.html'))
|
|
349
|
+
expect(element).to be_stale
|
|
350
|
+
expect(element).to be_stale
|
|
365
351
|
end
|
|
366
352
|
|
|
367
|
-
it '
|
|
368
|
-
|
|
369
|
-
expect(e).to exist
|
|
370
|
-
expect(e.class_name).to eq 'a'
|
|
371
|
-
end
|
|
353
|
+
it 'returns false if the element is not stale' do
|
|
354
|
+
element = browser.button(name: 'new_user_submit_disabled').locate
|
|
372
355
|
|
|
373
|
-
|
|
374
|
-
e = browser.div(class: 'b')
|
|
375
|
-
expect(e).to exist
|
|
376
|
-
expect(e.class_name).to eq 'a b c'
|
|
377
|
-
end
|
|
378
|
-
|
|
379
|
-
it 'does not match only part of the class name' do
|
|
380
|
-
expect(browser.div(class: 'bc')).to_not exist
|
|
356
|
+
expect(element).not_to be_stale
|
|
381
357
|
end
|
|
358
|
+
end
|
|
382
359
|
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
360
|
+
describe '#exist?' do
|
|
361
|
+
context 'when using :class locator' do
|
|
362
|
+
before do
|
|
363
|
+
browser.goto(WatirSpec.url_for('class_locator.html'))
|
|
364
|
+
end
|
|
386
365
|
|
|
387
|
-
context 'with multiple classes' do
|
|
388
366
|
it 'matches when the element has a single class' do
|
|
389
|
-
e = browser.div(class:
|
|
367
|
+
e = browser.div(class: 'a')
|
|
390
368
|
expect(e).to exist
|
|
391
369
|
expect(e.class_name).to eq 'a'
|
|
392
370
|
end
|
|
393
371
|
|
|
394
|
-
it 'matches
|
|
395
|
-
e = browser.div(class:
|
|
372
|
+
it 'matches when the element has several classes' do
|
|
373
|
+
e = browser.div(class: 'b')
|
|
396
374
|
expect(e).to exist
|
|
397
375
|
expect(e.class_name).to eq 'a b c'
|
|
398
376
|
end
|
|
399
377
|
|
|
400
|
-
it '
|
|
401
|
-
|
|
402
|
-
expect(e).to exist
|
|
403
|
-
expect(e.class_name).to eq 'abc'
|
|
378
|
+
it 'does not match only part of the class name' do
|
|
379
|
+
expect(browser.div(class: 'bc')).not_to exist
|
|
404
380
|
end
|
|
405
381
|
|
|
406
|
-
it 'matches
|
|
407
|
-
|
|
408
|
-
expect(e).to exist
|
|
409
|
-
expect(e.class_name).to eq 'a b'
|
|
382
|
+
it 'matches part of the class name when given a regexp' do
|
|
383
|
+
expect(browser.div(class: /c/)).to exist
|
|
410
384
|
end
|
|
411
385
|
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
386
|
+
context 'with multiple classes' do
|
|
387
|
+
it 'matches when the element has a single class' do
|
|
388
|
+
e = browser.div(class: ['a'])
|
|
389
|
+
expect(e).to exist
|
|
390
|
+
expect(e.class_name).to eq 'a'
|
|
391
|
+
end
|
|
392
|
+
|
|
393
|
+
it 'matches a non-ordered subset' do
|
|
394
|
+
e = browser.div(class: %w[c a])
|
|
395
|
+
expect(e).to exist
|
|
396
|
+
expect(e.class_name).to eq 'a b c'
|
|
397
|
+
end
|
|
398
|
+
|
|
399
|
+
it 'matches one with a negation' do
|
|
400
|
+
e = browser.div(class: ['!a'])
|
|
401
|
+
expect(e).to exist
|
|
402
|
+
expect(e.class_name).to eq 'abc'
|
|
403
|
+
end
|
|
404
|
+
|
|
405
|
+
it 'matches multiple with a negation' do
|
|
406
|
+
e = browser.div(class: ['a', '!c', 'b'])
|
|
407
|
+
expect(e).to exist
|
|
408
|
+
expect(e.class_name).to eq 'a b'
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
it 'matches with any whitespace' do
|
|
412
|
+
e = browser.div(class: %w[newline tabbed])
|
|
413
|
+
expect(e).to exist
|
|
414
|
+
expect(e.class_name).to eq "first\nnewline\ttabbed last"
|
|
415
|
+
end
|
|
416
416
|
end
|
|
417
417
|
end
|
|
418
|
-
end
|
|
419
418
|
|
|
420
|
-
|
|
421
|
-
|
|
419
|
+
context 'when using attribute presence' do
|
|
420
|
+
before { browser.goto WatirSpec.url_for('data_attributes.html') }
|
|
421
|
+
|
|
422
|
+
it 'finds element by attribute presence' do
|
|
423
|
+
expect(browser.p(data_type: true)).to exist
|
|
424
|
+
expect(browser.p(class: true)).not_to exist
|
|
425
|
+
end
|
|
422
426
|
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
427
|
+
it 'finds element by attribute absence' do
|
|
428
|
+
expect(browser.p(data_type: false)).not_to exist
|
|
429
|
+
expect(browser.p(class: false)).to exist
|
|
430
|
+
end
|
|
426
431
|
end
|
|
427
432
|
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
433
|
+
context 'when using :index locator' do
|
|
434
|
+
before { browser.goto WatirSpec.url_for('data_attributes.html') }
|
|
435
|
+
|
|
436
|
+
it 'finds the first element by index: 0' do
|
|
437
|
+
expect(browser.element(index: 0).tag_name).to eq 'html'
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
it 'finds the second element by index: 1' do
|
|
441
|
+
expect(browser.element(index: 1).tag_name).to eq 'head'
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
it 'finds the last element by index: -1' do
|
|
445
|
+
expect(browser.element(index: -1).tag_name).to eq 'div'
|
|
446
|
+
end
|
|
431
447
|
end
|
|
432
|
-
end
|
|
433
448
|
|
|
434
|
-
|
|
435
|
-
|
|
449
|
+
it "doesn't raise when called on nested elements" do
|
|
450
|
+
expect(browser.div(id: 'no_such_div').link(id: 'no_such_id')).not_to exist
|
|
451
|
+
end
|
|
436
452
|
|
|
437
|
-
it '
|
|
438
|
-
expect(browser.
|
|
453
|
+
it "doesn't raise when selector has with :xpath has :index" do
|
|
454
|
+
expect(browser.div(xpath: '//div', index: 1)).to exist
|
|
439
455
|
end
|
|
440
456
|
|
|
441
|
-
it '
|
|
442
|
-
expect(browser.
|
|
457
|
+
it "doesn't raise when selector has with :css has :index" do
|
|
458
|
+
expect(browser.div(css: 'div', index: 1)).to exist
|
|
443
459
|
end
|
|
444
460
|
|
|
445
|
-
it 'finds
|
|
446
|
-
expect(browser.element(
|
|
461
|
+
it 'finds element by Selenium name locator' do
|
|
462
|
+
expect(browser.element(name: 'new_user_first_name')).to exist
|
|
463
|
+
expect(browser.element(name: /new_user_first_name/)).to exist
|
|
447
464
|
end
|
|
448
|
-
end
|
|
449
465
|
|
|
450
|
-
|
|
451
|
-
|
|
466
|
+
it 'returns false when tag name does not match id' do
|
|
467
|
+
watir_element = browser.span(id: 'text')
|
|
468
|
+
expect(watir_element).not_to exist
|
|
469
|
+
end
|
|
452
470
|
end
|
|
453
471
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
472
|
+
describe '#send_keys' do
|
|
473
|
+
before do
|
|
474
|
+
browser.goto(WatirSpec.url_for('keylogger.html'))
|
|
475
|
+
end
|
|
457
476
|
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
end
|
|
477
|
+
let(:receiver) { browser.text_field(id: 'receiver') }
|
|
478
|
+
let(:events) { browser.element(id: 'output').ps.size }
|
|
461
479
|
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
480
|
+
it 'sends keystrokes to the element' do
|
|
481
|
+
receiver.send_keys 'hello world'
|
|
482
|
+
expect(receiver.value).to eq 'hello world'
|
|
483
|
+
expect(events).to eq 11
|
|
484
|
+
end
|
|
466
485
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
486
|
+
it 'accepts arbitrary list of arguments' do
|
|
487
|
+
receiver.send_keys 'hello', 'world'
|
|
488
|
+
expect(receiver.value).to eq 'helloworld'
|
|
489
|
+
expect(events).to eq 10
|
|
490
|
+
end
|
|
472
491
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
492
|
+
context 'with key combinations',
|
|
493
|
+
except: [{browser: :firefox, reason: 'https://github.com/mozilla/geckodriver/issues/245'},
|
|
494
|
+
{browser: :safari}] do
|
|
495
|
+
it 'performs from array' do
|
|
496
|
+
receiver.send_keys 'foo'
|
|
497
|
+
receiver.send_keys [@c, 'a']
|
|
498
|
+
receiver.send_keys :backspace
|
|
499
|
+
expect(receiver.value).to be_empty
|
|
500
|
+
expect(events).to eq 6
|
|
501
|
+
end
|
|
477
502
|
|
|
478
|
-
|
|
479
|
-
|
|
503
|
+
it 'performs from multiple arrays' do
|
|
504
|
+
receiver.send_keys 'foo'
|
|
505
|
+
receiver.send_keys [@c, 'a'], [@c, 'x']
|
|
506
|
+
expect(receiver.value).to be_empty
|
|
507
|
+
expect(events).to eq 7
|
|
508
|
+
end
|
|
480
509
|
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
510
|
+
it 'supports combination of strings and arrays' do
|
|
511
|
+
receiver.send_keys 'foo', [@c, 'a'], :backspace
|
|
512
|
+
expect(receiver.value).to be_empty
|
|
513
|
+
expect(events).to eq 6
|
|
514
|
+
end
|
|
515
|
+
end
|
|
485
516
|
end
|
|
486
517
|
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
518
|
+
describe '#click' do
|
|
519
|
+
it 'accepts modifiers', except: {browser: :ie} do
|
|
520
|
+
browser.a.click(@c)
|
|
521
|
+
expect { browser.windows.wait_until(size: 2) }.not_to raise_exception
|
|
522
|
+
ensure
|
|
523
|
+
browser.windows.restore!
|
|
524
|
+
end
|
|
491
525
|
end
|
|
492
526
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
receiver.send_keys [@c, 'a']
|
|
499
|
-
receiver.send_keys :backspace
|
|
500
|
-
expect(receiver.value).to be_empty
|
|
501
|
-
expect(events).to eq 6
|
|
527
|
+
describe '#set' do
|
|
528
|
+
it 'clicks an element by default that does not define #set' do
|
|
529
|
+
browser.goto(WatirSpec.url_for('non_control_elements.html'))
|
|
530
|
+
browser.element(id: 'best_language').set
|
|
531
|
+
expect(browser.div(id: 'best_language').text).to eq 'Ruby!'
|
|
502
532
|
end
|
|
503
533
|
|
|
504
|
-
it '
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
expect(
|
|
508
|
-
|
|
534
|
+
it 'clicks an element that does not define #set with provided modifiers', except: {browser: :ie} do
|
|
535
|
+
browser.a.set(@c)
|
|
536
|
+
browser.wait_until { |b| b.windows.size > 1 }
|
|
537
|
+
expect(browser.windows.size).to eq 2
|
|
538
|
+
ensure
|
|
539
|
+
browser.windows.restore!
|
|
509
540
|
end
|
|
510
541
|
|
|
511
|
-
it '
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
expect(
|
|
542
|
+
it 'does not click an element that does not define #set when passed false' do
|
|
543
|
+
browser.goto(WatirSpec.url_for('non_control_elements.html'))
|
|
544
|
+
browser.element(id: 'best_language').set(false)
|
|
545
|
+
expect(browser.div(id: 'best_language').text).not_to eq 'Ruby!'
|
|
515
546
|
end
|
|
516
|
-
end
|
|
517
|
-
end
|
|
518
547
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
end
|
|
526
|
-
end
|
|
548
|
+
it 'clicks a Button' do
|
|
549
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
550
|
+
browser.button(id: 'delete_user_submit').set
|
|
551
|
+
browser.wait_until { |b| !b.url.include? 'forms_with_input_elements.html' }
|
|
552
|
+
expect(browser.text).to include('Semantic table')
|
|
553
|
+
end
|
|
527
554
|
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
end
|
|
555
|
+
it 'sends keys to text element' do
|
|
556
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
557
|
+
browser.element(id: 'new_user_email').set('Bye Cruel World')
|
|
558
|
+
expect(browser.text_field(id: 'new_user_email').value).to eq 'Bye Cruel World'
|
|
559
|
+
end
|
|
534
560
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
browser.windows.restore!
|
|
541
|
-
end
|
|
561
|
+
it 'sends keys to text area' do
|
|
562
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
563
|
+
browser.element(id: 'delete_user_comment').set('Hello Cruel World')
|
|
564
|
+
expect(browser.textarea(id: 'delete_user_comment').value).to eq 'Hello Cruel World'
|
|
565
|
+
end
|
|
542
566
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
567
|
+
it 'checks a checkbox' do
|
|
568
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
569
|
+
browser.element(id: 'new_user_interests_cars').set
|
|
570
|
+
expect(browser.checkbox(id: 'new_user_interests_cars')).to be_set
|
|
571
|
+
end
|
|
548
572
|
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
end
|
|
573
|
+
it 'unchecks a checkbox' do
|
|
574
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
575
|
+
browser.element(id: 'new_user_interests_books').set(false)
|
|
576
|
+
expect(browser.checkbox(id: 'new_user_interests_books')).not_to be_set
|
|
577
|
+
end
|
|
555
578
|
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
579
|
+
it 'clicks a Radio' do
|
|
580
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
581
|
+
browser.radio(id: 'new_user_newsletter_no').set
|
|
582
|
+
expect(browser.radio(id: 'new_user_newsletter_no')).to be_set
|
|
583
|
+
expect(messages.size).to eq 1
|
|
584
|
+
end
|
|
561
585
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
586
|
+
it 'does not click a Radio when false or already clicked' do
|
|
587
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
|
588
|
+
browser.element(id: 'new_user_newsletter_no').set(false)
|
|
589
|
+
browser.element(id: 'new_user_newsletter_yes').set(true)
|
|
590
|
+
expect(messages.size).to eq 0
|
|
591
|
+
end
|
|
567
592
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
browser.element(id: 'new_user_interests_cars').set
|
|
571
|
-
expect(browser.checkbox(id: 'new_user_interests_cars')).to be_set
|
|
572
|
-
end
|
|
593
|
+
it 'uploads a file' do
|
|
594
|
+
browser.element(name: 'new_user_portrait').set __FILE__
|
|
573
595
|
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
browser.element(id: 'new_user_interests_books').set(false)
|
|
577
|
-
expect(browser.checkbox(id: 'new_user_interests_books')).to_not be_set
|
|
578
|
-
end
|
|
596
|
+
expect(browser.file_field(name: 'new_user_portrait').value).to include(File.basename(__FILE__))
|
|
597
|
+
end
|
|
579
598
|
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
end
|
|
599
|
+
it 'selects an option' do
|
|
600
|
+
browser.select_list(name: 'new_user_languages').clear
|
|
601
|
+
browser.element(name: 'new_user_languages').set('2')
|
|
602
|
+
expect(browser.select_list(name: 'new_user_languages').selected_options.map(&:text)).to eq %w[EN]
|
|
603
|
+
end
|
|
586
604
|
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
expect(messages.size).to eq 0
|
|
605
|
+
it 'sends keys to content editable element' do
|
|
606
|
+
browser.element(id: 'contenteditable').set('Bar')
|
|
607
|
+
expect(browser.div(id: 'contenteditable').text).to eq 'Bar'
|
|
608
|
+
end
|
|
592
609
|
end
|
|
593
610
|
|
|
594
|
-
|
|
595
|
-
browser.
|
|
611
|
+
describe '#flash' do
|
|
612
|
+
let(:h2) { browser.h2(text: 'Add user') }
|
|
613
|
+
let(:h1) { browser.h1(text: 'User administration') }
|
|
596
614
|
|
|
597
|
-
|
|
598
|
-
|
|
615
|
+
it 'returns the element on which it was called' do
|
|
616
|
+
expect(h2.flash).to eq h2
|
|
617
|
+
end
|
|
599
618
|
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
end
|
|
619
|
+
it 'keeps the element background color after flashing' do
|
|
620
|
+
expect(h2.style('background-color')).to eq h2.flash(:rainbow).style('background-color')
|
|
621
|
+
expect(h1.style('background-color')).to eq h1.flash.style('background-color')
|
|
622
|
+
end
|
|
605
623
|
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
624
|
+
it 'responds to preset symbols like :fast and :slow' do
|
|
625
|
+
expect(h1.flash(:rainbow)).to eq h1
|
|
626
|
+
expect(h2.flash(:slow)).to eq h2
|
|
627
|
+
expect(h1.flash(:fast)).to eq h1
|
|
628
|
+
expect(h2.flash(:long)).to eq h2
|
|
629
|
+
end
|
|
609
630
|
end
|
|
610
|
-
end
|
|
611
631
|
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
632
|
+
describe '#hover' do
|
|
633
|
+
def element_color(element)
|
|
634
|
+
case element.style('color')
|
|
635
|
+
when 'rgba(0, 0, 255, 1)'
|
|
636
|
+
:blue
|
|
637
|
+
when 'rgba(255, 165, 0, 1)', 'rgb(255, 165, 0)'
|
|
638
|
+
:orange
|
|
639
|
+
else
|
|
640
|
+
raise rgba
|
|
641
|
+
end
|
|
642
|
+
end
|
|
619
643
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
end
|
|
644
|
+
it 'allows scrolling to top', except: {browser: :ie} do
|
|
645
|
+
browser.goto(WatirSpec.url_for('scroll.html'))
|
|
646
|
+
element = browser.div(id: 'center')
|
|
624
647
|
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
expect(h2.flash(:slow)).to eq h2
|
|
628
|
-
expect(h1.flash(:fast)).to eq h1
|
|
629
|
-
expect(h2.flash(:long)).to eq h2
|
|
630
|
-
end
|
|
631
|
-
end
|
|
648
|
+
element.hover(scroll_to: :top)
|
|
649
|
+
expect(element_color(element)).to eq :orange
|
|
632
650
|
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
case element.style('color')
|
|
636
|
-
when 'rgba(0, 0, 255, 1)'
|
|
637
|
-
:blue
|
|
638
|
-
when 'rgba(255, 165, 0, 1)', 'rgb(255, 165, 0)'
|
|
639
|
-
:orange
|
|
640
|
-
else
|
|
641
|
-
raise rgba
|
|
651
|
+
element_top = browser.execute_script('return arguments[0].getBoundingClientRect().top', element)
|
|
652
|
+
expect(element_top).to be_within(1).of(0)
|
|
642
653
|
end
|
|
643
|
-
end
|
|
644
654
|
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
element = browser.div(id: 'center')
|
|
655
|
+
it 'scrolls to center by default', except: {browser: :ie} do
|
|
656
|
+
browser.goto(WatirSpec.url_for('scroll.html'))
|
|
657
|
+
element = browser.div(id: 'center')
|
|
649
658
|
|
|
650
|
-
|
|
651
|
-
|
|
659
|
+
element.hover
|
|
660
|
+
expect(element_color(element)).to eq :orange
|
|
652
661
|
|
|
653
|
-
|
|
654
|
-
expect(element_top).to be_within(1).of(0)
|
|
655
|
-
end
|
|
662
|
+
element_rect = browser.execute_script('return arguments[0].getBoundingClientRect()', element)
|
|
656
663
|
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
browser.goto(WatirSpec.url_for('scroll.html'))
|
|
660
|
-
element = browser.div(id: 'center')
|
|
664
|
+
expect(element_rect['top']).to eq(element_rect['bottom'] - element_rect['height'])
|
|
665
|
+
end
|
|
661
666
|
|
|
662
|
-
|
|
663
|
-
|
|
667
|
+
it 'allows scrolling to bottom', except: {browser: :ie} do
|
|
668
|
+
browser.goto(WatirSpec.url_for('scroll.html'))
|
|
669
|
+
element = browser.div(id: 'center')
|
|
664
670
|
|
|
665
|
-
|
|
671
|
+
element.hover(scroll_to: :bottom)
|
|
672
|
+
expect(element_color(element)).to eq :orange
|
|
666
673
|
|
|
667
|
-
|
|
668
|
-
|
|
674
|
+
element_bottom = browser.execute_script('return arguments[0].getBoundingClientRect().bottom', element)
|
|
675
|
+
window_height = browser.execute_script('return window.innerHeight')
|
|
669
676
|
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
browser.goto(WatirSpec.url_for('scroll.html'))
|
|
673
|
-
element = browser.div(id: 'center')
|
|
677
|
+
expect(element_bottom).to be_within(1).of(window_height)
|
|
678
|
+
end
|
|
674
679
|
|
|
675
|
-
|
|
676
|
-
|
|
680
|
+
it 'allows not scrolling', except: {browser: %i[chrome edge],
|
|
681
|
+
reason: 'https://bugs.chromium.org/p/chromedriver/issues/detail?id=3955'} do
|
|
682
|
+
browser.goto(WatirSpec.url_for('scroll.html'))
|
|
683
|
+
element = browser.div(id: 'center')
|
|
677
684
|
|
|
678
|
-
|
|
679
|
-
|
|
685
|
+
browser.execute_script('return window.pageYOffset;')
|
|
686
|
+
browser.execute_script('return window.innerHeight;')
|
|
680
687
|
|
|
681
|
-
|
|
688
|
+
expect {
|
|
689
|
+
element.hover(scroll_to: nil)
|
|
690
|
+
}.to raise_exception Selenium::WebDriver::Error::MoveTargetOutOfBoundsError
|
|
691
|
+
end
|
|
682
692
|
end
|
|
683
693
|
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
browser.goto(WatirSpec.url_for('scroll.html'))
|
|
687
|
-
element = browser.div(id: 'center')
|
|
694
|
+
describe '#inspect' do
|
|
695
|
+
before { browser.goto(WatirSpec.url_for('nested_iframes.html')) }
|
|
688
696
|
|
|
689
|
-
|
|
690
|
-
|
|
697
|
+
it 'does displays specified element type' do
|
|
698
|
+
expect(browser.div.inspect).to include('Watir::Div')
|
|
699
|
+
end
|
|
691
700
|
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
701
|
+
it 'does not display element type if not specified' do
|
|
702
|
+
element = browser.element(index: 4)
|
|
703
|
+
expect(element.inspect).to include('Watir::HTMLElement')
|
|
704
|
+
end
|
|
695
705
|
|
|
696
|
-
|
|
697
|
-
|
|
706
|
+
it 'displays keyword if specified' do
|
|
707
|
+
element = browser.h3
|
|
708
|
+
element.keyword = 'foo'
|
|
709
|
+
expect(element.inspect).to include('keyword: foo')
|
|
710
|
+
end
|
|
698
711
|
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
712
|
+
it 'does not display keyword if not specified' do
|
|
713
|
+
element = browser.h3
|
|
714
|
+
expect(element.inspect).not_to include('keyword')
|
|
715
|
+
end
|
|
702
716
|
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
717
|
+
it 'locate is false when not located' do
|
|
718
|
+
element = browser.div(id: 'not_present')
|
|
719
|
+
expect(element.inspect).to include('located: false')
|
|
720
|
+
end
|
|
707
721
|
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
722
|
+
it 'locate is true when located' do
|
|
723
|
+
element = browser.h3
|
|
724
|
+
element.exists?
|
|
725
|
+
expect(element.inspect).to include('located: true')
|
|
726
|
+
end
|
|
713
727
|
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
728
|
+
it 'displays selector string for element from colection' do
|
|
729
|
+
elements = browser.frames
|
|
730
|
+
expect(elements.last.inspect).to include '{:tag_name=>"frame", :index=>-1}'
|
|
731
|
+
end
|
|
718
732
|
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
733
|
+
it 'displays selector string for nested element' do
|
|
734
|
+
browser.goto(WatirSpec.url_for('wait.html'))
|
|
735
|
+
element = browser.div(index: 1).div(id: 'div2')
|
|
736
|
+
expect(element.inspect).to include '{:index=>1, :tag_name=>"div"} --> {:id=>"div2", :tag_name=>"div"}'
|
|
737
|
+
end
|
|
723
738
|
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
739
|
+
it 'displays selector string for nested element under frame' do
|
|
740
|
+
element = browser.iframe(id: 'one').iframe(id: 'three')
|
|
741
|
+
expect(element.inspect).to include '{:id=>"one", :tag_name=>"iframe"} --> {:id=>"three", :tag_name=>"iframe"}'
|
|
742
|
+
end
|
|
728
743
|
end
|
|
729
744
|
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
745
|
+
describe '#text_content' do
|
|
746
|
+
it 'returns inner Text code of element' do
|
|
747
|
+
browser.goto WatirSpec.url_for('non_control_elements.html')
|
|
748
|
+
expect(browser.div(id: 'shown').text_content).to eq('Not shownNot hidden')
|
|
749
|
+
end
|
|
733
750
|
end
|
|
734
751
|
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
752
|
+
describe '#inner_text' do
|
|
753
|
+
it 'returns inner HTML code of element',
|
|
754
|
+
except: {browser: :ie, reason: 'also returning explicitly hidden results'} do
|
|
755
|
+
browser.goto WatirSpec.url_for('non_control_elements.html')
|
|
756
|
+
div = browser.div(id: 'shown')
|
|
757
|
+
expect(div.inner_text).to eq('Not hidden')
|
|
758
|
+
end
|
|
739
759
|
end
|
|
740
760
|
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
761
|
+
describe '#inner_html' do
|
|
762
|
+
it 'returns inner HTML code of element' do
|
|
763
|
+
browser.goto WatirSpec.url_for('non_control_elements.html')
|
|
764
|
+
div = browser.div(id: 'shown')
|
|
765
|
+
expected_text = '<div id="hidden" style="display: none;">Not shown</div><div>Not hidden</div>'
|
|
766
|
+
expect(div.inner_html).to eq expected_text
|
|
767
|
+
end
|
|
744
768
|
end
|
|
745
|
-
end
|
|
746
769
|
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
770
|
+
describe '#outer_html' do
|
|
771
|
+
it 'returns outer (inner + element itself) HTML code of element' do
|
|
772
|
+
browser.goto WatirSpec.url_for('non_control_elements.html')
|
|
773
|
+
div = browser.div(id: 'shown')
|
|
774
|
+
text = '<div id="shown"><div id="hidden" style="display: none;">Not shown</div><div>Not hidden</div></div>'
|
|
775
|
+
expect(div.outer_html).to eq text
|
|
776
|
+
end
|
|
751
777
|
end
|
|
752
|
-
end
|
|
753
778
|
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
779
|
+
describe '#select_text and #selected_text' do
|
|
780
|
+
it 'selects text and returns selected text',
|
|
781
|
+
except: {browser: :ie, reason: 'Select Text atom appears broken in IE 11'} do
|
|
782
|
+
browser.goto WatirSpec.url_for('non_control_elements.html')
|
|
783
|
+
element = browser.element(visible_text: 'all visible')
|
|
784
|
+
element.select_text('all visible')
|
|
785
|
+
expect(element.selected_text).to eq 'all visible'
|
|
786
|
+
end
|
|
760
787
|
end
|
|
761
|
-
end
|
|
762
788
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
div = browser.div(id: 'shown')
|
|
767
|
-
expected_text = '<div id="hidden" style="display: none;">Not shown</div><div>Not hidden</div>'
|
|
768
|
-
expect(div.inner_html).to eq expected_text
|
|
769
|
-
end
|
|
770
|
-
end
|
|
789
|
+
describe '#location' do
|
|
790
|
+
it 'returns coordinates for element location' do
|
|
791
|
+
location = browser.button(name: 'new_user_image').location
|
|
771
792
|
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
text = '<div id="shown"><div id="hidden" style="display: none;">Not shown</div><div>Not hidden</div></div>'
|
|
777
|
-
expect(div.outer_html).to eq text
|
|
793
|
+
expect(location).to be_a Selenium::WebDriver::Point
|
|
794
|
+
expect(location['y']).to be > 0
|
|
795
|
+
expect(location['x']).to be > 0
|
|
796
|
+
end
|
|
778
797
|
end
|
|
779
|
-
end
|
|
780
798
|
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
element = browser.element(visible_text: 'all visible')
|
|
786
|
-
element.select_text('all visible')
|
|
787
|
-
expect(element.selected_text).to eq 'all visible'
|
|
788
|
-
end
|
|
789
|
-
end
|
|
799
|
+
describe '#size' do
|
|
800
|
+
it 'returns size of element' do
|
|
801
|
+
size = browser.button(name: 'new_user_image').size
|
|
802
|
+
expect(size).to be_a Selenium::WebDriver::Dimension
|
|
790
803
|
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
location = browser.button(name: 'new_user_image').location
|
|
804
|
+
expected_width = browser.name == :safari ? 105 : 104
|
|
805
|
+
expected_height = browser.name == :safari ? 71 : 70
|
|
794
806
|
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
807
|
+
expect(size['width']).to eq expected_width
|
|
808
|
+
expect(size['height']).to eq expected_height
|
|
809
|
+
end
|
|
798
810
|
end
|
|
799
|
-
end
|
|
800
811
|
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
expect(size).to be_a Selenium::WebDriver::Dimension
|
|
812
|
+
describe '#height' do
|
|
813
|
+
it 'returns height of element' do
|
|
814
|
+
height = browser.button(name: 'new_user_image').height
|
|
805
815
|
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
expect(size['width']).to eq expected_width
|
|
810
|
-
expect(size['height']).to eq expected_height
|
|
816
|
+
expected_height = browser.name == :safari ? 71 : 70
|
|
817
|
+
expect(height).to eq expected_height
|
|
818
|
+
end
|
|
811
819
|
end
|
|
812
|
-
end
|
|
813
820
|
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
821
|
+
describe '#width' do
|
|
822
|
+
it 'returns width of element' do
|
|
823
|
+
width = browser.button(name: 'new_user_image').width
|
|
817
824
|
|
|
818
|
-
|
|
819
|
-
|
|
825
|
+
expected_width = browser.name == :safari ? 105 : 104
|
|
826
|
+
expect(width).to eq expected_width
|
|
827
|
+
end
|
|
820
828
|
end
|
|
821
|
-
end
|
|
822
829
|
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
830
|
+
describe '#center' do
|
|
831
|
+
it 'returns center of element' do
|
|
832
|
+
center = browser.button(name: 'new_user_image').center
|
|
826
833
|
|
|
827
|
-
|
|
828
|
-
|
|
834
|
+
expect(center).to be_a Selenium::WebDriver::Point
|
|
835
|
+
expect(center['y']).to be > 0.0
|
|
836
|
+
expect(center['x']).to be > 0.0
|
|
837
|
+
end
|
|
829
838
|
end
|
|
830
|
-
end
|
|
831
839
|
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
center = browser.button(name: 'new_user_image').center
|
|
840
|
+
describe '#attribute_value' do
|
|
841
|
+
before { browser.goto WatirSpec.url_for('data_attributes.html') }
|
|
835
842
|
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
843
|
+
it 'returns attribute value by string attribute name' do
|
|
844
|
+
expect(browser.p.attribute_value('data-type')).to eq 'ruby-library'
|
|
845
|
+
end
|
|
846
|
+
|
|
847
|
+
it 'returns attribute value by symbol attribute name' do
|
|
848
|
+
expect(browser.p.attribute_value(:data_type)).to eq 'ruby-library'
|
|
849
|
+
end
|
|
839
850
|
end
|
|
840
|
-
end
|
|
841
851
|
|
|
842
|
-
|
|
843
|
-
|
|
852
|
+
describe '#attribute_values' do
|
|
853
|
+
before { browser.goto WatirSpec.url_for('data_attributes.html') }
|
|
844
854
|
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
855
|
+
it 'returns a Hash object' do
|
|
856
|
+
expect(browser.p.attribute_values).to be_an_instance_of(Hash)
|
|
857
|
+
end
|
|
848
858
|
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
859
|
+
it 'returns attribute values from an element' do
|
|
860
|
+
expected = {data_type: 'ruby-library'}
|
|
861
|
+
expect(browser.p.attribute_values).to eq expected
|
|
862
|
+
end
|
|
853
863
|
|
|
854
|
-
|
|
855
|
-
|
|
864
|
+
it 'returns attribute with special characters' do
|
|
865
|
+
expected = {data_type: 'description', 'data-type_$p3c!a1' => 'special-description'}
|
|
866
|
+
expect(browser.div.attribute_values).to eq expected
|
|
867
|
+
end
|
|
856
868
|
|
|
857
|
-
|
|
858
|
-
|
|
869
|
+
it 'returns attribute with special characters as a String' do
|
|
870
|
+
expect(browser.div.attribute_values.keys[0]).to be_an_instance_of(String)
|
|
871
|
+
end
|
|
859
872
|
end
|
|
860
873
|
|
|
861
|
-
|
|
862
|
-
|
|
863
|
-
expect(browser.p.attribute_values).to eq expected
|
|
864
|
-
end
|
|
874
|
+
describe '#attribute_list' do
|
|
875
|
+
before { browser.goto WatirSpec.url_for('data_attributes.html') }
|
|
865
876
|
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
877
|
+
it 'returns an Array object' do
|
|
878
|
+
expect(browser.div.attribute_list).to be_an_instance_of(Array)
|
|
879
|
+
end
|
|
880
|
+
|
|
881
|
+
it 'returns list of attributes from an element' do
|
|
882
|
+
expect(browser.p.attribute_list).to eq [:data_type]
|
|
883
|
+
end
|
|
870
884
|
|
|
871
|
-
|
|
872
|
-
|
|
885
|
+
it 'returns attribute name with special characters as a String' do
|
|
886
|
+
expect(browser.div.attribute_list[0]).to be_an_instance_of(String)
|
|
887
|
+
end
|
|
873
888
|
end
|
|
874
|
-
end
|
|
875
889
|
|
|
876
|
-
|
|
877
|
-
|
|
890
|
+
describe '#located?' do
|
|
891
|
+
it 'returns true if element has been located' do
|
|
892
|
+
expect(browser.form(id: 'new_user')).not_to be_located
|
|
893
|
+
end
|
|
878
894
|
|
|
879
|
-
|
|
880
|
-
|
|
895
|
+
it 'returns false if element has not been located' do
|
|
896
|
+
expect(browser.form(id: 'new_user').locate).to be_located
|
|
897
|
+
end
|
|
881
898
|
end
|
|
882
899
|
|
|
883
|
-
|
|
884
|
-
|
|
900
|
+
describe '#wd' do
|
|
901
|
+
it 'returns a Selenium::WebDriver::Element instance' do
|
|
902
|
+
element = browser.text_field(id: 'new_user_email')
|
|
903
|
+
expect(element.wd).to be_a(Selenium::WebDriver::Element)
|
|
904
|
+
end
|
|
885
905
|
end
|
|
886
906
|
|
|
887
|
-
|
|
888
|
-
|
|
907
|
+
describe '#hash' do
|
|
908
|
+
it 'returns a hash' do
|
|
909
|
+
element = browser.text_field(id: 'new_user_email')
|
|
910
|
+
hash1 = element.hash
|
|
911
|
+
hash2 = element.locate.hash
|
|
912
|
+
expect(hash1).to be_a Integer
|
|
913
|
+
expect(hash2).to be_a Integer
|
|
914
|
+
expect(hash1).not_to eq hash2
|
|
915
|
+
end
|
|
889
916
|
end
|
|
890
|
-
end
|
|
891
917
|
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
918
|
+
describe 'Numeric Attribute' do
|
|
919
|
+
it 'returns Float value',
|
|
920
|
+
except: {browser: :ie, reason: 'not recognizing the value of the element'} do
|
|
921
|
+
element = browser.text_field(id: 'number')
|
|
922
|
+
expect(element.valueasnumber).to be_a Float
|
|
923
|
+
end
|
|
896
924
|
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
|
|
925
|
+
it 'returns nil for unspecified value' do
|
|
926
|
+
element = browser.input
|
|
927
|
+
expect(element.valueasnumber).to be_nil
|
|
928
|
+
end
|
|
901
929
|
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
930
|
+
it 'returns Integer value' do
|
|
931
|
+
element = browser.form
|
|
932
|
+
expect(element.length).to be_a Integer
|
|
933
|
+
end
|
|
906
934
|
end
|
|
907
|
-
end
|
|
908
935
|
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
hash2 = element.locate.hash
|
|
914
|
-
expect(hash1).to be_a Integer
|
|
915
|
-
expect(hash2).to be_a Integer
|
|
916
|
-
expect(hash1).to_not eq hash2
|
|
917
|
-
end
|
|
918
|
-
end
|
|
936
|
+
describe 'Special Characters' do
|
|
937
|
+
before do
|
|
938
|
+
browser.goto WatirSpec.url_for('special_chars.html')
|
|
939
|
+
end
|
|
919
940
|
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
element = browser.text_field(id: 'number')
|
|
924
|
-
expect(element.valueasnumber).to be_a Float
|
|
925
|
-
end
|
|
941
|
+
it 'finds elements with single quotes' do
|
|
942
|
+
expect(browser.div(text: "single 'quotes'")).to exist
|
|
943
|
+
end
|
|
926
944
|
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
945
|
+
it 'finds elements with non-standard character locators' do
|
|
946
|
+
expect(browser.div('we{ird' => 'foo')).to exist
|
|
947
|
+
expect(browser.div('we{ird': 'foo')).to exist
|
|
948
|
+
end
|
|
931
949
|
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
950
|
+
it 'finds element with underscored attribute' do
|
|
951
|
+
expect(browser.div('underscored_attribute' => 'true')).to exist
|
|
952
|
+
expect(browser.div('underscored_attribute' => true)).to exist
|
|
953
|
+
end
|
|
935
954
|
end
|
|
936
|
-
end
|
|
937
955
|
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
956
|
+
describe '#class_name' do
|
|
957
|
+
it 'returns single class name' do
|
|
958
|
+
expect(browser.form(id: 'new_user').class_name).to eq 'user'
|
|
959
|
+
end
|
|
942
960
|
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
961
|
+
it 'returns multiple class names in a String' do
|
|
962
|
+
expect(browser.div(id: 'messages').class_name).to eq 'multiple classes here'
|
|
963
|
+
end
|
|
946
964
|
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
965
|
+
it 'returns an empty string if the element exists but there is no class attribute' do
|
|
966
|
+
expect(browser.div(id: 'changed_language').class_name).to eq ''
|
|
967
|
+
end
|
|
950
968
|
|
|
951
|
-
|
|
952
|
-
|
|
969
|
+
it 'raises UnknownObjectException if the element does not exist' do
|
|
970
|
+
expect { browser.div(id: 'no_such_id').class_name }.to raise_unknown_object_exception
|
|
971
|
+
end
|
|
953
972
|
end
|
|
954
|
-
end
|
|
955
973
|
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
974
|
+
describe '#classes' do
|
|
975
|
+
it 'returns the class attribute if the element exists' do
|
|
976
|
+
expect(browser.div(id: 'messages').classes).to eq %w[multiple classes here]
|
|
977
|
+
end
|
|
960
978
|
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
979
|
+
it 'returns an empty array if the element exists but there is no class attribute' do
|
|
980
|
+
expect(browser.div(id: 'changed_language').classes).to eq []
|
|
981
|
+
end
|
|
964
982
|
|
|
965
|
-
|
|
966
|
-
|
|
983
|
+
it 'raises UnknownObjectException if the element does not exist' do
|
|
984
|
+
expect { browser.div(id: 'no_such_id').classes }.to raise_unknown_object_exception
|
|
985
|
+
end
|
|
967
986
|
end
|
|
968
|
-
end
|
|
969
987
|
|
|
970
|
-
|
|
971
|
-
|
|
988
|
+
describe '#obscured?' do
|
|
989
|
+
before { browser.goto WatirSpec.url_for('obscured.html') }
|
|
972
990
|
|
|
973
|
-
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
|
|
991
|
+
it 'returns false if element center is not covered' do
|
|
992
|
+
btn = browser.button(id: 'not_obscured')
|
|
993
|
+
btn.scroll.to :center
|
|
994
|
+
expect { btn.click }.not_to raise_exception
|
|
995
|
+
expect(btn).not_to be_obscured
|
|
996
|
+
end
|
|
979
997
|
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
|
|
983
|
-
|
|
984
|
-
|
|
985
|
-
|
|
998
|
+
it 'returns false if element center is covered by its descendant' do
|
|
999
|
+
btn = browser.button(id: 'has_descendant')
|
|
1000
|
+
btn.scroll.to :center
|
|
1001
|
+
expect { btn.click }.not_to raise_exception
|
|
1002
|
+
expect(btn).not_to be_obscured
|
|
1003
|
+
end
|
|
986
1004
|
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
1005
|
+
it 'returns true if element center is covered by a non-descendant',
|
|
1006
|
+
except: {browser: :safari, reason: 'not getting element click intercepted'} do
|
|
1007
|
+
btn = browser.button(id: 'obscured')
|
|
1008
|
+
btn.scroll.to :center
|
|
1009
|
+
expect { btn.click }.to raise_exception(Selenium::WebDriver::Error::ElementClickInterceptedError)
|
|
1010
|
+
expect(btn).to be_obscured
|
|
1011
|
+
end
|
|
994
1012
|
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1013
|
+
it 'returns false if element center is surrounded by non-descendants' do
|
|
1014
|
+
btn = browser.button(id: 'surrounded')
|
|
1015
|
+
btn.scroll.to :center
|
|
1016
|
+
expect { btn.click }.not_to raise_exception
|
|
1017
|
+
expect(btn).not_to be_obscured
|
|
1018
|
+
end
|
|
1001
1019
|
|
|
1002
|
-
|
|
1003
|
-
|
|
1020
|
+
it 'correctly scrolls element below viewport' do
|
|
1021
|
+
browser.goto WatirSpec.url_for('sticky_elements.html')
|
|
1004
1022
|
|
|
1005
|
-
|
|
1023
|
+
element = browser.div(id: 'center')
|
|
1006
1024
|
|
|
1007
|
-
|
|
1008
|
-
|
|
1025
|
+
browser.scroll.to :top
|
|
1026
|
+
expect { element.click }.not_to raise_exception
|
|
1009
1027
|
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1028
|
+
browser.scroll.to :top
|
|
1029
|
+
expect(element).not_to be_obscured
|
|
1030
|
+
end
|
|
1013
1031
|
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1032
|
+
it 'correctly scrolls element above viewport',
|
|
1033
|
+
except: {browser: %i[chrome edge],
|
|
1034
|
+
reason: 'https://bugs.chromium.org/p/chromedriver/issues/detail?id=3954'} do
|
|
1035
|
+
browser.goto WatirSpec.url_for('sticky_elements.html')
|
|
1036
|
+
element = browser.div(id: 'center')
|
|
1019
1037
|
|
|
1020
|
-
|
|
1021
|
-
|
|
1038
|
+
browser.scroll.to :bottom
|
|
1039
|
+
expect { element.click }.not_to raise_exception
|
|
1022
1040
|
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1041
|
+
browser.scroll.to :bottom
|
|
1042
|
+
expect(element).not_to be_obscured
|
|
1043
|
+
end
|
|
1026
1044
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1045
|
+
it 'scrolls non-interactive element into view before checking if obscured' do
|
|
1046
|
+
div = browser.div(id: 'requires_scrolling_container')
|
|
1047
|
+
expect { div.click }.not_to raise_exception
|
|
1048
|
+
browser.scroll.to :top
|
|
1049
|
+
expect(div).not_to be_obscured
|
|
1050
|
+
end
|
|
1033
1051
|
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1052
|
+
it 'returns true if element cannot be scrolled into view' do
|
|
1053
|
+
btn = browser.button(id: 'off_screen')
|
|
1054
|
+
expect(btn).to be_obscured
|
|
1055
|
+
expect { btn.click }.to raise_unknown_object_exception
|
|
1056
|
+
end
|
|
1039
1057
|
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1058
|
+
it 'returns true if element is hidden' do
|
|
1059
|
+
btn = browser.button(id: 'hidden')
|
|
1060
|
+
expect(btn).to be_obscured
|
|
1061
|
+
expect { btn.click }.to raise_unknown_object_exception
|
|
1062
|
+
end
|
|
1045
1063
|
|
|
1046
|
-
|
|
1047
|
-
|
|
1064
|
+
it 'raises UnknownObjectException if element does not exist' do
|
|
1065
|
+
expect { browser.button(id: 'does_not_exist').obscured? }.to raise_unknown_object_exception
|
|
1066
|
+
end
|
|
1048
1067
|
end
|
|
1049
1068
|
end
|
|
1050
1069
|
end
|