watir-webdriver 0.4.1 → 0.5.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.
@@ -0,0 +1,5 @@
1
+ module Watir
2
+ class TextArea < HTMLElement
3
+ include UserEditable
4
+ end
5
+ end
@@ -1,48 +1,15 @@
1
1
  # encoding: utf-8
2
2
  module Watir
3
3
  class TextField < Input
4
+ include UserEditable
4
5
 
5
6
  attributes Watir::TextArea.typed_attributes
6
7
  remove_method :type # we want Input#type here, which was overriden by TextArea's attributes
7
8
 
8
- #
9
- # Clear the element, the type in the given value.
10
- #
11
-
12
- def set(*args)
13
- assert_exists
14
- assert_writable
15
-
16
- @element.clear
17
- @element.send_keys(*args)
18
- end
19
- alias_method :value=, :set
20
-
21
- #
22
- # Append the given value to the text in the text field.
23
- #
24
-
25
- def append(*args)
26
- assert_exists
27
- assert_writable
28
-
29
- @element.send_keys(*args)
30
- end
31
-
32
- #
33
- # Clear the text field.
34
- #
35
-
36
- def clear
37
- assert_exists
38
- @element.clear
39
- end
40
-
41
9
  private
42
10
 
43
- def locate
44
- @parent.assert_exists
45
- TextFieldLocator.new(@parent.wd, @selector, self.class.attribute_list).locate
11
+ def locator_class
12
+ TextFieldLocator
46
13
  end
47
14
 
48
15
  def selector_string
@@ -70,9 +70,12 @@ module Watir
70
70
  result = {}
71
71
 
72
72
  @interface_map.each do |tag, interface|
73
- result[tag] = @interfaces_by_name[interface] or raise "#{interface} not found in IDL"
73
+ result[tag] = fetch_interface(interface)
74
74
  end
75
75
 
76
+ # missing from the elements-1 table
77
+ result['frameset'] = fetch_interface('HTMLFrameSetElement')
78
+
76
79
  result
77
80
  end
78
81
 
@@ -90,6 +93,10 @@ module Watir
90
93
  end
91
94
  end
92
95
 
96
+ def fetch_interface(interface)
97
+ @interfaces_by_name[interface] or raise "#{interface} not found in IDL"
98
+ end
99
+
93
100
  def parse_idl(str)
94
101
  result = idl_parser.parse(str)
95
102
 
@@ -197,7 +197,7 @@ module Watir
197
197
 
198
198
  def normalize_selector(how, what)
199
199
  case how
200
- when :tag_name, :text, :xpath, :index, :class, :for, :label
200
+ when :tag_name, :text, :xpath, :index, :class, :label
201
201
  # include :class since the valid attribute is 'class_name'
202
202
  # include :for since the valid attribute is 'html_for'
203
203
  [how, what]
@@ -205,6 +205,9 @@ module Watir
205
205
  [:class, what]
206
206
  when :caption
207
207
  [:text, what]
208
+ when :for
209
+ assert_valid_as_attribute :html_for
210
+ [how, what]
208
211
  else
209
212
  assert_valid_as_attribute how
210
213
  [how, what]
@@ -295,8 +298,11 @@ module Watir
295
298
  end
296
299
 
297
300
  def equal_pair(key, value)
298
- # we assume :label means a corresponding label element, not the attribute
299
- if key == :label && should_use_label_element?
301
+ if key == :class
302
+ klass = XpathSupport.escape " #{value} "
303
+ "contains(concat(' ', @class, ' '), #{klass})"
304
+ elsif key == :label && should_use_label_element?
305
+ # we assume :label means a corresponding label element, not the attribute
300
306
  "@id=//label[normalize-space()=#{XpathSupport.escape value}]/@for"
301
307
  else
302
308
  "#{lhs_for(key)}=#{XpathSupport.escape value}"
@@ -63,5 +63,10 @@ module Watir
63
63
  def tag_name_matches?(tag_name, _)
64
64
  VALID_TEXT_FIELD_TAGS.include?(tag_name)
65
65
  end
66
+
67
+ def by_id
68
+ el = super
69
+ el if el and not NON_TEXT_TYPES.include? el.attribute(:type)
70
+ end
66
71
  end # TextFieldLocator
67
72
  end # Watir
@@ -0,0 +1,37 @@
1
+ module Watir
2
+ module UserEditable
3
+ #
4
+ # Clear the element, the type in the given value.
5
+ #
6
+
7
+ def set(*args)
8
+ assert_exists
9
+ assert_writable
10
+
11
+ @element.clear
12
+ @element.send_keys(*args)
13
+ end
14
+ alias_method :value=, :set
15
+
16
+ #
17
+ # Append the given value to the text in the text field.
18
+ #
19
+
20
+ def append(*args)
21
+ assert_exists
22
+ assert_writable
23
+
24
+ @element.send_keys(*args)
25
+ end
26
+ alias_method :<<, :append
27
+
28
+ #
29
+ # Clear the text field.
30
+ #
31
+
32
+ def clear
33
+ assert_exists
34
+ @element.clear
35
+ end
36
+ end
37
+ end
@@ -1,3 +1,3 @@
1
1
  module Watir
