page-object 2.0.0 → 2.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.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -2
  3. data/ChangeLog +10 -0
  4. data/README.md +12 -0
  5. data/Rakefile +2 -12
  6. data/cucumber.yml +2 -4
  7. data/lib/page-object.rb +12 -20
  8. data/lib/page-object/accessors.rb +50 -363
  9. data/lib/page-object/elements/bold.rb +0 -1
  10. data/lib/page-object/elements/button.rb +0 -4
  11. data/lib/page-object/elements/check_box.rb +19 -7
  12. data/lib/page-object/elements/div.rb +0 -4
  13. data/lib/page-object/elements/element.rb +159 -90
  14. data/lib/page-object/elements/file_field.rb +5 -7
  15. data/lib/page-object/elements/form.rb +0 -8
  16. data/lib/page-object/elements/hidden_field.rb +1 -4
  17. data/lib/page-object/elements/image.rb +13 -7
  18. data/lib/page-object/elements/label.rb +0 -4
  19. data/lib/page-object/elements/link.rb +0 -13
  20. data/lib/page-object/elements/list_item.rb +0 -3
  21. data/lib/page-object/elements/ordered_list.rb +30 -5
  22. data/lib/page-object/elements/radio_button.rb +12 -7
  23. data/lib/page-object/elements/select_list.rb +40 -8
  24. data/lib/page-object/elements/span.rb +0 -3
  25. data/lib/page-object/elements/table.rb +26 -5
  26. data/lib/page-object/elements/table_cell.rb +0 -4
  27. data/lib/page-object/elements/table_row.rb +30 -5
  28. data/lib/page-object/elements/text_area.rb +7 -7
  29. data/lib/page-object/elements/text_field.rb +5 -11
  30. data/lib/page-object/elements/unordered_list.rb +30 -5
  31. data/lib/page-object/indexed_properties.rb +1 -0
  32. data/lib/page-object/platforms.rb +0 -1
  33. data/lib/page-object/platforms/watir.rb +26 -4
  34. data/lib/page-object/platforms/watir/page_object.rb +4 -4
  35. data/lib/page-object/version.rb +1 -1
  36. data/lib/page-object/widgets.rb +0 -1
  37. data/page-object.gemspec +1 -15
  38. metadata +5 -47
  39. data/lib/page-object/platforms/selenium_webdriver.rb +0 -30
  40. data/lib/page-object/platforms/selenium_webdriver/button.rb +0 -15
  41. data/lib/page-object/platforms/selenium_webdriver/check_box.rb +0 -29
  42. data/lib/page-object/platforms/selenium_webdriver/element.rb +0 -335
  43. data/lib/page-object/platforms/selenium_webdriver/file_field.rb +0 -16
  44. data/lib/page-object/platforms/selenium_webdriver/form.rb +0 -16
  45. data/lib/page-object/platforms/selenium_webdriver/image.rb +0 -28
  46. data/lib/page-object/platforms/selenium_webdriver/link.rb +0 -23
  47. data/lib/page-object/platforms/selenium_webdriver/ordered_list.rb +0 -41
  48. data/lib/page-object/platforms/selenium_webdriver/page_object.rb +0 -1297
  49. data/lib/page-object/platforms/selenium_webdriver/radio_button.rb +0 -22
  50. data/lib/page-object/platforms/selenium_webdriver/select_list.rb +0 -93
  51. data/lib/page-object/platforms/selenium_webdriver/surrogate_selenium_element.rb +0 -42
  52. data/lib/page-object/platforms/selenium_webdriver/table.rb +0 -42
  53. data/lib/page-object/platforms/selenium_webdriver/table_row.rb +0 -43
  54. data/lib/page-object/platforms/selenium_webdriver/text_area.rb +0 -17
  55. data/lib/page-object/platforms/selenium_webdriver/text_field.rb +0 -17
  56. data/lib/page-object/platforms/selenium_webdriver/unordered_list.rb +0 -37
  57. data/lib/page-object/platforms/watir/check_box.rb +0 -29
  58. data/lib/page-object/platforms/watir/element.rb +0 -295
  59. data/lib/page-object/platforms/watir/file_field.rb +0 -16
  60. data/lib/page-object/platforms/watir/form.rb +0 -16
  61. data/lib/page-object/platforms/watir/image.rb +0 -22
  62. data/lib/page-object/platforms/watir/link.rb +0 -15
  63. data/lib/page-object/platforms/watir/ordered_list.rb +0 -40
  64. data/lib/page-object/platforms/watir/radio_button.rb +0 -22
  65. data/lib/page-object/platforms/watir/select_list.rb +0 -74
  66. data/lib/page-object/platforms/watir/table.rb +0 -38
  67. data/lib/page-object/platforms/watir/table_row.rb +0 -37
  68. data/lib/page-object/platforms/watir/text_area.rb +0 -23
  69. data/lib/page-object/platforms/watir/text_field.rb +0 -16
  70. data/lib/page-object/platforms/watir/unordered_list.rb +0 -42
