ayanko-watir-webdriver 0.1.1.1
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/.document +5 -0
- data/.gitignore +5 -0
- data/.gitmodules +3 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.rdoc +55 -0
- data/Rakefile +139 -0
- data/VERSION +1 -0
- data/lib/watir-webdriver.rb +71 -0
- data/lib/watir-webdriver/attribute_helper.rb +128 -0
- data/lib/watir-webdriver/browser.rb +164 -0
- data/lib/watir-webdriver/browserbot.js +49 -0
- data/lib/watir-webdriver/cell_container.rb +19 -0
- data/lib/watir-webdriver/container.rb +40 -0
- data/lib/watir-webdriver/core_ext/string.rb +22 -0
- data/lib/watir-webdriver/element_collection.rb +96 -0
- data/lib/watir-webdriver/elements/button.rb +75 -0
- data/lib/watir-webdriver/elements/checkbox.rb +73 -0
- data/lib/watir-webdriver/elements/element.rb +265 -0
- data/lib/watir-webdriver/elements/file_field.rb +69 -0
- data/lib/watir-webdriver/elements/font.rb +11 -0
- data/lib/watir-webdriver/elements/form.rb +17 -0
- data/lib/watir-webdriver/elements/frame.rb +110 -0
- data/lib/watir-webdriver/elements/generated.rb +2541 -0
- data/lib/watir-webdriver/elements/hidden.rb +24 -0
- data/lib/watir-webdriver/elements/image.rb +51 -0
- data/lib/watir-webdriver/elements/input.rb +42 -0
- data/lib/watir-webdriver/elements/link.rb +7 -0
- data/lib/watir-webdriver/elements/option.rb +55 -0
- data/lib/watir-webdriver/elements/radio.rb +49 -0
- data/lib/watir-webdriver/elements/select.rb +216 -0
- data/lib/watir-webdriver/elements/table.rb +37 -0
- data/lib/watir-webdriver/elements/table_cell.rb +36 -0
- data/lib/watir-webdriver/elements/table_row.rb +45 -0
- data/lib/watir-webdriver/elements/table_section.rb +9 -0
- data/lib/watir-webdriver/elements/text_field.rb +97 -0
- data/lib/watir-webdriver/exception.rb +21 -0
- data/lib/watir-webdriver/extensions/alerts.rb +69 -0
- data/lib/watir-webdriver/extensions/cookies.rb +39 -0
- data/lib/watir-webdriver/extensions/firefox/webdriver.xpi +0 -0
- data/lib/watir-webdriver/extensions/nokogiri.rb +14 -0
- data/lib/watir-webdriver/extensions/performance.rb +54 -0
- data/lib/watir-webdriver/extensions/wait.rb +141 -0
- data/lib/watir-webdriver/html.rb +19 -0
- data/lib/watir-webdriver/html/generator.rb +112 -0
- data/lib/watir-webdriver/html/idl_sorter.rb +49 -0
- data/lib/watir-webdriver/html/spec_extractor.rb +111 -0
- data/lib/watir-webdriver/html/util.rb +22 -0
- data/lib/watir-webdriver/html/visitor.rb +174 -0
- data/lib/watir-webdriver/locators/button_locator.rb +74 -0
- data/lib/watir-webdriver/locators/child_cell_locator.rb +32 -0
- data/lib/watir-webdriver/locators/child_row_locator.rb +37 -0
- data/lib/watir-webdriver/locators/element_locator.rb +352 -0
- data/lib/watir-webdriver/locators/text_field_locator.rb +65 -0
- data/lib/watir-webdriver/row_container.rb +34 -0
- data/lib/watir-webdriver/window_switching.rb +105 -0
- data/lib/watir-webdriver/xpath_support.rb +28 -0
- data/lib/yard/handlers/watir.rb +57 -0
- data/spec/alert_spec.rb +49 -0
- data/spec/browser_spec.rb +42 -0
- data/spec/container_spec.rb +42 -0
- data/spec/element_locator_spec.rb +304 -0
- data/spec/element_spec.rb +13 -0
- data/spec/html/alerts.html +11 -0
- data/spec/html/keylogger.html +15 -0
- data/spec/html/wait.html +27 -0
- data/spec/implementation.rb +17 -0
- data/spec/input_spec.rb +39 -0
- data/spec/locator_spec_helper.rb +51 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/wait_spec.rb +98 -0
- data/support/html5.html +90243 -0
- data/watir-webdriver.gemspec +59 -0
- metadata +238 -0
@@ -0,0 +1,24 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Watir
|
3
|
+
class Hidden < Input
|
4
|
+
def visible?
|
5
|
+
false
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
module Container
|
10
|
+
def hidden(*args)
|
11
|
+
Hidden.new(self, extract_selector(args).merge(:tag_name => "input", :type => "hidden"))
|
12
|
+
end
|
13
|
+
|
14
|
+
def hiddens(*args)
|
15
|
+
HiddenCollection.new(self, extract_selector(args).merge(:tag_name => "input", :type => "hidden"))
|
16
|
+
end
|
17
|
+
end # Container
|
18
|
+
|
19
|
+
class HiddenCollection < InputCollection
|
20
|
+
def element_class
|
21
|
+
Hidden
|
22
|
+
end
|
23
|
+
end # HiddenCollection
|
24
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Watir
|
3
|
+
class Image < HTMLElement
|
4
|
+
|
5
|
+
alias_method :loaded?, :complete?
|
6
|
+
|
7
|
+
#
|
8
|
+
# returns the image's width in pixels
|
9
|
+
#
|
10
|
+
# @return [Integer] width
|
11
|
+
#
|
12
|
+
|
13
|
+
def width
|
14
|
+
assert_exists
|
15
|
+
driver.execute_script "return arguments[0].width", @element
|
16
|
+
end
|
17
|
+
|
18
|
+
#
|
19
|
+
# returns the image's height in pixels
|
20
|
+
#
|
21
|
+
# @return [Integer] height
|
22
|
+
#
|
23
|
+
|
24
|
+
def height
|
25
|
+
assert_exists
|
26
|
+
driver.execute_script "return arguments[0].height", @element
|
27
|
+
end
|
28
|
+
|
29
|
+
def file_created_date
|
30
|
+
assert_exists
|
31
|
+
raise NotImplementedError
|
32
|
+
end
|
33
|
+
|
34
|
+
def file_size
|
35
|
+
assert_exists
|
36
|
+
raise NotImplementedError
|
37
|
+
end
|
38
|
+
|
39
|
+
def save(path)
|
40
|
+
assert_exists
|
41
|
+
raise NotImplementedError
|
42
|
+
end
|
43
|
+
|
44
|
+
end # Image
|
45
|
+
|
46
|
+
module Container
|
47
|
+
alias_method :image, :img
|
48
|
+
alias_method :images, :imgs
|
49
|
+
end # Container
|
50
|
+
|
51
|
+
end # Watir
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Watir
|
3
|
+
class Input < HTMLElement
|
4
|
+
|
5
|
+
alias_method :readonly?, :read_only?
|
6
|
+
|
7
|
+
#
|
8
|
+
# @private
|
9
|
+
#
|
10
|
+
# subclasses can use this to validate the incoming element
|
11
|
+
#
|
12
|
+
|
13
|
+
def self.from(parent, element)
|
14
|
+
unless element.tag_name == "input"
|
15
|
+
raise TypeError, "can't create #{self} from #{element.inspect}"
|
16
|
+
end
|
17
|
+
|
18
|
+
new(parent, :element => element)
|
19
|
+
end
|
20
|
+
|
21
|
+
def enabled?
|
22
|
+
!disabled?
|
23
|
+
end
|
24
|
+
|
25
|
+
#
|
26
|
+
# Return the type attribute of the element, or 'text' if the attribute is invalid.
|
27
|
+
# TODO: discuss.
|
28
|
+
#
|
29
|
+
# @return [String]
|
30
|
+
#
|
31
|
+
|
32
|
+
def type
|
33
|
+
assert_exists
|
34
|
+
value = @element.attribute("type").to_s
|
35
|
+
|
36
|
+
# we return 'text' if the type is invalid
|
37
|
+
# not sure if we really should do this
|
38
|
+
TextFieldLocator::NON_TEXT_TYPES.include?(value) ? value : 'text'
|
39
|
+
end
|
40
|
+
|
41
|
+
end # Input
|
42
|
+
end # Watir
|
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Watir
|
3
|
+
|
4
|
+
#
|
5
|
+
# Represents an option in a select list.
|
6
|
+
#
|
7
|
+
|
8
|
+
class Option < HTMLElement
|
9
|
+
|
10
|
+
#
|
11
|
+
# Select this option
|
12
|
+
#
|
13
|
+
|
14
|
+
def select
|
15
|
+
assert_exists
|
16
|
+
|
17
|
+
@element.select
|
18
|
+
fire_event("onclick") rescue nil
|
19
|
+
end
|
20
|
+
|
21
|
+
#
|
22
|
+
# Toggle the selected state of this option
|
23
|
+
#
|
24
|
+
|
25
|
+
def toggle
|
26
|
+
assert_exists
|
27
|
+
@element.toggle
|
28
|
+
end
|
29
|
+
|
30
|
+
#
|
31
|
+
# Is this option selected?
|
32
|
+
#
|
33
|
+
|
34
|
+
def selected?
|
35
|
+
assert_exists
|
36
|
+
@element.selected?
|
37
|
+
end
|
38
|
+
|
39
|
+
def text
|
40
|
+
assert_exists
|
41
|
+
|
42
|
+
# A little unintuitive - we'll return the 'label' or 'text' attribute if
|
43
|
+
# they exist, otherwise the inner text of the element
|
44
|
+
|
45
|
+
attribute = [:label, :text].find { |a| attribute? a }
|
46
|
+
|
47
|
+
if attribute
|
48
|
+
@element.attribute(attribute)
|
49
|
+
else
|
50
|
+
@element.text
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
end # Option
|
55
|
+
end # Watir
|
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Watir
|
3
|
+
class Radio < Input
|
4
|
+
def self.from(parent, element)
|
5
|
+
if element.attribute(:type) != "radio"
|
6
|
+
raise TypeError, "expected type=radio for #{element.inspect}"
|
7
|
+
end
|
8
|
+
|
9
|
+
super
|
10
|
+
end
|
11
|
+
#
|
12
|
+
# Select this radio button.
|
13
|
+
#
|
14
|
+
|
15
|
+
def set
|
16
|
+
assert_exists
|
17
|
+
assert_enabled
|
18
|
+
|
19
|
+
@element.click unless set?
|
20
|
+
end
|
21
|
+
|
22
|
+
#
|
23
|
+
# Is this radio set?
|
24
|
+
#
|
25
|
+
|
26
|
+
def set?
|
27
|
+
assert_exists
|
28
|
+
@element.selected?
|
29
|
+
end
|
30
|
+
end # Radio
|
31
|
+
|
32
|
+
module Container
|
33
|
+
def radio(*args)
|
34
|
+
Radio.new(self, extract_selector(args).merge(:tag_name => "input", :type => "radio"))
|
35
|
+
end
|
36
|
+
|
37
|
+
def radios(*args)
|
38
|
+
RadioCollection.new(self, extract_selector(args).merge(:tag_name => "input", :type => "radio" ))
|
39
|
+
end
|
40
|
+
end # Container
|
41
|
+
|
42
|
+
class RadioCollection < InputCollection
|
43
|
+
private
|
44
|
+
|
45
|
+
def element_class
|
46
|
+
Radio
|
47
|
+
end
|
48
|
+
end # RadioCollection
|
49
|
+
end # Watir
|
@@ -0,0 +1,216 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Watir
|
3
|
+
class Select < HTMLElement
|
4
|
+
include Watir::Exception
|
5
|
+
|
6
|
+
#
|
7
|
+
# Returns true if this element is enabled
|
8
|
+
#
|
9
|
+
# @return [Boolean]
|
10
|
+
#
|
11
|
+
|
12
|
+
def enabled?
|
13
|
+
!disabled?
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Clear all selected options
|
18
|
+
#
|
19
|
+
|
20
|
+
def clear
|
21
|
+
assert_exists
|
22
|
+
|
23
|
+
raise Error, "you can only clear multi-selects" unless multiple?
|
24
|
+
|
25
|
+
options.each do |o|
|
26
|
+
o.toggle if o.selected?
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def options
|
31
|
+
assert_exists
|
32
|
+
super
|
33
|
+
end
|
34
|
+
|
35
|
+
#
|
36
|
+
# Returns true if the select list has one or more options where text or label matches the given value.
|
37
|
+
#
|
38
|
+
# @param [String, Regexp] value A value.
|
39
|
+
# @return [Boolean]
|
40
|
+
#
|
41
|
+
|
42
|
+
def include?(str_or_rx)
|
43
|
+
assert_exists
|
44
|
+
# TODO: optimize similar to selected?
|
45
|
+
options.any? { |e| str_or_rx === e.text }
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# Select the option(s) whose text or label matches the given string.
|
50
|
+
# If this is a multi-select and several options match the value given, all will be selected.
|
51
|
+
#
|
52
|
+
# @param [String, Regexp] value A value.
|
53
|
+
# @raise [Watir::Exception::NoValueFoundException] if the value does not exist.
|
54
|
+
# @return [String] The text of the option selected. If multiple options match, returns the first match.
|
55
|
+
#
|
56
|
+
|
57
|
+
def select(str_or_rx)
|
58
|
+
select_by :text, str_or_rx
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Selects the option(s) whose value attribute matches the given string.
|
63
|
+
#
|
64
|
+
# @see +select+
|
65
|
+
#
|
66
|
+
# @param [String, Regexp] value A value.
|
67
|
+
# @raise [Watir::Exception::NoValueFoundException] if the value does not exist.
|
68
|
+
# @return [String] The option selected. If multiple options match, returns the first match
|
69
|
+
#
|
70
|
+
|
71
|
+
def select_value(str_or_rx)
|
72
|
+
select_by :value, str_or_rx
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
76
|
+
# Returns true if any of the selected options' text or label match the given value.
|
77
|
+
#
|
78
|
+
# @param [String, Regexp] value A value.
|
79
|
+
# @raise [Watir::Exception::UnknownObjectException] if the value does not exist.
|
80
|
+
# @return [Boolean]
|
81
|
+
#
|
82
|
+
|
83
|
+
def selected?(str_or_rx)
|
84
|
+
assert_exists
|
85
|
+
matches = @element.find_elements(:tag_name, 'option').select { |e| str_or_rx === e.text || str_or_rx === e.attribute(:label) }
|
86
|
+
|
87
|
+
if matches.empty?
|
88
|
+
raise UnknownObjectException, "Unable to locate option matching #{str_or_rx.inspect}"
|
89
|
+
end
|
90
|
+
|
91
|
+
matches.any? { |e| e.selected? }
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Returns the value of the first selected option in the select list.
|
96
|
+
# Returns nil if no option is selected.
|
97
|
+
#
|
98
|
+
# @return [String, nil]
|
99
|
+
#
|
100
|
+
|
101
|
+
def value
|
102
|
+
o = options.find { |e| e.selected? } || return
|
103
|
+
o.value
|
104
|
+
end
|
105
|
+
|
106
|
+
|
107
|
+
#
|
108
|
+
# @return [Array<String>] An array of strings representing the text value of the currently selected options.
|
109
|
+
#
|
110
|
+
|
111
|
+
def selected_options
|
112
|
+
assert_exists
|
113
|
+
options.map { |e| e.text if e.selected? }.compact
|
114
|
+
end
|
115
|
+
|
116
|
+
private
|
117
|
+
|
118
|
+
def select_by(how, str_or_rx)
|
119
|
+
assert_exists
|
120
|
+
|
121
|
+
case str_or_rx
|
122
|
+
when String, Numeric
|
123
|
+
select_by_string(how, str_or_rx.to_s)
|
124
|
+
when Regexp
|
125
|
+
select_by_regexp(how, str_or_rx)
|
126
|
+
else
|
127
|
+
raise TypeError, "expected String or Regexp, got #{str_or_rx.inspect}:#{str_or_rx.class}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def select_by_string(how, string)
|
132
|
+
xpath = option_xpath_for(how, string)
|
133
|
+
|
134
|
+
if multiple?
|
135
|
+
elements = @element.find_elements(:xpath, xpath)
|
136
|
+
no_value_found(string) if elements.empty?
|
137
|
+
|
138
|
+
elements.each { |e| e.select unless e.selected? }
|
139
|
+
elements.first.text
|
140
|
+
else
|
141
|
+
begin
|
142
|
+
e = @element.find_element(:xpath, xpath)
|
143
|
+
rescue WebDriver::Error::NoSuchElementError
|
144
|
+
no_value_found(string)
|
145
|
+
end
|
146
|
+
|
147
|
+
e.select unless e.selected?
|
148
|
+
|
149
|
+
safe_text(e)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
def select_by_regexp(how, exp)
|
154
|
+
elements = @element.find_elements(:tag_name, 'option')
|
155
|
+
no_value_found(nil, "no options in select list") if elements.empty?
|
156
|
+
|
157
|
+
if multiple?
|
158
|
+
found = elements.select do |e|
|
159
|
+
next unless matches_regexp?(how, e, exp)
|
160
|
+
e.select unless e.selected?
|
161
|
+
true
|
162
|
+
end
|
163
|
+
|
164
|
+
no_value_found(exp) if found.empty?
|
165
|
+
|
166
|
+
found.first.text
|
167
|
+
else
|
168
|
+
element = elements.find { |e| matches_regexp?(how, e, exp) }
|
169
|
+
no_value_found(exp) unless element
|
170
|
+
|
171
|
+
element.select unless element.selected?
|
172
|
+
|
173
|
+
safe_text(element)
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
def option_xpath_for(how, string)
|
178
|
+
case how
|
179
|
+
when :text
|
180
|
+
".//option[normalize-space()='#{string}' or @label='#{string}']"
|
181
|
+
when :value
|
182
|
+
".//option[@value='#{string}']"
|
183
|
+
else
|
184
|
+
raise Error, "unknown how: #{how.inspect}"
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
def matches_regexp?(how, element, exp)
|
189
|
+
case how
|
190
|
+
when :text
|
191
|
+
element.text =~ exp || element.attribute(:label) =~ exp
|
192
|
+
when :value
|
193
|
+
element.attribute(:value) =~ exp
|
194
|
+
else
|
195
|
+
raise Error, "unknown how: #{how.inspect}"
|
196
|
+
end
|
197
|
+
end
|
198
|
+
|
199
|
+
def safe_text(element)
|
200
|
+
element.text
|
201
|
+
rescue Selenium::WebDriver::Error::ObsoleteElementError
|
202
|
+
# guard for scenario where selecting the element changes the page, making our element obsolete
|
203
|
+
|
204
|
+
''
|
205
|
+
end
|
206
|
+
|
207
|
+
def no_value_found(arg, msg = nil)
|
208
|
+
raise NoValueFoundException, msg || "#{arg.inspect} not found in select list"
|
209
|
+
end
|
210
|
+
end # Select
|
211
|
+
|
212
|
+
module Container
|
213
|
+
alias_method :select_list, :select
|
214
|
+
alias_method :select_lists, :selects
|
215
|
+
end # Container
|
216
|
+
end # Watir
|