watir-webdriver 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -2
  3. data/.travis.yml +2 -3
  4. data/CHANGES.md +10 -1
  5. data/Gemfile +1 -1
  6. data/README.md +22 -17
  7. data/Rakefile +55 -52
  8. data/lib/watir-webdriver.rb +3 -2
  9. data/lib/watir-webdriver/alert.rb +0 -1
  10. data/lib/watir-webdriver/atoms/README +1 -1
  11. data/lib/watir-webdriver/browser.rb +4 -5
  12. data/lib/watir-webdriver/cell_container.rb +2 -2
  13. data/lib/watir-webdriver/container.rb +2 -3
  14. data/lib/watir-webdriver/cookies.rb +8 -8
  15. data/lib/watir-webdriver/element_collection.rb +3 -4
  16. data/lib/watir-webdriver/elements/area.rb +0 -1
  17. data/lib/watir-webdriver/elements/button.rb +0 -1
  18. data/lib/watir-webdriver/elements/checkbox.rb +2 -4
  19. data/lib/watir-webdriver/elements/element.rb +69 -45
  20. data/lib/watir-webdriver/elements/file_field.rb +2 -3
  21. data/lib/watir-webdriver/elements/font.rb +2 -2
  22. data/lib/watir-webdriver/elements/form.rb +0 -1
  23. data/lib/watir-webdriver/elements/hidden.rb +2 -3
  24. data/lib/watir-webdriver/elements/html_elements.rb +2282 -0
  25. data/lib/watir-webdriver/elements/iframe.rb +6 -7
  26. data/lib/watir-webdriver/elements/image.rb +0 -1
  27. data/lib/watir-webdriver/elements/input.rb +0 -1
  28. data/lib/watir-webdriver/elements/link.rb +0 -1
  29. data/lib/watir-webdriver/elements/option.rb +3 -4
  30. data/lib/watir-webdriver/elements/radio.rb +2 -3
  31. data/lib/watir-webdriver/elements/select.rb +0 -1
  32. data/lib/watir-webdriver/elements/svg_elements.rb +787 -0
  33. data/lib/watir-webdriver/elements/table.rb +0 -2
  34. data/lib/watir-webdriver/elements/table_section.rb +1 -1
  35. data/lib/watir-webdriver/elements/text_field.rb +2 -3
  36. data/lib/watir-webdriver/exception.rb +0 -2
  37. data/lib/watir-webdriver/extensions/nokogiri.rb +1 -1
  38. data/lib/watir-webdriver/generator.rb +3 -0
  39. data/lib/watir-webdriver/generator/base.rb +11 -0
  40. data/lib/watir-webdriver/{html → generator/base}/generator.rb +23 -33
  41. data/lib/watir-webdriver/{html → generator/base}/idl_sorter.rb +3 -5
  42. data/lib/watir-webdriver/{html → generator/base}/spec_extractor.rb +15 -41
  43. data/lib/watir-webdriver/generator/base/util.rb +21 -0
  44. data/lib/watir-webdriver/{html → generator/base}/visitor.rb +15 -15
  45. data/lib/watir-webdriver/{html.rb → generator/html.rb} +3 -11
  46. data/lib/watir-webdriver/generator/html/generator.rb +36 -0
  47. data/lib/watir-webdriver/generator/html/spec_extractor.rb +50 -0
  48. data/lib/watir-webdriver/generator/html/visitor.rb +21 -0
  49. data/lib/watir-webdriver/generator/svg.rb +7 -0
  50. data/lib/watir-webdriver/generator/svg/generator.rb +38 -0
  51. data/lib/watir-webdriver/generator/svg/spec_extractor.rb +46 -0
  52. data/lib/watir-webdriver/generator/svg/visitor.rb +21 -0
  53. data/lib/watir-webdriver/has_window.rb +3 -3
  54. data/lib/watir-webdriver/locators/button_locator.rb +7 -2
  55. data/lib/watir-webdriver/locators/child_cell_locator.rb +1 -1
  56. data/lib/watir-webdriver/locators/child_row_locator.rb +1 -1
  57. data/lib/watir-webdriver/locators/element_locator.rb +44 -9
  58. data/lib/watir-webdriver/locators/text_area_locator.rb +4 -0
  59. data/lib/watir-webdriver/locators/text_field_locator.rb +7 -2
  60. data/lib/watir-webdriver/screenshot.rb +0 -1
  61. data/lib/watir-webdriver/version.rb +1 -1
  62. data/lib/watir-webdriver/wait.rb +10 -11
  63. data/lib/watir-webdriver/window.rb +5 -5
  64. data/lib/watir-webdriver/xpath_support.rb +0 -1
  65. data/spec/always_locate_spec.rb +4 -4
  66. data/spec/browser_spec.rb +3 -3
  67. data/spec/click_spec.rb +11 -4
  68. data/spec/container_spec.rb +2 -2
  69. data/spec/element_locator_spec.rb +145 -84
  70. data/spec/element_spec.rb +29 -16
  71. data/spec/html/clicks.html +3 -0
  72. data/spec/html/removed_element.html +7 -0
  73. data/spec/implementation.rb +5 -5
  74. data/spec/input_spec.rb +1 -1
  75. data/spec/spec_helper.rb +1 -2
  76. data/spec/special_chars_spec.rb +2 -2
  77. data/support/doctest_helper.rb +4 -4
  78. data/support/version_differ.rb +2 -2
  79. data/watir-webdriver.gemspec +3 -3
  80. metadata +27 -17
  81. data/lib/watir-webdriver/elements/generated.rb +0 -3106
  82. data/lib/watir-webdriver/html/util.rb +0 -22
