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.
- data/.gitignore +2 -1
- data/.gitmodules +1 -1
- data/.travis.yml +2 -2
- data/LICENSE +1 -1
- data/README.md +4 -4
- data/Rakefile +7 -15
- data/lib/watir-webdriver.rb +13 -8
- data/lib/watir-webdriver/aliases.rb +6 -0
- data/lib/watir-webdriver/elements/element.rb +120 -10
- data/lib/watir-webdriver/elements/generated.rb +42 -12
- data/lib/watir-webdriver/elements/image.rb +8 -1
- data/lib/watir-webdriver/elements/option.rb +4 -0
- data/lib/watir-webdriver/elements/select.rb +2 -2
- data/lib/watir-webdriver/elements/text_area.rb +5 -0
- data/lib/watir-webdriver/elements/text_field.rb +3 -36
- data/lib/watir-webdriver/html/spec_extractor.rb +8 -1
- data/lib/watir-webdriver/locators/element_locator.rb +9 -3
- data/lib/watir-webdriver/locators/text_field_locator.rb +5 -0
- data/lib/watir-webdriver/user_editable.rb +37 -0
- data/lib/watir-webdriver/version.rb +1 -1
- data/lib/watir-webdriver/wait.rb +4 -0
- data/lib/yard/handlers/watir.rb +2 -4
- data/spec/click_spec.rb +36 -0
- data/spec/element_locator_spec.rb +23 -23
- data/spec/element_spec.rb +14 -1
- data/spec/html/clicks.html +16 -0
- data/spec/html/hover.html +12 -0
- data/spec/implementation.rb +82 -16
- data/spec/spec_helper.rb +5 -0
- data/spec/wait_spec.rb +12 -4
- data/support/html5.html +32579 -36525
- data/support/travis.sh +6 -7
- data/watir-webdriver.gemspec +11 -1
- metadata +27 -10
@@ -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
|
44
|
-
|
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] =
|
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, :
|
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
|
-
|
299
|
-
|
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}"
|
@@ -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
|
data/lib/watir-webdriver/wait.rb
CHANGED
@@ -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}"
|
data/lib/yard/handlers/watir.rb
CHANGED
data/spec/click_spec.rb
ADDED
@@ -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[@
|
18
|
+
expect_one :xpath, ".//div[@title='foo']"
|
19
19
|
|
20
20
|
locate_one :tag_name => "div",
|
21
|
-
:
|
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[@
|
35
|
+
expect_one :xpath, ".//div[@title='foo' and @dir='bar']"
|
36
36
|
|
37
37
|
locate_one [:tag_name, "div",
|
38
|
-
:
|
39
|
-
:
|
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, ".//*[@
|
43
|
+
expect_one :xpath, ".//*[@dir='foo' and @title='bar']"
|
44
44
|
|
45
|
-
locate_one [:
|
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
|
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 => { :
|
154
|
-
element(:tag_name => "div", :attributes => { :
|
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[@
|
157
|
+
expect_all(:xpath, ".//div[@dir='foo']").and_return(elements)
|
158
158
|
|
159
159
|
selector = {
|
160
160
|
:tag_name => "div",
|
161
|
-
:
|
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[@
|
195
|
+
expect_all(:xpath, ".//div[@dir='foo']").and_return(elements)
|
196
196
|
|
197
197
|
selector = {
|
198
198
|
:tag_name => "div",
|
199
|
-
:
|
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[@
|
253
|
+
expect_all :xpath, ".//div[@dir='foo']"
|
254
254
|
|
255
255
|
locate_all :tag_name => "div",
|
256
|
-
:
|
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[@
|
260
|
+
expect_all :xpath, ".//div[@dir='foo' and @title='bar']"
|
261
261
|
|
262
262
|
locate_all [:tag_name, "div",
|
263
|
-
:
|
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 => { :
|
284
|
-
element(:tag_name => "div", :attributes => { :
|
285
|
-
element(:tag_name => "div", :attributes => { :
|
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[@
|
288
|
+
expect_all(:xpath, ".//div[@dir='foo']").and_return(elements)
|
289
289
|
|
290
290
|
selector = {
|
291
291
|
:tag_name => "div",
|
292
|
-
:
|
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',
|
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>
|
data/spec/implementation.rb
CHANGED
@@ -1,27 +1,93 @@
|
|
1
1
|
require File.expand_path("../spec_helper", __FILE__)
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
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
|
-
|
8
|
-
|
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
|
-
|
52
|
+
def set_firefox_args
|
11
53
|
profile = Selenium::WebDriver::Firefox::Profile.new
|
12
|
-
profile.native_events =
|
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
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
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
|