page_object_wrapper 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +54 -18
- data/bad_pages/bad_page.rb +3 -0
- data/good_pages/some_test_page.rb +5 -1
- data/img/scheme.png +0 -0
- data/lib/page_object_wrapper/PageObject.rb +39 -2
- data/lib/page_object_wrapper/Validator.rb +11 -0
- data/lib/page_object_wrapper/version.rb +1 -1
- data/spec/define_page_object_spec.rb +15 -0
- data/spec/{fire_event_spec.rb → fire_event_and_validate_spec.rb} +3 -3
- data/spec/load_spec.rb +2 -0
- metadata +8 -7
data/README.md
CHANGED
@@ -70,7 +70,6 @@ where required attributes are marked with (*)
|
|
70
70
|
|
71
71
|
checkbox(:cb){ locator :id => 'f5' }
|
72
72
|
radio(:rb){ locator :id => 'f3' }
|
73
|
-
|
74
73
|
end
|
75
74
|
|
76
75
|
action(:press_cool_button, :test_page_with_table) do
|
@@ -78,7 +77,7 @@ where required attributes are marked with (*)
|
|
78
77
|
end
|
79
78
|
|
80
79
|
action(:fill_textarea, :some_test_page) do |fill_with|
|
81
|
-
data = (fill_with.
|
80
|
+
data = (fill_with.nil?)? 'Default data' : fill_with
|
82
81
|
textarea(:id => 'f2').set data
|
83
82
|
end
|
84
83
|
|
@@ -96,25 +95,33 @@ where required attributes are marked with (*)
|
|
96
95
|
pagination(:some_pagination) do
|
97
96
|
locator :xpath => ''
|
98
97
|
end
|
98
|
+
|
99
|
+
validator(:textarea_value) do |expected|
|
100
|
+
textarea(:id => 'f2').value == expected
|
101
|
+
end
|
99
102
|
end
|
100
103
|
|
101
104
|
here we have defined a page object with locator (url) = 'http://www.cs.tut.fi/~jkorpela/www/testel.html'
|
102
105
|
- uniq\_xxx is used to define a uniq element on that page, which uniquely identifies the page from other pages
|
103
106
|
- uniq\_xxx is being checked when openning the page with PageObjectWrapper.open\_page and when running an page\_object.action
|
104
107
|
- all defined elements have labels
|
105
|
-
- action and
|
108
|
+
- action and action\_alias defined with labels and next\_pages
|
109
|
+
- validator defined with label
|
106
110
|
|
107
111
|
#### openning the page
|
108
112
|
*preconditions*
|
109
113
|
There is a directory, where we've defined a page\_object inside a \*\_page.rb file
|
110
114
|
|
111
115
|
1. specify browser to be used by PageObjectWrapper
|
112
|
-
|
113
|
-
|
116
|
+
|
117
|
+
@b = Watir::Browser.new
|
118
|
+
PageObjectWrapper.use_browser @b
|
114
119
|
2. load defined pages
|
115
|
-
|
120
|
+
|
121
|
+
PageObjectWrapper.load("path/to/pages/directory")
|
116
122
|
3. open page in browser
|
117
|
-
|
123
|
+
|
124
|
+
test_page = PageObjectWrapper.open_page(:some_test_page)
|
118
125
|
|
119
126
|
*comments*
|
120
127
|
- it's possible to use any Watir::Browser with any profile
|
@@ -124,11 +131,10 @@ There is a directory, where we've defined a page\_object inside a \*\_page.rb fi
|
|
124
131
|
- .open\_page method takes page label, directs browser to that page and returns corresponding page\_object
|
125
132
|
- PageObjectWrapper.current\_page points to the opened page\_object
|
126
133
|
- it's possible to set page\_object locator in 2 different ways: specifying full url (like in example) or specifying PageObjectWrapper.domain and page\_object local path (like in specs)
|
127
|
-
- it's possible to set dynamic urls for pages, e.g.
|
128
|
-
|
129
|
-
locator 'www.google.com/:some_param'
|
130
|
-
|
131
|
-
PageObjectWrapper.open_page(:google, :some_param => 'advanced_search') # => 'http://google.com/advanced_search'
|
134
|
+
- it's possible to set dynamic urls for pages, e.g.
|
135
|
+
|
136
|
+
PageObjectWrapper.define_page(:google){ locator 'www.google.com/:some_param' }
|
137
|
+
PageObjectWrapper.open_page(:google, :some_param => 'advanced_search') # => 'http://google.com/advanced_search'
|
132
138
|
|
133
139
|
#### page\_object.xxx
|
134
140
|
*parameters*
|
@@ -173,12 +179,17 @@ current\_page
|
|
173
179
|
tp = PageObjectWrapper.open_page(:some_test_page)
|
174
180
|
tp.feed_test_elements(:missing_food)
|
175
181
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
182
|
+
#### xxx\_fresh\_food, xxx\_missing\_food
|
183
|
+
*parameters*
|
184
|
+
no
|
185
|
+
*returns*
|
186
|
+
fresh or missinf food value from page definition
|
187
|
+
|
188
|
+
*preconditions*
|
189
|
+
**tp** is a :some\_test\_page object opened in the browser
|
181
190
|
|
191
|
+
tp.tf_fresh_food # => 'some fresh food'
|
192
|
+
tp.ta_fresh_food # => 'default fresh food'
|
182
193
|
|
183
194
|
#### fire\_xxx
|
184
195
|
*parameters*
|
@@ -205,7 +216,24 @@ next\_page from xxx action
|
|
205
216
|
it "executes corresponding action":
|
206
217
|
tp = PageObjectWrapper.open_page(:some_test_page)
|
207
218
|
tp.fire_fill_textarea_alias
|
208
|
-
|
219
|
+
|
220
|
+
#### validate\_xxx
|
221
|
+
*parameters*
|
222
|
+
optional arguments defined inside action
|
223
|
+
*returns*
|
224
|
+
anything block inside xxx validator returns
|
225
|
+
it's expected that validator returns true | false
|
226
|
+
|
227
|
+
*preconditions*
|
228
|
+
**tp** is a :some\_test\_page object opened in the browser
|
229
|
+
|
230
|
+
tp = PageObjectWrapper.open_page(:some_test_page)
|
231
|
+
tp.fire_fill_textarea
|
232
|
+
tp.validate_textarea_value('Default data').should be(true)
|
233
|
+
|
234
|
+
tp = PageObjectWrapper.current_page
|
235
|
+
tp.fire_fill_textarea('User defined data')
|
236
|
+
tp.validate_textarea_value('User defined data').should be(true)
|
209
237
|
|
210
238
|
#### select\_from\_xxx
|
211
239
|
*parameters*
|
@@ -244,6 +272,14 @@ correct arguments are:
|
|
244
272
|
tp.select_from_table_without_header(:column_0, :column_1 => /123/).should eq nil
|
245
273
|
tp.select_from_table_with_header(:country, :total_area => /123/).should eq nil
|
246
274
|
|
275
|
+
context "next_page specified":
|
276
|
+
context "found by String":
|
277
|
+
it "returns found cells":
|
278
|
+
tp.select_from_table_without_header(:column_0, {:column_1 => '103,000'}, :some_test_page).should eq PageObjectWrapper.receive_page(:some_test_page)
|
279
|
+
context "not found by String":
|
280
|
+
it "returns nil":
|
281
|
+
tp.select_from_table_without_header(:column_0, {:column_1 => '123'}, :some_test_page).should eq nil
|
282
|
+
|
247
283
|
#### each\_xxx
|
248
284
|
TODO
|
249
285
|
#### open\_xxx
|
data/bad_pages/bad_page.rb
CHANGED
@@ -33,7 +33,7 @@ PageObjectWrapper.define_page(:some_test_page) do
|
|
33
33
|
end
|
34
34
|
|
35
35
|
action(:fill_textarea, :some_test_page) do |fill_with|
|
36
|
-
data = (fill_with.
|
36
|
+
data = (fill_with.nil?)? 'Default data' : fill_with
|
37
37
|
textarea(:id => 'f2').set data
|
38
38
|
end
|
39
39
|
|
@@ -51,4 +51,8 @@ PageObjectWrapper.define_page(:some_test_page) do
|
|
51
51
|
pagination(:some_pagination) do
|
52
52
|
locator :xpath => ''
|
53
53
|
end
|
54
|
+
|
55
|
+
validator(:textarea_value) do |expected|
|
56
|
+
textarea(:id => 'f2').value == expected
|
57
|
+
end
|
54
58
|
end
|
data/img/scheme.png
CHANGED
Binary file
|
@@ -6,12 +6,13 @@ require 'ElementsSet'
|
|
6
6
|
require 'Element'
|
7
7
|
require 'Action'
|
8
8
|
require 'Alias'
|
9
|
+
require 'Validator'
|
9
10
|
require 'Table'
|
10
11
|
require 'Pagination'
|
11
12
|
require 'known_elements'
|
12
13
|
|
13
14
|
class PageObject < DslElementWithLocator
|
14
|
-
attr_reader :esets, :elements, :actions, :aliases, :tables, :paginations, :uniq_element_type, :uniq_element_hash
|
15
|
+
attr_reader :esets, :elements, :actions, :aliases, :validators, :tables, :paginations, :uniq_element_type, :uniq_element_hash
|
15
16
|
@@browser = nil
|
16
17
|
@@pages = []
|
17
18
|
@@current_page = nil
|
@@ -24,6 +25,7 @@ class PageObject < DslElementWithLocator
|
|
24
25
|
SELECT_FROM = Regexp.new(/^select_from_([\w_]+)$/)
|
25
26
|
PAGINATION_EACH = Regexp.new(/^([\w_]+)_each$/)
|
26
27
|
PAGINATION_OPEN = Regexp.new(/^([\w_]+)_open$/)
|
28
|
+
VALIDATE = Regexp.new(/^validate_([\w_]+)$/)
|
27
29
|
|
28
30
|
def initialize(label)
|
29
31
|
super label
|
@@ -33,6 +35,7 @@ class PageObject < DslElementWithLocator
|
|
33
35
|
@elements = []
|
34
36
|
@actions = []
|
35
37
|
@aliases = []
|
38
|
+
@validators = []
|
36
39
|
@tables = []
|
37
40
|
@paginations = []
|
38
41
|
end
|
@@ -67,6 +70,10 @@ class PageObject < DslElementWithLocator
|
|
67
70
|
# page_object.fire_some_action
|
68
71
|
a = alias_for($1)
|
69
72
|
fire_action(a, *args)
|
73
|
+
when (VALIDATE.match(method_name) and has_validator?($1))
|
74
|
+
# page_object.validate_something
|
75
|
+
v = validator_for($1)
|
76
|
+
run_validator(v, *args)
|
70
77
|
when (SELECT_FROM.match(method_name) and has_table?($1))
|
71
78
|
# page_object.select_from_some_table(:header_column, {:column => 'value'})
|
72
79
|
table = table_for($1)
|
@@ -109,6 +116,9 @@ class PageObject < DslElementWithLocator
|
|
109
116
|
when (FIRE_ACTION.match(method_name) and has_alias?($1))
|
110
117
|
# page_object.fire_some_action
|
111
118
|
true
|
119
|
+
when (VALIDATE.match(method_name) and has_action?($1))
|
120
|
+
# page_object.validate_xxx
|
121
|
+
true
|
112
122
|
when (SELECT_FROM.match(method_name) and has_table?($1))
|
113
123
|
# page_object.select_from_some_table(:header_column, {:column => 'value'})
|
114
124
|
true
|
@@ -201,6 +211,12 @@ class PageObject < DslElementWithLocator
|
|
201
211
|
a
|
202
212
|
end
|
203
213
|
|
214
|
+
def validator(label, &block)
|
215
|
+
v = Validator.new(label, &block)
|
216
|
+
@validators << v
|
217
|
+
v
|
218
|
+
end
|
219
|
+
|
204
220
|
def table(label, &block)
|
205
221
|
t = Table.new(label)
|
206
222
|
t.instance_eval(&block)
|
@@ -257,6 +273,14 @@ class PageObject < DslElementWithLocator
|
|
257
273
|
alias_output.unshift "alias(#{a.label_value.inspect}):\n" if not alias_output.empty?
|
258
274
|
output += alias_output
|
259
275
|
}
|
276
|
+
@validators.each{|v|
|
277
|
+
validator_output = []
|
278
|
+
validator_output << "\tvalidator #{v.label_value.inspect} already defined\n" if labeled(@validators).count(v.label_value) > 1
|
279
|
+
validator_output << "\tlabel #{v.label_value.inspect} not a Symbol\n" if not v.label_value.is_a?(Symbol)
|
280
|
+
validator_output << "\tvalidation block is not a Proc\n" if not v.validate_block_value.is_a?(Proc)
|
281
|
+
validator_output.unshift "validator(#{v.label_value.inspect}):\n" if not validator_output.empty?
|
282
|
+
output += validator_output
|
283
|
+
}
|
260
284
|
@tables.each{|t|
|
261
285
|
table_output = []
|
262
286
|
table_output << "\ttable #{t.label_value.inspect} already defined\n" if labeled(@tables).count(t.label_value) > 1
|
@@ -329,11 +353,16 @@ private
|
|
329
353
|
def fire_action(a, *args)
|
330
354
|
raise PageObjectWrapper::BrowserNotFound if @@browser.nil? or not @@browser.exist?
|
331
355
|
block = (a.is_a? Action)? a.fire_block_value : action_for(a.action_value).fire_block_value
|
332
|
-
@@browser.instance_exec args, &block
|
356
|
+
@@browser.instance_exec *args, &block
|
333
357
|
self.class.map_current_page a.next_page_value
|
334
358
|
@@current_page
|
335
359
|
end
|
336
360
|
|
361
|
+
def run_validator(v, *args)
|
362
|
+
raise PageObjectWrapper::BrowserNotFound if @@browser.nil? or not @@browser.exist?
|
363
|
+
@@browser.instance_exec *args, &v.validate_block_value
|
364
|
+
end
|
365
|
+
|
337
366
|
def select_from_table(table, header, *args)
|
338
367
|
where = args[0]
|
339
368
|
next_page = args[1]
|
@@ -414,6 +443,10 @@ private
|
|
414
443
|
labeled(@actions).include?(label.to_sym)
|
415
444
|
end
|
416
445
|
|
446
|
+
def has_validator?(label)
|
447
|
+
labeled(@validators).include?(label.to_sym)
|
448
|
+
end
|
449
|
+
|
417
450
|
def has_alias?(label)
|
418
451
|
labeled(@aliases).include?(label.to_sym)
|
419
452
|
end
|
@@ -438,6 +471,10 @@ private
|
|
438
471
|
@actions[labeled(@actions).index(label.to_sym)]
|
439
472
|
end
|
440
473
|
|
474
|
+
def validator_for(label)
|
475
|
+
@validators[labeled(@validators).index(label.to_sym)]
|
476
|
+
end
|
477
|
+
|
441
478
|
def alias_for(label)
|
442
479
|
@aliases[labeled(@aliases).index(label.to_sym)]
|
443
480
|
end
|
@@ -127,6 +127,21 @@ describe "define_page_object" do
|
|
127
127
|
end
|
128
128
|
end
|
129
129
|
|
130
|
+
context "validator" do
|
131
|
+
subject { page_object.validators[page_object.validators.collect(&:label_value).index(:textarea_value)] }
|
132
|
+
|
133
|
+
it { should be_a(Validator) }
|
134
|
+
|
135
|
+
describe "validator label" do
|
136
|
+
it_should_behave_like "a label"
|
137
|
+
end
|
138
|
+
|
139
|
+
describe "validator attributes" do
|
140
|
+
it { should respond_to(:validate_block_value) }
|
141
|
+
its(:validate_block_value) { should be_a Proc }
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
130
145
|
context "table" do
|
131
146
|
subject { page_object.tables[page_object.tables.collect(&:label_value).index(:table_without_header)] }
|
132
147
|
|
@@ -18,7 +18,7 @@ describe "page_object.fire_xxx" do
|
|
18
18
|
it "executes fire_block in Watir::Browser context" do
|
19
19
|
tp = PageObjectWrapper.open_page(:some_test_page)
|
20
20
|
tp.fire_fill_textarea
|
21
|
-
|
21
|
+
tp.validate_textarea_value('Default data').should be(true)
|
22
22
|
end
|
23
23
|
|
24
24
|
context "xxx not found among current_page actions" do
|
@@ -31,14 +31,14 @@ describe "page_object.fire_xxx" do
|
|
31
31
|
it "can be invoked with parameters" do
|
32
32
|
tp = PageObjectWrapper.current_page
|
33
33
|
tp.fire_fill_textarea('User defined data')
|
34
|
-
|
34
|
+
tp.validate_textarea_value('User defined data').should be(true)
|
35
35
|
end
|
36
36
|
|
37
37
|
context "xxx is alias" do
|
38
38
|
it "executes corresponding action" do
|
39
39
|
tp = PageObjectWrapper.open_page(:some_test_page)
|
40
40
|
tp.fire_fill_textarea_alias
|
41
|
-
|
41
|
+
tp.validate_textarea_value('Default data').should be(true)
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
data/spec/load_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: page_object_wrapper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -13,7 +13,7 @@ date: 2012-12-23 00:00:00.000000000Z
|
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: watir-webdriver
|
16
|
-
requirement: &
|
16
|
+
requirement: &20975200 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *20975200
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: rspec
|
27
|
-
requirement: &
|
27
|
+
requirement: &20999680 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
version: 2.0.0
|
33
33
|
type: :development
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *20999680
|
36
36
|
description: Wraps watir-webdriver with convenient testing interface, based on PageObjects
|
37
37
|
automation testing pattern. Simplifies resulting automated test understanding.
|
38
38
|
email:
|
@@ -65,6 +65,7 @@ files:
|
|
65
65
|
- lib/page_object_wrapper/PageObject.rb
|
66
66
|
- lib/page_object_wrapper/Pagination.rb
|
67
67
|
- lib/page_object_wrapper/Table.rb
|
68
|
+
- lib/page_object_wrapper/Validator.rb
|
68
69
|
- lib/page_object_wrapper/known_elements.rb
|
69
70
|
- lib/page_object_wrapper/version.rb
|
70
71
|
- page_object_wrapper.gemspec
|
@@ -72,7 +73,7 @@ files:
|
|
72
73
|
- spec/defined_elements_spec.rb
|
73
74
|
- spec/each_page.rb
|
74
75
|
- spec/feed_elements_spec.rb
|
75
|
-
- spec/
|
76
|
+
- spec/fire_event_and_validate_spec.rb
|
76
77
|
- spec/generate_spec.rb
|
77
78
|
- spec/get_food_spec.rb
|
78
79
|
- spec/load_spec.rb
|
@@ -110,7 +111,7 @@ test_files:
|
|
110
111
|
- spec/defined_elements_spec.rb
|
111
112
|
- spec/each_page.rb
|
112
113
|
- spec/feed_elements_spec.rb
|
113
|
-
- spec/
|
114
|
+
- spec/fire_event_and_validate_spec.rb
|
114
115
|
- spec/generate_spec.rb
|
115
116
|
- spec/get_food_spec.rb
|
116
117
|
- spec/load_spec.rb
|