ayanko-watir-webdriver 0.1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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,49 @@
|
|
1
|
+
// stolen from injectableSelenium.js in WebDriver
|
2
|
+
var browserbot = {
|
3
|
+
|
4
|
+
triggerEvent: function(element, eventType, canBubble, controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown) {
|
5
|
+
canBubble = (typeof(canBubble) == undefined) ? true: canBubble;
|
6
|
+
if (element.fireEvent && element.ownerDocument && element.ownerDocument.createEventObject) {
|
7
|
+
// IE
|
8
|
+
var evt = this.createEventObject(element, controlKeyDown, altKeyDown, shiftKeyDown, metaKeyDown);
|
9
|
+
element.fireEvent('on' + eventType, evt);
|
10
|
+
} else {
|
11
|
+
var evt = document.createEvent('HTMLEvents');
|
12
|
+
|
13
|
+
try {
|
14
|
+
evt.shiftKey = shiftKeyDown;
|
15
|
+
evt.metaKey = metaKeyDown;
|
16
|
+
evt.altKey = altKeyDown;
|
17
|
+
evt.ctrlKey = controlKeyDown;
|
18
|
+
} catch(e) {
|
19
|
+
// Nothing sane to do
|
20
|
+
}
|
21
|
+
|
22
|
+
evt.initEvent(eventType, canBubble, true);
|
23
|
+
return element.dispatchEvent(evt);
|
24
|
+
}
|
25
|
+
},
|
26
|
+
|
27
|
+
getVisibleText: function() {
|
28
|
+
var selection = getSelection();
|
29
|
+
var range = document.createRange();
|
30
|
+
range.selectNodeContents(document.documentElement);
|
31
|
+
selection.addRange(range);
|
32
|
+
var string = selection.toString();
|
33
|
+
selection.removeAllRanges();
|
34
|
+
|
35
|
+
return string;
|
36
|
+
},
|
37
|
+
|
38
|
+
getOuterHTML: function(element) {
|
39
|
+
if (element.outerHTML) {
|
40
|
+
return element.outerHTML;
|
41
|
+
} else if (typeof(XMLSerializer) != undefined) {
|
42
|
+
return new XMLSerializer().serializeToString(element);
|
43
|
+
} else {
|
44
|
+
throw "can't get outerHTML in this browser";
|
45
|
+
}
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
};
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Watir
|
2
|
+
module CellContainer
|
3
|
+
|
4
|
+
def cell(*args)
|
5
|
+
cell = TableCell.new(self, extract_selector(args).merge(:tag_name => /^(th|td)$/))
|
6
|
+
cell.locator_class = ChildCellLocator
|
7
|
+
|
8
|
+
cell
|
9
|
+
end
|
10
|
+
|
11
|
+
def cells(*args)
|
12
|
+
cells = TableCellCollection.new(self, extract_selector(args).merge(:tag_name => /^(th|td)$/))
|
13
|
+
cells.locator_class = ChildCellLocator
|
14
|
+
|
15
|
+
cells
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Watir
|
3
|
+
module Container
|
4
|
+
include XpathSupport
|
5
|
+
|
6
|
+
def element(*args)
|
7
|
+
HTMLElement.new(self, extract_selector(args))
|
8
|
+
end
|
9
|
+
|
10
|
+
def elements(*args)
|
11
|
+
HTMLElementCollection.new(self, extract_selector(args))
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def browserbot(function_name, *arguments)
|
17
|
+
script = browserbot_script + "return browserbot.#{function_name}.apply(browserbot, arguments);"
|
18
|
+
driver.execute_script(script, *arguments)
|
19
|
+
end
|
20
|
+
|
21
|
+
def browserbot_script
|
22
|
+
@browserbot_script ||= File.read("#{File.dirname(__FILE__)}/browserbot.js")
|
23
|
+
end
|
24
|
+
|
25
|
+
def extract_selector(selectors)
|
26
|
+
case selectors.size
|
27
|
+
when 2
|
28
|
+
return { selectors[0] => selectors[1] }
|
29
|
+
when 1
|
30
|
+
obj = selectors.first
|
31
|
+
return obj if obj.kind_of? Hash
|
32
|
+
when 0
|
33
|
+
return {}
|
34
|
+
end
|
35
|
+
|
36
|
+
raise ArgumentError, "expected Hash or (:how, 'what'), got #{selectors.inspect}"
|
37
|
+
end
|
38
|
+
|
39
|
+
end # Container
|
40
|
+
end # Watir
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
class String
|
3
|
+
#
|
4
|
+
# Convert from camel case to snake case
|
5
|
+
#
|
6
|
+
# 'FooBar'.snake_case # => "foo_bar"
|
7
|
+
#
|
8
|
+
|
9
|
+
def snake_case
|
10
|
+
gsub(/\B[A-Z][^A-Z]/, '_\&').downcase.gsub(' ', '_')
|
11
|
+
end
|
12
|
+
|
13
|
+
#
|
14
|
+
# Convert from snake case to camel case
|
15
|
+
#
|
16
|
+
# 'foo_bar'.camel_case # => "FooBar"
|
17
|
+
#
|
18
|
+
|
19
|
+
def camel_case
|
20
|
+
split('_').map { |e| e.capitalize }.join
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Watir
|
3
|
+
|
4
|
+
#
|
5
|
+
# Base class for element collections.
|
6
|
+
#
|
7
|
+
|
8
|
+
class ElementCollection
|
9
|
+
include Enumerable
|
10
|
+
|
11
|
+
def initialize(parent, selector)
|
12
|
+
@parent = parent
|
13
|
+
@selector = selector
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# @yieldparam [Watir::Element] element Iterate through the elements in this collection.
|
18
|
+
#
|
19
|
+
|
20
|
+
def each(&blk)
|
21
|
+
to_a.each(&blk)
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# @return [Fixnum] The number of elements in this collection.
|
26
|
+
#
|
27
|
+
|
28
|
+
def length
|
29
|
+
elements.length
|
30
|
+
end
|
31
|
+
alias_method :size, :length
|
32
|
+
|
33
|
+
#
|
34
|
+
# Get the element at the given index.
|
35
|
+
# Note that this is 0-indexed and not compatible with older Watir implementations.
|
36
|
+
#
|
37
|
+
# Also note that because of Watir's lazy loading, this will return an Element
|
38
|
+
# instance even if the index is out of bounds.
|
39
|
+
#
|
40
|
+
# @param [Fixnum] n Index of wanted element, 0-indexed
|
41
|
+
# @return [Watir::Element] Returns an instance of a Watir::Element subclass
|
42
|
+
#
|
43
|
+
|
44
|
+
|
45
|
+
def [](idx)
|
46
|
+
to_a[idx] || element_class.new(@parent, :index => idx)
|
47
|
+
end
|
48
|
+
|
49
|
+
#
|
50
|
+
# First element of this collection
|
51
|
+
#
|
52
|
+
# @return [Watir::Element] Returns an instance of a Watir::Element subclass
|
53
|
+
#
|
54
|
+
|
55
|
+
def first
|
56
|
+
self[0]
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Last element of the collection
|
61
|
+
#
|
62
|
+
# @return [Watir::Element] Returns an instance of a Watir::Element subclass
|
63
|
+
#
|
64
|
+
|
65
|
+
def last
|
66
|
+
self[-1]
|
67
|
+
end
|
68
|
+
|
69
|
+
#
|
70
|
+
# This collection as an Array
|
71
|
+
#
|
72
|
+
# @return [Array<Watir::Element>]
|
73
|
+
#
|
74
|
+
|
75
|
+
def to_a
|
76
|
+
# TODO: optimize - lazy element_class instance?
|
77
|
+
@to_a ||= elements.map { |e| element_class.new(@parent, :element => e) }
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
def elements
|
83
|
+
@elements ||= locator_class.new(
|
84
|
+
@parent.wd,
|
85
|
+
@selector,
|
86
|
+
element_class.attribute_list
|
87
|
+
).locate_all
|
88
|
+
end
|
89
|
+
|
90
|
+
# overridable by subclasses
|
91
|
+
def locator_class
|
92
|
+
ElementLocator
|
93
|
+
end
|
94
|
+
|
95
|
+
end # ElementCollection
|
96
|
+
end # Watir
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Watir
|
3
|
+
|
4
|
+
#
|
5
|
+
# Class representing button elements.
|
6
|
+
#
|
7
|
+
# This class covers both <button> and <input type="submit|reset|image|button" /> elements.
|
8
|
+
#
|
9
|
+
|
10
|
+
class Button < HTMLElement
|
11
|
+
|
12
|
+
# add the attributes from <input>
|
13
|
+
attributes Watir::Input.typed_attributes
|
14
|
+
|
15
|
+
VALID_TYPES = %w[button reset submit image]
|
16
|
+
|
17
|
+
def self.from(parent, element)
|
18
|
+
if element.tag_name == "button" ||
|
19
|
+
element.tag_name == "input" && VALID_TYPES.include?(element.attribute(:type))
|
20
|
+
Button.new(parent, :element => element)
|
21
|
+
else
|
22
|
+
raise TypeError, "expected button or input[@type=#{VALID_TYPES.join("|")}] for #{element.inspect}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Returns the text of the button.
|
28
|
+
#
|
29
|
+
# For input elements, returns the "value" attribute.
|
30
|
+
# For button elements, returns the inner text.
|
31
|
+
#
|
32
|
+
|
33
|
+
def text
|
34
|
+
assert_exists
|
35
|
+
case @element.tag_name
|
36
|
+
when 'input'
|
37
|
+
@element.attribute(:value)
|
38
|
+
when 'button'
|
39
|
+
@element.text
|
40
|
+
else
|
41
|
+
raise Exception::Error, "unknown tag name for button: #{@element.tag_name}"
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Returns true if this element is enabled
|
47
|
+
#
|
48
|
+
# @return [Boolean]
|
49
|
+
#
|
50
|
+
|
51
|
+
def enabled?
|
52
|
+
!disabled?
|
53
|
+
end
|
54
|
+
|
55
|
+
private
|
56
|
+
|
57
|
+
def locate
|
58
|
+
@parent.assert_exists
|
59
|
+
ButtonLocator.new(@parent.wd, @selector, self.class.attribute_list).locate
|
60
|
+
end
|
61
|
+
|
62
|
+
end # Button
|
63
|
+
|
64
|
+
class ButtonCollection < ElementCollection
|
65
|
+
private
|
66
|
+
|
67
|
+
def locator_class
|
68
|
+
ButtonLocator
|
69
|
+
end
|
70
|
+
|
71
|
+
def element_class
|
72
|
+
Button
|
73
|
+
end
|
74
|
+
end # ButtonsCollection
|
75
|
+
end # Watir
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Watir
|
4
|
+
class CheckBox < Input
|
5
|
+
|
6
|
+
def self.from(parent, element)
|
7
|
+
if element.attribute(:type) != "checkbox"
|
8
|
+
raise TypeError, "expected type=checkbox for #{element.inspect}"
|
9
|
+
end
|
10
|
+
|
11
|
+
super
|
12
|
+
end
|
13
|
+
|
14
|
+
#
|
15
|
+
# Set this checkbox to the given value
|
16
|
+
#
|
17
|
+
# Example:
|
18
|
+
#
|
19
|
+
# checkbox.set? #=> false
|
20
|
+
# checkbox.set
|
21
|
+
# checkbox.set? #=> true
|
22
|
+
# checkbox.set(false)
|
23
|
+
# checkbox.set? #=> false
|
24
|
+
#
|
25
|
+
|
26
|
+
def set(bool = true)
|
27
|
+
assert_exists
|
28
|
+
assert_enabled
|
29
|
+
|
30
|
+
if @element.selected?
|
31
|
+
@element.click unless bool
|
32
|
+
else
|
33
|
+
@element.click if bool
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
#
|
38
|
+
# returns true if the element is checked
|
39
|
+
# @return [Boolean]
|
40
|
+
#
|
41
|
+
|
42
|
+
def set?
|
43
|
+
assert_exists
|
44
|
+
@element.selected?
|
45
|
+
end
|
46
|
+
|
47
|
+
#
|
48
|
+
# Unset this checkbox.
|
49
|
+
#
|
50
|
+
# Same as +set(false)+
|
51
|
+
#
|
52
|
+
|
53
|
+
def clear
|
54
|
+
set false
|
55
|
+
end
|
56
|
+
end # CheckBox
|
57
|
+
|
58
|
+
module Container
|
59
|
+
def checkbox(*args)
|
60
|
+
CheckBox.new(self, extract_selector(args).merge(:tag_name => "input", :type => "checkbox"))
|
61
|
+
end
|
62
|
+
|
63
|
+
def checkboxes(*args)
|
64
|
+
CheckBoxCollection.new(self, extract_selector(args).merge(:tag_name => "input", :type => "checkbox"))
|
65
|
+
end
|
66
|
+
end # Container
|
67
|
+
|
68
|
+
class CheckBoxCollection < InputCollection
|
69
|
+
def element_class
|
70
|
+
CheckBox
|
71
|
+
end
|
72
|
+
end # CheckBoxCollection
|
73
|
+
end
|
@@ -0,0 +1,265 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Watir
|
4
|
+
|
5
|
+
#
|
6
|
+
# Base class for HTML elements.
|
7
|
+
#
|
8
|
+
|
9
|
+
class Element
|
10
|
+
include Exception
|
11
|
+
include Container
|
12
|
+
include Selenium
|
13
|
+
extend AttributeHelper
|
14
|
+
|
15
|
+
def initialize(parent, selector)
|
16
|
+
@parent = parent
|
17
|
+
@selector = selector
|
18
|
+
|
19
|
+
unless @selector.kind_of? Hash
|
20
|
+
raise ArgumentError, "invalid argument: #{selector.inspect}"
|
21
|
+
end
|
22
|
+
|
23
|
+
if @selector.has_key?(:element)
|
24
|
+
@element = @selector[:element]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def exists?
|
29
|
+
assert_exists
|
30
|
+
true
|
31
|
+
rescue UnknownObjectException, UnknownFrameException
|
32
|
+
false
|
33
|
+
end
|
34
|
+
alias_method :exist?, :exists?
|
35
|
+
|
36
|
+
def inspect
|
37
|
+
if @selector.has_key?(:element)
|
38
|
+
'#<%s:0x%x located=%s selector=%s>' % [self.class, hash*2, !!@element, '{:element=>(webdriver element)}']
|
39
|
+
else
|
40
|
+
'#<%s:0x%x located=%s selector=%s>' % [self.class, hash*2, !!@element, selector_string]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def ==(other)
|
45
|
+
return false unless other.kind_of? self.class
|
46
|
+
|
47
|
+
assert_exists
|
48
|
+
@element == other.element
|
49
|
+
end
|
50
|
+
alias_method :eql?, :==
|
51
|
+
|
52
|
+
def hash
|
53
|
+
@element ? @element.hash : super
|
54
|
+
end
|
55
|
+
|
56
|
+
def text
|
57
|
+
assert_exists
|
58
|
+
@element.text
|
59
|
+
end
|
60
|
+
|
61
|
+
def tag_name
|
62
|
+
assert_exists
|
63
|
+
@element.tag_name
|
64
|
+
end
|
65
|
+
|
66
|
+
def click
|
67
|
+
assert_exists
|
68
|
+
assert_enabled
|
69
|
+
@element.click
|
70
|
+
run_checkers
|
71
|
+
end
|
72
|
+
|
73
|
+
def double_click
|
74
|
+
assert_exists
|
75
|
+
raise NotImplementedError, "need support in WebDriver"
|
76
|
+
|
77
|
+
@element.double_click
|
78
|
+
run_checkers
|
79
|
+
end
|
80
|
+
|
81
|
+
def right_click
|
82
|
+
assert_exists
|
83
|
+
raise NotImplementedError, "need support in WebDriver"
|
84
|
+
|
85
|
+
@element.right_click
|
86
|
+
run_checkers
|
87
|
+
end
|
88
|
+
|
89
|
+
def flash
|
90
|
+
original_color = style("backgroundColor")
|
91
|
+
|
92
|
+
10.times do |n|
|
93
|
+
color = (n % 2 == 0) ? "red" : original_color
|
94
|
+
driver.execute_script("arguments[0].style.backgroundColor = '#{color}'", @element)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def value
|
99
|
+
assert_exists
|
100
|
+
|
101
|
+
begin
|
102
|
+
@element.value || ''
|
103
|
+
rescue WebDriver::Error::ElementNotEnabledError
|
104
|
+
""
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
def attribute_value(attribute_name)
|
109
|
+
assert_exists
|
110
|
+
@element.attribute attribute_name
|
111
|
+
end
|
112
|
+
|
113
|
+
def html
|
114
|
+
assert_exists
|
115
|
+
browserbot('getOuterHTML', @element).strip
|
116
|
+
end
|
117
|
+
|
118
|
+
def send_keys(*args)
|
119
|
+
assert_exists
|
120
|
+
@element.send_keys(*args)
|
121
|
+
end
|
122
|
+
|
123
|
+
#
|
124
|
+
# Note: Firefox queues focus events until the window actually has focus.
|
125
|
+
#
|
126
|
+
# See http://code.google.com/p/selenium/issues/detail?id=157
|
127
|
+
#
|
128
|
+
|
129
|
+
def focus
|
130
|
+
assert_exists
|
131
|
+
driver.execute_script "return arguments[0].focus()", @element
|
132
|
+
end
|
133
|
+
|
134
|
+
def fire_event(event_name, bubble = false)
|
135
|
+
assert_exists
|
136
|
+
event_name = event_name.to_s.sub(/^on/, '')
|
137
|
+
browserbot('triggerEvent', @element, event_name, bubble)
|
138
|
+
end
|
139
|
+
|
140
|
+
def parent
|
141
|
+
assert_exists
|
142
|
+
|
143
|
+
e = driver.execute_script "return arguments[0].parentNode", @element
|
144
|
+
|
145
|
+
if e.kind_of?(WebDriver::Element)
|
146
|
+
Watir.element_class_for(e.tag_name).new(@parent, :element => e)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def driver
|
151
|
+
@parent.driver
|
152
|
+
end
|
153
|
+
|
154
|
+
def element
|
155
|
+
assert_exists
|
156
|
+
@element
|
157
|
+
end
|
158
|
+
alias_method :wd, :element # ensures duck typing with Browser
|
159
|
+
|
160
|
+
def visible?
|
161
|
+
assert_exists
|
162
|
+
@element.displayed?
|
163
|
+
end
|
164
|
+
|
165
|
+
def style(property = nil)
|
166
|
+
if property
|
167
|
+
assert_exists
|
168
|
+
@element.style property
|
169
|
+
else
|
170
|
+
attribute_value("style") || ''
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def run_checkers
|
175
|
+
@parent.run_checkers
|
176
|
+
end
|
177
|
+
|
178
|
+
#
|
179
|
+
# Cast this Element instance to a more specific subtype.
|
180
|
+
#
|
181
|
+
# Example:
|
182
|
+
#
|
183
|
+
# browser.element(:xpath => "//input[@type='submit']").to_subtype #=> #<Watir::Button>
|
184
|
+
#
|
185
|
+
|
186
|
+
def to_subtype
|
187
|
+
elem = element()
|
188
|
+
tag_name = elem.tag_name
|
189
|
+
|
190
|
+
klass = nil
|
191
|
+
|
192
|
+
if tag_name == "input"
|
193
|
+
klass = case elem.attribute(:type)
|
194
|
+
when *Button::VALID_TYPES
|
195
|
+
Button
|
196
|
+
when 'checkbox'
|
197
|
+
CheckBox
|
198
|
+
when 'radio'
|
199
|
+
Radio
|
200
|
+
when 'file'
|
201
|
+
FileField
|
202
|
+
else
|
203
|
+
TextField
|
204
|
+
end
|
205
|
+
else
|
206
|
+
klass = Watir.element_class_for(tag_name)
|
207
|
+
end
|
208
|
+
|
209
|
+
klass.new(@parent, :element => elem)
|
210
|
+
end
|
211
|
+
|
212
|
+
protected
|
213
|
+
|
214
|
+
def assert_exists
|
215
|
+
@element ||= locate
|
216
|
+
|
217
|
+
unless @element
|
218
|
+
raise UnknownObjectException, "unable to locate element, using #{selector_string}"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
def browser
|
223
|
+
@parent.browser
|
224
|
+
end
|
225
|
+
|
226
|
+
def locate
|
227
|
+
@parent.assert_exists
|
228
|
+
locator_class.new(@parent.wd, @selector, self.class.attribute_list).locate
|
229
|
+
end
|
230
|
+
|
231
|
+
private
|
232
|
+
|
233
|
+
def locator_class
|
234
|
+
ElementLocator
|
235
|
+
end
|
236
|
+
|
237
|
+
def selector_string
|
238
|
+
@selector.inspect
|
239
|
+
end
|
240
|
+
|
241
|
+
def attribute?(attribute)
|
242
|
+
assert_exists
|
243
|
+
driver.execute_script "return !!arguments[0].getAttributeNode(arguments[1]);", @element, attribute.to_s.downcase
|
244
|
+
end
|
245
|
+
|
246
|
+
def assert_enabled
|
247
|
+
raise ObjectDisabledException, "object is disabled #{selector_string}" unless @element.enabled?
|
248
|
+
end
|
249
|
+
|
250
|
+
def assert_writable
|
251
|
+
assert_enabled
|
252
|
+
raise ObjectReadOnlyException if respond_to?(:readonly?) && readonly?
|
253
|
+
end
|
254
|
+
|
255
|
+
def method_missing(meth, *args, &blk)
|
256
|
+
method = meth.to_s
|
257
|
+
if method =~ /^data_(.+)$/
|
258
|
+
attribute_value(method.gsub(/_/, '-'), *args)
|
259
|
+
else
|
260
|
+
super
|
261
|
+
end
|
262
|
+
end
|
263
|
+
|
264
|
+
end # Element
|
265
|
+
end # Watir
|