@@ -8,7 +8,7 @@ module Watir
8
8
 
9
9
  if selector.empty?
10
10
  @handle = current_window
11
- elsif selector.has_key? :handle
11
+ elsif selector.key? :handle
12
12
  @handle = selector.delete :handle
13
13
  else
14
14
  unless selector.keys.all? { |k| [:title, :url, :index].include? k }
@@ -116,7 +116,7 @@ module Watir
116
116
  # Returns true if two windows are equal.
117
117
  #
118
118
  # @example
119
- # browser.window(:index => 0) == browser.window(:index => 1)
119
+ # browser.window(index: 0) == browser.window(index: 1)
120
120
  # #=> false
121
121
  #
122
122
  # @param [Window] other
@@ -183,8 +183,8 @@ module Watir
183
183
  # Switches to given window and executes block, then switches back.
184
184
  #
185
185
  # @example
186
- # browser.window(:title => "closeable window").use do
187
- # browser.a(:id => "close").click
186
+ # browser.window(title: "closeable window").use do
187
+ # browser.a(id: "close").click
188
188
  # end
189
189
  #
190
190
 
@@ -210,7 +210,7 @@ module Watir
210
210
  def locate
211
211
  if @selector.empty?
212
212
  nil
213
- elsif @selector.has_key?(:index)
213
+ elsif @selector.key?(:index)
214
214
  @driver.window_handles[Integer(@selector[:index])]
215
215
  else
216
216
  @driver.window_handles.find { |wh| matches?(wh) }
@@ -1,4 +1,3 @@
1
- # encoding: utf-8
2
1
  module Watir
3
2
  module XpathSupport
4
3
 
@@ -4,11 +4,11 @@ describe 'Watir' do
4
4
  describe '#always_locate?' do
5
5
 
6
6
  before do
7
- browser.goto WatirSpec.url_for('removed_element.html', :needs_server => true)
7
+ browser.goto WatirSpec.url_for('removed_element.html', needs_server: true)
8
8
  end
9
9
 
10
10
  it 'determines whether #exist? returns false for stale element' do
11
- element = browser.div(:id => "text")
11
+ element = browser.div(id: "text")
12
12
  expect(element.exists?).to be true
13
13
 
14
14
  browser.refresh
@@ -17,7 +17,7 @@ describe 'Watir' do
17
17
  end
18
18
 
19
19
  it 'allows using cached elements regardless of setting, when element is not stale' do
20
- element = browser.div(:id => "text")
20
+ element = browser.div(id: "text")
21
21
  expect(element.exists?).to be true
22
22
 
23
23
  # exception raised if element is re-looked up
@@ -27,7 +27,7 @@ describe 'Watir' do
27
27
  end
28
28
 
29
29
  it 'determines whether an exception is raised when taking an action on a stale element' do
30
- element = browser.div(:id => "text")
30
+ element = browser.div(id: "text")
31
31
  expect(element.exists?).to be true
