page-object 0.3.1 → 0.3.2
Sign up to get free protection for your applications and to get access to all the features.
- data/ChangeLog +13 -1
- data/features/element.feature +10 -0
- data/features/headings.feature +54 -0
- data/features/html/nested_elements.html +6 -2
- data/features/html/static_elements.html +11 -26
- data/features/nested_elements.feature +14 -1
- data/features/step_definitions/element_steps.rb +4 -0
- data/features/step_definitions/headings_steps.rb +12 -0
- data/features/step_definitions/nested_elements_steps.rb +27 -0
- data/features/step_definitions/text_area_steps.rb +4 -0
- data/features/support/page.rb +24 -0
- data/features/text_area.feature +6 -0
- data/lib/page-object/accessors.rb +87 -0
- data/lib/page-object/element_locators.rb +45 -0
- data/lib/page-object/elements.rb +1 -0
- data/lib/page-object/elements/element.rb +1 -1
- data/lib/page-object/elements/heading.rb +7 -0
- data/lib/page-object/nested_elements.rb +12 -0
- data/lib/page-object/platforms/selenium_webdriver/element.rb +3 -12
- data/lib/page-object/platforms/selenium_webdriver/page_object.rb +72 -0
- data/lib/page-object/platforms/watir_webdriver/element.rb +3 -0
- data/lib/page-object/platforms/watir_webdriver/page_object.rb +57 -0
- data/lib/page-object/platforms/watir_webdriver/text_area.rb +7 -0
- data/lib/page-object/version.rb +1 -1
- data/page-object.gemspec +1 -1
- data/spec/page-object/accessors_spec.rb +135 -0
- data/spec/page-object/element_locators_spec.rb +18 -0
- data/spec/page-object/elements/element_spec.rb +42 -0
- data/spec/page-object/elements/heading_spec.rb +22 -0
- data/spec/page-object/elements/nested_element_spec.rb +33 -3
- metadata +11 -6
- data/features/element_attributes.feature +0 -233
data/ChangeLog
CHANGED
@@ -1,4 +1,16 @@
|
|
1
|
-
=== Version
|
1
|
+
=== Version 0.3.2 / 2011-09-22
|
2
|
+
* Enhancements
|
3
|
+
* Element#when_present now returns the element object
|
4
|
+
* Element#when_visible now returns the element object
|
5
|
+
* Element#when_not_visible now returns the element object
|
6
|
+
* Added #clear method for TextArea
|
7
|
+
* Added support for Heading element
|
8
|
+
* Added all of the h1 locators
|
9
|
+
* Added all of the h2 locators
|
10
|
+
* Added all of the h3 locators
|
11
|
+
* Updated to use selenium-webdriver 2.6.0
|
12
|
+
|
13
|
+
=== Version 0.3.1 / 2011-09-08
|
2
14
|
* Enhancements
|
3
15
|
* Updated to use watir-webdriver 0.3.3
|
4
16
|
|
data/features/element.feature
CHANGED
@@ -237,3 +237,13 @@ Feature: Elements
|
|
237
237
|
And I should know its' tag name is "ol"
|
238
238
|
And I should know the attribute "readonly" is false
|
239
239
|
And I should be able to click it
|
240
|
+
|
241
|
+
Scenario: Heading element methods
|
242
|
+
When I retrieve a heading element
|
243
|
+
Then I should know it exists
|
244
|
+
And I should know it is visible
|
245
|
+
And I should know its' text is "h1's are cool"
|
246
|
+
And I should know it is equal to itself
|
247
|
+
And I should know its' tag name is "h1"
|
248
|
+
And I should know the attribute "readonly" is false
|
249
|
+
And I should be able to click it
|
@@ -0,0 +1,54 @@
|
|
1
|
+
Feature: Headings
|
2
|
+
|
3
|
+
Background:
|
4
|
+
Given I am on the static elements page
|
5
|
+
|
6
|
+
Scenario: Getting the text of headings
|
7
|
+
When I get the text for the "h1" element
|
8
|
+
Then I should see "h1's are cool"
|
9
|
+
When I get the text for the "h2" element
|
10
|
+
Then I should see "h2's are cool"
|
11
|
+
When I get the text for the "h3" element
|
12
|
+
Then I should see "h3's are cool"
|
13
|
+
# When I get the text for the "h4" element
|
14
|
+
# Then I should see "h4's are cool"
|
15
|
+
# When I get the text for the "h5" element
|
16
|
+
# Then I should see "h5's are cool"
|
17
|
+
# When I get the text for the "h6" element
|
18
|
+
# Then I should see "h6's are cool"
|
19
|
+
|
20
|
+
Scenario Outline: Locating h1s on the Page
|
21
|
+
When I search for the heading1 by "<search_by>"
|
22
|
+
Then I should see "h1's are cool"
|
23
|
+
|
24
|
+
Scenarios:
|
25
|
+
| search_by |
|
26
|
+
| id |
|
27
|
+
| class |
|
28
|
+
| name |
|
29
|
+
| xpath |
|
30
|
+
| index |
|
31
|
+
|
32
|
+
Scenario Outline: Locating h2s on the Page
|
33
|
+
When I search for the heading2 by "<search_by>"
|
34
|
+
Then I should see "h2's are cool"
|
35
|
+
|
36
|
+
Scenarios:
|
37
|
+
| search_by |
|
38
|
+
| id |
|
39
|
+
| class |
|
40
|
+
| name |
|
41
|
+
| xpath |
|
42
|
+
| index |
|
43
|
+
|
44
|
+
Scenario Outline: Locating h3s on the Page
|
45
|
+
When I search for the heading3 by "<search_by>"
|
46
|
+
Then I should see "h3's are cool"
|
47
|
+
|
48
|
+
Scenarios:
|
49
|
+
| search_by |
|
50
|
+
| id |
|
51
|
+
| class |
|
52
|
+
| name |
|
53
|
+
| xpath |
|
54
|
+
| index |
|
@@ -3,7 +3,6 @@
|
|
3
3
|
<title>Nested Elements</title>
|
4
4
|
</head>
|
5
5
|
<body>
|
6
|
-
<h1>Nested Elements</h1>
|
7
6
|
|
8
7
|
<div id="div_id">
|
9
8
|
<a href="success.html">Success</a>
|
@@ -36,7 +35,12 @@
|
|
36
35
|
<ul>
|
37
36
|
<li>Item One</li>
|
38
37
|
<li>Item Two</li>
|
39
|
-
</ul
|
38
|
+
</ul
|
39
|
+
|
40
40
|
</div>
|
41
|
+
<h1>h1's are cool</h1>
|
42
|
+
<h2>h2's are cool</h2>
|
43
|
+
<h3>h3's are cool</h3>
|
44
|
+
|
41
45
|
</body>
|
42
46
|
</html>
|
@@ -3,49 +3,37 @@
|
|
3
3
|
<title>Static Elements Page</title>
|
4
4
|
</head>
|
5
5
|
<body>
|
6
|
-
<
|
6
|
+
<p>Static Elements Page</p>
|
7
7
|
|
8
|
-
|
9
|
-
<h3>Text Field</h3>
|
10
8
|
<input id="text_field_id" name="text_field_name" class="text_field_class"
|
11
9
|
size="40" type="text"/>
|
12
10
|
|
13
|
-
<h3>Hidden Field</h3>
|
14
11
|
<input id="hidden_field_id" name="hidden_field_name" class="hidden_field_class"
|
15
12
|
size="40" type="hidden" value="12345"/>
|
16
13
|
|
17
|
-
<h3>Text Area</h3>
|
18
14
|
<textarea rows="2" cols="20" id="text_area_id" class="text_area_class" name="text_area_name"></textarea>
|
19
15
|
|
20
|
-
<h3>Select List</h3>
|
21
16
|
<select name="sel_list_name" id="sel_list_id", class="sel_list_class">
|
22
17
|
<option value="option1">Test 1</option>
|
23
18
|
<option value="option2">Test 2</option>
|
24
19
|
</select>
|
25
20
|
|
26
21
|
|
27
|
-
<h3>Link</h3>
|
28
22
|
<a href="success.html" id="link_id" name="link_name" class="link_class">Google Search</a>
|
29
23
|
|
30
|
-
<h3>Check Boxes</h3>
|
31
24
|
<input id="cb_id" name="cb_name" class="cb_class" type="checkbox" value="1"/>
|
32
25
|
|
33
|
-
<h3>Radio Buttons</h3>
|
34
26
|
<input type="radio" id="milk_id" name="milk_name" class="milk_class" value="Milk"> Milk <br/>
|
35
27
|
<input type="radio" id="butter_id" name="butter_name" class="butter_class" value="Butter">Butter
|
36
28
|
|
37
|
-
<h3>Div</h3>
|
38
|
-
|
39
29
|
<div id="div_id" name="div_name" class="div_class">
|
40
30
|
page-object rocks!
|
41
31
|
</div>
|
42
32
|
|
43
|
-
<
|
44
|
-
|
45
|
-
|
46
|
-
</span>
|
33
|
+
<span id="span_id" name="span_name" class="span_class">
|
34
|
+
My alert
|
35
|
+
</span>
|
47
36
|
|
48
|
-
<h3>Table</h3>
|
49
37
|
<table id='table_id' name='table_name' class='table_class' border='1'>
|
50
38
|
<tr>
|
51
39
|
<td>Data1</td>
|
@@ -57,45 +45,42 @@
|
|
57
45
|
</tr>
|
58
46
|
</table>
|
59
47
|
|
60
|
-
<h3>Button</h3>
|
61
|
-
|
62
48
|
<form method="get" action="success.html">
|
63
49
|
<input id='button_id' name='button_name' class='button_class' type="submit" value="Click Me">
|
64
50
|
</form>
|
65
51
|
|
66
|
-
<h3>Image</h3>
|
67
52
|
<img src="images/circle.png" id="image_id" name="image_name" class="image_class">
|
68
53
|
|
69
|
-
<h3>Form</h3>
|
70
|
-
|
71
54
|
<form id="form_id" class="form_class" name="form_name" action="/">
|
72
55
|
</form>
|
73
56
|
|
74
|
-
<h3>Unordered List</h3>
|
75
57
|
<ul id="ul_id" name="ul_name" class="ul_class">
|
76
58
|
<li id="li_id" name="li_name" class="li_class">Item One</li>
|
77
59
|
<li>Item Two</li>
|
78
60
|
<li>Item Three</li>
|
79
61
|
</ul>
|
80
62
|
|
81
|
-
<h3>Ordered List</h3>
|
82
63
|
<ol id="ol_id" name="ol_name" class="ol_class">
|
83
64
|
<li>Number One</li>
|
84
65
|
<li>Number Two</li>
|
85
66
|
<li>Number Three</li>
|
86
67
|
</ol>
|
87
68
|
|
88
|
-
<h3>Links for multi select</h3>
|
89
69
|
<a href="success.html">Hello</a>
|
90
70
|
<a href="success.html">Hello</a>
|
91
71
|
<a href="success.html">Hello</a>
|
92
72
|
|
93
|
-
<h3>Alerts / Confirms / Prompts</h3>
|
94
73
|
<input id=alert_button type=button onclick="alert('I am an alert')" value=Alert>
|
95
74
|
<input id=confirm_button type=button onclick="this.value = confirm('set the value')" value=Confirm>
|
96
75
|
<input id=prompt_button type=button onclick='this.value = prompt("enter your name", "John Doe")' value=Prompt>
|
97
76
|
|
98
|
-
<
|
77
|
+
<h1 id="h1_id" class="h1_class" name="h1_name">h1's are cool</h1>
|
78
|
+
<h2 id="h2_id" class="h2_class" name="h2_name">h2's are cool</h2>
|
79
|
+
<h3 id="h3_id" class="h3_class" name="h3_name">h3's are cool</h3>
|
80
|
+
<h4 id="h4_id" class="h4_class" name="h4_name">h4's are cool</h4>
|
81
|
+
<h5 id="h5_id" class="h5_class" name="h5_name">h5's are cool</h5>
|
82
|
+
<h6 id="h6_id" class="h6_class" name="h6_name">h6's are cool</h6>
|
83
|
+
|
99
84
|
<a href="success.html" target="_blank">New Window</a>
|
100
85
|
</body>
|
101
86
|
</html>
|
@@ -1,4 +1,4 @@
|
|
1
|
-
Feature:
|
1
|
+
Feature: Nested Elements
|
2
2
|
|
3
3
|
Background:
|
4
4
|
Given I am on the nested elements page
|
@@ -71,3 +71,16 @@ Feature: Attributes on Elements
|
|
71
71
|
Scenario: Finding a list item nested in an ordered list within a div
|
72
72
|
When I search for a list item nested in an ordered list in a div
|
73
73
|
Then I should see the nested list items text should be "Number One"
|
74
|
+
|
75
|
+
Scenario: Finding a h1 within a div
|
76
|
+
When I search for a h1 located list in a div
|
77
|
+
Then I should see the nested h1s text should be "h1's are cool"
|
78
|
+
|
79
|
+
Scenario: Finding a h2 within a div
|
80
|
+
When I search for a h2 located list in a div
|
81
|
+
Then I should see the nested h2s text should be "h2's are cool"
|
82
|
+
|
83
|
+
Scenario: Finding a h3 within a div
|
84
|
+
When I search for a h3 located list in a div
|
85
|
+
Then I should see the nested h3s text should be "h3's are cool"
|
86
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
When /^I get the text for the "([^\"]*)" element$/ do |el|
|
2
|
+
@heading = @page.send "#{el}_id"
|
3
|
+
end
|
4
|
+
|
5
|
+
Then /^I should see "([^\"]*)"$/ do |text|
|
6
|
+
@heading.should == text
|
7
|
+
end
|
8
|
+
|
9
|
+
When /^I search for the heading(\d+) by "([^"]*)"$/ do |head_type, type|
|
10
|
+
@heading = @page.send "h#{head_type}_#{type}"
|
11
|
+
end
|
12
|
+
|
@@ -19,6 +19,9 @@ class NestedElementsPage
|
|
19
19
|
ordered_list(:nested_ordered_list) { |page| page.outer_div_element.ordered_list_element }
|
20
20
|
unordered_list(:nested_unordered_list) { |page| page.outer_div_element.unordered_list_element }
|
21
21
|
list_item(:nested_list_item) { |page| page.nested_ordered_list_element.list_item_element }
|
22
|
+
h1(:nested_h1) { |page| page.outer_div_element.h1_element}
|
23
|
+
h2(:nested_h2) { |page| page.outer_div_element.h2_element }
|
24
|
+
h3(:nested_h3) { |page| page.outer_div_element.h3_element }
|
22
25
|
end
|
23
26
|
|
24
27
|
Given /^I am on the nested elements page$/ do
|
@@ -163,3 +166,27 @@ end
|
|
163
166
|
Then /^I should see the nested list items text should be "([^"]*)"$/ do |value|
|
164
167
|
@li.text.should == value
|
165
168
|
end
|
169
|
+
|
170
|
+
When /^I search for a h1 located list in a div$/ do
|
171
|
+
@h1 = @page.nested_h1_element
|
172
|
+
end
|
173
|
+
|
174
|
+
Then /^I should see the nested h1s text should be "([^"]*)"$/ do |value|
|
175
|
+
@h1.text.should == value
|
176
|
+
end
|
177
|
+
|
178
|
+
When /^I search for a h2 located list in a div$/ do
|
179
|
+
@h2 = @page.nested_h2_element
|
180
|
+
end
|
181
|
+
|
182
|
+
Then /^I should see the nested h2s text should be "([^"]*)"$/ do |value|
|
183
|
+
@h2.text.should == value
|
184
|
+
end
|
185
|
+
|
186
|
+
When /^I search for a h3 located list in a div$/ do
|
187
|
+
@h3 = @page.nested_h3_element
|
188
|
+
end
|
189
|
+
|
190
|
+
Then /^I should see the nested h3s text should be "([^"]*)"$/ do |value|
|
191
|
+
@h3.text.should == value
|
192
|
+
end
|
data/features/support/page.rb
CHANGED
@@ -163,6 +163,30 @@ class Page
|
|
163
163
|
ordered_list(:ol_xpath, :xpath => '//ol')
|
164
164
|
ordered_list(:ol_class_index, :class => "ol_class", :index => 0)
|
165
165
|
ordered_list(:ol_name_index, :name => "ol_name", :index => 0)
|
166
|
+
|
167
|
+
h1(:h1_id, :id => 'h1_id')
|
168
|
+
h1(:h1_class, :class => 'h1_class')
|
169
|
+
h1(:h1_name, :name => 'h1_name')
|
170
|
+
h1(:h1_index, :index => 0)
|
171
|
+
h1(:h1_xpath, :xpath => '//h1')
|
172
|
+
h1(:h1_class_index, :class => 'h1_class', :index => 0)
|
173
|
+
h1(:h1_name_index, :name => 'h1_name', :index => 0)
|
174
|
+
|
175
|
+
h2(:h2_id, :id => 'h2_id')
|
176
|
+
h2(:h2_class, :class => 'h2_class')
|
177
|
+
h2(:h2_name, :name => 'h2_name')
|
178
|
+
h2(:h2_index, :index => 0)
|
179
|
+
h2(:h2_xpath, :xpath => '//h2')
|
180
|
+
h2(:h2_class_index, :class => 'h2_class', :index => 0)
|
181
|
+
h2(:h2_name_index, :name => 'h2_name', :index => 0)
|
182
|
+
|
183
|
+
h3(:h3_id, :id => 'h3_id')
|
184
|
+
h3(:h3_class, :class => 'h3_class')
|
185
|
+
h3(:h3_name, :name => 'h3_name')
|
186
|
+
h3(:h3_index, :index => 0)
|
187
|
+
h3(:h3_xpath, :xpath => '//h3')
|
188
|
+
h3(:h3_class_index, :class => 'h3_class', :index => 0)
|
189
|
+
h3(:h3_name_index, :name => 'h3_name', :index => 0)
|
166
190
|
|
167
191
|
button(:alert_button, :id => 'alert_button')
|
168
192
|
button(:confirm_button, :id => 'confirm_button')
|
data/features/text_area.feature
CHANGED
@@ -35,3 +35,9 @@ Feature: Text Area
|
|
35
35
|
Scenario: Finding a text area dynamically
|
36
36
|
When I find a text area while the script is executing
|
37
37
|
Then I should be able to type "I found it" into the area element
|
38
|
+
|
39
|
+
Scenario: Clearing the text area
|
40
|
+
When I type "abcdefghijklmnop" into the text area
|
41
|
+
Then the text area should contain "abcdefghijklmnop"
|
42
|
+
When I clear the text area
|
43
|
+
Then the text area should contain ""
|
@@ -581,5 +581,92 @@ module PageObject
|
|
581
581
|
end
|
582
582
|
alias_method "#{name}_ordered_list".to_sym, "#{name}_element".to_sym
|
583
583
|
end
|
584
|
+
|
585
|
+
#
|
586
|
+
# adds a method to retrieve the text of a h1 and a h1 element
|
587
|
+
#
|
588
|
+
# @example
|
589
|
+
# h1(:title, :id => 'title')
|
590
|
+
# # will generate a 'title' and 'title_element' method
|
591
|
+
#
|
592
|
+
# @param [String] the name used for the generated methods
|
593
|
+
# @param [Hash] identifier how we find a H1. You can use a multiple paramaters
|
594
|
+
# by combining of any of the following except xpath. The valid keys are:
|
595
|
+
# * :class => Watir and Selenium
|
596
|
+
# * :id => Watir and Selenium
|
597
|
+
# * :index => Watir and Selenium
|
598
|
+
# * :name => Watir and Selenium
|
599
|
+
# * :xpath => Watir and Selenium
|
600
|
+
# @param optional block to be invoked when element method is called
|
601
|
+
#
|
602
|
+
def h1(name, identifier=nil, &block)
|
603
|
+
define_method(name) do
|
604
|
+
return platform.h1_text_for identifier.clone unless block_given?
|
605
|
+
self.send("#{name}_element").text
|
606
|
+
end
|
607
|
+
define_method("#{name}_element") do
|
608
|
+
return call_block(&block) if block_given?
|
609
|
+
platform.h1_for(identifier.clone)
|
610
|
+
end
|
611
|
+
alias_method "#{name}_h1".to_sym, "#{name}_element".to_sym
|
612
|
+
end
|
613
|
+
|
614
|
+
#
|
615
|
+
# adds a method to retrieve the text of a h2 and a h2 element
|
616
|
+
#
|
617
|
+
# @example
|
618
|
+
# h2(:title, :id => 'title')
|
619
|
+
# # will generate a 'title' and 'title_element' method
|
620
|
+
#
|
621
|
+
# @param [String] the name used for the generated methods
|
622
|
+
# @param [Hash] identifier how we find a H2. You can use a multiple paramaters
|
623
|
+
# by combining of any of the following except xpath. The valid keys are:
|
624
|
+
# * :class => Watir and Selenium
|
625
|
+
# * :id => Watir and Selenium
|
626
|
+
# * :index => Watir and Selenium
|
627
|
+
# * :name => Watir and Selenium
|
628
|
+
# * :xpath => Watir and Selenium
|
629
|
+
# @param optional block to be invoked when element method is called
|
630
|
+
#
|
631
|
+
def h2(name, identifier=nil, &block)
|
632
|
+
define_method(name) do
|
633
|
+
return platform.h2_text_for identifier.clone unless block_given?
|
634
|
+
self.send("#{name}_element").text
|
635
|
+
end
|
636
|
+
define_method("#{name}_element") do
|
637
|
+
return call_block(&block) if block_given?
|
638
|
+
platform.h2_for(identifier.clone)
|
639
|
+
end
|
640
|
+
alias_method "#{name}_h2".to_sym, "#{name}_element".to_sym
|
641
|
+
end
|
642
|
+
|
643
|
+
#
|
644
|
+
# adds a method to retrieve the text of a h3 and a h3 element
|
645
|
+
#
|
646
|
+
# @example
|
647
|
+
# h3(:title, :id => 'title')
|
648
|
+
# # will generate a 'title' and 'title_element' method
|
649
|
+
#
|
650
|
+
# @param [String] the name used for the generated methods
|
651
|
+
# @param [Hash] identifier how we find a H3. You can use a multiple paramaters
|
652
|
+
# by combining of any of the following except xpath. The valid keys are:
|
653
|
+
# * :class => Watir and Selenium
|
654
|
+
# * :id => Watir and Selenium
|
655
|
+
# * :index => Watir and Selenium
|
656
|
+
# * :name => Watir and Selenium
|
657
|
+
# * :xpath => Watir and Selenium
|
658
|
+
# @param optional block to be invoked when element method is called
|
659
|
+
#
|
660
|
+
def h3(name, identifier=nil, &block)
|
661
|
+
define_method(name) do
|
662
|
+
return platform.h3_text_for identifier.clone unless block_given?
|
663
|
+
self.send("#{name}_element").text
|
664
|
+
end
|
665
|
+
define_method("#{name}_element") do
|
666
|
+
return call_block(&block) if block_given?
|
667
|
+
platform.h3_for(identifier.clone)
|
668
|
+
end
|
669
|
+
alias_method "#{name}_h3".to_sym, "#{name}_element".to_sym
|
670
|
+
end
|
584
671
|
end
|
585
672
|
end
|