page_object_wrapper 0.0.6 → 1.0.0

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 (43) hide show
  1. data/README.md +180 -340
  2. data/bad_pages/bad_page.rb +34 -0
  3. data/good_pages/another_test_page.rb +14 -0
  4. data/good_pages/some_test_page.rb +53 -0
  5. data/good_pages/test_table_page.rb +12 -0
  6. data/img/scheme.png +0 -0
  7. data/lib/page_object_wrapper.rb +57 -92
  8. data/lib/page_object_wrapper/Action.rb +11 -0
  9. data/lib/page_object_wrapper/Dsl.rb +35 -0
  10. data/lib/page_object_wrapper/Element.rb +15 -0
  11. data/lib/page_object_wrapper/ElementsSet.rb +22 -0
  12. data/lib/page_object_wrapper/Exceptions.rb +7 -21
  13. data/lib/page_object_wrapper/PageObject.rb +371 -0
  14. data/lib/page_object_wrapper/Pagination.rb +6 -57
  15. data/lib/page_object_wrapper/Table.rb +13 -48
  16. data/lib/page_object_wrapper/known_elements.rb +31 -0
  17. data/lib/page_object_wrapper/version.rb +1 -1
  18. data/spec/define_page_object_spec.rb +162 -0
  19. data/spec/defined_elements_spec.rb +77 -0
  20. data/spec/feed_elements_spec.rb +95 -0
  21. data/spec/fire_event_spec.rb +53 -0
  22. data/spec/generate_spec.rb +20 -0
  23. data/spec/load_spec.rb +46 -0
  24. data/spec/open_spec.rb +70 -0
  25. data/spec/select_from_spec.rb +84 -0
  26. data/spec/shared_examples.rb +12 -0
  27. data/spec/spec_helper.rb +2 -15
  28. metadata +35 -27
  29. data/Gemfile +0 -4
  30. data/LICENSE.txt +0 -22
  31. data/Rakefile +0 -1
  32. data/lib/page_object_wrapper/Distribution.rb +0 -43
  33. data/lib/page_object_wrapper/DynamicClass.rb +0 -31
  34. data/lib/page_object_wrapper/Editable.rb +0 -13
  35. data/lib/page_object_wrapper/Form.rb +0 -116
  36. data/lib/page_object_wrapper/Submitter.rb +0 -8
  37. data/page_object_wrapper.gemspec +0 -22
  38. data/spec/example_spec.rb +0 -42
  39. data/spec/form_spec.rb +0 -176
  40. data/spec/page_object_spec.rb +0 -173
  41. data/spec/pagination_spec.rb +0 -14
  42. data/spec/table_spec.rb +0 -52
  43. data/spec/test_data_spec.rb +0 -38
