centric_page_object 2.3.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.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +8 -0
- data/.rspec +2 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +17 -0
- data/ChangeLog +931 -0
- data/Gemfile +12 -0
- data/Guardfile +20 -0
- data/LICENSE +20 -0
- data/README.md +114 -0
- data/Rakefile +29 -0
- data/centric_page_object.gemspec +31 -0
- data/cucumber.yml +8 -0
- data/lib/page-object/accessors.rb +1201 -0
- data/lib/page-object/element_locators.rb +21 -0
- data/lib/page-object/elements/area.rb +9 -0
- data/lib/page-object/elements/audio.rb +9 -0
- data/lib/page-object/elements/bold.rb +9 -0
- data/lib/page-object/elements/button.rb +12 -0
- data/lib/page-object/elements/canvas.rb +10 -0
- data/lib/page-object/elements/check_box.rb +9 -0
- data/lib/page-object/elements/date_field.rb +10 -0
- data/lib/page-object/elements/div.rb +9 -0
- data/lib/page-object/elements/element.rb +212 -0
- data/lib/page-object/elements/file_field.rb +9 -0
- data/lib/page-object/elements/form.rb +9 -0
- data/lib/page-object/elements/heading.rb +14 -0
- data/lib/page-object/elements/hidden_field.rb +9 -0
- data/lib/page-object/elements/image.rb +10 -0
- data/lib/page-object/elements/italic.rb +9 -0
- data/lib/page-object/elements/label.rb +9 -0
- data/lib/page-object/elements/link.rb +9 -0
- data/lib/page-object/elements/list_item.rb +9 -0
- data/lib/page-object/elements/media.rb +11 -0
- data/lib/page-object/elements/option.rb +9 -0
- data/lib/page-object/elements/ordered_list.rb +43 -0
- data/lib/page-object/elements/paragraph.rb +9 -0
- data/lib/page-object/elements/radio_button.rb +9 -0
- data/lib/page-object/elements/select_list.rb +42 -0
- data/lib/page-object/elements/span.rb +9 -0
- data/lib/page-object/elements/table.rb +85 -0
- data/lib/page-object/elements/table_cell.rb +10 -0
- data/lib/page-object/elements/table_row.rb +52 -0
- data/lib/page-object/elements/text_area.rb +9 -0
- data/lib/page-object/elements/text_field.rb +10 -0
- data/lib/page-object/elements/unordered_list.rb +42 -0
- data/lib/page-object/elements/video.rb +9 -0
- data/lib/page-object/elements.rb +62 -0
- data/lib/page-object/indexed_properties.rb +41 -0
- data/lib/page-object/javascript/angularjs.rb +14 -0
- data/lib/page-object/javascript/jquery.rb +14 -0
- data/lib/page-object/javascript/prototype.rb +14 -0
- data/lib/page-object/javascript/yui.rb +19 -0
- data/lib/page-object/javascript_framework_facade.rb +80 -0
- data/lib/page-object/locator_generator.rb +183 -0
- data/lib/page-object/nested_elements.rb +17 -0
- data/lib/page-object/page_factory.rb +108 -0
- data/lib/page-object/page_populator.rb +105 -0
- data/lib/page-object/platforms/watir/page_object.rb +1155 -0
- data/lib/page-object/platforms/watir.rb +50 -0
- data/lib/page-object/section_collection.rb +16 -0
- data/lib/page-object/version.rb +4 -0
- data/lib/page-object/widgets.rb +98 -0
- data/lib/page-object.rb +431 -0
- data/pageobject.gems +1 -0
- metadata +239 -0
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'page-object/locator_generator'
|
2
|
+
|
3
|
+
module PageObject
|
4
|
+
module ElementLocators
|
5
|
+
|
6
|
+
def self.included(cls)
|
7
|
+
::PageObject::LocatorGenerator.generate_locators(cls)
|
8
|
+
end
|
9
|
+
|
10
|
+
def element(tag, identifier={:index => 0})
|
11
|
+
platform.element_for(tag, identifier.clone)
|
12
|
+
end
|
13
|
+
|
14
|
+
private
|
15
|
+
|
16
|
+
def locator(identifier)
|
17
|
+
identifier[0] ? identifier[0] : {:index => 0}
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module PageObject
|
2
|
+
module Elements
|
3
|
+
class Button < Element
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
::PageObject::Elements.type_to_class[:submit] = ::PageObject::Elements::Button
|
8
|
+
::PageObject::Elements.type_to_class[:image] = ::PageObject::Elements::Button
|
9
|
+
::PageObject::Elements.type_to_class[:button] = ::PageObject::Elements::Button
|
10
|
+
::PageObject::Elements.type_to_class[:reset] = ::PageObject::Elements::Button
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,212 @@
|
|
1
|
+
require 'page-object/nested_elements'
|
2
|
+
|
3
|
+
module PageObject
|
4
|
+
module Elements
|
5
|
+
#
|
6
|
+
# Contains functionality that is common across all elements.
|
7
|
+
#
|
8
|
+
# @see PageObject::Platforms::Watir::Element for the Watir version of all common methods
|
9
|
+
#
|
10
|
+
class Element
|
11
|
+
include ::PageObject::NestedElements
|
12
|
+
|
13
|
+
attr_reader :element
|
14
|
+
|
15
|
+
def initialize(element)
|
16
|
+
@element = element
|
17
|
+
@platform = PageObject::Platforms::Watir::PageObject.new(@element)
|
18
|
+
end
|
19
|
+
|
20
|
+
#
|
21
|
+
# return true if the element is not enabled
|
22
|
+
#
|
23
|
+
def disabled?
|
24
|
+
not enabled?
|
25
|
+
end
|
26
|
+
|
27
|
+
#
|
28
|
+
# return true if the element exists and is visible
|
29
|
+
#
|
30
|
+
def present?
|
31
|
+
element.present?
|
32
|
+
end
|
33
|
+
|
34
|
+
def drag_and_drop_on(droppable)
|
35
|
+
droppable_native = droppable.kind_of?(PageObject::Elements::Element) ? droppable.element : droppable
|
36
|
+
element.drag_and_drop_on(droppable_native)
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# specify plural form of element
|
41
|
+
#
|
42
|
+
def self.plural_form
|
43
|
+
"#{self.to_s.split('::')[-1].
|
44
|
+
gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').
|
45
|
+
gsub(/([a-z\d])([A-Z])/, '\1_\2').
|
46
|
+
tr("-", "_").
|
47
|
+
downcase}s"
|
48
|
+
end
|
49
|
+
|
50
|
+
#
|
51
|
+
# Keeps checking until the element is visible
|
52
|
+
#
|
53
|
+
# @param [Integer] (defaults to: 5) seconds to wait before timing out
|
54
|
+
#
|
55
|
+
def check_visible(timeout=::PageObject.default_element_wait)
|
56
|
+
timed_loop(timeout) do |element|
|
57
|
+
element.present?
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
#
|
62
|
+
# Keeps checking until the element exists
|
63
|
+
#
|
64
|
+
# @param [Integer] (defaults to: 5) seconds to wait before timing out
|
65
|
+
#
|
66
|
+
def check_exists(timeout=::PageObject.default_element_wait)
|
67
|
+
timed_loop(timeout) do |element|
|
68
|
+
element.exists?
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
#
|
73
|
+
# compare this element to another to determine if they are equal
|
74
|
+
#
|
75
|
+
def ==(other)
|
76
|
+
other.is_a? self.class and element == other.element
|
77
|
+
end
|
78
|
+
|
79
|
+
#
|
80
|
+
# find the parent element
|
81
|
+
#
|
82
|
+
def parent(opt = {})
|
83
|
+
parent = element.parent(opt)
|
84
|
+
pageobject_wrapper(parent)
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Return the element that exists at the same level of the DOM
|
89
|
+
# immediately prior to this element
|
90
|
+
#
|
91
|
+
def preceding_sibling(opt = {})
|
92
|
+
sibling = element.preceding_sibling(opt)
|
93
|
+
pageobject_wrapper(sibling)
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# Return the element that exists at the same level of the DOM
|
98
|
+
# immediately after this element
|
99
|
+
#
|
100
|
+
def following_sibling(opt={})
|
101
|
+
sibling = element.following_sibling(opt)
|
102
|
+
pageobject_wrapper(sibling)
|
103
|
+
end
|
104
|
+
|
105
|
+
#
|
106
|
+
# Return all elements that are direct children of this element's parent
|
107
|
+
#
|
108
|
+
def siblings(opt={})
|
109
|
+
siblings = element.siblings(opt)
|
110
|
+
siblings.collect {|sibling| pageobject_wrapper(sibling)}
|
111
|
+
end
|
112
|
+
|
113
|
+
#
|
114
|
+
# Return all elements that are children of this element
|
115
|
+
#
|
116
|
+
def children(opt={})
|
117
|
+
children = element.children(opt)
|
118
|
+
children.collect {|child| pageobject_wrapper(child)}
|
119
|
+
end
|
120
|
+
|
121
|
+
#
|
122
|
+
# Return all elements that exist at the same level of the DOM
|
123
|
+
# immediately prior to this element
|
124
|
+
#
|
125
|
+
def preceding_siblings(opt={})
|
126
|
+
siblings = element.preceding_siblings(opt)
|
127
|
+
siblings.collect {|sibling| pageobject_wrapper(sibling)}
|
128
|
+
end
|
129
|
+
|
130
|
+
#
|
131
|
+
# Return all elements that exist at the same level of the DOM
|
132
|
+
# immediately after this element
|
133
|
+
#
|
134
|
+
def following_siblings(opt={})
|
135
|
+
siblings = element.following_siblings(opt)
|
136
|
+
siblings.collect {|sibling| pageobject_wrapper(sibling)}
|
137
|
+
end
|
138
|
+
|
139
|
+
#
|
140
|
+
# Waits until the element is present
|
141
|
+
#
|
142
|
+
# @param [Integer] (defaults to: 5) seconds to wait before timing out
|
143
|
+
#
|
144
|
+
def when_present(timeout=::PageObject.default_element_wait)
|
145
|
+
element.wait_until(timeout: timeout, message: "Element not present in #{timeout} seconds", &:present?)
|
146
|
+
self
|
147
|
+
end
|
148
|
+
alias_method :when_visible, :when_present
|
149
|
+
|
150
|
+
#
|
151
|
+
# Waits until the element is not present
|
152
|
+
#
|
153
|
+
# @param [Integer] (defaults to: 5) seconds to wait before
|
154
|
+
# timing out
|
155
|
+
#
|
156
|
+
def when_not_present(timeout=::PageObject.default_element_wait)
|
157
|
+
element.wait_while(timeout: timeout, message: "Element still present in #{timeout} seconds", &:present?)
|
158
|
+
end
|
159
|
+
alias_method :when_not_visible, :when_not_present
|
160
|
+
|
161
|
+
#
|
162
|
+
# Waits until the block returns true
|
163
|
+
#
|
164
|
+
# @param [Integer] (defaults to: 5) seconds to wait before timing out
|
165
|
+
# @param [String] the message to display if the event timeouts
|
166
|
+
# @param the block to execute when the event occurs
|
167
|
+
#
|
168
|
+
def wait_until(timeout=::PageObject.default_element_wait, message=nil, &block)
|
169
|
+
element.wait_until(timeout: timeout, message: message, &block)
|
170
|
+
end
|
171
|
+
|
172
|
+
def name
|
173
|
+
element.attribute(:name)
|
174
|
+
end
|
175
|
+
|
176
|
+
# @private
|
177
|
+
# delegate calls to driver element
|
178
|
+
def method_missing(method, *args, &block)
|
179
|
+
if element.respond_to?(method)
|
180
|
+
element.send(method, *args, &block)
|
181
|
+
else
|
182
|
+
super
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def respond_to_missing?(m,*args)
|
187
|
+
element.respond_to?(m) || super
|
188
|
+
end
|
189
|
+
|
190
|
+
protected
|
191
|
+
|
192
|
+
def pageobject_wrapper(watir_object)
|
193
|
+
type = element.type if watir_object.tag_name.to_sym == :input
|
194
|
+
cls = ::PageObject::Elements.element_class_for(watir_object.tag_name, type)
|
195
|
+
cls.new(watir_object.to_subtype)
|
196
|
+
end
|
197
|
+
|
198
|
+
private
|
199
|
+
|
200
|
+
def timed_loop(timeout)
|
201
|
+
end_time = ::Time.now + timeout
|
202
|
+
until ::Time.now > end_time
|
203
|
+
result = yield(self)
|
204
|
+
return result if result
|
205
|
+
sleep 0.5
|
206
|
+
end
|
207
|
+
false
|
208
|
+
end
|
209
|
+
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module PageObject
|
2
|
+
module Elements
|
3
|
+
class Heading < Element
|
4
|
+
|
5
|
+
end
|
6
|
+
|
7
|
+
::PageObject::Elements.tag_to_class[:h1] = ::PageObject::Elements::Heading
|
8
|
+
::PageObject::Elements.tag_to_class[:h2] = ::PageObject::Elements::Heading
|
9
|
+
::PageObject::Elements.tag_to_class[:h3] = ::PageObject::Elements::Heading
|
10
|
+
::PageObject::Elements.tag_to_class[:h4] = ::PageObject::Elements::Heading
|
11
|
+
::PageObject::Elements.tag_to_class[:h5] = ::PageObject::Elements::Heading
|
12
|
+
::PageObject::Elements.tag_to_class[:h6] = ::PageObject::Elements::Heading
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
|
2
|
+
module PageObject
|
3
|
+
module Elements
|
4
|
+
class OrderedList < Element
|
5
|
+
include Enumerable
|
6
|
+
|
7
|
+
#
|
8
|
+
# iterator that yields with a PageObject::Elements::ListItem
|
9
|
+
#
|
10
|
+
# @return [PageObject::Elements::ListItem]
|
11
|
+
#
|
12
|
+
def each(&block)
|
13
|
+
list_items.each(&block)
|
14
|
+
end
|
15
|
+
|
16
|
+
#
|
17
|
+
# Return the PageObject::Elements::ListItem for the index provided. Index
|
18
|
+
# is zero based.
|
19
|
+
#
|
20
|
+
# @return [PageObject::Elements::ListItem]
|
21
|
+
#
|
22
|
+
def [](idx)
|
23
|
+
list_items[idx]
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Return the number of items contained in the ordered list
|
28
|
+
#
|
29
|
+
def items
|
30
|
+
list_items.size
|
31
|
+
end
|
32
|
+
|
33
|
+
#
|
34
|
+
# Return Array of ListItem objects that are children of the OrderedList
|
35
|
+
#
|
36
|
+
def list_items
|
37
|
+
@list_items ||= children(tag_name: 'li')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
::PageObject::Elements.tag_to_class[:ol] = ::PageObject::Elements::OrderedList
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module PageObject
|
2
|
+
module Elements
|
3
|
+
class SelectList < Element
|
4
|
+
|
5
|
+
#
|
6
|
+
# Return the PageObject::Elements::Option for the index provided. Index
|
7
|
+
# is zero based.
|
8
|
+
#
|
9
|
+
# @return [PageObject::Elements::Option]
|
10
|
+
#
|
11
|
+
def [](idx)
|
12
|
+
options[idx]
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Return an array of Options contained in the select list.
|
17
|
+
#
|
18
|
+
# @return [array of PageObject::Elements::Option]
|
19
|
+
#
|
20
|
+
def options
|
21
|
+
element.options.map { |e| PageObject::Elements::Option.new(e) }
|
22
|
+
end
|
23
|
+
|
24
|
+
#
|
25
|
+
# @return [Array<String>] An array of strings representing the text of the currently selected options.
|
26
|
+
#
|
27
|
+
def selected_options
|
28
|
+
element.selected_options.map(&:text).compact
|
29
|
+
end
|
30
|
+
|
31
|
+
#
|
32
|
+
# @return [Array<String>] An array of strings representing the value of the currently selected options.
|
33
|
+
#
|
34
|
+
def selected_values
|
35
|
+
element.selected_options.map(&:value).compact
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
::PageObject::Elements.tag_to_class[:select] = ::PageObject::Elements::SelectList
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module PageObject
|
2
|
+
module Elements
|
3
|
+
class Table < Element
|
4
|
+
include Enumerable
|
5
|
+
|
6
|
+
#
|
7
|
+
# iterator that yields with a PageObject::Elements::TableRow
|
8
|
+
#
|
9
|
+
# @return [PageObject::Elements::TableRow]
|
10
|
+
#
|
11
|
+
def each(&block)
|
12
|
+
row_items.each(&block)
|
13
|
+
end
|
14
|
+
|
15
|
+
alias_method :first_row, :first
|
16
|
+
|
17
|
+
#
|
18
|
+
# return the last row
|
19
|
+
#
|
20
|
+
# @return PageObject::Elements::TableRow
|
21
|
+
#
|
22
|
+
def last_row
|
23
|
+
self[-1]
|
24
|
+
end
|
25
|
+
|
26
|
+
#
|
27
|
+
# Return the PageObject::Elements::TableRow for the index provided. Index
|
28
|
+
# is zero based. If the index provided is a String then it
|
29
|
+
# will be matched with the text from any column. The text can be a substring of the full column text.
|
30
|
+
#
|
31
|
+
# @return [PageObject::Elements::TableRow]
|
32
|
+
#
|
33
|
+
def [](what)
|
34
|
+
idx = find_index(what)
|
35
|
+
idx && row_items[idx]
|
36
|
+
end
|
37
|
+
|
38
|
+
#
|
39
|
+
# Returns the number of rows in the table.
|
40
|
+
#
|
41
|
+
def rows
|
42
|
+
row_items.size
|
43
|
+
end
|
44
|
+
|
45
|
+
#
|
46
|
+
# Returns the Array of values(String) in a column for the index provided. Index
|
47
|
+
# is zero based. If the index provided is a String then it
|
48
|
+
# will be matched with the text from the header. The text can be a substring of the full header text.
|
49
|
+
#
|
50
|
+
def column_values(what)
|
51
|
+
idx = find_index_of_header(what)
|
52
|
+
idx && row_items.drop(1).collect { |row| row.cell(index: idx).text }
|
53
|
+
end
|
54
|
+
|
55
|
+
protected
|
56
|
+
|
57
|
+
def row_items
|
58
|
+
meth = strategy == :descendants ? :trs : :rows
|
59
|
+
@row_items ||= element.send(meth).map do |obj|
|
60
|
+
::PageObject::Elements::TableRow.new(obj)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def strategy
|
65
|
+
:children
|
66
|
+
end
|
67
|
+
|
68
|
+
def find_index_of_header(what)
|
69
|
+
return what if what.is_a? Integer
|
70
|
+
row_items[0].cells.find_index do |cell|
|
71
|
+
cell.text.include? Regexp.escape(what)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def find_index(what)
|
76
|
+
return what if what.is_a? Integer
|
77
|
+
row_items.find_index do |row|
|
78
|
+
row.cell(text: /#{Regexp.escape(what)}/).exist?
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
::PageObject::Elements.tag_to_class[:table] = ::PageObject::Elements::Table
|
84
|
+
end
|
85
|
+
end
|