2
- VERSION = "0.4.1"
2
+ VERSION = "0.5.0"
3
3
  end
@@ -72,6 +72,10 @@ module Watir
72
72
  @message = message
73
73
  end
74
74
 
75
+ def respond_to?(*args)
76
+ @element.respond_to?(*args)
77
+ end
78
+
75
79
  def method_missing(m, *args, &block)
76
80
  unless @element.respond_to?(m)
77
81
  raise NoMethodError, "undefined method `#{m}' for #{@element.inspect}:#{@element.class}"
@@ -1,12 +1,10 @@
1
- require "watir-webdriver/core_ext/string"
2
-
3
1
  module YARD
4
2
  module Handlers
5
3
  module Watir
6
4
  #
7
5
  # @private
8
- #
9
-
6
+ #
7
+
10
8
  class AttributesHandler < YARD::Handlers::Ruby::Base
11
9
  handles method_call(:attributes)
12
10
 
@@ -0,0 +1,36 @@
1
+ require File.expand_path('../watirspec/spec_helper', __FILE__)
2
+
3
+ describe Watir::Element do
4
+ describe "#click" do
5
+ before {
6
+ browser.goto('file://' + File.expand_path('../html/clicks.html', __FILE__))
7
+ }
8
+
9
+ let(:clicker) { browser.element(:id => "click-logger") }
10
+ let(:log) { browser.element(:id => "log").ps.map { |e| e.text } }
11
+
12
+ # TODO: make guards more flexible, in reality this currently only works on linux with native events
13
+ compliant_on [:webdriver, :firefox, :native_events] do
14
+ it "should perform a click with no modifier keys" do
15
+ clicker.click
16
+ log.should == ["shift=false alt=false"]
17
+ end
18
+
19
+ it "should perform a click with the shift key pressed" do
20
+ clicker.click(:shift)
21
+ log.should == ["shift=true alt=false"]
22
+ end
23
+
24
+ it "should perform a click with the alt key pressed" do
25
+ clicker.click(:alt)
26
+ log.should == ["shift=false alt=true"]
27
+ end
28
+
29
+ it "should perform a click with the shift and alt keys pressed" do
30
+ clicker.click(:shift, :alt)
31
+ log.should == ["shift=true alt=true"]
32
+ end
33
+ end
34
+
35
+ end
36
+ end
@@ -15,10 +15,10 @@ describe Watir::ElementLocator do
15
15
 
16
16
  describe "with selectors not supported by webdriver" do
17
17
  it "handles selector with tag name and a single attribute" do
18
- expect_one :xpath, ".//div[@class='foo']"
18
+ expect_one :xpath, ".//div[@title='foo']"
19
19
 
20
20
  locate_one :tag_name => "div",
21
- :class => "foo"
21
+ :title => "foo"
22
22
  end
23
23
 
24
24
  it "handles selector with no tag name and and a single attribute" do
@@ -32,17 +32,17 @@ describe Watir::ElementLocator do
32
32
  end
33
33
 
34
34
  it "handles selector with tag name and multiple attributes" do
35
- expect_one :xpath, ".//div[@class='foo' and @title='bar']"
35
+ expect_one :xpath, ".//div[@title='foo' and @dir='bar']"
36
36
 
37
37
  locate_one [:tag_name, "div",
38
- :class , "foo",
39
- :title , 'bar']
38
+ :title , "foo",
39
+ :dir , 'bar']
40
40
  end
41
41
 
42
42
  it "handles selector with no tag name and multiple attributes" do
43
- expect_one :xpath, ".//*[@class='foo' and @title='bar']"
43
+ expect_one :xpath, ".//*[@dir='foo' and @title='bar']"
44
44
 