@@ -6,6 +6,5 @@ module PageObject
6
6
 
7
7
  ::PageObject::Elements.tag_to_class[:b] = ::PageObject::Elements::Bold
8
8
 
9
-
10
9
  end
11
10
  end
@@ -14,10 +14,6 @@ module PageObject
14
14
  super + [:text, :value, :src, :alt, :css]
15
15
  end
16
16
 
17
- def self.selenium_finders
18
- super + [:value, :src, :alt]
19
- end
20
-
21
17
  end
22
18
 
23
19
  ::PageObject::Elements.type_to_class[:submit] = ::PageObject::Elements::Button
@@ -2,9 +2,25 @@ module PageObject
2
2
  module Elements
3
3
  class CheckBox < Element
4
4
 
5
- def initialize(element, platform)
6
- @element = element
7
- include_platform_for platform
5
+ #
6
+ # check the checkbox
7
+ #
8
+ def check
9
+ element.set
10
+ end
11
+
12
+ #
13
+ # uncheck the checkbox
14
+ #
15
+ def uncheck
16
+ element.clear
17
+ end
18
+
19
+ #
20
+ # return true if checkbox is checked
21
+ #
22
+ def checked?
23
+ element.set?
8
24
  end
9
25
 
10
26
  protected
@@ -13,10 +29,6 @@ module PageObject
13
29
  super + [:value, :label]
14
30
  end
15
31
 
16
- def self.selenium_finders
17
- super + [:value, :label, :css]
18
- end
19
-
20
32
  end
21
33
 
22
34
  ::PageObject::Elements.type_to_class[:checkbox] = ::PageObject::Elements::CheckBox
@@ -8,10 +8,6 @@ module PageObject
8
8
  super + [:text, :title]
9
9
  end
10
10
 
11
- def self.selenium_finders
12
- super + [:text, :title]
13
- end
14
-
15
11
  end
16
12
 
17
13
  ::PageObject::Elements.tag_to_class[:div] = ::PageObject::Elements::Div
@@ -1,4 +1,5 @@
1
1
  require 'page-object/nested_elements'
2
+ require 'watir/extensions/select_text'
2
3
 
3
4
  module PageObject
4
5
  module Elements
@@ -6,7 +7,6 @@ module PageObject
6
7
  # Contains functionality that is common across all elements.
7
8
  #
8
9
  # @see PageObject::Platforms::WatirWebDriver::Element for the Watir version of all common methods
9
- # @see PageObject::Platforms::SeleniumWebDriver::Element for the Selenium version of all common methods
10
10
  #
11
11
  class Element
12
12
  include ::PageObject::NestedElements
@@ -18,22 +18,6 @@ module PageObject
18
18
  include_platform_for platform
19
19
  end
20
20
 
21
- #
22
- # click the element
23
- #
24
- def click
25
- element.click
26
- end
27
-
28
-
29
-
30
- #
31
- # return true if the element is enabled
32
- #
33
- def enabled?
34
- element.enabled?
35
- end
36
-
37
21
  #
38
22
  # return true if the element is not enabled
39
23
  #