32
32
 
33
33
  browser.refresh
data/spec/browser_spec.rb CHANGED
@@ -51,12 +51,12 @@ describe Watir::Browser do
51
51
  browser.goto WatirSpec.url_for "forms_with_input_elements.html"
52
52
 
53
53
  browser.send_keys "hello"
54
- expect(browser.text_field(:id => "new_user_first_name").value).to eq "hello"
54
+ expect(browser.text_field(id: "new_user_first_name").value).to eq "hello"
55
55
  end
56
56
 
57
57
  it "sends keys to a frame" do
58
58
  browser.goto WatirSpec.url_for "frames.html"
59
- tf = browser.frame.text_field(:id => "senderElement")
59
+ tf = browser.frame.text_field(id: "senderElement")
60
60
  tf.clear
61
61
 
62
62
  browser.frame.send_keys "hello"
@@ -70,7 +70,7 @@ describe Watir::Browser do
70
70
  b.goto WatirSpec.url_for "definition_lists.html"
71
71
  b.close
72
72
 
73
- expect { b.dl(:id => "experience-list").id }.to raise_error(Watir::Exception::Error, "browser was closed")
73
+ expect { b.dl(id: "experience-list").id }.to raise_error(Watir::Exception::Error, "browser was closed")
74
74
  end
75
75
 
76
76
  describe "#wait_while" do
data/spec/click_spec.rb CHANGED
@@ -3,14 +3,21 @@ require File.expand_path('../watirspec/spec_helper', __FILE__)
3
3
  describe Watir::Element do
4
4
  describe "#click" do
5
5
  before {
6
- browser.goto WatirSpec.url_for('clicks.html', :needs_server => true)
6
+ browser.goto WatirSpec.url_for('clicks.html', needs_server: true)
7
7
  }
8
8
 
9
- let(:clicker) { browser.element(:id => "click-logger") }
10
- let(:log) { browser.element(:id => "log").ps.map { |e| e.text } }
9
+ let(:clicker) { browser.element(id: "click-logger") }
10
+ let(:log) { browser.element(id: "log").ps.map { |e| e.text } }
11
+
12
+ bug "https://github.com/watir/watir-webdriver/issues/343", :webdriver do
13
+ it "clicks an element with text in nested text node using text selector" do
14
+ browser.element(text: "Can You Click This?").click
15
+ expect(browser.element(text: "You Clicked It!")).to exist
16
+ end
17
+ end
11
18
 
12
19
  # TODO: make guards more flexible, in reality this currently only works on linux with native events
13
- compliant_on [:webdriver, :firefox, :native_events] do
20
+ compliant_on %i(webdriver firefox native_events) do
14
21
  it "should perform a click with no modifier keys" do
15
22
  clicker.click
16
23
  expect(log).to eq ["shift=false alt=false"]
@@ -11,11 +11,11 @@ describe Watir::Container do
11
11
  end
12
12
 
13
13
  it "converts 2-arg selector into a hash" do
14
- expect(@container.public_extract_selector([:how, 'what'])).to eq Hash[:how => 'what']
14
+ expect(@container.public_extract_selector([:how, 'what'])).to eq Hash[how: 'what']
15
15
  end
16
16
 
17
17
  it "returns the hash given" do
18
- expect(@container.public_extract_selector([:how => "what"])).to eq Hash[:how => "what"]
18
+ expect(@container.public_extract_selector([how: "what"])).to eq Hash[how: "what"]
19
19
  end
20
20
 
21
21
  it "returns an empty hash if given no args" do
@@ -7,7 +7,7 @@ describe Watir::ElementLocator do
7
7
  describe "by delegating to webdriver" do
8
8
  WEBDRIVER_SELECTORS.each do |loc|
9
9
  it "delegates to webdriver's #{loc} locator" do
10
- expect_one(loc, "bar").and_return(element(:tag_name => "div"))
10
+ expect_one(loc, "bar").and_return(element(tag_name: "div"))
11
11
  locate_one loc => "bar"
12
12
  end
13
13
  end
@@ -21,8 +21,8 @@ describe Watir::ElementLocator do
21
21
  expect_one :xpath, ".//div[@title='foo']"
22
22
  end
23
23
 