45
- locate_one [:class, "foo",
45
+ locate_one [:dir, "foo",
46
46
  :title, "bar"]
47
47
  end
48
48
  end
@@ -63,7 +63,7 @@ describe Watir::ElementLocator do
63
63
  end
64
64
 
65
65
  it "translates :class_name to :class" do
66
- expect_one :xpath, ".//div[@class='foo']"
66
+ expect_one :xpath, ".//div[contains(concat(' ', @class, ' '), ' foo ')]"
67
67
 
68
68
  locate_one :tag_name => "div",
69
69
  :class_name => "foo"
@@ -150,15 +150,15 @@ describe Watir::ElementLocator do
150
150
 
151
151
  it "handles mix of string and regexp attributes" do
152
152
  elements = [
153
- element(:tag_name => "div", :attributes => { :class => "foo", :title => "bar" }),
154
- element(:tag_name => "div", :attributes => { :class => "foo", :title => "baz" })
153
+ element(:tag_name => "div", :attributes => { :dir => "foo", :title => "bar" }),
154
+ element(:tag_name => "div", :attributes => { :dir => "foo", :title => "baz" })
155
155
  ]
156
156
 
157
- expect_all(:xpath, ".//div[@class='foo']").and_return(elements)
157
+ expect_all(:xpath, ".//div[@dir='foo']").and_return(elements)
158
158
 
159
159
  selector = {
160
160
  :tag_name => "div",
161
- :class => "foo",
161
+ :dir => "foo",
162
162
  :title => /baz/
163
163
  }
164
164
 
@@ -192,11 +192,11 @@ describe Watir::ElementLocator do
192
192
  element(:tag_name => "div")
193
193
  ]
194
194
 
195
- expect_all(:xpath, ".//div[@class='foo']").and_return(elements)
195
+ expect_all(:xpath, ".//div[@dir='foo']").and_return(elements)
196
196
 
197
197
  selector = {
198
198
  :tag_name => "div",
199
- :class => "foo",
199
+ :dir => "foo",
200
200
  :index => 1
201
201
  }
202
202
 
@@ -250,17 +250,17 @@ describe Watir::ElementLocator do
250
250
 
251
251
  describe "with selectors not supported by webdriver" do
252
252
  it "handles selector with tag name and a single attribute" do
253
- expect_all :xpath, ".//div[@class='foo']"
253
+ expect_all :xpath, ".//div[@dir='foo']"
254
254
 
255
255
  locate_all :tag_name => "div",
256
- :class => "foo"
256
+ :dir => "foo"
257
257
  end
258
258
 
259
259
  it "handles selector with tag name and multiple attributes" do
260
- expect_all :xpath, ".//div[@class='foo' and @title='bar']"
260
+ expect_all :xpath, ".//div[@dir='foo' and @title='bar']"
261
261
 
262
262
  locate_all [:tag_name, "div",
263
- :class , "foo",
263
+ :dir , "foo",
264
264
  :title , 'bar']
265
265
  end
266
266
  end
@@ -280,16 +280,16 @@ describe Watir::ElementLocator do
280
280
 
281
281
  it "handles mix of string and regexp attributes" do
282
282
  elements = [
283
- element(:tag_name => "div", :attributes => { :class => "foo", :title => "bar" }),
284
- element(:tag_name => "div", :attributes => { :class => "foo", :title => "baz" }),
285
- element(:tag_name => "div", :attributes => { :class => "foo", :title => "bazt"})
283
+ element(:tag_name => "div", :attributes => { :dir => "foo", :title => "bar" }),
284
+ element(:tag_name => "div", :attributes => { :dir => "foo", :title => "baz" }),
285
+ element(:tag_name => "div", :attributes => { :dir => "foo", :title => "bazt"})
286
286
  ]
287
287
 
288
- expect_all(:xpath, ".//div[@class='foo']").and_return(elements)
288
+ expect_all(:xpath, ".//div[@dir='foo']").and_return(elements)
289
289
 
290
290
  selector = {
291
291
  :tag_name => "div",
292
- :class => "foo",
292
+ :dir => "foo",
293
293
  :title => /baz/
294
294
  }
295
295
 
data/spec/element_spec.rb CHANGED
@@ -32,7 +32,7 @@ describe Watir::Element do
32
32
 
33
33
  describe "#exists?" do
34
34
  it "should not propagate ObsoleteElementErrors" do
35
- browser.goto 'file://' + File.expand_path('html/removed_element.html', File.dirname(__FILE__))
35
+ browser.goto 'file://' + File.expand_path('../html/removed_element.html', __FILE__)
36
36
 
37
37
  button = browser.button(:id => "remove-button")
38
38
  element = browser.div(:id => "text")
@@ -43,4 +43,17 @@ describe Watir::Element do
43
43
  end
44
44
  end
45
45
 
46
+ describe "#hover" do
47
+ not_compliant_on [:webdriver, :firefox, :synthesized_events], [:webdriver, :ie] do
48
+ it "should hover over the element" do
49
+ browser.goto 'file://' + File.expand_path('../html/hover.html', __FILE__)
50
+ link = browser.a
51
+
52
+ link.style("font-size").should == "10px"
53
+ link.hover
54
+ link.style("font-size").should == "20px"
55
+ end
56
+ end
57
+ end
58
+
46
59
  end