@@ -41,12 +25,6 @@ module PageObject
41
25
  not enabled?
42
26
  end
43
27
 
44
- #
45
- # get the value of the given CSS property
46
- #
47
- def style(property = nil)
48
- element.style property
49
- end
50
28
 
51
29
  def inspect
52
30
  element.inspect
@@ -81,12 +59,169 @@ module PageObject
81
59
  end
82
60
  end
83
61
 
62
+ #
63
+ # Keeps checking until the element exists
64
+ #
65
+ # @param [Integer] (defaults to: 5) seconds to wait before timing out
66
+ #
84
67
  def check_exists(timeout=::PageObject.default_element_wait)
85
68
  timed_loop(timeout) do |element|
86
69
  element.exists?
87
70
  end
88
71
  end
89
72
 
73
+ #
74
+ # return true if an element is visible
75
+ #
76
+ # def visible?
77
+ # element.present?
78
+ # end
79
+
80
+ #
81
+ # compare this element to another to determine if they are equal
82
+ #
83
+ def ==(other)
84
+ other.is_a? self.class and element == other.element
85
+ end
86
+
87
+ #
88
+ # Get the value of a the given attribute of the element. Will
89
+ # return the current value, even if this has been modified
90
+ # after the page has been loaded. More exactly, this method
91
+ # will return the value of the given attribute, unless that
92
+ # attribute is not present, in which case the value of the
93
+ # property with the same name is returned. If neither value is
94
+ # set, nil is returned. The "style" attribute is converted as
95
+ # best can be to a text representation with a trailing
96
+ # semi-colon. The following are deemed to be "boolean"
97
+ # attributes, and will return either "true" or "false":
98
+ #
99
+ # async, autofocus, autoplay, checked, compact, complete,
100
+ # controls, declare, defaultchecked, defaultselected, defer,
101
+ # disabled, draggable, ended, formnovalidate, hidden, indeterminate,
102
+ # iscontenteditable, ismap, itemscope, loop, multiple, muted,
103
+ # nohref, noresize, noshade, novalidate, nowrap, open, paused,
104
+ # pubdate, readonly, required, reversed, scoped, seamless, seeking,
105
+ # selected, spellcheck, truespeed, willvalidate
106
+ #
107
+ # Finally, the following commonly mis-capitalized
108
+ # attribute/property names are evaluated as expected:
109
+ #
110
+ # class, readonly
111
+ #
112
+ # @param [String]
113
+ # attribute name
114
+ # @return [String,nil]
115
+ # attribute value
116
+ #
117
+ def attribute(attribute_name)
118
+ element.attribute_value attribute_name
119
+ end
120
+
121
+ #
122
+ # find the parent element
123
+ #
124
+ def parent
125
+ parent = element.parent
126
+ type = element.type if parent.tag_name.to_sym == :input
127
+ cls = ::PageObject::Elements.element_class_for(parent.tag_name, type)
128
+ cls.new(parent, :platform => :watir)
129
+ end
130
+
131
+ #
132
+ # Waits until the element is present
133
+ #
134
+ # @param [Integer] (defaults to: 5) seconds to wait before timing out
135
+ #
136
+ def when_present(timeout=::PageObject.default_element_wait)
137
+ element.wait_until(timeout: timeout, message: "Element not present in #{timeout} seconds", &:present?)
138
+ self
139
+ end
140
+
141
+ #
142
+ # Waits until the element is not present
143
+ #
144
+ # @param [Integer] (defaults to: 5) seconds to wait before
145
+ # timing out
146
+ #
147
+ def when_not_present(timeout=::PageObject.default_element_wait)
148
+ element.wait_while(timeout: timeout, message: "Element still present in #{timeout} seconds", &:present?)
149
+ end
150
+
151
+ #
152
+ # Waits until the element is visible
153
+ #
154
+ # @param [Integer] (defaults to: 5) seconds to wait before timing out
155
+ #
156
+ def when_visible(timeout=::PageObject.default_element_wait)
157
+ element.wait_until(timeout: timeout, message: "Element not visible in #{timeout} seconds", &:visible?)
158
+ self
159
+ end
160
+
161
+ #
162
+ # Waits until the element is not visible
163
+ #
164
+ # @param [Integer] (defaults to: 5) seconds to wait before timing out
165
+ #
166
+ def when_not_visible(timeout=::PageObject.default_element_wait)
167
+ element.wait_while(timeout: timeout, message: "Element still visible after #{timeout} seconds", &:visible?)
168
+ end
169
+
170
+ #
171
+ # Waits until the block returns true
172
+ #
173
+ # @param [Integer] (defaults to: 5) seconds to wait before timing out
174
+ # @param [String] the message to display if the event timeouts
175
+ # @param the block to execute when the event occurs
176
+ #
177
+ def wait_until(timeout=::PageObject.default_element_wait, message=nil, &block)
178
+ element.wait_until(timeout: timeout, message: message, &block)
179
+ end
180
+
181
+ #
182
+ # Scroll until the element is viewable
183
+ #
184
+ def scroll_into_view
185
+ element.wd.location_once_scrolled_into_view
186
+ end
187
+
188
+ #
189
+ # location of element (x, y)
190
+ #
191
+ def location
192
+ element.wd.location
193
+ end
194
+
195
+ #
196
+ # size of element (width, height)
197
+ #
198
+ def size
199
+ element.wd.size
200
+ end
201
+
202
+ #
203
+ # Get height of element
204
+ #
205
+ def height
206
+ element.wd.size['height']
207
+ end
208
+
209
+ #
210
+ # Get width of element
211
+ #
212
+ def width
213
+ element.wd.size['width']
214
+ end
215
+
216
+ #
217
+ # Get centre coordinates of element
218
+ #
219
+ def centre
220
+ location = element.wd.location
221
+ size = element.wd.size
222
+ {'y' => (location['y'] + (size['height']/2)), 'x' => (location['x'] + (size['width']/2))}
223
+ end
224
+
90
225
  # @private
