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.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +8 -0
  4. data/.rspec +2 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +17 -0
  8. data/ChangeLog +931 -0
  9. data/Gemfile +12 -0
  10. data/Guardfile +20 -0
  11. data/LICENSE +20 -0
  12. data/README.md +114 -0
  13. data/Rakefile +29 -0
  14. data/centric_page_object.gemspec +31 -0
  15. data/cucumber.yml +8 -0
  16. data/lib/page-object/accessors.rb +1201 -0
  17. data/lib/page-object/element_locators.rb +21 -0
  18. data/lib/page-object/elements/area.rb +9 -0
  19. data/lib/page-object/elements/audio.rb +9 -0
  20. data/lib/page-object/elements/bold.rb +9 -0
  21. data/lib/page-object/elements/button.rb +12 -0
  22. data/lib/page-object/elements/canvas.rb +10 -0
  23. data/lib/page-object/elements/check_box.rb +9 -0
  24. data/lib/page-object/elements/date_field.rb +10 -0
  25. data/lib/page-object/elements/div.rb +9 -0
  26. data/lib/page-object/elements/element.rb +212 -0
  27. data/lib/page-object/elements/file_field.rb +9 -0
  28. data/lib/page-object/elements/form.rb +9 -0
  29. data/lib/page-object/elements/heading.rb +14 -0
  30. data/lib/page-object/elements/hidden_field.rb +9 -0
  31. data/lib/page-object/elements/image.rb +10 -0
  32. data/lib/page-object/elements/italic.rb +9 -0
  33. data/lib/page-object/elements/label.rb +9 -0
  34. data/lib/page-object/elements/link.rb +9 -0
  35. data/lib/page-object/elements/list_item.rb +9 -0
  36. data/lib/page-object/elements/media.rb +11 -0
  37. data/lib/page-object/elements/option.rb +9 -0
  38. data/lib/page-object/elements/ordered_list.rb +43 -0
  39. data/lib/page-object/elements/paragraph.rb +9 -0
  40. data/lib/page-object/elements/radio_button.rb +9 -0
  41. data/lib/page-object/elements/select_list.rb +42 -0
  42. data/lib/page-object/elements/span.rb +9 -0
  43. data/lib/page-object/elements/table.rb +85 -0
  44. data/lib/page-object/elements/table_cell.rb +10 -0
  45. data/lib/page-object/elements/table_row.rb +52 -0
  46. data/lib/page-object/elements/text_area.rb +9 -0
  47. data/lib/page-object/elements/text_field.rb +10 -0
  48. data/lib/page-object/elements/unordered_list.rb +42 -0
  49. data/lib/page-object/elements/video.rb +9 -0
  50. data/lib/page-object/elements.rb +62 -0
  51. data/lib/page-object/indexed_properties.rb +41 -0
  52. data/lib/page-object/javascript/angularjs.rb +14 -0
  53. data/lib/page-object/javascript/jquery.rb +14 -0
  54. data/lib/page-object/javascript/prototype.rb +14 -0
  55. data/lib/page-object/javascript/yui.rb +19 -0
  56. data/lib/page-object/javascript_framework_facade.rb +80 -0
  57. data/lib/page-object/locator_generator.rb +183 -0
  58. data/lib/page-object/nested_elements.rb +17 -0
  59. data/lib/page-object/page_factory.rb +108 -0
  60. data/lib/page-object/page_populator.rb +105 -0
  61. data/lib/page-object/platforms/watir/page_object.rb +1155 -0
  62. data/lib/page-object/platforms/watir.rb +50 -0
  63. data/lib/page-object/section_collection.rb +16 -0
  64. data/lib/page-object/version.rb +4 -0
  65. data/lib/page-object/widgets.rb +98 -0
  66. data/lib/page-object.rb +431 -0
  67. data/pageobject.gems +1 -0
  68. metadata +239 -0