@@ -0,0 +1,34 @@
1
+ require 'page_object_wrapper'
2
+
3
+ PageObjectWrapper.define_page('some_page_with_lost_of_errors') do
4
+ locator ''
5
+ uniq_element 'uniq element locator'
6
+
7
+ elements_set('some elements_set label') do
8
+ end
9
+
10
+ elements_set(:bad_elements) do
11
+ element('') do
12
+ end
13
+ element(:e) do
14
+ locator ':e element locator'
15
+ end
16
+ element(:e) do
17
+ locator Hash.new
18
+ end
19
+ end
20
+
21
+ action('',nil) do
22
+ end
23
+
24
+ table('') do
25
+ end
26
+ table(:some_table) do
27
+ header []
28
+ end
29
+
30
+ pagination('') do
31
+ locator 'pagination locator'
32
+ end
33
+ end
34
+
@@ -0,0 +1,14 @@
1
+ require 'page_object_wrapper'
2
+ PageObjectWrapper.define_page(:another_test_page) do
3
+ locator 'http://www.cs.tut.fi/~jkorpela/www/testel.html'
4
+ uniq_h1 :text => 'Testing display of HTML elements'
5
+
6
+ elements_set(:test_elements) do
7
+ select(:s1) do
8
+ locator :id => 'f10'
9
+ fresh_food 'not in select list'
10
+ missing_food 'not in select list'
11
+ end
12
+ end
13
+ end
14
+
@@ -0,0 +1,53 @@
1
+ require 'page_object_wrapper'
2
+ PageObjectWrapper.define_page(:some_test_page) do
3
+ locator 'http://www.cs.tut.fi/~jkorpela/www/testel.html'
4
+ uniq_h1 :text => 'Testing display of HTML elements'
5
+
6
+ elements_set(:test_elements) do
7
+ text_field(:tf) do
8
+ locator :id => 'f1'
9
+ missing_food 'some missing food'
10
+ fresh_food 'some fresh food'
11
+ end
12
+
13
+ textarea(:ta) do
14
+ locator :id => 'f2'
15
+ end
16
+
17
+ select(:s1) do
18
+ locator :id => 'f10'
19
+ fresh_food 'one'
20
+ missing_food 'three'
21
+ end
22
+
23
+ select(:s2) do
24
+ locator :id => 'f11'
25
+ fresh_food 'one'
26
+ end
27
+
28
+ checkbox(:cb){ locator :id => 'f5' }
29
+ radio(:rb){ locator :id => 'f3' }
30
+ end
31
+
32
+ action(:press_cool_button, :test_page_with_table) do
33
+ button(:name => 'foo').when_present.click
34
+ end
35
+
36
+ action(:fill_textarea, :some_test_page) do |fill_with|
37
+ data = (fill_with.empty?)? 'Default data' : fill_with
38
+ textarea(:id => 'f2').set data
39
+ end
40
+
41
+ table(:table_without_header) do
42
+ locator :summary => 'Each row names a Nordic country and specifies its total area and land area, in square kilometers'
43
+ end
44
+
45
+ table(:table_with_header) do
46
+ locator :summary => 'Each row names a Nordic country and specifies its total area and land area, in square kilometers'
47
+ header [:country, :total_area, :land_area]
48
+ end
49
+
50
+ pagination(:some_pagination) do
51
+ locator :xpath => ''
52
+ end
53
+ end
@@ -0,0 +1,12 @@
1
+ require 'page_object_wrapper'
2
+ PageObjectWrapper.define_page(:test_page_with_table) do
3
+ locator 'http://www.cs.tut.fi/cgi-bin/run/~jkorpela/echo.cgi?hidden+field=42&foo=bar&text=Default+text.&textarea=Default+text.%0D%0A&radio=2&checkbox2=on&select1=two+%28default%29&select2=two+%28default%29'
4
+ uniq_h1 :text => 'Echoing submitted form data'
5
+
6
+ table(:test_table) do
7
+ locator :index => 0
8
+ end
9
+
10
+ elements_set(:empty_set) do
11
+ end
12
+ end
Binary file
@@ -1,99 +1,64 @@
1
1
  # -*- encoding : utf-8 -*-
2
2
  require "watir-webdriver"
3
3
  require "version"
4
- require 'Exceptions'
5
- require 'Form'
6
- require 'Table'
7
- require 'Pagination'
8
- require 'DynamicClass'
4
+ require 'PageObject'
9
5
 
10
6
  module PageObjectWrapper
11
7
 