91
226
  def self.watir_identifier_for identifier
92
227
  if should_build_watir_xpath(identifier)
@@ -103,33 +238,11 @@ module PageObject
103
238
  all_identities
104
239
  end
105
240
 
106
- # @private
107
- def self.selenium_identifier_for identifier
108
- if identifier.length == 1
109
- identifier = identifier_for identifier, selenium_finders, selenium_mapping
110
- return identifier.keys.first, identifier.values.first
111
- elsif identifier.length > 1
112
- how = :xpath
113
- what = build_xpath_for identifier
114
- return how, what
115
- end
116
- end
117
-
118
241
  # @private
119
242
  # delegate calls to driver element
120
243
  def method_missing(*args, &block)
121
244
  m = args.shift
122
- $stderr.puts "*** DEPRECATION WARNING"
123
- $stderr.puts "*** You are calling a method named #{m} at #{caller[0]}."
124
- $stderr.puts "*** This method does not exist in page-object so it is being passed to the driver."
125
- $stderr.puts "*** This feature will be removed in the near future."
126
- $stderr.puts "*** Please change your code to call the correct page-object method."
127
- $stderr.puts "*** If you are using functionality that does not exist in page-object please request it be added."
128
- begin
129
- element.send m, *args, &block
130
- rescue Exception => e
131
- raise
132
- end
245
+ element.send m, *args, &block
133
246
  end
134
247
 
135
248
  protected
@@ -215,14 +328,6 @@ module PageObject
215
328
  {}
216
329
  end
217
330
 
218
- def self.selenium_finders
219
- [:class, :css, :id, :index, :name, :xpath]
220
- end
221
-
222
- def self.selenium_mapping
223
- {}
224
- end
225
-
226
331
  def include_platform_for platform
227
332
  platform_information = PageObject::Platforms.get
228
333
  raise ArgumentError,"Expected hash with at least a key :platform for platform information! (#{platform.inspect})" unless platform.class == Hash && platform.has_key?(:platform)
@@ -231,29 +336,7 @@ module PageObject
231
336
  raise ArgumentError, "Unknown platform #{platform_name}! Expect platform to be one of the following: #{platform_information.keys.inspect}" unless platform_information.keys.include?(platform_name)