24
- locate_one :tag_name => "div",
25
- :title => "foo"
24
+ locate_one tag_name: "div",
25
+ title: "foo"
26
26
  end
27
27
 
28
28
  it "handles selector with no tag name and and a single attribute" do
@@ -32,7 +32,7 @@ describe Watir::ElementLocator do
32
32
  expect_one :xpath, ".//*[@title='foo']"
33
33
  end
34
34
 
35
- locate_one :title => "foo"
35
+ locate_one title: "foo"
36
36
  end
37
37
 
38
38
  it "handles single quotes in the attribute string" do
@@ -42,7 +42,7 @@ describe Watir::ElementLocator do
42
42
  expect_one :xpath, %{.//*[@title=concat('foo and ',"'",'bar',"'",'')]}
43
43
  end
44
44
 
45
- locate_one :title => "foo and 'bar'"
45
+ locate_one title: "foo and 'bar'"
46
46
  end
47
47
 
48
48
  it "handles selector with tag name and multiple attributes" do
@@ -73,15 +73,15 @@ describe Watir::ElementLocator do
73
73
  describe "with special cased selectors" do
74
74
  it "normalizes space for :text" do
75
75
  expect_one :xpath, ".//div[normalize-space()='foo']"
76
- locate_one :tag_name => "div",
77
- :text => "foo"
76
+ locate_one tag_name: "div",
77
+ text: "foo"
78
78
  end
79
79
 
80
80
  it "translates :caption to :text" do
81
81
  expect_one :xpath, ".//div[normalize-space()='foo']"
82
82
 
83
- locate_one :tag_name => "div",
84
- :caption => "foo"
83
+ locate_one tag_name: "div",
84
+ caption: "foo"
85
85
  end
86
86
 
87
87
  it "translates :class_name to :class" do
@@ -91,8 +91,8 @@ describe Watir::ElementLocator do
91
91
  expect_one :xpath, ".//div[contains(concat(' ', @class, ' '), ' foo ')]"
92
92
  end
93
93
 
94
- locate_one :tag_name => "div",
95
- :class_name => "foo"
94
+ locate_one tag_name: "div",
95
+ class_name: "foo"
96
96
  end
97
97
 
98
98
  it "handles data-* attributes" do
@@ -102,8 +102,8 @@ describe Watir::ElementLocator do
102
102
  expect_one :xpath, ".//div[@data-name='foo']"
103
103
  end
104
104
 
105
- locate_one :tag_name => "div",
106
- :data_name => "foo"
105
+ locate_one tag_name: "div",
106
+ data_name: "foo"
107
107
  end
108
108
 
109
109
  it "handles aria-* attributes" do
@@ -113,8 +113,8 @@ describe Watir::ElementLocator do
113
113
  expect_one :xpath, ".//div[@aria-label='foo']"
114
114
  end
115
115
 
116
- locate_one :tag_name => "div",
117
- :aria_label => "foo"
116
+ locate_one tag_name: "div",
117
+ aria_label: "foo"
118
118
  end
119
119
 
120
120
  it "normalizes space for the :href attribute" do
@@ -125,8 +125,8 @@ describe Watir::ElementLocator do
125
125
  end
126
126
 
127
127
  selector = {
128
- :tag_name => "a",
129
- :href => "foo"
128
+ tag_name: "a",
129
+ href: "foo"
130
130
  }
131
131
 
132
132
  locate_one selector, Watir::Anchor.attributes
@@ -160,7 +160,7 @@ describe Watir::ElementLocator do
160
160
  it "uses label attribute if it is valid for element" do
161
161
  expect_one :xpath, ".//option[@label='foo']"
162
162
 
163
- selector = { :tag_name => "option", :label => "foo" }
163
+ selector = { tag_name: "option", label: "foo" }
164
164
  locate_one selector, Watir::Option.attributes
165
165
  end
166
166
 
@@ -172,8 +172,8 @@ describe Watir::ElementLocator do
172
172
  end
173
173
 
174
174
  selector = {
175
- :tag_name => "meta",
176
- :http_equiv => "foo"
175
+ tag_name: "meta",
176
+ http_equiv: "foo"
177
177
  }
178
178
 
179
179
  locate_one selector, Watir::Meta.attributes
@@ -185,35 +185,35 @@ describe Watir::ElementLocator do
185
185
  describe "with regexp selectors" do
186
186
  it "handles selector with tag name and a single regexp attribute" do
187
187
  elements = [
188
- element(:tag_name => "div", :attributes => { :class => "foo" }),
189
- element(:tag_name => "div", :attributes => { :class => "foob"})
188
+ element(tag_name: "div", attributes: { class: "foo" }),
189
+ element(tag_name: "div", attributes: { class: "foob"})
190
190
  ]
191
191
 
192
192
  if Watir.prefer_css?
193
193
  expect_all(:css, "div").and_return(elements)
194
194
  else
195
- expect_all(:xpath, ".//div").and_return(elements)
195
+ expect_all(:xpath, "(.//div)[contains(@class, 'oob')]").and_return(elements)
196
196
  end
197
197
 
198
- expect(locate_one(:tag_name => "div", :class => /oob/)).to eq elements[1]
198
+ expect(locate_one(tag_name: "div", class: /oob/)).to eq elements[1]
199
199
  end
200
200
 
201
201
  it "handles :tag_name, :index and a single regexp attribute" do
202
202
  elements = [
203
- element(:tag_name => "div", :attributes => { :class => "foo" }),
204
- element(:tag_name => "div", :attributes => { :class => "foo" })
203
+ element(tag_name: "div", attributes: { class: "foo" }),
204
+ element(tag_name: "div", attributes: { class: "foo" })
205
205
  ]
206
206
 
207
207
  if Watir.prefer_css?
208
208
  expect_all(:css, "div").and_return(elements)
209
209
  else
210
- expect_all(:xpath, ".//div").and_return(elements)
210
+ expect_all(:xpath, "(.//div)[contains(@class, 'foo')]").and_return(elements)
211
211
  end
212
212
 
213
213
  selector = {
214
- :tag_name => "div",
215
- :class => /foo/,
216
- :index => 1
214
+ tag_name: "div",
215
+ class: /foo/,
216
+ index: 1
217
217
  }
218
218
 
219
219
  expect(locate_one(selector)).to eq elements[1]
@@ -221,15 +221,15 @@ describe Watir::ElementLocator do
221
221
 
222
222
  it "handles :xpath and :index selectors" do
223
223
  elements = [
224
- element(:tag_name => "div", :attributes => { :class => "foo" }),
225
- element(:tag_name => "div", :attributes => { :class => "foo" })
224
+ element(tag_name: "div", attributes: { class: "foo" }),
225
+ element(tag_name: "div", attributes: { class: "foo" })
226
226
  ]
227
227
 
228
228
  expect_all(:xpath, './/div[@class="foo"]').and_return(elements)
229
229
 
230
230
  selector = {
231
- :xpath => './/div[@class="foo"]',
232
- :index => 1
231
+ xpath: './/div[@class="foo"]',
232
+ index: 1
233
233
  }
234
234
 
235
235
  expect(locate_one(selector)).to eq elements[1]
@@ -237,15 +237,15 @@ describe Watir::ElementLocator do
237
237
 
238
238
  it "handles :css and :index selectors" do
239
239
  elements = [
240
- element(:tag_name => "div", :attributes => { :class => "foo" }),
241
- element(:tag_name => "div", :attributes => { :class => "foo" })
240
+ element(tag_name: "div", attributes: { class: "foo" }),
241
+ element(tag_name: "div", attributes: { class: "foo" })
242
242
  ]
243
243
 
244
244
  expect_all(:css, 'div[class="foo"]').and_return(elements)
245
245
 
246
246
  selector = {
247
- :css => 'div[class="foo"]',
248
- :index => 1
247
+ css: 'div[class="foo"]',
248
+ index: 1
249
249
  }
250
250
 
251
251
  expect(locate_one(selector)).to eq elements[1]
@@ -253,21 +253,20 @@ describe Watir::ElementLocator do
253
253
 
254
254
  it "handles mix of string and regexp attributes" do
255
255
  elements = [
256
- element(:tag_name => "div", :attributes => { :dir => "foo", :title => "bar" }),
257
- element(:tag_name => "div", :attributes => { :dir => "foo", :title => "baz" })
256
+ element(tag_name: "div", attributes: { dir: "foo", title: "bar" }),
257
+ element(tag_name: "div", attributes: { dir: "foo", title: "baz" })
258
258
  ]
259
259
 
260
260
  if Watir.prefer_css?
261
261
  expect_all(:css, 'div[dir="foo"]').and_return(elements)
262
262
  else
263
- expect_all(:xpath, ".//div[@dir='foo']").and_return(elements)
263
+ expect_all(:xpath, "(.//div[@dir='foo'])[contains(@title, 'baz')]").and_return(elements)
264
264
  end
265
265
 
266
-
267
266
  selector = {
268
- :tag_name => "div",
269
- :dir => "foo",
270
- :title => /baz/
267
+ tag_name: "div",
268
+ dir: "foo",
269
+ title: /baz/
271
270
  }
272
271
 
273
272
  expect(locate_one(selector)).to eq elements[1]
@@ -275,20 +274,20 @@ describe Watir::ElementLocator do
275
274
 
276
275
  it "handles data-* attributes with regexp" do
277
276
  elements = [
278
- element(:tag_name => "div", :attributes => { :'data-automation-id' => "foo" }),
279
- element(:tag_name => "div", :attributes => { :'data-automation-id' => "bar" })
277
+ element(tag_name: "div", attributes: { :'data-automation-id' => "foo" }),
278
+ element(tag_name: "div", attributes: { :'data-automation-id' => "bar" })
280
279
  ]
281
280
 
282
281
  if Watir.prefer_css?
283
282
  expect_all(:css, 'div').and_return(elements)
284
283
  else
285
- expect_all(:xpath, ".//div").and_return(elements)
284
+ expect_all(:xpath, "(.//div)[contains(@data-automation-id, 'bar')]").and_return(elements)
286
285
  end
287
286
 
288
287
 
289
288
  selector = {
290
- :tag_name => "div",
291
- :data_automation_id => /bar/
289
+ tag_name: "div",
290
+ data_automation_id: /bar/
292
291
  }
293
292
 
294
293
  expect(locate_one(selector)).to eq elements[1]
@@ -296,10 +295,10 @@ describe Watir::ElementLocator do
296
295
 
297
296
  it "handles :label => /regexp/ selector" do
298
297
  label_elements = [
299
- element(:tag_name => "label", :text => "foo", :attributes => { :for => "bar"}),
300
- element(:tag_name => "label", :text => "foob", :attributes => { :for => "baz"})
298
+ element(tag_name: "label", text: "foo", attributes: { for: "bar"}),
299
+ element(tag_name: "label", text: "foob", attributes: { for: "baz"})
301
300
  ]
302
- div_elements = [element(:tag_name => "div")]
301
+ div_elements = [element(tag_name: "div")]
303
302
 
304
303
  expect_all(:tag_name, "label").ordered.and_return(label_elements)
305
304
 
@@ -309,21 +308,20 @@ describe Watir::ElementLocator do
309
308
  expect_all(:xpath, ".//div[@id='baz']").ordered.and_return(div_elements)
310
309
  end
311
310
 
312
- expect(locate_one(:tag_name => "div", :label => /oob/)).to eq div_elements.first
311
+ expect(locate_one(tag_name: "div", label: /oob/)).to eq div_elements.first
313
312
  end
314
313
 
315
314
  it "returns nil when no label matching the regexp is found" do
316
315
  expect_all(:tag_name, "label").and_return([])
317
- expect(locate_one(:tag_name => "div", :label => /foo/)).to be_nil
316
+ expect(locate_one(tag_name: "div", label: /foo/)).to be_nil
318
317
  end
319
-
320
318
  end
321
319
 
322
320
  it "finds all if :index is given" do
323
321
  # or could we use XPath indeces reliably instead?
324
322
  elements = [
325
- element(:tag_name => "div"),
326
- element(:tag_name => "div")
323
+ element(tag_name: "div"),
324
+ element(tag_name: "div")
327
325
  ]
328
326
 
329
327
  if Watir.prefer_css?
@@ -333,20 +331,20 @@ describe Watir::ElementLocator do
333
331
  end
334
332
 
335
333
  selector = {
336
- :tag_name => "div",
337
- :dir => "foo",
338
- :index => 1
334
+ tag_name: "div",
335
+ dir: "foo",
336
+ index: 1
339
337
  }
340
338
 
341
339
  expect(locate_one(selector)).to eq elements[1]
342
340
  end
343
341
 
344
342
  it "returns nil if found element didn't match the selector tag_name" do
345
- expect_one(:xpath, "//div").and_return(element(:tag_name => "div"))
343
+ expect_one(:xpath, "//div").and_return(element(tag_name: "div"))
346
344
 
347
345
  selector = {
348
- :tag_name => "input",
349
- :xpath => "//div"
346
+ tag_name: "input",
347
+ xpath: "//div"
350
348
  }
351
349
 
352
350
  expect(locate_one(selector, Watir::Input.attributes)).to be_nil
@@ -354,17 +352,17 @@ describe Watir::ElementLocator do
354
352
 
355
353
  describe "errors" do
356
354
  it "raises a TypeError if :index is not a Fixnum" do
357
- expect { locate_one(:tag_name => "div", :index => "bar") }.to \
355
+ expect { locate_one(tag_name: "div", index: "bar") }.to \
358
356
  raise_error(TypeError, %[expected Fixnum, got "bar":String])
359
357
  end
360
358
 
361
359
  it "raises a TypeError if selector value is not a String or Regexp" do
362
- expect { locate_one(:tag_name => 123) }.to \
360
+ expect { locate_one(tag_name: 123) }.to \
363
361
  raise_error(TypeError, %[expected one of [String, Regexp], got 123:Fixnum])
364
362
  end
365
363
 
366
364
  it "raises a MissingWayOfFindingObjectException if the attribute is not valid" do
367
- bad_selector = {:tag_name => "input", :href => "foo"}
365
+ bad_selector = {tag_name: "input", href: "foo"}
368
366
  valid_attributes = Watir::Input.attributes
369
367
 
370
368
  expect { locate_one(bad_selector, valid_attributes) }.to \
@@ -377,7 +375,7 @@ describe Watir::ElementLocator do
377
375
  describe "by delegating to webdriver" do
378
376
  WEBDRIVER_SELECTORS.each do |loc|
379
377
  it "delegates to webdriver's #{loc} locator" do
380
- expect_all(loc, "bar").and_return([element(:tag_name => "div")])
378
+ expect_all(loc, "bar").and_return([element(tag_name: "div")])
381
379
  locate_all(loc => "bar")
382
380
  end
383
381
  end
@@ -403,8 +401,8 @@ describe Watir::ElementLocator do
403
401
  expect_all :xpath, ".//div[@dir='foo']"
404
402
  end
405
403
 
406
- locate_all :tag_name => "div",
407
- :dir => "foo"
404
+ locate_all tag_name: "div",
405
+ dir: "foo"
408
406
  end
409
407
 
410
408
  it "handles selector with tag name and multiple attributes" do
@@ -423,47 +421,110 @@ describe Watir::ElementLocator do
423
421
  describe "with regexp selectors" do
424
422
  it "handles selector with tag name and a single regexp attribute" do
425
423
  elements = [
426
- element(:tag_name => "div", :attributes => { :class => "foo" }),
427
- element(:tag_name => "div", :attributes => { :class => "foob"}),
428
- element(:tag_name => "div", :attributes => { :class => "doob"}),
429
- element(:tag_name => "div", :attributes => { :class => "noob"})
424
+ element(tag_name: "div", attributes: { class: "foo" }),
425
+ element(tag_name: "div", attributes: { class: "foob"}),
426
+ element(tag_name: "div", attributes: { class: "doob"}),
427
+ element(tag_name: "div", attributes: { class: "noob"})
430
428
  ]
431
429
 
432
430
  if Watir.prefer_css?
433
431
  expect_all(:css, "div").and_return(elements)
434
432
  else
435
- expect_all(:xpath, ".//div").and_return(elements)
433
+ expect_all(:xpath, "(.//div)[contains(@class, 'oob')]").and_return(elements)
436
434
  end
437
435
 
438
- expect(locate_all(:tag_name => "div", :class => /oob/)).to eq elements.last(3)
436
+ expect(locate_all(tag_name: "div", class: /oob/)).to eq elements.last(3)
439
437
  end
440
438
 
441
439
  it "handles mix of string and regexp attributes" do
442
440
  elements = [
443
- element(:tag_name => "div", :attributes => { :dir => "foo", :title => "bar" }),
444
- element(:tag_name => "div", :attributes => { :dir => "foo", :title => "baz" }),
445
- element(:tag_name => "div", :attributes => { :dir => "foo", :title => "bazt"})
441
+ element(tag_name: "div", attributes: { dir: "foo", title: "bar" }),
442
+ element(tag_name: "div", attributes: { dir: "foo", title: "baz" }),
443
+ element(tag_name: "div", attributes: { dir: "foo", title: "bazt"})
446
444
  ]
447
445
 
448
446
  if Watir.prefer_css?
449
447
  expect_all(:css, 'div[dir="foo"]').and_return(elements)
450
448
  else
451
- expect_all(:xpath, ".//div[@dir='foo']").and_return(elements)
449
+ expect_all(:xpath, "(.//div[@dir='foo'])[contains(@title, 'baz')]").and_return(elements)
452
450
  end
453
451
 
454
452
  selector = {
455
- :tag_name => "div",
456
- :dir => "foo",
457
- :title => /baz/
453
+ tag_name: "div",
454
+ dir: "foo",
455
+ title: /baz/
458
456
  }
459
457
 
460
458
  expect(locate_all(selector)).to eq elements.last(2)
461
459
  end
460
+
461
+ context "and xpath" do
462
+ before do
463
+ expect(Watir).to receive(:prefer_css?).and_return(false)
464
+ end
465
+
466
+ it "converts a leading run of regexp literals to a contains() expression" do
467
+ elements = [
468
+ element(tag_name: "div", attributes: { class: "foo" }),
469
+ element(tag_name: "div", attributes: { class: "foob" }),
470
+ element(tag_name: "div", attributes: { class: "bar" })
471
+ ]
472
+
473
+ expect_all(:xpath, "(.//div)[contains(@class, 'fo')]").and_return(elements.first(2))
474
+
475
+ expect(locate_one(tag_name: "div", class: /fo.b$/)).to eq elements[1]
476
+ end
477
+
478
+ it "converts a trailing run of regexp literals to a contains() expression" do
479
+ elements = [
480
+ element(tag_name: "div", attributes: { class: "foo" }),
481
+ element(tag_name: "div", attributes: { class: "foob" })
482
+ ]
483
+
484
+ expect_all(:xpath, "(.//div)[contains(@class, 'b')]").and_return(elements.last(1))
485
+
486
+ expect(locate_one(tag_name: "div", class: /^fo.b/)).to eq elements[1]
487
+ end
488
+
489
+ it "converts a leading and a trailing run of regexp literals to a contains() expression" do
490
+ elements = [
491
+ element(tag_name: "div", attributes: { class: "foo" }),
492
+ element(tag_name: "div", attributes: { class: "foob" })
493
+ ]
494
+
495
+ expect_all(:xpath, "(.//div)[contains(@class, 'fo') and contains(@class, 'b')]").
496
+ and_return(elements.last(1))
497
+
498
+ expect(locate_one(tag_name: "div", class: /fo.b/)).to eq elements[1]
499
+ end
500
+
501
+ it "does not try to convert case insensitive expressions" do
502
+ elements = [
503
+ element(tag_name: "div", attributes: { class: "foo" }),
504
+ element(tag_name: "div", attributes: { class: "foob"})
505
+ ]
506
+
507
+ expect_all(:xpath, ".//div").and_return(elements.last(1))
508
+
509
+ expect(locate_one(tag_name: "div", class: /FOOB/i)).to eq elements[1]
510
+ end
511
+
512
+ it "does not try to convert expressions containing '|'" do
513
+ elements = [
514
+ element(tag_name: "div", attributes: { class: "foo" }),
515
+ element(tag_name: "div", attributes: { class: "foob"})
516
+ ]
517
+
518
+ expect_all(:xpath, ".//div").and_return(elements.last(1))
519
+
520
+ expect(locate_one(tag_name: "div", class: /x|b/)).to eq elements[1]
521
+ end
522
+ end
462
523
  end
463
524
 
464
525
  describe "errors" do
465
526
  it "raises ArgumentError if :index is given" do
466
- expect { locate_all(:tag_name => "div", :index => 1) }.to \
527
+ expect { locate_all(tag_name: "div", index: 1) }.to \
467
528
  raise_error(ArgumentError, "can't locate all elements by :index")
468
529
  end
469
530
  end