12
- class TestData < DynamicClass; end
13
-
14
- def self.start_browser b=nil
15
- Page.accessor = (b.nil?)? Watir::Browser.new : b
16
- Page.accessor.driver.manage.timeouts.implicit_wait=3
17
- Page.accessor.driver.manage.timeouts.page_load=30
18
- Page.accessor.driver.manage.timeouts.script_timeout=30
19
- end
20
-
21
- def self.stop_browser
22
- Page.accessor.quit
23
- end
24
-
25
- def self.restart_browser
26
- self.stop_browser
27
- self.start_browser
28
- end
29
-
30
- def self.domain=(val)
31
- Page.base_url = val
32
- end
33
-
34
- class Page
35
- class << self
36
- attr_accessor :url, :expected_elements, :full_url
37
- end
38
-
39
- @@base_url = ''
40
- @@accessor = nil
41
- @url = ''
42
- @expected_elements = {}
43
-
44
- def initialize visit = false
45
- self.class.full_url = @@base_url + self.class.url
46
- @@accessor.goto self.class.full_url if visit
47
-
48
- if not self.class.expected_elements.nil?
49
- if not (self.class.expected_elements.empty?)
50
- self.class.expected_elements.each{|element_type, identifier|
51
- begin
52
- @@accessor.send(element_type,identifier).wait_until_present
53
- rescue
54
- raise PageError.new("expected_element #{element_type}, #{identifier.inspect} not found after a set timeout",self.class,self.class.full_url)
55
- end
56
- }
57
- end
58
- end
59
- end
60
-
61
- def self.base_url=(val)
62
- @@base_url = val
63
- end
64
-
65
- def self.base_url
66
- @@base_url
67
- end
68
-
69
- def self.accessor
70
- @@accessor
71
- end
72
-
73
- def self.accessor=(val)
74
- @@accessor = val
75
- end
76
- def self.expected_element(element_type,identifier)
77
- self.expected_elements = {} if self.expected_elements.nil?
78
- self.expected_elements[element_type] = identifier
79
- end
80
-
81
- def form(target_page,*args)
82
- Form.new(self.class,target_page,@@accessor,*args)
83
- end
84
-
85
- def table(*args)
86
- Table.new(@@accessor,*args)
87
- end
88
-
89
- def paginate(div_args)
90
- Pagination.new(self,div_args)
91
- end
92
-
93
- def has_warning?(text)
94
- @@accessor.text.include?(text)
95
- end
96
-
97
- alias :has_text? :has_warning?
98
- end
8
+ @@domain = nil
9
+ @@browser = nil
10
+
11
+ def self.domain=val
12
+ @@domain=val
13
+ end
14
+
15
+ def self.use_browser b
16
+ PageObject.browser = b
17
+ end
18
+
19
+ def self.browser
20
+ PageObject.browser
21
+ end
22
+
23
+ def self.define_page(label, &block)
24
+ page = PageObject.new(label)
25
+ page.instance_eval(&block)
26
+ PageObject.pages << page
27
+ page
28
+ end
29
+
30
+ def self.current_page
31
+ PageObject.current_page
32
+ end
33
+
34
+ def self.load(path_to_pages='.')
35
+ processed = 0
36
+ Dir.glob("#{path_to_pages}/*_page.rb"){|fn|
37
+ processed +=1
38
+ require fn
39
+ }
40
+ raise PageObjectWrapper::Load, "No *_page.rb files found in #{path_to_pages}" if processed.zero?
41
+ output = []
42
+ PageObject.pages.each{|p|
43
+ output += p.validate
44
+ }
45
+ raise PageObjectWrapper::Load, output.join if not output.empty?
46
+ end
47
+
48
+ def self.domain=val
49
+ @@domain = val
50
+ end
51
+
52
+ def self.domain
53
+ @@domain
54
+ end
55
+
56
+ def self.receive_page(label)
57
+ PageObject.find_page_object(label)
58
+ end
59
+
60
+ def self.open_page(label)
61
+ PageObject.open_page label
62
+ PageObject.map_current_page label
63
+ end
99
64
  end