@@ -0,0 +1,52 @@
1
+ require 'watir/elements/html_elements'
2
+
3
+ module PageObject
4
+ module Elements
5
+ class TableRow < Element
6
+ include Enumerable
7
+
8
+ #
9
+ # iterator that yields with a PageObject::Elements::TableCell
10
+ #
11
+ def each(&block)
12
+ cell_items.each(&block)
13
+ end
14
+
15
+ #
16
+ # Return the PageObject::Elements::TableCell for the index provided. Index
17
+ # is zero based. If the index provided is a String then it
18
+ # will be matched with the text from the columns in the first row.
19
+ # The text can be a substring of the full column text.
20
+ #
21
+ def [](what)
22
+ idx = find_index(what)
23
+ idx && cell_items[idx]
24
+ end
25
+
26
+ #
27
+ # Returns the number of columns in the table.
28
+ #
29
+ def columns
30
+ cell_items.size
31
+ end
32
+
33
+ protected
34
+
35
+ def cell_items
36
+ @cell_items ||= element.cells.map do |obj|
37
+ ::PageObject::Elements::TableCell.new(obj)
38
+ end
39
+ end
40
+
41
+ def find_index(what)
42
+ return what if what.is_a? Integer
43
+
44
+ parent(tag_name: 'table').headers.find_index do |header|
45
+ header.text.include? what
46
+ end
47
+ end
48
+ end
49
+
50
+ ::PageObject::Elements.tag_to_class[:tr] = ::PageObject::Elements::TableRow
51
+ end
52
+ end
@@ -0,0 +1,9 @@
1
+ module PageObject
2
+ module Elements
3
+ class TextArea < Element
4
+
5
+ end
6
+
7
+ ::PageObject::Elements.tag_to_class[:textarea] = ::PageObject::Elements::TextArea
8
+ end
9
+ end
@@ -0,0 +1,10 @@
1
+ module PageObject
2
+ module Elements
3
+ class TextField < Element
4
+
5
+ end
6
+
7
+ ::PageObject::Elements.type_to_class[:text] = ::PageObject::Elements::TextField
8
+ ::PageObject::Elements.type_to_class[:password] = ::PageObject::Elements::TextField
9
+ end
10
+ end
@@ -0,0 +1,42 @@
1
+ module PageObject
2
+ module Elements
3
+ class UnorderedList < Element
4
+ include Enumerable
5
+
6
+ #
7
+ # iterator that yields with a PageObject::Elements::ListItem
8
+ #
9
+ # @return [PageObject::Elements::ListItem]
10
+ #
11
+ def each(&block)
12
+ list_items.each(&block)
13
+ end
14
+
15
+ #
16
+ # Return the PageObject::Elements::ListItem for the index provided. Index
17
+ # is zero based.
18
+ #
19
+ # @return [PageObject::Elements::ListItem]
20
+ #
21
+ def [](idx)
22
+ list_items[idx]
23
+ end
24
+
25
+ #
26
+ # Return the number of items contained in the unordered list
27
+ #
28
+ def items
29
+ list_items.size
30
+ end
31
+
32
+ #
33
+ # Return Array of ListItem objects that are children of the UnorderedList
34
+ #
35
+ def list_items
36
+ @list_items ||= children(tag_name: 'li')
37
+ end
38
+ end
39
+
40
+ ::PageObject::Elements.tag_to_class[:ul] = ::PageObject::Elements::UnorderedList
41
+ end
42
+ end
@@ -0,0 +1,9 @@
1
+ module PageObject
2
+ module Elements
3
+ class Video < Media
4
+
5
+ end
6
+
7
+ ::PageObject::Elements.type_to_class[:video] = ::PageObject::Elements::Video
8
+ end
9
+ end
@@ -0,0 +1,62 @@
1
+ module PageObject
2
+ module Elements
3
+ class << self
4
+
5
+ #
6
+ # method to return the collection of tag_name to class mappings
7
+ #
8
+ def tag_to_class
9
+ @tag_to_class ||= {}
10
+ end
11
+
12
+ def type_to_class
13
+ @type_to_class ||= {}
14
+ end
15
+
16
+ #
17
+ # method to return the element for a tag_name
18
+ #
19
+ def element_class_for(tag_name, type=nil)
20
+ return type_to_class[type.to_sym] if type
21
+ tag_to_class[tag_name.to_sym] || ::PageObject::Elements::Element
22
+ end
23
+
24
+ end
25
+ end
26
+ end
27
+
28
+
29
+ require 'page-object/elements/element'
30
+ require 'page-object/elements/link'
31
+ require 'page-object/elements/text_field'
32
+ require 'page-object/elements/date_field'
33
+ require 'page-object/elements/select_list'
34
+ require 'page-object/elements/check_box'
35
+ require 'page-object/elements/button'
36
+ require 'page-object/elements/radio_button'
37
+ require 'page-object/elements/div'
38
+ require 'page-object/elements/table'
39
+ require 'page-object/elements/table_cell'
40
+ require 'page-object/elements/table_row'
41
+ require 'page-object/elements/span'
42
+ require 'page-object/elements/image'
43
+ require 'page-object/elements/hidden_field'
44
+ require 'page-object/elements/form'
45
+ require 'page-object/elements/text_area'
46
+ require 'page-object/elements/list_item'
47
+ require 'page-object/elements/unordered_list'
48
+ require 'page-object/elements/ordered_list'
49
+ require 'page-object/elements/option'
50
+ require 'page-object/elements/heading'
51
+ require 'page-object/elements/paragraph'
52
+ require 'page-object/elements/label'
53
+ require 'page-object/elements/file_field'
54
+ require 'page-object/elements/area'
55
+ require 'page-object/elements/canvas'
56
+ require 'page-object/elements/media'
57
+ require 'page-object/elements/audio'
58
+ require 'page-object/elements/video'
59
+ require 'page-object/elements/bold'
60
+ require 'page-object/elements/italic'
61
+
62
+
@@ -0,0 +1,41 @@
1
+ module PageObject
2
+ module IndexedProperties
3
+ class TableOfElements
4
+ include PageObject
5
+
6
+ def initialize (browser, identifier_list)
7
+ initialize_browser(browser)
8
+ @identifier_list = identifier_list
9
+ @indexed_property_class = Class.new {
10
+ include PageObject
11
+ extend Accessors
12
+
13
+ def initialize (browser, index, identifier_list)
14
+ initialize_browser(browser)
15
+
16
+ identifier_list.each do |identifier|
17
+ type = identifier[0]
18
+ name = identifier[1]
19
+ how_and_what = identifier[2].clone # Cannot modify the original...
20
+ how_and_what.each do |key, value|
21
+ next if value.is_a? Regexp # Cannot format Regexp with %
22
+ if key == :index
23
+ how_and_what[key] = (value % index).to_i
24
+ elsif key == :frame
25
+ how_and_what[key] = value #passthrough frame without modification
26
+ else
27
+ how_and_what[key] = value % index
28
+ end
29
+ end
30
+ self.class.send type, name, how_and_what unless Class.instance_methods.include? name
31
+ end
32
+ end
33
+ }
34
+ end
35
+
36
+ def [] (index)
37
+ @indexed_property_class.new(@browser, index, @identifier_list)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,14 @@
1
+ module PageObject
2
+ module Javascript
3
+
4
+ module AngularJS
5
+ #
6
+ # return the number of pending ajax requests
7
+ #
8
+ def self.pending_requests
9
+ 'return angular.element(document.body).injector().get(\'$http\').pendingRequests.length;'
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module PageObject
2
+ module Javascript
3
+
4
+ module JQuery
5
+ #
6
+ # return the number of pending ajax requests
7
+ #
8
+ def self.pending_requests
9
+ 'return jQuery.active'
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module PageObject
2
+ module Javascript
3
+
4
+ module Prototype
5
+ #
6
+ # return the number of pending ajax requests
7
+ #
8
+ def self.pending_requests
9
+ 'return Ajax.activeRequestCount'
10
+ end
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,19 @@
1
+ module PageObject
2
+ module Javascript
3
+
4
+ module YUI
5
+ #
6
+ # return the number of pending ajax requests
7
+ #
8
+ def self.pending_requests
9
+ "var inProgress=0
10
+ for(var i=0; i < YAHOO.util.Connect._transaction_id; i++) {
11
+ if(YAHOO.util.Connect.isCallInProgress(i))
12
+ inProgress++;
13
+ }
14
+ return inProgress;"
15
+ end
16
+ end
17
+
18
+ end
19
+ end
@@ -0,0 +1,80 @@
1
+ require 'page-object/javascript/jquery'
2
+ require 'page-object/javascript/prototype'
3
+ require 'page-object/javascript/yui'
4
+ require 'page-object/javascript/angularjs'
5
+
6
+
7
+ module PageObject
8
+ #
9
+ # Provide hooks into different common Javascript Frameworks.
10
+ # Currently this module only supports jQuery and Prototype but it
11
+ # has the ability for you to plug your own framework into it and
12
+ # therefore have it work with this gem. You do this by calling the
13
+ # #add_framework method. The module you provide must implement the
14
+ # necessary methods. Please look at the jQuery or Prototype
15
+ # implementations to determine the necessary methods
16
+ #
17
+ module JavascriptFrameworkFacade
18
+
19
+ class << self
20
+ #
21
+ # Set the framework to use.
22
+ #
23
+ # @param[Symbol] the framework to use. :jquery, :prototype, :yui,
24
+ # and :angularjs are supported
25
+ #
26
+ def framework=(framework)
27
+ initialize_script_builder unless @builder
28
+ raise unknown_framework(framework) unless @builder[framework]
29
+ @framework = framework
30
+ end
31
+
32
+ #
33
+ # Get the framework that will be used
34
+ #
35
+ def framework
36
+ @framework
37
+ end
38
+
39
+ #
40
+ # Add a framework and make it available to the system.
41
+ #
42
+ def add_framework(key, value)
43
+ raise invalid_framework unless value.respond_to? :pending_requests
44
+ initialize_script_builder unless @builder
45
+ @builder[key] = value
46
+ end
47
+
48
+ #
49
+ # get the javascript to determine number of pending requests
50
+ #
51
+ def pending_requests
52
+ script_builder.pending_requests
53
+ end
54
+
55
+ def script_builder
56
+ initialize_script_builder unless @builder
57
+ @builder[@framework]
58
+ end
59
+
60
+ private
61
+
62
+ def initialize_script_builder
63
+ @builder = {
64
+ :jquery => ::PageObject::Javascript::JQuery,
65
+ :prototype => ::PageObject::Javascript::Prototype,
66
+ :yui => ::PageObject::Javascript::YUI,
67
+ :angularjs => ::PageObject::Javascript::AngularJS
68
+ }
69
+ end
70
+
71
+ def unknown_framework(framework)
72
+ "You specified the Javascript framework #{framework} and it is unknown to the system"
73
+ end
74
+
75
+ def invalid_framework
76
+ "The Javascript framework you provided does not implement the necessary methods"
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,183 @@
1
+ module PageObject
2
+ module LocatorGenerator
3
+
4
+ BASIC_ELEMENTS = %i(
5
+ abbr
6
+ address
7
+ animate
8
+ animate_motion
9
+ animate_transform
10
+ article
11
+ as
12
+ aside
13
+ base
14
+ bdi
15
+ bdo
16
+ blockquote
17
+ body
18
+ br
19
+ caption
20
+ circle
21
+ cite
22
+ code
23
+ col
24
+ colgroup
25
+ command
26
+ cursor
27
+ data
28
+ datalist
29
+ dd
30
+ defs
31
+ del
32
+ desc
33
+ details
34
+ dfn
35
+ dialog
36
+ discard
37
+ dl
38
+ dt
39
+ ellipse
40
+ em
41
+ embed
42
+ fieldset
43
+ figcaption
44
+ figure
45
+ font
46
+ footer
47
+ foreign_object
48
+ g
49
+ head
50
+ header
51
+ hgroup
52
+ hr
53
+ html
54
+ ins
55
+ kbd
56
+ keygen
57
+ legend
58
+ line
59
+ linear_gradient
60
+ main
61
+ map
62
+ mark
63
+ marker
64
+ menu
65
+ menuitem
66
+ mesh_gradient
67
+ mesh_patch
68
+ mesh_row
69
+ meta
70
+ metadata
71
+ meter
72
+ mpath
73
+ nav
74
+ noscript
75
+ object
76
+ optgroup
77
+ output
78
+ p
79
+ param
80
+ path
81
+ pattern
82
+ polygon
83
+ polyline
84
+ pre
85
+ progress
86
+ q
87
+ radial_gradient
88
+ rect
89
+ rp
90
+ rt
91
+ ruby
92
+ s
93
+ samp
94
+ script
95
+ section
96
+ set
97
+ small
98
+ source
99
+ stop
100
+ strong
101
+ style
102
+ sub
103
+ summary
104
+ sup
105
+ switch
106
+ symbol
107
+ template
108
+ text_path
109
+ thread
110
+ time
111
+ title
112
+ track
113
+ tspan
114
+ u
115
+ use
116
+ var
117
+ view
118
+ wbr
119
+ )
120
+
121
+
122
+ ADVANCED_ELEMENTS = %i(
123
+ text_field
124
+ date_field
125
+ hidden_field
126
+ text_area
127
+ select_list
128
+ link
129
+ checkbox
130
+ radio_button
131
+ button
132
+ div
133
+ span
134
+ table
135
+ cell
136
+ row
137
+ image
138
+ form
139
+ list_item
140
+ ordered_list
141
+ unordered_list
142
+ h1
143
+ h2
144
+ h3
145
+ h4
146
+ h5
147
+ h6
148
+ paragraph
149
+ label
150
+ file_field
151
+ area
152
+ canvas
153
+ audio
154
+ video
155
+ b
156
+ i
157
+ svg
158
+ )
159
+
160
+ def self.generate_locators(target)
161
+ ADVANCED_ELEMENTS.each do |tag|
162
+ target.send(:define_method, "#{tag.to_s}_element") do |*identifier|
163
+ @platform.send "#{tag.to_s}_for", locator(identifier)
164
+ end
165
+
166
+ target.send(:define_method, "#{tag.to_s}_elements") do |*identifier|
167
+ @platform.send("#{tag.to_s}s_for", identifier[0] ? identifier[0] : {})
168
+ end
169
+ end
170
+
171
+ BASIC_ELEMENTS.each do |tag|
172
+ target.send(:define_method, "#{tag.to_s}_element") do |*identifier|
173
+ @platform.send :element_for, tag, locator(identifier)
174
+ end
175
+
176
+ target.send(:define_method, "#{tag.to_s}_elements") do |*identifier|
177
+ @platform.send(:elements_for, tag, identifier[0] ? identifier[0] : {})
178
+ end
179
+ end
180
+ end
181
+
182
+ end
183
+ end
@@ -0,0 +1,17 @@
1
+ require 'page-object/locator_generator'
2
+
3
+ module PageObject
4
+ module NestedElements
5
+
6
+ def self.included(cls)
7
+ ::PageObject::LocatorGenerator.generate_locators(cls)
8
+ end
9
+
10
+ private
11
+
12
+ def locator(identifier)
13
+ identifier[0] ? identifier[0] : {:index => 0}
14
+ end
15
+
16
+ end
17
+ end
@@ -0,0 +1,108 @@
1
+ require 'page_navigation'
2
+
3
+ module PageObject
4
+ #
5
+ # Module to facilitate to creating of page objects in step definitions. You
6
+ # can make the methods below available to all of your step definitions by adding
7
+ # this module to World. This idea was first discussed in Alister Scott's blog
8
+ # entry http://watirmelon.com/2011/06/07/removing-local-page-references-from-cucumber-steps/.
9
+ #
10
+ # @example Making the PageFactory available to your step definitions
11
+ # World PageObject::PageFactory
12
+ #
13
+ # @example Visiting a page for the first time in a Scenario
14
+ # visit_page MyPageObject do |page|
15
+ # page.name = 'Cheezy'
16
+ # end
17
+ #
18
+ # @example using a page that has already been visited in a Scenario
19
+ # on_page MyPageObject do |page|
20
+ # page.name.should == 'Cheezy'
21
+ # end
22
+ #
23
+ # If you plan to use the navigate_to method you will need to ensure
24
+ # you setup the possible routes ahead of time. You must always have
25
+ # a default route in order for this to work. Here is an example of
26
+ # how you define routes:
27
+ #
28
+ # @example Example routes defined in env.rb
29
+ # PageObject::PageFactory.routes = {
30
+ # :default => [[PageOne,:method1], [PageTwoA,:method2], [PageThree,:method3]],
31
+ # :another_route => [[PageOne,:method1, "arg1"], [PageTwoB,:method2b], [PageThree,:method3]]
32
+ # }
33
+ #
34
+ # Notice the first entry of :another_route is passing an argument
35
+ # to the method.
36
+ #
37
+ module PageFactory
38
+ include PageNavigation
39
+
40
+
41
+ #
42
+ # Create and navigate to a page object. The navigation will only work if the
43
+ # 'page_url' method was call on the page object.
44
+ #
45
+ # @param [PageObject, String] a class that has included the
46
+ # PageObject module or a string containing the name of the class
47
+ # @param Hash values that is pass through to page class a
48
+ # available in the @params instance variable.
49
+ # @param an optional block to be called
50
+ # @return [PageObject] the newly created page object
51
+ #
52
+ def visit_page(page_class, params={:using_params => {}}, &block)
53
+ on_page page_class, params, true, &block
54
+ end
55
+
56
+ # Support 'visit' for readability of usage
57
+ alias_method :visit, :visit_page
58
+
59
+ #
60
+ # Create a page object.
61
+ #
62
+ # @param [PageObject, String] a class that has included the PageObject module or a string containing the name of the class
63
+ # @param Hash values that is pass through to page class a
64
+ # available in the @params instance variable.
65
+ # @param [Boolean] a boolean indicating if the page should be visited? default is false.
66
+ # @param [block] an optional block to be called
67
+ # @return [PageObject] the newly created page object
68
+ #
69
+ def on_page(page_class, params={:using_params => {}}, visit=false, &block)
70
+ page_class = class_from_string(page_class) if page_class.is_a? String
71
+ return super(page_class, params, visit, &block) unless page_class.ancestors.include? PageObject
72
+ merged = page_class.params.merge(params[:using_params])
73
+ page_class.instance_variable_set("@merged_params", merged) unless merged.empty?
74
+ @current_page = page_class.new(@browser, visit)
75
+ block.call @current_page if block
76
+ @current_page
77
+ end
78
+
79
+ # Support 'on' for readability of usage
80
+ alias_method :on, :on_page
81
+
82
+ #
83
+ # Create a page object if and only if the current page is the same page to be created
84
+ #
85
+ # @param [PageObject, String] a class that has included the PageObject module or a string containing the name of the class
86
+ # @param Hash values that is pass through to page class a
87
+ # available in the @params instance variable.
88
+ # @param [block] an optional block to be called
89
+ # @return [PageObject] the newly created page object
90
+ #
91
+ def if_page(page_class, params={:using_params => {}},&block)
92
+ page_class = class_from_string(page_class) if page_class.is_a? String
93
+ return @current_page unless @current_page.class == page_class
94
+ on_page(page_class, params, false, &block)
95
+ end
96
+
97
+ # Support 'if' for readability of usage
98
+ alias_method :if, :if_page
99
+
100
+ private
101
+
102
+ def class_from_string(str)
103
+ str.split('::').inject(Object) do |mod, class_name|
104
+ mod.const_get(class_name)
105
+ end
106
+ end
107
+ end
108
+ end