@@ -0,0 +1,16 @@
1
+ <html>
2
+ <head>
3
+ <script src="../watirspec/html/javascript/jquery-1.7.1.min.js" type="text/javascript" charset="utf-8"></script>
4
+ </head>
5
+ <script>
6
+ $(document).ready(function() {
7
+ $("#click-logger").click(function(evt) {
8
+ $("#log").append("<p>shift=" + evt.shiftKey + " alt=" + evt.altKey + "</p>");
9
+ });
10
+ });
11
+ </script>
12
+ <body>
13
+ <div id="click-logger">click me</div>
14
+ <div id="log"></div>
15
+ </body>
16
+ </html>
@@ -0,0 +1,12 @@
1
+ <html>
2
+ <head>
3
+ <style type="text/css" media="screen">
4
+ a { font-size: 10px; }
5
+ a:hover { font-size: 20px; }
6
+ </style>
7
+ </head>
8
+
9
+ <body>
10
+ <a href="#">hello</a>
11
+ </body>
12
+ </html>
@@ -1,27 +1,93 @@
1
1
  require File.expand_path("../spec_helper", __FILE__)
2
2
 
3
- WatirSpec.implementation do |imp|
4
- name = :webdriver
5
- browser = (ENV['WATIR_WEBDRIVER_BROWSER'] || :firefox).to_sym
3
+ class ImplementationConfig
4
+ def initialize(imp)
5
+ @imp = imp
6
+ end
7
+
8
+ def configure
9
+ set_webdriver
10
+ set_browser_args
11
+ set_guard_proc
12
+ end
13
+
14
+ private
15
+
16
+ def set_webdriver
17
+ @imp.name = :webdriver
18
+ @imp.browser_class = Watir::Browser
19
+ end
6
20
 
7
- imp.name = name
8
- imp.browser_class = Watir::Browser
21
+ def set_browser_args
22
+ case browser
23
+ when :firefox
24
+ set_firefox_args
25
+ when :chrome
26
+ set_chrome_args
27
+ else
28
+ @imp.browser_args = [browser]
29
+ end
30
+ end
31
+
32
+ def set_guard_proc
33
+ matching_guards = [
34
+ :webdriver, # guard only applies to webdriver
35
+ browser, # guard only applies to this browser
36
+ [:webdriver, browser] # guard only applies to this browser on webdriver
37
+ ]
38
+
39
+ if native_events? || native_events_by_default?
40
+ # guard only applies to this browser on webdriver with native events enabled
41
+ matching_guards << [:webdriver, browser, :native_events]
42
+ else
43
+ # guard only applies to this browser on webdriver with native events disabled
44
+ matching_guards << [:webdriver, browser, :synthesized_events]
45
+ end
46
+
47
+ @imp.guard_proc = lambda { |args|
48
+ args.any? { |arg| matching_guards.include?(arg) }
49
+ }
50
+ end
9
51
 
10
- if browser == :firefox && ENV['NATIVE_EVENTS'] == "true"
52
+ def set_firefox_args
11
53
  profile = Selenium::WebDriver::Firefox::Profile.new
12
- profile.native_events = true
54
+ profile.native_events = native_events?
13
55
 
14
- imp.browser_args = [:firefox, {:profile => profile}]
15
- elsif browser == :chrome && ENV['NATIVE_EVENTS'] == "true"
16
- imp.browser_args = [:chrome, {:native_events => true}]
17
- else
18
- imp.browser_args = [browser]
56
+ @imp.browser_args = [:firefox, {:profile => profile}]
19
57
  end
20
58
 
21
- imp.guard_proc = lambda { |args|
22
- args.any? { |arg| arg == name || arg == browser || arg == [name, browser]}
23
- }
24
- end
59
+ def set_chrome_args
60
+ opts = {
61
+ :switches => ["--disable-translate"],
62
+ :native_events => native_events?
63
+ }
64
+
65
+ if url = ENV['WATIR_WEBDRIVER_CHROME_SERVER']
66
+ opts[:url] = url
67
+ end
68
+
69
+ if driver = ENV['WATIR_WEBDRIVER_CHROME_DRIVER']
70
+ Selenium::WebDriver::Chrome.driver_path = driver
71
+ end
25
72
 
73
+ if path = ENV['WATIR_WEBDRIVER_CHROME_BINARY']
74
+ Selenium::WebDriver::Chrome.path = path
75
+ end
26
76
 
77
+ @imp.browser_args = [:chrome, opts]
78
+ end
79
+
80
+ def browser
81
+ @browser ||= (ENV['WATIR_WEBDRIVER_BROWSER'] || :firefox).to_sym
82
+ end
83
+
84
+ def native_events?
85
+ ENV['NATIVE_EVENTS'] == "true"
86
+ end
87
+
88
+ def native_events_by_default?
89
+ Selenium::WebDriver::Platform.windows? && [:firefox, :ie].include?(browser)
90
+ end
91
+ end
27
92
 
93
+ ImplementationConfig.new(WatirSpec.implementation).configure