watir 6.14.0 → 6.15.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +24 -6
- data/CHANGES.md +10 -0
- data/Gemfile +0 -2
- data/README.md +1 -1
- data/Rakefile +2 -2
- data/lib/watir.rb +2 -3
- data/lib/watir/adjacent.rb +2 -2
- data/lib/watir/alert.rb +5 -9
- data/lib/watir/attribute_helper.rb +2 -3
- data/lib/watir/browser.rb +5 -17
- data/lib/watir/capabilities.rb +11 -0
- data/lib/watir/cell_container.rb +2 -2
- data/lib/watir/container.rb +7 -8
- data/lib/watir/cookies.rb +2 -12
- data/lib/watir/element_collection.rb +2 -2
- data/lib/watir/elements/button.rb +2 -11
- data/lib/watir/elements/element.rb +43 -25
- data/lib/watir/elements/hidden.rb +1 -1
- data/lib/watir/elements/iframe.rb +7 -5
- data/lib/watir/elements/option.rb +2 -13
- data/lib/watir/elements/select.rb +6 -22
- data/lib/watir/elements/table.rb +2 -2
- data/lib/watir/exception.rb +1 -2
- data/lib/watir/generator/base/idl_sorter.rb +1 -1
- data/lib/watir/generator/base/spec_extractor.rb +2 -2
- data/lib/watir/generator/base/visitor.rb +1 -1
- data/lib/watir/generator/html/generator.rb +0 -1
- data/lib/watir/generator/html/spec_extractor.rb +1 -1
- data/lib/watir/generator/html/visitor.rb +1 -1
- data/lib/watir/generator/svg/spec_extractor.rb +1 -1
- data/lib/watir/generator/svg/visitor.rb +1 -1
- data/lib/watir/js_execution.rb +11 -0
- data/lib/watir/js_snippets.rb +1 -1
- data/lib/watir/js_snippets/elementObscured.js +14 -0
- data/lib/watir/js_snippets/selectedText.js +17 -0
- data/lib/watir/legacy_wait.rb +5 -5
- data/lib/watir/locators.rb +16 -5
- data/lib/watir/locators/anchor/selector_builder.rb +38 -0
- data/lib/watir/locators/button/locator.rb +14 -12
- data/lib/watir/locators/button/selector_builder.rb +0 -22
- data/lib/watir/locators/button/selector_builder/xpath.rb +67 -12
- data/lib/watir/locators/button/validator.rb +2 -1
- data/lib/watir/locators/cell/selector_builder.rb +0 -14
- data/lib/watir/locators/cell/selector_builder/xpath.rb +21 -0
- data/lib/watir/locators/element/locator.rb +60 -153
- data/lib/watir/locators/element/selector_builder.rb +103 -84
- data/lib/watir/locators/element/selector_builder/regexp_disassembler.rb +66 -0
- data/lib/watir/locators/element/selector_builder/xpath.rb +195 -82
- data/lib/watir/locators/element/selector_builder/xpath_support.rb +27 -0
- data/lib/watir/locators/element/validator.rb +2 -9
- data/lib/watir/locators/row/selector_builder.rb +5 -22
- data/lib/watir/locators/row/selector_builder/xpath.rb +53 -0
- data/lib/watir/locators/text_area/selector_builder.rb +1 -1
- data/lib/watir/locators/text_area/selector_builder/xpath.rb +19 -0
- data/lib/watir/locators/text_field/locator.rb +11 -8
- data/lib/watir/locators/text_field/selector_builder.rb +0 -23
- data/lib/watir/locators/text_field/selector_builder/xpath.rb +33 -4
- data/lib/watir/locators/text_field/validator.rb +4 -4
- data/lib/watir/radio_set.rb +5 -5
- data/lib/watir/row_container.rb +2 -2
- data/lib/watir/user_editable.rb +2 -2
- data/lib/watir/version.rb +1 -1
- data/lib/watir/wait.rb +24 -37
- data/lib/watir/window.rb +11 -8
- data/lib/watirspec/remote_server.rb +3 -1
- data/spec/locator_spec_helper.rb +1 -1
- data/spec/spec_helper.rb +25 -1
- data/spec/unit/anchor_locator_spec.rb +68 -0
- data/spec/unit/capabilities_spec.rb +27 -0
- data/spec/unit/element_locator_spec.rb +184 -101
- data/spec/unit/logger_spec.rb +5 -0
- data/spec/watirspec/adjacent_spec.rb +34 -34
- data/spec/watirspec/after_hooks_spec.rb +78 -35
- data/spec/watirspec/alert_spec.rb +10 -0
- data/spec/watirspec/browser_spec.rb +27 -1
- data/spec/watirspec/element_hidden_spec.rb +6 -0
- data/spec/watirspec/elements/button_spec.rb +5 -11
- data/spec/watirspec/elements/buttons_spec.rb +1 -1
- data/spec/watirspec/elements/checkbox_spec.rb +2 -15
- data/spec/watirspec/elements/date_time_field_spec.rb +6 -1
- data/spec/watirspec/elements/dd_spec.rb +0 -17
- data/spec/watirspec/elements/del_spec.rb +0 -14
- data/spec/watirspec/elements/div_spec.rb +0 -18
- data/spec/watirspec/elements/dl_spec.rb +0 -17
- data/spec/watirspec/elements/dt_spec.rb +0 -17
- data/spec/watirspec/elements/element_spec.rb +177 -17
- data/spec/watirspec/elements/elements_spec.rb +7 -6
- data/spec/watirspec/elements/em_spec.rb +0 -13
- data/spec/watirspec/elements/filefield_spec.rb +0 -11
- data/spec/watirspec/elements/form_spec.rb +6 -0
- data/spec/watirspec/elements/hn_spec.rb +0 -14
- data/spec/watirspec/elements/iframe_spec.rb +15 -0
- data/spec/watirspec/elements/ins_spec.rb +0 -14
- data/spec/watirspec/elements/labels_spec.rb +1 -1
- data/spec/watirspec/elements/li_spec.rb +0 -14
- data/spec/watirspec/elements/link_spec.rb +22 -14
- data/spec/watirspec/elements/links_spec.rb +13 -0
- data/spec/watirspec/elements/list_spec.rb +15 -0
- data/spec/watirspec/elements/ol_spec.rb +0 -14
- data/spec/watirspec/elements/option_spec.rb +0 -10
- data/spec/watirspec/elements/p_spec.rb +0 -14
- data/spec/watirspec/elements/pre_spec.rb +0 -14
- data/spec/watirspec/elements/radio_spec.rb +0 -14
- data/spec/watirspec/elements/select_list_spec.rb +0 -10
- data/spec/watirspec/elements/span_spec.rb +4 -15
- data/spec/watirspec/elements/strong_spec.rb +4 -15
- data/spec/watirspec/elements/table_nesting_spec.rb +1 -1
- data/spec/watirspec/elements/table_spec.rb +7 -0
- data/spec/watirspec/elements/text_field_spec.rb +10 -2
- data/spec/watirspec/elements/text_fields_spec.rb +1 -1
- data/spec/watirspec/elements/tr_spec.rb +1 -1
- data/spec/watirspec/elements/ul_spec.rb +0 -14
- data/spec/watirspec/html/closeable.html +8 -0
- data/spec/watirspec/html/forms_with_input_elements.html +28 -23
- data/spec/watirspec/html/nested_elements.html +9 -9
- data/spec/watirspec/html/obscured.html +34 -0
- data/spec/watirspec/html/tables.html +13 -13
- data/spec/watirspec/radio_set_spec.rb +5 -0
- data/spec/watirspec/selector_builder/button_spec.rb +254 -0
- data/spec/watirspec/selector_builder/cell_spec.rb +93 -0
- data/spec/watirspec/selector_builder/element_spec.rb +639 -0
- data/spec/watirspec/selector_builder/row_spec.rb +150 -0
- data/spec/watirspec/selector_builder/text_spec.rb +170 -0
- data/spec/watirspec/support/rspec_matchers.rb +6 -1
- data/spec/watirspec/user_editable_spec.rb +4 -0
- data/spec/watirspec/wait_spec.rb +65 -14
- data/spec/watirspec/window_switching_spec.rb +54 -1
- data/spec/watirspec_helper.rb +2 -0
- data/watir.gemspec +7 -1
- metadata +86 -8
- data/lib/watir/locators/text_area/locator.rb +0 -13
- data/lib/watir/xpath_support.rb +0 -18
@@ -0,0 +1,150 @@
|
|
1
|
+
require 'watirspec_helper'
|
2
|
+
|
3
|
+
describe Watir::Locators::Row::SelectorBuilder do
|
4
|
+
let(:attributes) { Watir::HTMLElement.attribute_list }
|
5
|
+
let(:selector_builder) { described_class.new(attributes, @scope_tag_name) }
|
6
|
+
|
7
|
+
describe '#build' do
|
8
|
+
after(:each) do |example|
|
9
|
+
next if example.metadata[:skip_after]
|
10
|
+
|
11
|
+
@scope_tag_name ||= @query_scope.tag_name
|
12
|
+
|
13
|
+
built = selector_builder.build(@selector)
|
14
|
+
expect(built).to eq [@wd_locator, (@remaining || {})]
|
15
|
+
|
16
|
+
next unless @data_locator || @tag_name
|
17
|
+
|
18
|
+
expect { @located = @query_scope.wd.first(@wd_locator) }.not_to raise_exception
|
19
|
+
|
20
|
+
if @data_locator
|
21
|
+
expect(@located.attribute('data-locator')).to eq(@data_locator)
|
22
|
+
else
|
23
|
+
expect {
|
24
|
+
expect(@located.tag_name).to eq @tag_name
|
25
|
+
}.not_to raise_exception
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context 'with query scopes' do
|
30
|
+
before(:each) do
|
31
|
+
browser.goto(WatirSpec.url_for('tables.html'))
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'with only table query scope' do
|
35
|
+
@query_scope = browser.element(id: 'outer').locate
|
36
|
+
@selector = {}
|
37
|
+
@wd_locator = {xpath: "./*[local-name()='tr'] | ./*[local-name()='tbody']/*[local-name()='tr'] | " \
|
38
|
+
"./*[local-name()='thead']/*[local-name()='tr'] | ./*[local-name()='tfoot']/*[local-name()='tr']"}
|
39
|
+
@data_locator = 'first row'
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'with tbody query scope' do
|
43
|
+
@query_scope = browser.element(id: 'first').locate
|
44
|
+
@selector = {}
|
45
|
+
@wd_locator = {xpath: "./*[local-name()='tr']"}
|
46
|
+
@data_locator = 'tbody row'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'with thead query scope' do
|
50
|
+
@query_scope = browser.element(id: 'tax_headers').locate
|
51
|
+
@selector = {}
|
52
|
+
@wd_locator = {xpath: "./*[local-name()='tr']"}
|
53
|
+
@data_locator = 'thead row'
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'with tfoot query scope' do
|
57
|
+
@query_scope = browser.element(id: 'tax_totals').locate
|
58
|
+
@selector = {}
|
59
|
+
@wd_locator = {xpath: "./*[local-name()='tr']"}
|
60
|
+
@data_locator = 'tfoot row'
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'with index' do
|
65
|
+
before(:each) do
|
66
|
+
browser.goto(WatirSpec.url_for('tables.html'))
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'positive' do
|
70
|
+
@query_scope = browser.element(id: 'outer').locate
|
71
|
+
@selector = {index: 1}
|
72
|
+
@wd_locator = {xpath: "(./*[local-name()='tr'] | ./*[local-name()='tbody']/*[local-name()='tr'] | " \
|
73
|
+
"./*[local-name()='thead']/*[local-name()='tr'] | ./*[local-name()='tfoot']/*[local-name()='tr'])[2]"}
|
74
|
+
@data_locator = 'middle row'
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'negative' do
|
78
|
+
@query_scope = browser.element(id: 'outer').locate
|
79
|
+
@selector = {index: -3}
|
80
|
+
@wd_locator = {xpath: "(./*[local-name()='tr'] | ./*[local-name()='tbody']/*[local-name()='tr'] | " \
|
81
|
+
"./*[local-name()='thead']/*[local-name()='tr'] | ./*[local-name()='tfoot']/*[local-name()='tr'])[last()-2]"}
|
82
|
+
@data_locator = 'first row'
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'last' do
|
86
|
+
@query_scope = browser.element(id: 'outer').locate
|
87
|
+
@selector = {index: -1}
|
88
|
+
@wd_locator = {xpath: "(./*[local-name()='tr'] | ./*[local-name()='tbody']/*[local-name()='tr'] | " \
|
89
|
+
"./*[local-name()='thead']/*[local-name()='tr'] | ./*[local-name()='tfoot']/*[local-name()='tr'])[last()]"}
|
90
|
+
@data_locator = 'last row'
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'does not return index if it is zero' do
|
94
|
+
@query_scope = browser.element(id: 'outer').locate
|
95
|
+
@selector = {index: 0}
|
96
|
+
@wd_locator = {xpath: "./*[local-name()='tr'] | ./*[local-name()='tbody']/*[local-name()='tr'] | " \
|
97
|
+
"./*[local-name()='thead']/*[local-name()='tr'] | ./*[local-name()='tfoot']/*[local-name()='tr']"}
|
98
|
+
@data_locator = 'first row'
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'raises exception when index is not an Integer', skip_after: true do
|
102
|
+
@query_scope = browser.element(id: 'outer').locate
|
103
|
+
selector = {index: 'foo'}
|
104
|
+
msg = 'expected Integer, got "foo":String'
|
105
|
+
expect { selector_builder.build(selector) }.to raise_exception TypeError, msg
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'with multiple locators' do
|
110
|
+
before(:each) do
|
111
|
+
browser.goto(WatirSpec.url_for('tables.html'))
|
112
|
+
@query_scope = browser.table.locate
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'attribute and class' do
|
116
|
+
@selector = {id: 'gregory', class: /brick/}
|
117
|
+
@wd_locator = {xpath: "./*[local-name()='tr'][contains(@class, 'brick')][@id='gregory'] | " \
|
118
|
+
"./*[local-name()='tbody']/*[local-name()='tr'][contains(@class, 'brick')][@id='gregory'] | " \
|
119
|
+
"./*[local-name()='thead']/*[local-name()='tr'][contains(@class, 'brick')][@id='gregory'] | " \
|
120
|
+
"./*[local-name()='tfoot']/*[local-name()='tr'][contains(@class, 'brick')][@id='gregory']"}
|
121
|
+
@data_locator = 'House row'
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'returns locators that can not be directly translated' do
|
126
|
+
before(:each) do
|
127
|
+
browser.goto(WatirSpec.url_for('tables.html'))
|
128
|
+
@query_scope = browser.table(id: 'outer').locate
|
129
|
+
end
|
130
|
+
|
131
|
+
it 'any text value' do
|
132
|
+
@selector = {text: 'Gregory'}
|
133
|
+
@wd_locator = {xpath: "./*[local-name()='tr'] | ./*[local-name()='tbody']/*[local-name()='tr'] | " \
|
134
|
+
"./*[local-name()='thead']/*[local-name()='tr'] | ./*[local-name()='tfoot']/*[local-name()='tr']"}
|
135
|
+
@remaining = {text: 'Gregory'}
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
it 'delegates adjacent to Element SelectorBuilder' do
|
140
|
+
browser.goto(WatirSpec.url_for('tables.html'))
|
141
|
+
|
142
|
+
@scope_tag_name = 'table'
|
143
|
+
@query_scope = browser.element(id: 'gregory').locate
|
144
|
+
|
145
|
+
@selector = {adjacent: :ancestor, index: 1}
|
146
|
+
@wd_locator = {xpath: './ancestor::*[2]'}
|
147
|
+
@data_locator = 'top table'
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
@@ -0,0 +1,170 @@
|
|
1
|
+
require 'watirspec_helper'
|
2
|
+
|
3
|
+
describe Watir::Locators::TextField::SelectorBuilder do
|
4
|
+
let(:attributes) { Watir::HTMLElement.attribute_list }
|
5
|
+
let(:scope_tag_name) { nil }
|
6
|
+
let(:selector_builder) { described_class.new(attributes) }
|
7
|
+
let(:uppercase) { 'ABCDEFGHIJKLMNOPQRSTUVWXYZÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞŸŽŠŒ' }
|
8
|
+
let(:lowercase) { 'abcdefghijklmnopqrstuvwxyzàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿžšœ' }
|
9
|
+
let(:negative_types) do
|
10
|
+
"translate(@type,'#{uppercase}','#{lowercase}')!='file' and "\
|
11
|
+
"translate(@type,'#{uppercase}','#{lowercase}')!='radio' and " \
|
12
|
+
"translate(@type,'#{uppercase}','#{lowercase}')!='checkbox' and " \
|
13
|
+
"translate(@type,'#{uppercase}','#{lowercase}')!='submit' and " \
|
14
|
+
"translate(@type,'#{uppercase}','#{lowercase}')!='reset' and " \
|
15
|
+
"translate(@type,'#{uppercase}','#{lowercase}')!='image' and " \
|
16
|
+
"translate(@type,'#{uppercase}','#{lowercase}')!='button' and " \
|
17
|
+
"translate(@type,'#{uppercase}','#{lowercase}')!='hidden' and " \
|
18
|
+
"translate(@type,'#{uppercase}','#{lowercase}')!='range' and " \
|
19
|
+
"translate(@type,'#{uppercase}','#{lowercase}')!='color' and " \
|
20
|
+
"translate(@type,'#{uppercase}','#{lowercase}')!='date' and " \
|
21
|
+
"translate(@type,'#{uppercase}','#{lowercase}')!='datetime-local'"
|
22
|
+
end
|
23
|
+
|
24
|
+
describe '#build' do
|
25
|
+
after(:each) do |example|
|
26
|
+
next if example.metadata[:skip_after]
|
27
|
+
|
28
|
+
@query_scope ||= browser
|
29
|
+
|
30
|
+
built = selector_builder.build(@selector)
|
31
|
+
expect(built).to eq [@wd_locator, (@remaining || {})]
|
32
|
+
|
33
|
+
next unless @data_locator || @tag_name
|
34
|
+
|
35
|
+
expect { @located = @query_scope.wd.first(@wd_locator) }.not_to raise_exception
|
36
|
+
|
37
|
+
if @data_locator
|
38
|
+
expect(@located.attribute('data-locator')).to eq(@data_locator)
|
39
|
+
else
|
40
|
+
expect {
|
41
|
+
expect(@located.tag_name).to eq @tag_name
|
42
|
+
}.not_to raise_exception
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'without any arguments' do
|
47
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
48
|
+
@selector = {}
|
49
|
+
@wd_locator = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]"}
|
50
|
+
@data_locator = 'input name'
|
51
|
+
end
|
52
|
+
|
53
|
+
context 'with type' do
|
54
|
+
before(:each) { browser.goto(WatirSpec.url_for('forms_with_input_elements.html')) }
|
55
|
+
|
56
|
+
it 'specified text field type that is text' do
|
57
|
+
@selector = {type: 'text'}
|
58
|
+
@wd_locator = {xpath: ".//*[local-name()='input']" \
|
59
|
+
"[translate(@type,'#{uppercase}','#{lowercase}')='text']"}
|
60
|
+
@data_locator = 'first text'
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'specified text field type that is not text' do
|
64
|
+
@selector = {type: 'number'}
|
65
|
+
@wd_locator = {xpath: ".//*[local-name()='input']" \
|
66
|
+
"[translate(@type,'#{uppercase}','#{lowercase}')='number']"}
|
67
|
+
@data_locator = '42'
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'true locates text field with a type specified' do
|
71
|
+
@selector = {type: true}
|
72
|
+
@wd_locator = {xpath: ".//*[local-name()='input'][#{negative_types}]"}
|
73
|
+
@data_locator = 'input name'
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'false locates text field without type specified' do
|
77
|
+
@selector = {type: false}
|
78
|
+
@wd_locator = {xpath: ".//*[local-name()='input'][not(@type)]"}
|
79
|
+
@data_locator = 'input name'
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'raises exception when a non-text field type input is specified', skip_after: true do
|
83
|
+
selector = {type: 'checkbox'}
|
84
|
+
msg = 'TextField Elements can not be located by type: checkbox'
|
85
|
+
expect { selector_builder.build(selector) }
|
86
|
+
.to raise_exception Watir::Exception::LocatorException, msg
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
context 'with index' do
|
91
|
+
before(:each) do
|
92
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'positive' do
|
96
|
+
@selector = {index: 4}
|
97
|
+
@wd_locator = {xpath: "(.//*[local-name()='input'][not(@type) or (#{negative_types})])[5]"}
|
98
|
+
@data_locator = 'dev'
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'negative' do
|
102
|
+
@selector = {index: -3}
|
103
|
+
@wd_locator = {xpath: "(.//*[local-name()='input'][not(@type) or (#{negative_types})])[last()-2]"}
|
104
|
+
@data_locator = '42'
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'last' do
|
108
|
+
@selector = {index: -1}
|
109
|
+
@wd_locator = {xpath: "(.//*[local-name()='input'][not(@type) or (#{negative_types})])[last()]"}
|
110
|
+
@data_locator = 'last text'
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'does not return index if it is zero' do
|
114
|
+
@selector = {index: 0}
|
115
|
+
@wd_locator = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]"}
|
116
|
+
@data_locator = 'input name'
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'raises exception when index is not an Integer', skip_after: true do
|
120
|
+
selector = {index: 'foo'}
|
121
|
+
msg = 'expected Integer, got "foo":String'
|
122
|
+
expect { selector_builder.build(selector) }.to raise_exception TypeError, msg
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
context 'with text' do
|
127
|
+
before(:each) { browser.goto(WatirSpec.url_for('forms_with_input_elements.html')) }
|
128
|
+
|
129
|
+
it 'String for value' do
|
130
|
+
@selector = {text: 'Developer'}
|
131
|
+
@wd_locator = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]"}
|
132
|
+
@remaining = {text: 'Developer'}
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'Simple Regexp for value' do
|
136
|
+
@selector = {text: /Dev/}
|
137
|
+
@wd_locator = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]"}
|
138
|
+
@remaining = {text: /Dev/}
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'returns complicated Regexp to the locator as a value' do
|
142
|
+
@selector = {text: /^foo$/}
|
143
|
+
@wd_locator = {xpath: ".//*[local-name()='input'][not(@type) or (#{negative_types})]"}
|
144
|
+
@remaining = {text: /^foo$/}
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
context 'with multiple locators' do
|
149
|
+
before(:each) do
|
150
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
151
|
+
end
|
152
|
+
|
153
|
+
it 'locates using tag name, class, attributes and text' do
|
154
|
+
@selector = {text: 'Developer', class: /c/, id: true}
|
155
|
+
@wd_locator = {xpath: ".//*[local-name()='input'][contains(@class, 'c')]" \
|
156
|
+
"[not(@type) or (#{negative_types})][@id]"}
|
157
|
+
@remaining = {text: 'Developer'}
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'delegates adjacent to Element SelectorBuilder' do
|
161
|
+
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
162
|
+
@query_scope = browser.element(id: 'new_user_email').locate
|
163
|
+
|
164
|
+
@selector = {adjacent: :ancestor, index: 1}
|
165
|
+
@wd_locator = {xpath: './ancestor::*[2]'}
|
166
|
+
@data_locator = 'form'
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
@@ -1,12 +1,17 @@
|
|
1
1
|
if defined?(RSpec)
|
2
2
|
DEPRECATION_WARNINGS = %i[selector_parameters
|
3
|
+
ready_state
|
3
4
|
class_array
|
4
5
|
use_capabilities
|
5
6
|
visible_text
|
7
|
+
link_text
|
6
8
|
text_regexp
|
9
|
+
stale_exists
|
7
10
|
stale_visible
|
8
11
|
stale_present
|
9
|
-
select_by
|
12
|
+
select_by
|
13
|
+
wait_until_present
|
14
|
+
wait_while_present].freeze
|
10
15
|
|
11
16
|
DEPRECATION_WARNINGS.each do |deprecation|
|
12
17
|
RSpec::Matchers.define "have_deprecated_#{deprecation}" do
|
@@ -128,6 +128,10 @@ describe Watir::UserEditable do
|
|
128
128
|
it "raises UnknownObjectException if the text field doesn't exist" do
|
129
129
|
expect { browser.text_field(id: 'no_such_id').set('secret') }.to raise_unknown_object_exception
|
130
130
|
end
|
131
|
+
|
132
|
+
it 'raises ObjectReadOnlyException if the object is read only' do
|
133
|
+
expect { browser.text_field(id: 'new_user_code').set('Foo') }.to raise_object_read_only_exception
|
134
|
+
end
|
131
135
|
end
|
132
136
|
|
133
137
|
describe '#set!' do
|
data/spec/watirspec/wait_spec.rb
CHANGED
@@ -107,48 +107,63 @@ describe Watir::Element do
|
|
107
107
|
describe '#wait_until_present' do
|
108
108
|
it 'waits until the element appears' do
|
109
109
|
browser.a(id: 'show_bar').click
|
110
|
-
expect {
|
110
|
+
expect {
|
111
|
+
expect { browser.div(id: 'bar').wait_until_present(timeout: 5) }.to_not raise_exception
|
112
|
+
}.to have_deprecated_wait_until_present
|
111
113
|
end
|
112
114
|
|
113
115
|
it 'waits until the element re-appears' do
|
114
116
|
browser.link(id: 'readd_bar').click
|
115
|
-
expect {
|
117
|
+
expect {
|
118
|
+
expect { browser.div(id: 'bar').wait_until_present }.to_not raise_exception
|
119
|
+
}.to have_deprecated_wait_until_present
|
116
120
|
end
|
117
121
|
|
118
122
|
it "times out if the element doesn't appear" do
|
119
123
|
inspected = '#<Watir::Div: located: true; {:id=>"bar", :tag_name=>"div"}>'
|
120
124
|
error = Watir::Wait::TimeoutError
|
121
|
-
message = "timed out after 1 seconds, waiting for
|
125
|
+
message = "timed out after 1 seconds, waiting for #{inspected} to become present"
|
122
126
|
|
123
|
-
expect {
|
127
|
+
expect {
|
128
|
+
expect { browser.div(id: 'bar').wait_until_present(timeout: 1) }.to raise_error(error, message)
|
129
|
+
}.to have_deprecated_wait_until_present
|
124
130
|
end
|
125
131
|
|
126
132
|
it 'uses provided interval' do
|
127
133
|
element = browser.div(id: 'bar')
|
128
134
|
expect(element).to receive(:present?).twice
|
129
135
|
|
130
|
-
expect {
|
136
|
+
expect {
|
137
|
+
expect { element.wait_until_present(timeout: 0.4, interval: 0.2) }.to raise_timeout_exception
|
138
|
+
}.to have_deprecated_wait_until_present
|
131
139
|
end
|
132
140
|
end
|
133
141
|
|
134
142
|
describe '#wait_while_present' do
|
135
143
|
it 'waits until the element disappears' do
|
136
144
|
browser.a(id: 'hide_foo').click
|
137
|
-
expect {
|
145
|
+
expect {
|
146
|
+
expect { browser.div(id: 'foo').wait_while_present(timeout: 2) }.to_not raise_exception
|
147
|
+
}.to have_deprecated_wait_while_present
|
138
148
|
end
|
139
149
|
|
140
150
|
it "times out if the element doesn't disappear" do
|
141
151
|
error = Watir::Wait::TimeoutError
|
142
152
|
inspected = '#<Watir::Div: located: true; {:id=>"foo", :tag_name=>"div"}>'
|
143
|
-
message = "timed out after 1 seconds, waiting for
|
144
|
-
expect {
|
153
|
+
message = "timed out after 1 seconds, waiting for #{inspected} not to be present"
|
154
|
+
expect {
|
155
|
+
expect { browser.div(id: 'foo').wait_while_present(timeout: 1) }.to raise_error(error, message)
|
156
|
+
}.to have_deprecated_wait_while_present
|
145
157
|
end
|
146
158
|
|
147
159
|
it 'uses provided interval' do
|
160
|
+
error = Watir::Wait::TimeoutError
|
148
161
|
element = browser.div(id: 'foo')
|
149
|
-
expect(element).to receive(:present?).twice
|
162
|
+
expect(element).to receive(:present?).and_return(true).twice
|
150
163
|
|
151
|
-
expect {
|
164
|
+
expect {
|
165
|
+
expect { element.wait_while_present(timeout: 0.4, interval: 0.2) }.to raise_error(error)
|
166
|
+
}.to have_deprecated_wait_while_present
|
152
167
|
end
|
153
168
|
|
154
169
|
it 'does not error when element goes stale' do
|
@@ -157,13 +172,17 @@ describe Watir::Element do
|
|
157
172
|
allow(element).to receive(:stale?).and_return(false, true)
|
158
173
|
|
159
174
|
browser.a(id: 'hide_foo').click
|
160
|
-
expect {
|
175
|
+
expect {
|
176
|
+
expect { element.wait_while_present(timeout: 1) }.to_not raise_exception
|
177
|
+
}.to have_deprecated_wait_while_present
|
161
178
|
end
|
162
179
|
|
163
180
|
it 'waits until the selector no longer matches' do
|
164
181
|
element = browser.link(name: 'add_select').wait_until(&:exists?)
|
165
182
|
browser.link(id: 'change_select').click
|
166
|
-
expect {
|
183
|
+
expect {
|
184
|
+
expect { element.wait_while_present }.not_to raise_error
|
185
|
+
}.to have_deprecated_wait_while_present
|
167
186
|
end
|
168
187
|
end
|
169
188
|
|
@@ -303,6 +322,34 @@ describe Watir::Element do
|
|
303
322
|
expect { element.wait_while(custom: '') }.to_not raise_exception
|
304
323
|
end
|
305
324
|
|
325
|
+
it 'accepts keywords and block' do
|
326
|
+
element = browser.div(id: 'foo')
|
327
|
+
browser.a(id: 'hide_foo').click
|
328
|
+
expect { element.wait_while(custom: '', &:present?) }.to_not raise_exception
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'browser accepts keywords' do
|
332
|
+
expect { browser.wait_until(title: 'wait test') }.to_not raise_exception
|
333
|
+
expect { browser.wait_until(title: 'wrong') }.to raise_timeout_exception
|
334
|
+
end
|
335
|
+
|
336
|
+
it 'alert accepts keywords' do
|
337
|
+
browser.goto WatirSpec.url_for('alerts.html')
|
338
|
+
|
339
|
+
begin
|
340
|
+
browser.button(id: 'alert').click
|
341
|
+
expect { browser.alert.wait_until(text: 'ok') }.to_not raise_exception
|
342
|
+
expect { browser.alert.wait_until(text: 'not ok') }.to raise_timeout_exception
|
343
|
+
ensure
|
344
|
+
browser.alert.ok
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
it 'window accepts keywords' do
|
349
|
+
expect { browser.window.wait_until(title: 'wait test') }.to_not raise_exception
|
350
|
+
expect { browser.window.wait_until(title: 'wrong') }.to raise_timeout_exception
|
351
|
+
end
|
352
|
+
|
306
353
|
it 'times out when single keyword not met' do
|
307
354
|
element = browser.div(id: 'foo')
|
308
355
|
expect { element.wait_while(id: 'foo') }.to raise_timeout_exception
|
@@ -338,11 +385,15 @@ describe Watir do
|
|
338
385
|
end
|
339
386
|
|
340
387
|
it 'is used by Element#wait_until_present' do
|
341
|
-
expect {
|
388
|
+
expect {
|
389
|
+
expect { browser.div(id: 'bar').wait_until_present }.to wait_and_raise_timeout_exception(timeout: 1)
|
390
|
+
}.to have_deprecated_wait_until_present
|
342
391
|
end
|
343
392
|
|
344
393
|
it 'is used by Element#wait_while_present' do
|
345
|
-
expect {
|
394
|
+
expect {
|
395
|
+
expect { browser.div(id: 'foo').wait_while_present }.to wait_and_raise_timeout_exception(timeout: 1)
|
396
|
+
}.to have_deprecated_wait_while_present
|
346
397
|
end
|
347
398
|
end
|
348
399
|
end
|