watir-webdriver 0.6.11 → 0.7.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/.travis.yml +14 -12
- data/CHANGES.md +17 -0
- data/LICENSE +1 -1
- data/README.md +8 -1
- data/Rakefile +7 -2
- data/lib/watir-webdriver/alert.rb +5 -1
- data/lib/watir-webdriver/attribute_helper.rb +4 -8
- data/lib/watir-webdriver/browser.rb +41 -21
- data/lib/watir-webdriver/element_collection.rb +1 -2
- data/lib/watir-webdriver/elements/button.rb +3 -5
- data/lib/watir-webdriver/elements/checkbox.rb +2 -11
- data/lib/watir-webdriver/elements/element.rb +93 -86
- data/lib/watir-webdriver/elements/file_field.rb +1 -2
- data/lib/watir-webdriver/elements/form.rb +2 -1
- data/lib/watir-webdriver/elements/generated.rb +24 -11
- data/lib/watir-webdriver/elements/iframe.rb +25 -17
- data/lib/watir-webdriver/elements/option.rb +6 -14
- data/lib/watir-webdriver/elements/radio.rb +2 -5
- data/lib/watir-webdriver/elements/select.rb +15 -7
- data/lib/watir-webdriver/exception.rb +0 -2
- data/lib/watir-webdriver/extensions/alerts.rb +0 -14
- data/lib/watir-webdriver/has_window.rb +2 -4
- data/lib/watir-webdriver/html/spec_extractor.rb +3 -2
- data/lib/watir-webdriver/html/visitor.rb +2 -2
- data/lib/watir-webdriver/locators/element_locator.rb +22 -21
- data/lib/watir-webdriver/locators/text_field_locator.rb +11 -3
- data/lib/watir-webdriver/user_editable.rb +5 -10
- data/lib/watir-webdriver/version.rb +1 -1
- data/lib/watir-webdriver/wait.rb +26 -26
- data/lib/watir-webdriver/window.rb +30 -25
- data/spec/always_locate_spec.rb +42 -0
- data/spec/browser_spec.rb +1 -1
- data/spec/element_locator_spec.rb +13 -1
- data/spec/element_spec.rb +43 -8
- data/spec/input_spec.rb +0 -31
- data/spec/spec_helper.rb +0 -1
- data/support/doctest_helper.rb +72 -0
- data/support/travis.sh +4 -0
- data/watir-webdriver.gemspec +2 -1
- metadata +50 -35
- data/spec/html/inner_outer.html +0 -5
@@ -19,8 +19,6 @@ module Watir
|
|
19
19
|
attribute(String, :access_key_label, :accessKeyLabel)
|
20
20
|
attribute("Boolean", :draggable?, :draggable)
|
21
21
|
attribute(String, :dropzone, :dropzone)
|
22
|
-
attribute(String, :content_editable, :contentEditable)
|
23
|
-
attribute("Boolean", :content_editable?, :isContentEditable)
|
24
22
|
attribute(String, :context_menu, :contextMenu)
|
25
23
|
attribute("Boolean", :spellcheck?, :spellcheck)
|
26
24
|
attribute(String, :command_type, :commandType)
|
@@ -92,6 +90,8 @@ module Watir
|
|
92
90
|
attribute(String, :ontoggle, :ontoggle)
|
93
91
|
attribute(String, :onvolumechange, :onvolumechange)
|
94
92
|
attribute(String, :onwaiting, :onwaiting)
|
93
|
+
attribute(String, :content_editable, :contentEditable)
|
94
|
+
attribute("Boolean", :content_editable?, :isContentEditable)
|
95
95
|
end
|
96
96
|
class HTMLElementCollection < ElementCollection
|
97
97
|
def element_class
|
@@ -662,6 +662,7 @@ module Watir
|
|
662
662
|
class Media < HTMLElement
|
663
663
|
attribute(String, :error, :error)
|
664
664
|
attribute(String, :src, :src)
|
665
|
+
attribute(String, :src_object, :srcObject)
|
665
666
|
attribute(String, :current_src, :currentSrc)
|
666
667
|
attribute(String, :cross_origin, :crossOrigin)
|
667
668
|
attribute(Fixnum, :network_state, :networkState)
|
@@ -727,15 +728,6 @@ module Watir
|
|
727
728
|
Track
|
728
729
|
end
|
729
730
|
end
|
730
|
-
class Source < HTMLElement
|
731
|
-
attribute(String, :src, :src)
|
732
|
-
attribute(String, :type, :type)
|
733
|
-
end
|
734
|
-
class SourceCollection < ElementCollection
|
735
|
-
def element_class
|
736
|
-
Source
|
737
|
-
end
|
738
|
-
end
|
739
731
|
class Param < HTMLElement
|
740
732
|
attribute(String, :name, :name)
|
741
733
|
attribute(String, :value, :value)
|
@@ -817,6 +809,7 @@ module Watir
|
|
817
809
|
attribute(String, :alt, :alt)
|
818
810
|
attribute(String, :src, :src)
|
819
811
|
attribute(String, :srcset, :srcset)
|
812
|
+
attribute(String, :sizes, :sizes)
|
820
813
|
attribute(String, :cross_origin, :crossOrigin)
|
821
814
|
attribute(String, :use_map, :useMap)
|
822
815
|
attribute("Boolean", :map?, :isMap)
|
@@ -825,6 +818,7 @@ module Watir
|
|
825
818
|
attribute(Fixnum, :natural_width, :naturalWidth)
|
826
819
|
attribute(Fixnum, :natural_height, :naturalHeight)
|
827
820
|
attribute("Boolean", :complete?, :complete)
|
821
|
+
attribute(String, :current_src, :currentSrc)
|
828
822
|
attribute(String, :name, :name)
|
829
823
|
attribute(String, :lowsrc, :lowsrc)
|
830
824
|
attribute(String, :align, :align)
|
@@ -838,6 +832,25 @@ module Watir
|
|
838
832
|
Image
|
839
833
|
end
|
840
834
|
end
|
835
|
+
class Source < HTMLElement
|
836
|
+
attribute(String, :srcset, :srcset)
|
837
|
+
attribute(String, :sizes, :sizes)
|
838
|
+
attribute(String, :media, :media)
|
839
|
+
attribute(String, :src, :src)
|
840
|
+
attribute(String, :type, :type)
|
841
|
+
end
|
842
|
+
class SourceCollection < ElementCollection
|
843
|
+
def element_class
|
844
|
+
Source
|
845
|
+
end
|
846
|
+
end
|
847
|
+
class Picture < HTMLElement
|
848
|
+
end
|
849
|
+
class PictureCollection < ElementCollection
|
850
|
+
def element_class
|
851
|
+
Picture
|
852
|
+
end
|
853
|
+
end
|
841
854
|
class Mod < HTMLElement
|
842
855
|
attribute(String, :cite, :cite)
|
843
856
|
attribute(String, :date_time, :dateTime)
|
@@ -5,29 +5,22 @@ module Watir
|
|
5
5
|
def locate
|
6
6
|
@parent.assert_exists
|
7
7
|
|
8
|
-
locator = locator_class.new(@parent.wd, @selector.merge(:tag_name =>
|
8
|
+
locator = locator_class.new(@parent.wd, @selector.merge(:tag_name => frame_tag), self.class.attribute_list)
|
9
9
|
element = locator.locate
|
10
10
|
element or raise UnknownFrameException, "unable to locate #{@selector[:tag_name]} using #{selector_string}"
|
11
11
|
|
12
|
-
@parent.reset!
|
13
|
-
|
14
12
|
FramedDriver.new(element, driver)
|
15
13
|
end
|
16
14
|
|
15
|
+
def switch_to!
|
16
|
+
locate.send :switch!
|
17
|
+
end
|
18
|
+
|
17
19
|
def assert_exists
|
18
20
|
if @selector.has_key? :element
|
19
21
|
raise UnknownFrameException, "wrapping a WebDriver element as a Frame is not currently supported"
|
20
22
|
end
|
21
23
|
|
22
|
-
if @element && !Watir.always_locate?
|
23
|
-
begin
|
24
|
-
@element.tag_name # rpc
|
25
|
-
return @element
|
26
|
-
rescue Selenium::WebDriver::Error::ObsoleteElementError
|
27
|
-
@element = nil # re-locate
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
24
|
super
|
32
25
|
end
|
33
26
|
|
@@ -36,7 +29,7 @@ module Watir
|
|
36
29
|
|
37
30
|
# this will actually give us the innerHTML instead of the outerHTML of the <frame>,
|
38
31
|
# but given the choice this seems more useful
|
39
|
-
execute_atom(:getOuterHtml, @element.find_element(:tag_name => "html")).strip
|
32
|
+
element_call { execute_atom(:getOuterHtml, @element.find_element(:tag_name => "html")).strip }
|
40
33
|
end
|
41
34
|
|
42
35
|
def execute_script(*args)
|
@@ -45,7 +38,7 @@ module Watir
|
|
45
38
|
|
46
39
|
private
|
47
40
|
|
48
|
-
def
|
41
|
+
def frame_tag
|
49
42
|
'iframe'
|
50
43
|
end
|
51
44
|
|
@@ -55,13 +48,28 @@ module Watir
|
|
55
48
|
class IFrameCollection < ElementCollection
|
56
49
|
|
57
50
|
def to_a
|
58
|
-
|
51
|
+
# In case `#all_elements` returns empty array, but `#elements`
|
52
|
+
# returns non-empty array (i.e. any frame has loaded between these two calls),
|
53
|
+
# index will return nil. That's why `#all_elements` should always
|
54
|
+
# be called after `#elements.`
|
55
|
+
element_indexes = elements.map { |el| all_elements.index(el) }
|
56
|
+
element_indexes.map { |idx| element_class.new(@parent, tag_name: @selector[:tag_name], :index => idx) }
|
59
57
|
end
|
60
58
|
|
61
59
|
def element_class
|
62
60
|
IFrame
|
63
61
|
end
|
64
62
|
|
63
|
+
private
|
64
|
+
|
65
|
+
def all_elements
|
66
|
+
locator_class.new(
|
67
|
+
@parent.wd,
|
68
|
+
{ tag_name: @selector[:tag_name] },
|
69
|
+
element_class.attribute_list
|
70
|
+
).locate_all
|
71
|
+
end
|
72
|
+
|
65
73
|
end # IFrameCollection
|
66
74
|
|
67
75
|
|
@@ -69,7 +77,7 @@ module Watir
|
|
69
77
|
|
70
78
|
private
|
71
79
|
|
72
|
-
def
|
80
|
+
def frame_tag
|
73
81
|
'frame'
|
74
82
|
end
|
75
83
|
|
@@ -110,7 +118,7 @@ module Watir
|
|
110
118
|
end
|
111
119
|
|
112
120
|
def ==(other)
|
113
|
-
|
121
|
+
wd == other.wd
|
114
122
|
end
|
115
123
|
alias_method :eql?, :==
|
116
124
|
|
@@ -14,10 +14,7 @@ module Watir
|
|
14
14
|
# browser.select(:id => "foo").options.first.select
|
15
15
|
#
|
16
16
|
|
17
|
-
|
18
|
-
assert_exists
|
19
|
-
@element.click
|
20
|
-
end
|
17
|
+
alias_method :select, :click
|
21
18
|
|
22
19
|
#
|
23
20
|
# Toggles the selected state of this option.
|
@@ -26,10 +23,7 @@ module Watir
|
|
26
23
|
# browser.select(:id => "foo").options.first.toggle
|
27
24
|
#
|
28
25
|
|
29
|
-
|
30
|
-
assert_exists
|
31
|
-
@element.click
|
32
|
-
end
|
26
|
+
alias_method :toggle, :click
|
33
27
|
|
34
28
|
#
|
35
29
|
# Clears (i.e. toggles selected state) option.
|
@@ -39,7 +33,7 @@ module Watir
|
|
39
33
|
#
|
40
34
|
|
41
35
|
def clear
|
42
|
-
|
36
|
+
click if selected?
|
43
37
|
end
|
44
38
|
|
45
39
|
#
|
@@ -50,7 +44,7 @@ module Watir
|
|
50
44
|
|
51
45
|
def selected?
|
52
46
|
assert_exists
|
53
|
-
@element.selected?
|
47
|
+
element_call { @element.selected? }
|
54
48
|
end
|
55
49
|
|
56
50
|
#
|
@@ -65,17 +59,15 @@ module Watir
|
|
65
59
|
#
|
66
60
|
|
67
61
|
def text
|
68
|
-
assert_exists
|
69
|
-
|
70
62
|
# A little unintuitive - we'll return the 'label' or 'text' attribute if
|
71
63
|
# they exist, otherwise the inner text of the element
|
72
64
|
|
73
65
|
attribute = [:label, :text].find { |a| attribute? a }
|
74
66
|
|
75
67
|
if attribute
|
76
|
-
|
68
|
+
attribute_value(attribute)
|
77
69
|
else
|
78
|
-
|
70
|
+
super
|
79
71
|
end
|
80
72
|
end
|
81
73
|
|
@@ -7,10 +7,7 @@ module Watir
|
|
7
7
|
#
|
8
8
|
|
9
9
|
def set
|
10
|
-
|
11
|
-
assert_enabled
|
12
|
-
|
13
|
-
@element.click unless set?
|
10
|
+
click unless set?
|
14
11
|
end
|
15
12
|
|
16
13
|
#
|
@@ -21,7 +18,7 @@ module Watir
|
|
21
18
|
|
22
19
|
def set?
|
23
20
|
assert_exists
|
24
|
-
@element.selected?
|
21
|
+
element_call { @element.selected? }
|
25
22
|
end
|
26
23
|
|
27
24
|
end # Radio
|
@@ -46,7 +46,6 @@ module Watir
|
|
46
46
|
#
|
47
47
|
|
48
48
|
def include?(str_or_rx)
|
49
|
-
assert_exists
|
50
49
|
# TODO: optimize similar to selected?
|
51
50
|
options.any? { |e| str_or_rx === e.text }
|
52
51
|
end
|
@@ -88,7 +87,11 @@ module Watir
|
|
88
87
|
|
89
88
|
def selected?(str_or_rx)
|
90
89
|
assert_exists
|
91
|
-
matches =
|
90
|
+
matches = element_call do
|
91
|
+
@element.find_elements(:tag_name, 'option').select do |e|
|
92
|
+
str_or_rx === e.text || str_or_rx === e.attribute(:label)
|
93
|
+
end
|
94
|
+
end
|
92
95
|
|
93
96
|
if matches.empty?
|
94
97
|
raise UnknownObjectException, "Unable to locate option matching #{str_or_rx.inspect}"
|
@@ -117,7 +120,6 @@ module Watir
|
|
117
120
|
#
|
118
121
|
|
119
122
|
def selected_options
|
120
|
-
assert_exists
|
121
123
|
options.select { |e| e.selected? }
|
122
124
|
end
|
123
125
|
|
@@ -140,14 +142,18 @@ module Watir
|
|
140
142
|
xpath = option_xpath_for(how, string)
|
141
143
|
|
142
144
|
if multiple?
|
143
|
-
elements =
|
145
|
+
elements = element_call do
|
146
|
+
@element.find_elements(:xpath, xpath)
|
147
|
+
end
|
144
148
|
no_value_found(string) if elements.empty?
|
145
149
|
|
146
150
|
elements.each { |e| e.click unless e.selected? }
|
147
151
|
elements.first.text
|
148
152
|
else
|
149
153
|
begin
|
150
|
-
e =
|
154
|
+
e = element_call do
|
155
|
+
@element.find_element(:xpath, xpath)
|
156
|
+
end
|
151
157
|
rescue Selenium::WebDriver::Error::NoSuchElementError
|
152
158
|
no_value_found(string)
|
153
159
|
end
|
@@ -159,7 +165,9 @@ module Watir
|
|
159
165
|
end
|
160
166
|
|
161
167
|
def select_by_regexp(how, exp)
|
162
|
-
elements =
|
168
|
+
elements = element_call do
|
169
|
+
@element.find_elements(:tag_name, 'option')
|
170
|
+
end
|
163
171
|
no_value_found(nil, "no options in select list") if elements.empty?
|
164
172
|
|
165
173
|
if multiple?
|
@@ -208,7 +216,7 @@ module Watir
|
|
208
216
|
|
209
217
|
def safe_text(element)
|
210
218
|
element.text
|
211
|
-
rescue Selenium::WebDriver::Error::
|
219
|
+
rescue Selenium::WebDriver::Error::StaleElementReferenceError, Selenium::WebDriver::Error::UnhandledAlertError
|
212
220
|
# guard for scenario where selecting the element changes the page, making our element obsolete
|
213
221
|
|
214
222
|
''
|
@@ -12,8 +12,6 @@ module Watir
|
|
12
12
|
class MissingWayOfFindingObjectException < Error; end
|
13
13
|
class UnknownCellException < Error; end
|
14
14
|
class NoMatchingWindowFoundException < Error; end
|
15
|
-
class NoStatusBarException < Error; end
|
16
|
-
class NavigationException < Error; end
|
17
15
|
class UnknownFrameException < Error; end
|
18
16
|
class UnknownRowException < Error; end
|
19
17
|
|
@@ -15,11 +15,6 @@ module Watir
|
|
15
15
|
#
|
16
16
|
# This method is provided by an optional require - API is subject to change.
|
17
17
|
#
|
18
|
-
# @example
|
19
|
-
# browser.alert do
|
20
|
-
# browser.button(:value => "Alert").click
|
21
|
-
# end #=> "the alert message"
|
22
|
-
#
|
23
18
|
|
24
19
|
def alert(&blk)
|
25
20
|
warn 'AlertHelper is deprecated. Use the new Alert API instead (e.g. browser.alert.ok)'
|
@@ -33,10 +28,6 @@ module Watir
|
|
33
28
|
#
|
34
29
|
# This method is provided by an optional require - API is subject to change.
|
35
30
|
#
|
36
|
-
# @example
|
37
|
-
# browser.confirm(true) do
|
38
|
-
# browser.button(:value => "Confirm").click
|
39
|
-
# end #=> "the confirm message"
|
40
31
|
|
41
32
|
def confirm(bool, &blk)
|
42
33
|
warn 'AlertHelper is deprecated. Use the new Alert API instead (e.g. browser.alert.ok)'
|
@@ -50,11 +41,6 @@ module Watir
|
|
50
41
|
#
|
51
42
|
# This method is provided by an optional require - API is subject to change.
|
52
43
|
#
|
53
|
-
# @example
|
54
|
-
# browser.prompt("hello") do
|
55
|
-
# browser.button(:value => "Prompt").click
|
56
|
-
# end #=> { :message => "foo", :default_value => "bar" }
|
57
|
-
#
|
58
44
|
|
59
45
|
def prompt(answer, &blk)
|
60
46
|
warn 'AlertHelper is deprecated. Use the new Alert API instead (e.g. browser.alert.ok)'
|
@@ -5,8 +5,7 @@ module Watir
|
|
5
5
|
# Returns browser windows array.
|
6
6
|
#
|
7
7
|
# @example
|
8
|
-
# browser.
|
9
|
-
# browser.windows(:title => "new")
|
8
|
+
# browser.windows(:title => 'closeable window')
|
10
9
|
#
|
11
10
|
# @return [Array<Window>]
|
12
11
|
#
|
@@ -25,8 +24,7 @@ module Watir
|
|
25
24
|
# Returns browser window.
|
26
25
|
#
|
27
26
|
# @example
|
28
|
-
# browser.
|
29
|
-
# browser.window(:title => "new")
|
27
|
+
# browser.window(:title => 'closeable window')
|
30
28
|
#
|
31
29
|
# @return [Window]
|
32
30
|
#
|
@@ -74,8 +74,8 @@ module Watir
|
|
74
74
|
|
75
75
|
def extract_interface_map
|
76
76
|
# http://www.whatwg.org/specs/web-apps/current-work/#elements-1
|
77
|
-
table = @doc.search("//h3[@id='elements-
|
78
|
-
table or raise "could not find elements-
|
77
|
+
table = @doc.search("//h3[@id='elements-3']/following-sibling::table[1]").first
|
78
|
+
table or raise "could not find elements-3 table"
|
79
79
|
|
80
80
|
@interface_map = {}
|
81
81
|
|
@@ -143,6 +143,7 @@ module Watir
|
|
143
143
|
|
144
144
|
duplicates.each do |intf|
|
145
145
|
final = non_duplicates.find { |i| i.name == intf.name }
|
146
|
+
final.inherits += intf.inherits
|
146
147
|
final.members += intf.members
|
147
148
|
final.extended_attributes += intf.extended_attributes
|
148
149
|
end
|
@@ -148,9 +148,9 @@ module Watir
|
|
148
148
|
Float
|
149
149
|
when 'Boolean'
|
150
150
|
'Boolean'
|
151
|
-
when 'WindowProxy', 'ValidityState', '
|
151
|
+
when 'WindowProxy', 'ValidityState', 'TimeRanges', 'Location',
|
152
152
|
'Any', 'TimedTrackArray', 'TimedTrack', 'TextTrackArray', 'TextTrack',
|
153
|
-
|
153
|
+
/Media.+/, 'TextTrackKind', 'Function', /.*EventHandler$/,
|
154
154
|
'Document', 'DocumentFragment', 'DOMTokenList', 'DOMSettableTokenList',
|
155
155
|
'DOMStringMap', 'HTMLPropertiesCollection', /HTML(.*)Element/, /HTML(.*)Collection/,
|
156
156
|
'CSSStyleDeclaration', /.+List$/, 'Date', 'Element'
|