@@ -0,0 +1,11 @@
1
+ require 'Dsl'
2
+ class Action < DslElement
3
+ attr_reader :fire_block_value, :next_page_value
4
+
5
+ def initialize(label, next_page, &block)
6
+ super label
7
+ @next_page_value = next_page
8
+ @fire_block_value = block
9
+ end
10
+ end
11
+
@@ -0,0 +1,35 @@
1
+ class Class
2
+ def dsl_attr_accessor(*args)
3
+ # iterate through each passed in argument...
4
+ args.each do |arg|
5
+ # getter
6
+ self.class_eval("def #{arg}_value;@#{arg};end")
7
+ # setter
8
+ self.class_eval("def #{arg} val;@#{arg}=val;end")
9
+ end
10
+ end
11
+ end
12
+ class DslElement
13
+ dsl_attr_accessor :label
14
+
15
+ def initialize label
16
+ @label = label
17
+ end
18
+ protected
19
+ def to_tree(*args)
20
+ args.collect(&:label_value).join(" -> ")
21
+ end
22
+
23
+ def validate_label
24
+
25
+ end
26
+ end
27
+
28
+ class DslElementWithLocator < DslElement
29
+ dsl_attr_accessor :locator
30
+
31
+ def initialize label
32
+ super label
33
+ @locator = nil
34
+ end
35
+ end
@@ -0,0 +1,15 @@
1
+ require 'Dsl'
2
+ class Element < DslElementWithLocator
3
+ attr_reader :type
4
+ dsl_attr_accessor :fresh_food, :missing_food
5
+
6
+ DEFAULT_FRESH_FOOD = 'default fresh food'
7
+ DEFAULT_MISSING_FOOD = 'default missing food'
8
+
9
+ def initialize(label, type)
10
+ super label
11
+ @type = type
12
+ @fresh_food = DEFAULT_FRESH_FOOD
13
+ @missing_food = DEFAULT_MISSING_FOOD
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ require 'Dsl'
2
+ require 'known_elements'
3
+
4
+ class ElementsSet < DslElement
5
+
6
+ def initialize(label)
7
+ super label
8
+ @elements = []
9
+ end
10
+
11
+ KNOWN_ELEMENTS.each{|m|
12
+ ElementsSet.send :define_method, m do |label, &block|
13
+ e = Element.new(label, m.to_sym)
14
+ e.instance_eval(&block)
15
+ @elements << e
16
+ end
17
+ }
18
+
19
+ def elements
20
+ @elements
21
+ end
22
+ end
@@ -1,22 +1,8 @@
1
- class PageError < StandardError
2
- attr_accessor :page_url, :page_name
3
- def initialize(msg,page_name,page_url)
4
- @page_url=page_url
5
- @page_name=page_name
6
- super "PROBLEM: #{(msg.nil?)? '??' : msg}, PAGE: #{page_name}, URL: #{page_url}"
7
- end
8
-
1
+ module PageObjectWrapper
2
+ class UnknownFoodType < StandardError; end
3
+ class UnableToFeedObject < StandardError; end
4
+ class UnknownPageObject < StandardError; end
5
+ class UnmappedPageObject < StandardError; end
6
+ class Load < StandardError; end
7
+ class BrowserNotFound < StandardError; end
9
8
  end