232
337
  base_platform_class = "#{platform_information[platform_name]}::"
233
338
 
234
- self.send :extend, constantize_classname(base_platform_class + "Element")
235
339
  @platform = constantize_classname(base_platform_class+ "PageObject").new(@element)
236
-
237
- # include class specific code
238
- class_to_include = case
239
- when self.class == PageObject::Elements::Element
240
- # already loaded
241
- return true
242
- when self.class.name =~/PageObject:Elements::/
243
- self.class
244
- # inherited classes for example the widgets
245
- else
246
- parent_classes = self.class.ancestors.select { |item| item.name =~/PageObject::Elements::/ }
247
- raise RuntimeError,"Could not identify page-object inherited class for #{self.class}!" if parent_classes.empty?
248
- parent_classes.first
249
- end
250
-
251
- element_type_specific_code = File.expand_path(File.dirname(__FILE__) + "../../platforms/#{platform_name}/"+ get_element_type_underscored(class_to_include) )
252
- if File.exist? element_type_specific_code + '.rb'
253
- require element_type_specific_code
254
- self.send :extend, constantize_classname( base_platform_class + get_element_type(class_to_include) )
255
- end
256
-
257
340
  end
258
341
 
259
342
  def to_ary
@@ -276,20 +359,6 @@ module PageObject
276
359
  name.split("::").inject(Object) { |k,n| k.const_get(n) }
277
360
  end
278
361
 
279
-
280
- def get_element_type(class_name = self.class)
281
- class_name.name.split('::').last
282
- end
283
-
284
- # retrieved from ruby on rails underscore method
285
- def get_element_type_underscored(class_name = self.class)
286
- get_element_type(class_name).to_s.gsub(/::/, '/').
287
- gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
288
- gsub(/([a-z\d])([A-Z])/,'\1_\2').
289
- tr("-", "_").
290
- downcase
291
- end
292
-
293
362
  end
294
363
  end
295
364
  end
@@ -3,9 +3,11 @@ module PageObject
3
3
  module Elements
4
4
  class FileField < Element
5
5
 
6
- def initialize(element, platform)
7
- @element = element
8
- include_platform_for platform
6
+ #
7
+ # Set the value of the FileField
8
+ #
9
+ def value=(new_value)
10
+ element.set(new_value)
9
11
  end
10
12
 
11
13
  protected
@@ -14,10 +16,6 @@ module PageObject
14
16
  super + [:title, :label]
15
17
  end
16
18
 
17
- def self.selenium_finders
18
- super + [:title, :label]
19
- end
20
-
21
19
  end
22
20
 
23
21
  ::PageObject::Elements.type_to_class[:file] = ::PageObject::Elements::FileField
@@ -2,10 +2,6 @@
2
2
  module PageObject
3
3
  module Elements
4
4
  class Form < Element
5
- def initialize(element, platform)
6
- @element = element
7
- include_platform_for platform
8
- end
9
5
 
10
6
  protected
11
7
 
@@ -13,10 +9,6 @@ module PageObject
13
9
  super + [:action]
14
10
  end
15
11
 
16
- def self.selenium_finders
17
- super + [:action]
18
- end
19
-
20
12
  end
21
13
 
22
14
  ::PageObject::Elements.tag_to_class[:form] = ::PageObject::Elements::Form
@@ -3,7 +3,7 @@ module PageObject
3
3
  class HiddenField < Element
4
4
 
5
5
  def click
6
- raise "click is not available on hidden field element with Selenium or Watir"
6
+ raise "click is not available on the hidden field element"
7
7
  end
8
8
 
9
9
  protected
@@ -12,9 +12,6 @@ module PageObject
12
12
  super + [:text, :value]
13
13
  end
14
14
 
15
- def self.selenium_finders
16
- super + [:value]
17
- end
18
15
  end
19
16
 
20
17
  ::PageObject::Elements.type_to_class[:hidden] = ::PageObject::Elements::HiddenField