watir 6.15.1 → 6.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +3 -2
- data/.travis.yml +2 -0
- data/CHANGES.md +13 -0
- data/Rakefile +6 -0
- data/lib/watir.rb +1 -0
- data/lib/watir/browser.rb +4 -1
- data/lib/watir/element_collection.rb +27 -17
- data/lib/watir/elements/element.rb +41 -14
- data/lib/watir/elements/iframe.rb +3 -1
- data/lib/watir/elements/radio.rb +7 -2
- data/lib/watir/elements/select.rb +1 -0
- data/lib/watir/locators.rb +21 -21
- data/lib/watir/locators/button/matcher.rb +40 -0
- data/lib/watir/locators/cell/selector_builder.rb +3 -0
- data/lib/watir/locators/element/locator.rb +29 -172
- data/lib/watir/locators/element/matcher.rb +127 -0
- data/lib/watir/locators/element/selector_builder.rb +69 -23
- data/lib/watir/locators/element/selector_builder/xpath.rb +3 -10
- data/lib/watir/locators/row/selector_builder.rb +5 -5
- data/lib/watir/locators/text_area/selector_builder.rb +0 -14
- data/lib/watir/locators/text_area/selector_builder/xpath.rb +2 -2
- data/lib/watir/locators/text_field/matcher.rb +38 -0
- data/lib/watir/radio_set.rb +28 -31
- data/lib/watir/scroll.rb +69 -0
- data/lib/watir/version.rb +1 -1
- data/spec/locator_spec_helper.rb +58 -14
- data/spec/unit/element_locator_spec.rb +46 -591
- data/spec/unit/match_elements/button_spec.rb +80 -0
- data/spec/unit/match_elements/element_spec.rb +368 -0
- data/spec/unit/match_elements/text_field_spec.rb +79 -0
- data/spec/unit/selector_builder/anchor_spec.rb +51 -0
- data/spec/unit/selector_builder/button_spec.rb +206 -0
- data/spec/unit/selector_builder/cell_spec.rb +63 -0
- data/spec/unit/selector_builder/element_spec.rb +744 -0
- data/spec/unit/selector_builder/row_spec.rb +111 -0
- data/spec/unit/selector_builder/text_field_spec.rb +189 -0
- data/spec/unit/selector_builder/textarea_spec.rb +25 -0
- data/spec/watirspec/browser_spec.rb +7 -8
- data/spec/watirspec/element_hidden_spec.rb +1 -2
- data/spec/watirspec/elements/element_spec.rb +52 -16
- data/spec/watirspec/elements/iframe_spec.rb +1 -1
- data/spec/watirspec/elements/select_list_spec.rb +1 -1
- data/spec/watirspec/html/obscured.html +3 -1
- data/spec/watirspec/html/scroll.html +32 -0
- data/spec/watirspec/relaxed_locate_spec.rb +6 -1
- data/spec/watirspec/scroll_spec.rb +106 -0
- data/spec/watirspec/support/rspec_matchers.rb +2 -0
- data/spec/watirspec/wait_spec.rb +1 -1
- data/watir.gemspec +2 -4
- metadata +36 -33
- data/lib/watir/locators/button/locator.rb +0 -32
- data/lib/watir/locators/button/validator.rb +0 -17
- data/lib/watir/locators/cell/locator.rb +0 -13
- data/lib/watir/locators/element/validator.rb +0 -11
- data/lib/watir/locators/row/locator.rb +0 -13
- data/lib/watir/locators/text_field/locator.rb +0 -31
- data/lib/watir/locators/text_field/validator.rb +0 -13
- data/spec/unit/anchor_locator_spec.rb +0 -68
- data/spec/watirspec/selector_builder/button_spec.rb +0 -250
- data/spec/watirspec/selector_builder/cell_spec.rb +0 -92
- data/spec/watirspec/selector_builder/element_spec.rb +0 -628
- data/spec/watirspec/selector_builder/row_spec.rb +0 -148
- data/spec/watirspec/selector_builder/text_spec.rb +0 -199
@@ -1,17 +0,0 @@
|
|
1
|
-
module Watir
|
2
|
-
module Locators
|
3
|
-
class Button
|
4
|
-
class Validator < Element::Validator
|
5
|
-
def validate(element, _tag_name)
|
6
|
-
tag_name = element.tag_name.downcase
|
7
|
-
return unless %w[input button].include?(tag_name)
|
8
|
-
|
9
|
-
# TODO: - Verify this is desired behavior based on https://bugzilla.mozilla.org/show_bug.cgi?id=1290963
|
10
|
-
return if tag_name == 'input' && !Watir::Button::VALID_TYPES.include?(element.attribute(:type).downcase)
|
11
|
-
|
12
|
-
element
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
module Watir
|
2
|
-
module Locators
|
3
|
-
class TextField
|
4
|
-
class Locator < Element::Locator
|
5
|
-
private
|
6
|
-
|
7
|
-
def using_selenium(*)
|
8
|
-
# force Watir usage
|
9
|
-
end
|
10
|
-
|
11
|
-
def matches_values?(element, rx_selector)
|
12
|
-
conversions = %i[text value label visible_text] & rx_selector.keys
|
13
|
-
|
14
|
-
tag_name = nil
|
15
|
-
|
16
|
-
conversions.each do |key|
|
17
|
-
tag_name ||= element.tag_name.downcase
|
18
|
-
correct_key = tag_name == 'input' ? :value : :text
|
19
|
-
rx_selector[correct_key] = rx_selector.delete(key)
|
20
|
-
end
|
21
|
-
|
22
|
-
super
|
23
|
-
end
|
24
|
-
|
25
|
-
def text_regexp_deprecation(*)
|
26
|
-
# does not apply to text_field
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module Watir
|
2
|
-
module Locators
|
3
|
-
class TextField
|
4
|
-
class Validator < Element::Validator
|
5
|
-
def validate(element, _tag_name)
|
6
|
-
# Zero for Ruby 2.3, Ruby 2.4+ this evaluates true/false
|
7
|
-
result = element.tag_name.casecmp('input')
|
8
|
-
result.zero? || result.eq(true)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,68 +0,0 @@
|
|
1
|
-
require_relative 'unit_helper'
|
2
|
-
|
3
|
-
describe Watir::Locators::Element::Locator do
|
4
|
-
include LocatorSpecHelper
|
5
|
-
|
6
|
-
def locator(selector, attrs)
|
7
|
-
attrs ||= Watir::HTMLElement.attributes
|
8
|
-
element_validator = Watir::Locators::Element::Validator.new
|
9
|
-
selector_builder = Watir::Locators::Anchor::SelectorBuilder.new(attrs)
|
10
|
-
Watir::Locators::Element::Locator.new(browser, selector, selector_builder, element_validator)
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'converts :visible_text with String to :link_text' do
|
14
|
-
link = element(tag_name: 'a')
|
15
|
-
expect_one(:link_text, 'exact text').and_return(link)
|
16
|
-
expect(link).not_to receive(:text) # matching does not validate text
|
17
|
-
|
18
|
-
locate_one(tag_name: 'a', visible_text: 'exact text')
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'converts :visible_text with basic Regexp to :partial_link_text' do
|
22
|
-
link = element(tag_name: 'a')
|
23
|
-
expect_one(:partial_link_text, 'partial text').and_return(link)
|
24
|
-
expect(link).not_to receive(:text) # matching does not validate text
|
25
|
-
|
26
|
-
locate_one(tag_name: 'a', visible_text: /partial text/)
|
27
|
-
end
|
28
|
-
|
29
|
-
it 'does not convert :visible_text with complex Regexp' do
|
30
|
-
elements = [
|
31
|
-
element(tag_name: 'a', text: 'other text'),
|
32
|
-
element(tag_name: 'a', text: 'matching complex!text')
|
33
|
-
]
|
34
|
-
expect_all(:xpath, ".//*[local-name()='a']").and_return(elements)
|
35
|
-
|
36
|
-
expect(locate_one(tag_name: 'a', visible_text: /complex.text/)).to eq(elements[1])
|
37
|
-
end
|
38
|
-
|
39
|
-
it 'does not convert :visible_text with casefold Regexp' do
|
40
|
-
elements = [
|
41
|
-
element(tag_name: 'a', text: 'other text'),
|
42
|
-
element(tag_name: 'a', text: 'partial text')
|
43
|
-
]
|
44
|
-
expect_all(:xpath, ".//*[local-name()='a']").and_return(elements)
|
45
|
-
|
46
|
-
expect(locate_one(tag_name: 'a', visible_text: /partial text/i)).to eq(elements[1])
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'does not convert :visible_text with String and other locators' do
|
50
|
-
els = [
|
51
|
-
element(tag_name: 'a', attributes: {class: 'klass', name: 'abc'}, text: 'other text'),
|
52
|
-
element(tag_name: 'a', attributes: {class: 'klass', name: 'abc'}, text: 'exact text')
|
53
|
-
]
|
54
|
-
expect_all(:xpath, ".//*[local-name()='a'][contains(concat(' ', @class, ' '), ' klass ')][@name]").and_return(els)
|
55
|
-
|
56
|
-
expect(locate_one(tag_name: 'a', class: 'klass', name: /a|.c/, visible_text: 'exact text')).to eq(els[1])
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'does not convert :visible_text with Regexp and other locators' do
|
60
|
-
els = [
|
61
|
-
element(tag_name: 'a', attributes: {class: 'klass', name: 'abc'}, text: 'other text'),
|
62
|
-
element(tag_name: 'a', attributes: {class: 'klass', name: 'abc'}, text: 'partial text')
|
63
|
-
]
|
64
|
-
expect_all(:xpath, ".//*[local-name()='a'][contains(concat(' ', @class, ' '), ' klass ')][@name]").and_return(els)
|
65
|
-
|
66
|
-
expect(locate_one(tag_name: 'a', class: 'klass', name: /a|.c/, visible_text: /partial text/)).to eq(els[1])
|
67
|
-
end
|
68
|
-
end
|
@@ -1,250 +0,0 @@
|
|
1
|
-
require 'watirspec_helper'
|
2
|
-
|
3
|
-
describe Watir::Locators::Button::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(:default_types) do
|
10
|
-
"translate(@type,'#{uppercase}','#{lowercase}')='button' or" \
|
11
|
-
" translate(@type,'#{uppercase}','#{lowercase}')='reset' or"\
|
12
|
-
" translate(@type,'#{uppercase}','#{lowercase}')='submit' or"\
|
13
|
-
" translate(@type,'#{uppercase}','#{lowercase}')='image'"
|
14
|
-
end
|
15
|
-
|
16
|
-
describe '#build' do
|
17
|
-
after(:each) do |example|
|
18
|
-
next if example.metadata[:skip_after]
|
19
|
-
|
20
|
-
@query_scope ||= browser
|
21
|
-
expect(selector_builder.build(@selector)).to eq @built
|
22
|
-
|
23
|
-
next unless @data_locator || @tag_name
|
24
|
-
|
25
|
-
expect { @located = @query_scope.wd.first(@built) }.not_to raise_exception
|
26
|
-
|
27
|
-
if @data_locator
|
28
|
-
expect(@located.attribute('data-locator')).to eq(@data_locator)
|
29
|
-
else
|
30
|
-
expect {
|
31
|
-
expect(@located.tag_name).to eq @tag_name
|
32
|
-
}.not_to raise_exception
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'without any arguments' do
|
37
|
-
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
38
|
-
@selector = {}
|
39
|
-
@built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]"}
|
40
|
-
@data_locator = 'user submit'
|
41
|
-
end
|
42
|
-
|
43
|
-
context 'with type' do
|
44
|
-
before(:each) { browser.goto(WatirSpec.url_for('forms_with_input_elements.html')) }
|
45
|
-
|
46
|
-
it 'false only locates with button without a type' do
|
47
|
-
@selector = {type: false}
|
48
|
-
@built = {xpath: ".//*[(local-name()='button' and not(@type))]"}
|
49
|
-
@data_locator = 'No Type'
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'true locates button or input with a type' do
|
53
|
-
@selector = {type: true}
|
54
|
-
@built = {xpath: ".//*[(local-name()='button' and @type) or " \
|
55
|
-
"(local-name()='input' and (#{default_types}))]"}
|
56
|
-
@data_locator = 'user submit'
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'locates input or button element with specified type' do
|
60
|
-
@selector = {type: 'reset'}
|
61
|
-
@built = {xpath: ".//*[(local-name()='button' and " \
|
62
|
-
"translate(@type,'#{uppercase}','#{lowercase}')='reset') or " \
|
63
|
-
"(local-name()='input' and (translate(@type,'#{uppercase}','#{lowercase}')='reset'))]"}
|
64
|
-
@data_locator = 'reset'
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'raises exception when a non-button type input is specified', skip_after: true do
|
68
|
-
selector = {type: 'checkbox'}
|
69
|
-
msg = 'Button Elements can not be located by input type: checkbox'
|
70
|
-
expect { selector_builder.build(selector) }
|
71
|
-
.to raise_exception Watir::Exception::LocatorException, msg
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
context 'with xpath or css' do
|
76
|
-
before(:each) do
|
77
|
-
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
78
|
-
end
|
79
|
-
|
80
|
-
it 'returns tag name and type to the locator' do
|
81
|
-
@selector = {xpath: '#disabled_button', tag_name: 'input', type: 'submit'}
|
82
|
-
@built = {xpath: '#disabled_button', tag_name: 'input', type: 'submit'}
|
83
|
-
end
|
84
|
-
end
|
85
|
-
|
86
|
-
context 'with text' do
|
87
|
-
before(:each) { browser.goto(WatirSpec.url_for('forms_with_input_elements.html')) }
|
88
|
-
|
89
|
-
it 'locates value of input element with String' do
|
90
|
-
@selector = {text: 'Button'}
|
91
|
-
@built = {xpath: ".//*[(local-name()='button' and normalize-space()='Button') or " \
|
92
|
-
"(local-name()='input' and (#{default_types}) and @value='Button')]"}
|
93
|
-
@data_locator = 'new user'
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'locates text of button element with String' do
|
97
|
-
@selector = {text: 'Button 2'}
|
98
|
-
@built = {xpath: ".//*[(local-name()='button' and normalize-space()='Button 2') or " \
|
99
|
-
"(local-name()='input' and (#{default_types}) and @value='Button 2')]"}
|
100
|
-
@data_locator = 'Benjamin'
|
101
|
-
end
|
102
|
-
|
103
|
-
it 'locates value of input element with simple Regexp' do
|
104
|
-
@selector = {text: /Button/}
|
105
|
-
@built = {xpath: ".//*[(local-name()='button' and contains(text(), 'Button')) or " \
|
106
|
-
"(local-name()='input' and (#{default_types}) and contains(@value, 'Button'))]"}
|
107
|
-
@data_locator = 'new user'
|
108
|
-
end
|
109
|
-
|
110
|
-
it 'locates text of button element with simple Regexp' do
|
111
|
-
@selector = {text: /Button 2/}
|
112
|
-
@built = {xpath: ".//*[(local-name()='button' and contains(text(), 'Button 2')) or " \
|
113
|
-
"(local-name()='input' and (#{default_types}) and contains(@value, 'Button 2'))]"}
|
114
|
-
@data_locator = 'Benjamin'
|
115
|
-
end
|
116
|
-
|
117
|
-
it 'Simple Regexp for text' do
|
118
|
-
@selector = {text: /n 2/}
|
119
|
-
@built = {xpath: ".//*[(local-name()='button' and contains(text(), 'n 2')) or " \
|
120
|
-
"(local-name()='input' and (#{default_types}) and contains(@value, 'n 2'))]"}
|
121
|
-
@data_locator = 'Benjamin'
|
122
|
-
end
|
123
|
-
|
124
|
-
it 'Simple Regexp for value' do
|
125
|
-
@selector = {text: /Prev/}
|
126
|
-
@built = {xpath: ".//*[(local-name()='button' and contains(text(), 'Prev')) or " \
|
127
|
-
"(local-name()='input' and (#{default_types}) and contains(@value, 'Prev'))]"}
|
128
|
-
@data_locator = 'preview'
|
129
|
-
end
|
130
|
-
|
131
|
-
it 'returns complex Regexp to the locator' do
|
132
|
-
@selector = {text: /^foo$/}
|
133
|
-
@built = {xpath: ".//*[(local-name()='button' and contains(text(), 'foo')) or " \
|
134
|
-
"(local-name()='input' and (#{default_types}) and contains(@value, 'foo'))]", text: /^foo$/}
|
135
|
-
end
|
136
|
-
end
|
137
|
-
|
138
|
-
context 'with value' do
|
139
|
-
before(:each) { browser.goto(WatirSpec.url_for('forms_with_input_elements.html')) }
|
140
|
-
|
141
|
-
it 'input element value with String' do
|
142
|
-
@selector = {value: 'Preview'}
|
143
|
-
@built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
|
144
|
-
"[normalize-space()='Preview' or @value='Preview']"}
|
145
|
-
@data_locator = 'preview'
|
146
|
-
end
|
147
|
-
|
148
|
-
it 'button element value with String' do
|
149
|
-
@selector = {value: 'button_2'}
|
150
|
-
@built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
|
151
|
-
"[normalize-space()='button_2' or @value='button_2']"}
|
152
|
-
@data_locator = 'Benjamin'
|
153
|
-
end
|
154
|
-
|
155
|
-
it 'input element value with simple Regexp' do
|
156
|
-
@selector = {value: /Prev/}
|
157
|
-
@built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
|
158
|
-
"[contains(text(), 'Prev') or contains(@value, 'Prev')]"}
|
159
|
-
@data_locator = 'preview'
|
160
|
-
end
|
161
|
-
|
162
|
-
it 'button element value with simple Regexp' do
|
163
|
-
@selector = {value: /on_2/}
|
164
|
-
@built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
|
165
|
-
"[contains(text(), 'on_2') or contains(@value, 'on_2')]"}
|
166
|
-
@data_locator = 'Benjamin'
|
167
|
-
end
|
168
|
-
|
169
|
-
it 'button element text with String' do
|
170
|
-
@selector = {value: 'Button 2'}
|
171
|
-
@built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
|
172
|
-
"[normalize-space()='Button 2' or @value='Button 2']"}
|
173
|
-
@data_locator = 'Benjamin'
|
174
|
-
end
|
175
|
-
|
176
|
-
it 'button element text with simple Regexp' do
|
177
|
-
@selector = {value: /ton 2/}
|
178
|
-
@built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
|
179
|
-
"[contains(text(), 'ton 2') or contains(@value, 'ton 2')]"}
|
180
|
-
@data_locator = 'Benjamin'
|
181
|
-
end
|
182
|
-
|
183
|
-
it 'returns complex Regexp to the locator' do
|
184
|
-
@selector = {value: /^foo$/}
|
185
|
-
@built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
|
186
|
-
"[contains(text(), 'foo') or contains(@value, 'foo')]", value: /^foo$/}
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
context 'with index' do
|
191
|
-
before(:each) do
|
192
|
-
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
193
|
-
end
|
194
|
-
|
195
|
-
it 'positive' do
|
196
|
-
@selector = {index: 3}
|
197
|
-
@built = {xpath: "(.//*[(local-name()='button') or (local-name()='input' and (#{default_types}))])[4]"}
|
198
|
-
@data_locator = 'preview'
|
199
|
-
end
|
200
|
-
|
201
|
-
it 'negative' do
|
202
|
-
@selector = {index: -4}
|
203
|
-
@built = {xpath: "(.//*[(local-name()='button') or " \
|
204
|
-
"(local-name()='input' and (#{default_types}))])[last()-3]"}
|
205
|
-
@data_locator = 'submittable button'
|
206
|
-
end
|
207
|
-
|
208
|
-
it 'last' do
|
209
|
-
@selector = {index: -1}
|
210
|
-
@built = {xpath: "(.//*[(local-name()='button') or " \
|
211
|
-
"(local-name()='input' and (#{default_types}))])[last()]"}
|
212
|
-
@data_locator = 'last button'
|
213
|
-
end
|
214
|
-
|
215
|
-
it 'does not return index if it is zero' do
|
216
|
-
@selector = {index: 0}
|
217
|
-
@built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]"}
|
218
|
-
@data_locator = 'user submit'
|
219
|
-
end
|
220
|
-
|
221
|
-
it 'raises exception when index is not an Integer', skip_after: true do
|
222
|
-
selector = {index: 'foo'}
|
223
|
-
msg = /expected one of \[(Integer|Fixnum)\], got "foo":String/
|
224
|
-
expect { selector_builder.build(selector) }.to raise_exception TypeError, msg
|
225
|
-
end
|
226
|
-
end
|
227
|
-
|
228
|
-
context 'with multiple locators' do
|
229
|
-
before(:each) do
|
230
|
-
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
231
|
-
end
|
232
|
-
|
233
|
-
it 'locates using class and attributes' do
|
234
|
-
@selector = {class: 'image', name: 'new_user_image', src: true}
|
235
|
-
@built = {xpath: ".//*[(local-name()='button') or (local-name()='input' and (#{default_types}))]" \
|
236
|
-
"[contains(concat(' ', @class, ' '), ' image ')][@name='new_user_image' and @src]"}
|
237
|
-
@data_locator = 'submittable button'
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
it 'delegates adjacent to Element SelectorBuilder' do
|
242
|
-
browser.goto(WatirSpec.url_for('forms_with_input_elements.html'))
|
243
|
-
@query_scope = browser.element(id: 'new_user_button').locate
|
244
|
-
|
245
|
-
@selector = {adjacent: :ancestor, index: 2}
|
246
|
-
@built = {xpath: './ancestor::*[3]'}
|
247
|
-
@data_locator = 'body'
|
248
|
-
end
|
249
|
-
end
|
250
|
-
end
|
@@ -1,92 +0,0 @@
|
|
1
|
-
require 'watirspec_helper'
|
2
|
-
|
3
|
-
describe Watir::Locators::Cell::SelectorBuilder do
|
4
|
-
let(:attributes) { Watir::HTMLElement.attribute_list }
|
5
|
-
let(:selector_builder) { described_class.new(attributes) }
|
6
|
-
|
7
|
-
describe '#build' do
|
8
|
-
after(:each) do |example|
|
9
|
-
next if example.metadata[:skip_after]
|
10
|
-
|
11
|
-
@query_scope ||= browser.element(id: 'gregory').locate
|
12
|
-
|
13
|
-
expect(selector_builder.build(@selector)).to eq @built
|
14
|
-
|
15
|
-
next unless @data_locator || @tag_name
|
16
|
-
|
17
|
-
expect { @located = @query_scope.wd.first(@built) }.not_to raise_exception
|
18
|
-
|
19
|
-
if @data_locator
|
20
|
-
expect(@located.attribute('data-locator')).to eq(@data_locator)
|
21
|
-
else
|
22
|
-
expect {
|
23
|
-
expect(@located.tag_name).to eq @tag_name
|
24
|
-
}.not_to raise_exception
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'without any arguments' do
|
29
|
-
browser.goto(WatirSpec.url_for('tables.html'))
|
30
|
-
@selector = {}
|
31
|
-
@built = {xpath: "./*[local-name()='th' or local-name()='td']"}
|
32
|
-
@data_locator = 'first cell'
|
33
|
-
end
|
34
|
-
|
35
|
-
context 'with index' do
|
36
|
-
before(:each) do
|
37
|
-
browser.goto(WatirSpec.url_for('tables.html'))
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'positive' do
|
41
|
-
@selector = {index: 3}
|
42
|
-
@built = {xpath: "(./*[local-name()='th' or local-name()='td'])[4]"}
|
43
|
-
@data_locator = 'after tax'
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'negative' do
|
47
|
-
@selector = {index: -3}
|
48
|
-
@built = {xpath: "(./*[local-name()='th' or local-name()='td'])[last()-2]"}
|
49
|
-
@data_locator = 'before tax'
|
50
|
-
end
|
51
|
-
|
52
|
-
it 'last' do
|
53
|
-
@selector = {index: -1}
|
54
|
-
@built = {xpath: "(./*[local-name()='th' or local-name()='td'])[last()]"}
|
55
|
-
@data_locator = 'after tax'
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'does not return index if it is zero' do
|
59
|
-
@selector = {index: 0}
|
60
|
-
@built = {xpath: "./*[local-name()='th' or local-name()='td']"}
|
61
|
-
@data_locator = 'first cell'
|
62
|
-
end
|
63
|
-
|
64
|
-
it 'raises exception when index is not an Integer', skip_after: true do
|
65
|
-
selector = {index: 'foo'}
|
66
|
-
msg = /expected one of \[(Integer|Fixnum)\], got "foo":String/
|
67
|
-
expect { selector_builder.build(selector) }.to raise_exception TypeError, msg
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
context 'with multiple locators' do
|
72
|
-
before(:each) do
|
73
|
-
browser.goto(WatirSpec.url_for('tables.html'))
|
74
|
-
end
|
75
|
-
|
76
|
-
it 'attribute and text' do
|
77
|
-
@selector = {headers: /before_tax/, text: '5 934'}
|
78
|
-
@built = {xpath: "./*[local-name()='th' or local-name()='td']" \
|
79
|
-
"[normalize-space()='5 934'][contains(@headers, 'before_tax')]"}
|
80
|
-
@data_locator = 'before tax'
|
81
|
-
end
|
82
|
-
end
|
83
|
-
|
84
|
-
it 'delegates adjacent to Element SelectorBuilder' do
|
85
|
-
@query_scope = browser.element(id: 'p3').locate
|
86
|
-
|
87
|
-
@selector = {adjacent: :ancestor, index: 2}
|
88
|
-
@built = {xpath: './ancestor::*[3]'}
|
89
|
-
@data_locator = 'top table'
|
90
|
-
end
|
91
|
-
end
|
92
|
-
end
|