10
-
11
- class ParameterError < StandardError
12
- attr_accessor :method, :params
13
- def initialize(msg,method,*params)
14
- @method=method
15
- @params=params
16
- super "PROBLEM: #{(msg.nil?)? '??' : msg}, METHOD: #{method}, PARAMS: #{params.join('; ').to_s}"
17
- end
18
- end
19
-
20
- class TableError < ParameterError; end
21
- class FormError < ParameterError; end
22
- class DynamicClassError < ParameterError; end
@@ -0,0 +1,371 @@
1
+ require 'Dsl'
2
+ require 'Exceptions'
3
+ include PageObjectWrapper
4
+
5
+ require 'ElementsSet'
6
+ require 'Element'
7
+ require 'Action'
8
+ require 'Table'
9
+ require 'Pagination'
10
+ require 'known_elements'
11
+
12
+ class PageObject < DslElementWithLocator
13
+ attr_reader :esets, :elements, :actions, :tables, :paginations, :uniq_element_type, :uniq_element_hash
14
+ @@browser = nil
15
+ @@pages = []
16
+ @@current_page = nil
17
+
18
+ FOOD_TYPES = [:missing_food, :fresh_food]
19
+ FEED_ALL = Regexp.new(/^feed_all$/)
20
+ FEED_SET = Regexp.new(/^feed_([\w_]+)$/)
21
+ FIRE_ACTION = Regexp.new(/^fire_([\w_]+)$/)
22
+ SELECT_FROM = Regexp.new(/^select_from_([\w_]+)$/)
23
+ PAGINATION_EACH = Regexp.new(/^([\w_]+)_each$/)
24
+ PAGINATION_OPEN = Regexp.new(/^([\w_]+)_open$/)
25
+
26
+ def initialize(label)
27
+ super label
28
+ @uniq_element_type = 'element'
29
+ @uniq_element_hash = {}
30
+ @esets = []
31
+ @elements = []
32
+ @actions = []
33
+ @tables = []
34
+ @paginations = []
35
+ end
36
+
37
+ # lazy evaluated calls of real watir elements are handled by :method_missing
38
+ def method_missing(method_name, *args)
39
+ case
40
+ when KNOWN_ELEMENTS.include?(method_name.to_s.gsub(/^uniq_/,''))
41
+ # page_object.uniq_xxx(hash)
42
+ @uniq_element_type = method_name.to_s.gsub(/^uniq_/,'').to_sym
43
+ @uniq_element_hash = args[0]
44
+ when has_eset?(method_name)
45
+ # page_object.some_elements_set
46
+ eset = eset_for(method_name)
47
+ return_array_of_watir_elements(eset)
48
+ when has_element?(method_name)
49
+ # page_object.some_element
50
+ element = element_for(method_name)
51
+ return_watir_element(element)
52
+ when FEED_ALL.match(method_name)
53
+ # page_object.feed_all(:fresh_food)
54
+ feed_elements(@elements, *args)
55
+ when (FEED_SET.match(method_name) and has_eset?($1))
56
+ # page_object.feed_some_elements_set(:fresh_food)
57
+ eset = eset_for($1)
58
+ feed_elements(eset.elements, *args)
59
+ when (FIRE_ACTION.match(method_name) and has_action?($1))
60
+ # page_object.fire_some_action
61
+ a = action_for($1)
62
+ fire_action(a, *args)
63
+ when (SELECT_FROM.match(method_name) and has_table?($1))
64
+ # page_object.select_from_some_table(:header_column, {:column => 'value'})
65
+ table = table_for($1)
66
+ select_from_table(table, *args)
67
+ when (PAGINATION_EACH.match(method_name) and has_pagination?($1))
68
+ # page_object.each_pagination
69
+ pagination = pagination_for($1)
70
+ run_each_subpage(pagination, *args)
71
+ when (PAGINATION_OPEN.match(method_name) and has_pagination?($1))
72
+ # page_object.open_padination(1)
73
+ pagination = pagination_for($1)
74
+ open_subpage(pagination, *args)
75
+ else
76
+ super
77
+ end
78
+ end
79
+
80
+ # corresponding respond_to?
81
+ def respond_to?(method_sym, include_private = false)
82
+ method_name = method_sym.to_s
83
+ case
84
+ when KNOWN_ELEMENTS.include?(method_name.gsub(/^uniq_/,''))
85
+ # page_object.uniq_xxx(hash)
86
+ true
87
+ when has_eset?(method_name)
88
+ # page_object.some_elements_set
89
+ true
90
+ when has_element?(method_name)
91
+ # page_object.some_element
92
+ true
93
+ when FEED_ALL.match(method_name)
94
+ # page_object.feed_all(:fresh_food)
95
+ true
96
+ when (FEED_SET.match(method_name) and has_eset?($1))
97
+ # page_object.feed_some_elements_set(:fresh_food)
98
+ true
99
+ when (FIRE_ACTION.match(method_name) and has_action?($1))
100
+ # page_object.fire_some_action
101
+ true
102
+ when (SELECT_FROM.match(method_name) and has_table?($1))
103
+ # page_object.select_from_some_table(:header_column, {:column => 'value'})
104
+ true
105
+ when (PAGINATION_EACH.match(method_name) and has_pagination?($1))
106
+ # page_object.each_pagination
107
+ true
108
+ when (PAGINATION_OPEN.match(method_name) and has_pagination?($1))
109
+ # page_object.open_padination(1)
110
+ true
111
+ else
112
+ super
113
+ end
114
+ end
115
+
116
+ def self.open_page label
117
+ raise PageObjectWrapper::BrowserNotFound if @@browser.nil?
118
+ raise PageObjectWrapper::UnknownPageObject, label if not @@pages.collect(&:label_value).include?(label)
119
+ page_object = PageObject.find_page_object(label)
120
+ url = ''
121
+ url += @@domain if page_object.locator_value[0]=='/'
122
+ url += page_object.locator_value
123
+ @@browser.goto url
124
+ end
125
+
126
+ def self.map_current_page label
127
+ raise PageObjectWrapper::BrowserNotFound if @@browser.nil?
128
+ raise PageObjectWrapper::UnknownPageObject, label if not @@pages.collect(&:label_value).include?(label)
129
+ page_object = PageObject.find_page_object(label)
130
+ watir_uniq_element = @@browser.send page_object.uniq_element_type, page_object.uniq_element_hash
131
+ raise PageObjectWrapper::UnmappedPageObject, "#{label} <=> #{@@browser.url}" if not watir_uniq_element.present?
132
+ @@current_page = page_object
133
+ end
134
+
135
+ def self.current_page
136
+ @@current_page
137
+ end
138
+
139
+ def self.pages
140
+ @@pages
141
+ end
142
+
143
+ def self.browser=(val)
144
+ @@browser = val
145
+ end
146
+
147
+ def self.browser
148
+ @@browser
149
+ end
150
+
151
+ def elements_set(label, &block)
152
+ eset = ElementsSet.new(label)
153
+ eset.instance_eval(&block)
154
+ @esets << eset
155
+ @elements += eset.elements
156
+ eset
157
+ end
158
+
159
+ def action(label, next_page, &block)
160
+ a = Action.new(label, next_page, &block)
161
+ @actions << a
162
+ a
163
+ end
164
+
165
+ def table(label, &block)
166
+ t = Table.new(label)
167
+ t.instance_eval(&block)
168
+ @tables << t
169
+ t
170
+ end
171
+
172
+
173
+ def pagination(label, &block)
174
+ p = Pagination.new(label)
175
+ p.instance_eval(&block)
176
+ @paginations << p
177
+ p
178
+ end
179
+
180
+ def validate
181
+ output = []
182
+ # commented out; already defined pages will e redifined with new definitions
183
+ raise PageObjectWrapper::Load, "\tpage_object #{label_value.inspect} already defined\n" if labeled(@@pages).count(label_value) > 1
184
+ output << "\tlabel #{label_value.inspect} not a Symbol\n" if not label_value.is_a?(Symbol)
185
+ output << "\tlocator #{locator_value.inspect} not a meaningful String\n" if not locator_value.is_a?(String) or locator_value.empty?
186
+ @esets.each{|eset|
187
+ eset_output = []
188
+ eset_output << "\telements_set #{eset.label_value.inspect} already defined\n" if labeled(@esets).count(eset.label_value) > 1
189
+ eset_output << "\tlabel #{eset.label_value.inspect} not a Symbol\n" if not eset.label_value.is_a?(Symbol)
190
+ eset_output.unshift "elements_set(#{eset.label_value.inspect}):\n" if not eset_output.empty?
191
+ output += eset_output
192
+ eset.elements.each{|e|
193
+ element_output = []
194
+ element_output << "\t\telement #{e.label_value.inspect} already defined\n" if labeled(eset.elements).count(e.label_value) > 1
195
+ element_output << "\t\tlabel #{e.label_value.inspect} not a Symbol\n" if not e.label_value.is_a?(Symbol)
196
+ element_output << "\t\tlocator #{e.locator_value.inspect} not a meaningful Hash\n" if not e.locator_value.is_a?(Hash) or e.locator_value.empty?
197
+ element_output.unshift "\telement(#{e.label_value.inspect}):\n" if not element_output.empty?
198
+ output += element_output
199
+ }
200
+ }
201
+ @actions.each{|a|
202
+ action_output = []
203
+ action_output << "\taction #{a.label_value.inspect} already defined\n" if labeled(@actions).count(a.label_value) > 1
204
+ action_output << "\tlabel #{a.label_value.inspect} not a Symbol\n" if not a.label_value.is_a?(Symbol)
205
+ action_output << "\tnext_page #{a.next_page_value.inspect} not a Symbol\n" if not a.next_page_value.is_a? Symbol
206
+ action_output << "\tnext_page #{a.next_page_value.inspect} unknown page_object\n" if not labeled(@@pages).include?(a.next_page_value)
207
+ action_output << "\tfire event is not a Proc\n" if not a.fire_block_value.is_a?(Proc)
208
+ action_output.unshift "action(#{a.label_value.inspect}):\n" if not action_output.empty?
209
+ output += action_output
210
+ }
211
+ @tables.each{|t|
212
+ table_output = []
213
+ table_output << "\ttable #{t.label_value.inspect} already defined\n" if labeled(@tables).count(t.label_value) > 1
214
+ table_output << "\tlabel #{t.label_value.inspect} not a Symbol\n" if not t.label_value.is_a?(Symbol)
215
+ table_output << "\tlocator #{t.locator_value.inspect} not a meaningful Hash\n" if not t.locator_value.is_a?(Hash) or t.locator_value.empty?
216
+ table_output << "\theader #{t.header_value.inspect} not a meaningful Array\n" if not t.header_value.is_a?(Array) or t.header_value.empty?
217
+ table_output.unshift "table(#{t.label_value.inspect}):\n" if not table_output.empty?
218
+ output += table_output
219
+ }
220
+ @paginations.each{|p|
221
+ pagination_output = []
222
+ pagination_output << "\tpagination #{p.label_value.inspect} already defined\n" if labeled(@paginations).count(p.label_value) > 1
223
+ pagination_output << "\tlabel #{p.label_value.inspect} not a Symbol\n" if not p.label_value.is_a?(Symbol)
224
+ pagination_output << "\tlocator #{p.locator_value.inspect} not a meaningful Hash\n" if not p.locator_value.is_a?(Hash) or p.locator_value.empty?
225
+ pagination_output.unshift "pagination(#{p.label_value.inspect}):\n" if not pagination_output.empty?
226
+ output += pagination_output
227
+ }
228
+ output.unshift "page_object(#{label_value.inspect}):\n" if not output.empty?
229
+ output
230
+ end
231
+
232
+ private
233
+
234
+ def self.find_page_object(l)
235
+ @@pages.select{|p| p.label_value == l}.first
236
+ end
237
+
238
+ def return_watir_element(e)
239
+ @@browser.send e.type, e.locator_value
240
+ end
241
+
242
+ def return_array_of_watir_elements(eset)
243
+ eset.elements.collect{|e| @@browser.send(e.type, e.locator_value)}
244
+ end
245
+
246
+ def feed_elements(elements, food_type=nil)
247
+ raise PageObjectWrapper::BrowserNotFound if @@browser.nil?
248
+ raise PageObjectWrapper::BrowserNotFound if not @@browser.exist?
249
+ food_type ||= :fresh_food
250
+ raise PageObjectWrapper::UnknownFoodType, food_type.inspect if not FOOD_TYPES.include?(food_type)
251
+ elements.each{|e|
252
+ food = e.send (food_type.to_s+'_value').to_sym
253
+ watir_element = @@browser.send e.type, e.locator_value
254
+ case watir_element
255
+ when Watir::CheckBox
256
+ watir_element.when_present.set
257
+ when Watir::Radio
258
+ watir_element.when_present.set
259
+ when Watir::Select
260
+ begin
261
+ watir_element.when_present.select food
262
+ rescue Watir::Exception::NoValueFoundException => e
263
+ if food_type == :missing_food
264
+ # proceed to next element if missing_food is not found in select list
265
+ next
266
+ else
267
+ raise e
268
+ end
269
+ end
270
+ else
271
+ if watir_element.respond_to?(:set)
272
+ watir_element.when_present.set food
273
+ else
274
+ raise PageObjectWrapper::UnableToFeedObject, to_tree(@@current_page, eset, e)
275
+ end
276
+ end
277
+ }
278
+ self
279
+ end
280
+
281
+ def fire_action(a, *args)
282
+ raise PageObjectWrapper::BrowserNotFound if @@browser.nil?
283
+ @@browser.instance_exec args, &a.fire_block_value
284
+ self.class.map_current_page a.next_page_value
285
+ @@current_page
286
+ end
287
+
288
+ def select_from_table(table, header, where=nil)
289
+ raise PageObjectWrapper::BrowserNotFound if @@browser.nil?
290
+ t = @@browser.table(table.locator_value)
291
+ raise ArgumentError, "#{header.inspect} not a Symbol" if not header.is_a? Symbol
292
+ raise ArgumentError, "#{header.inspect} not in table header" if not table.header_value.include? header
293
+ search_for_index = table.header_value.index(header)
294
+ found = nil
295
+
296
+ if not where.nil?
297
+ raise ArgumentError, "#{where.inspect} not a meaningful Hash" if not where.is_a? Hash or where.empty?
298
+ raise ArgumentError, "#{where.inspect} has more than 1 keys" if not where.keys.length == 1
299
+ raise ArgumentError, "#{where.keys.first.inspect} not a Symbol" if not where.keys.first.is_a? Symbol
300
+ raise ArgumentError, "#{where.keys.first.inspect} not in table header" if not table.header_value.include? where.keys.first
301
+ raise ArgumentError, "#{where.values.first.inspect} not a String or Regexp" if not (where.values.first.is_a? String or where.values.first.is_a? Regexp)
302
+ search_in_index = table.header_value.index(where.keys.first)
303
+ search_value = where.values.first
304
+ t.rows.each{|r|
305
+ if search_value.is_a? String
306
+ found = r.cells[search_for_index] if r.cells[search_in_index].text == search_value
307
+ elsif search_value.is_a? Regexp
308
+ found = r.cells[search_for_index] if search_value.match(r.cells[search_in_index].text)
309
+ else
310
+ raise ArgumentError, "#{search_value} not a Regexp or String"
311
+ end
312
+ }
313
+ else # where == nil
314
+ found = t.rows.last.cells[search_for_index]
315
+ end
316
+ found
317
+ end
318
+
319
+ def each_pagination
320
+ raise PageObjectWrapper::BrowserNotFound if @@browser.nil?
321
+ end
322
+
323
+ def open_padination n
324
+ raise PageObjectWrapper::BrowserNotFound if @@browser.nil?
325
+ end
326
+
327
+
328
+ def labeled(ary)
329
+ ary.collect(&:label_value)
330
+ end
331
+
332
+ def has_eset?(label)
333
+ labeled(@esets).include?(label.to_sym)
334
+ end
335
+
336
+ def has_element?(label)
337
+ labeled(@elements).include?(label.to_sym)
338
+ end
339
+
340
+ def has_table?(label)
341
+ labeled(@tables).include?(label.to_sym)
342
+ end
343
+
344
+ def has_pagination?(label)
345
+ labeled(@paginations).include?(label.to_sym)
346
+ end
347
+
348
+ def has_action?(label)
349
+ labeled(@actions).include?(label.to_sym)
350
+ end
351
+
352
+ def eset_for(label)
353
+ @esets[labeled(@esets).index(label.to_sym)]
354
+ end
355
+
356
+ def element_for(label)
357
+ @elements[labeled(@elements).index(label.to_sym)]
358
+ end
359
+
360
+ def table_for(label)
361
+ @tables[labeled(@tables).index(label.to_sym)]
362
+ end
363
+
364
+ def pagination_for(label)
365
+ @paginations[labeled(@paginations).index(label.to_sym)]
366
+ end
367
+
368
+ def action_for(label)
369
+ @actions[labeled(@actions).index(label.to_sym)]
370
+ end
371
+ end