page-object 0.0.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.
- data/.gitignore +6 -0
- data/Gemfile +3 -0
- data/LICENSE +20 -0
- data/README.md +87 -0
- data/Rakefile +51 -0
- data/cucumber.yml +5 -0
- data/features/check_box.feature +39 -0
- data/features/html/static_elements.html +34 -0
- data/features/link.feature +42 -0
- data/features/page_level_actions.feature +19 -0
- data/features/radio_button.feature +40 -0
- data/features/select_list.feature +40 -0
- data/features/step_definitions/accessor_steps.rb +88 -0
- data/features/step_definitions/element_steps.rb +28 -0
- data/features/step_definitions/page_level_actions_steps.rb +12 -0
- data/features/step_definitions/page_traversal_steps.rb +5 -0
- data/features/support/env.rb +18 -0
- data/features/support/page.rb +45 -0
- data/features/support/url_helper.rb +16 -0
- data/features/text_field.feature +39 -0
- data/lib/page-object.rb +52 -0
- data/lib/page-object/accessors.rb +171 -0
- data/lib/page-object/elements.rb +8 -0
- data/lib/page-object/elements/button.rb +15 -0
- data/lib/page-object/elements/check_box.rb +15 -0
- data/lib/page-object/elements/element.rb +52 -0
- data/lib/page-object/elements/link.rb +34 -0
- data/lib/page-object/elements/radio_button.rb +15 -0
- data/lib/page-object/elements/select_list.rb +21 -0
- data/lib/page-object/elements/text_field.rb +33 -0
- data/lib/page-object/selenium_element.rb +12 -0
- data/lib/page-object/selenium_page_object.rb +190 -0
- data/lib/page-object/version.rb +3 -0
- data/lib/page-object/watir_element.rb +12 -0
- data/lib/page-object/watir_page_object.rb +190 -0
- data/page-object.gemspec +29 -0
- data/spec/page-object/accessors_spec.rb +297 -0
- data/spec/page-object/elements/button_spec.rb +23 -0
- data/spec/page-object/elements/check_box_spec.rb +21 -0
- data/spec/page-object/elements/element_spec.rb +54 -0
- data/spec/page-object/elements/link_spec.rb +34 -0
- data/spec/page-object/elements/radio_button_spec.rb +21 -0
- data/spec/page-object/elements/select_list_spec.rb +22 -0
- data/spec/page-object/elements/text_field_spec.rb +32 -0
- data/spec/page-object/page-object_spec.rb +78 -0
- data/spec/spec_helper.rb +31 -0
- metadata +179 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
When /^I retrieve a check box element$/ do
|
2
|
+
@element = @page.cb_id_checkbox
|
3
|
+
end
|
4
|
+
|
5
|
+
When /^I retrieve a link element$/ do
|
6
|
+
@element = @page.google_search_id_link
|
7
|
+
end
|
8
|
+
|
9
|
+
When /^I retrieve a radio button$/ do
|
10
|
+
@element = @page.milk_id_radio_button
|
11
|
+
end
|
12
|
+
|
13
|
+
When /^I retrieve a select list$/ do
|
14
|
+
@element = @page.sel_list_id_select_list
|
15
|
+
end
|
16
|
+
|
17
|
+
When /^I retrieve a text field$/ do
|
18
|
+
@element = @page.text_field_id_text_field
|
19
|
+
end
|
20
|
+
|
21
|
+
Then /^I should know it exists$/ do
|
22
|
+
@element.should exist
|
23
|
+
end
|
24
|
+
|
25
|
+
Then /^I should know it is visible$/ do
|
26
|
+
@element.should be_visible
|
27
|
+
end
|
28
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
Then /^the page should contain the text "([^\"]*)"$/ do |text|
|
3
|
+
@page.text.should include text
|
4
|
+
end
|
5
|
+
|
6
|
+
Then /^the page should contain the html "([^\"]*)"$/ do |html|
|
7
|
+
@page.html.should include html
|
8
|
+
end
|
9
|
+
|
10
|
+
Then /^the page should have the title "([^\"]*)"$/ do |title|
|
11
|
+
@page.title.should include title
|
12
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '../../', 'lib'))
|
2
|
+
|
3
|
+
require 'rspec/expectations'
|
4
|
+
require 'watir-webdriver'
|
5
|
+
require 'selenium-webdriver'
|
6
|
+
|
7
|
+
require 'page-object'
|
8
|
+
|
9
|
+
Before do
|
10
|
+
@browser = Watir::Browser.new :firefox if ENV['DRIVER'] == 'WATIR'
|
11
|
+
@browser = Selenium::WebDriver.for :firefox if ENV['DRIVER'] == 'SELENIUM'
|
12
|
+
end
|
13
|
+
|
14
|
+
After do |s|
|
15
|
+
@browser.close
|
16
|
+
end
|
17
|
+
|
18
|
+
|
@@ -0,0 +1,45 @@
|
|
1
|
+
class Page
|
2
|
+
include PageObject
|
3
|
+
|
4
|
+
text_field(:text_field_id, :id => "text_field_id")
|
5
|
+
text_field(:text_field_class, :class => "text_field_class")
|
6
|
+
text_field(:text_field_name, :name => "text_field_name")
|
7
|
+
text_field(:text_field_xpath, :xpath => "//input[@type='text']")
|
8
|
+
text_field(:text_field_css, :css => "input[type='text']")
|
9
|
+
text_field(:text_field_tag_name, :tag_name => "input[type='text']")
|
10
|
+
text_field(:text_field_index, :index => 0)
|
11
|
+
text_field(:text_field_text, :text => "")
|
12
|
+
text_field(:text_field_value, :value => "")
|
13
|
+
|
14
|
+
link(:google_search_id, :id => "link_id")
|
15
|
+
link(:google_search_name, :name => "link_name")
|
16
|
+
link(:google_search_class, :class => "link_class")
|
17
|
+
link(:google_search_xpath, :xpath => "//a[text()='Google Search']")
|
18
|
+
link(:google_search_link, :link => "Google Search")
|
19
|
+
link(:google_search_link_text, :link_text => "Google Search")
|
20
|
+
link(:google_search_href, :href => "http://www.google.com")
|
21
|
+
link(:google_search_text, :text => "Google Search")
|
22
|
+
link(:google_search_index, :index => 0)
|
23
|
+
|
24
|
+
select_list(:sel_list_id, :id => "sel_list_id")
|
25
|
+
select_list(:sel_list_class, :class => "sel_list_class")
|
26
|
+
select_list(:sel_list_index, :index => 0)
|
27
|
+
select_list(:sel_list_name, :name => "sel_list_name")
|
28
|
+
select_list(:sel_list_value, :value => "option1")
|
29
|
+
select_list(:sel_list_xpath, :xpath => "//select")
|
30
|
+
select_list(:sel_list_text, :text => "Test 1")
|
31
|
+
|
32
|
+
checkbox(:cb_id, :id => 'cb_id')
|
33
|
+
checkbox(:cb_name, :name => 'cb_name')
|
34
|
+
checkbox(:cb_class, :class => 'cb_class')
|
35
|
+
checkbox(:cb_index, :index => 0)
|
36
|
+
checkbox(:cb_xpath, :xpath => "//input[@type='checkbox']")
|
37
|
+
|
38
|
+
radio_button(:milk_id, :id => 'milk_id')
|
39
|
+
radio_button(:milk_name, :name => 'milk_name')
|
40
|
+
radio_button(:milk_class, :class => 'milk_class')
|
41
|
+
radio_button(:milk_index, :index => 0)
|
42
|
+
radio_button(:milk_xpath, :xpath => "//input[@type='radio']")
|
43
|
+
|
44
|
+
radio_button(:butter_id, :id => 'butter_id')
|
45
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
Feature: Text Fields
|
2
|
+
In order to interact with text fields
|
3
|
+
Testers will need access and interrogation ability
|
4
|
+
|
5
|
+
|
6
|
+
Background:
|
7
|
+
Given I am on the static elements page
|
8
|
+
|
9
|
+
Scenario: Setting and getting a value from a text field
|
10
|
+
When I type "abcDEF" into the text field
|
11
|
+
Then the text field should contain "abcDEF"
|
12
|
+
|
13
|
+
Scenario Outline: Locating text fields on the Page
|
14
|
+
When I search for the text field by "<search_by>"
|
15
|
+
Then I should be able to type "I found it" into the field
|
16
|
+
|
17
|
+
Scenarios:
|
18
|
+
| search_by |
|
19
|
+
| id |
|
20
|
+
| class |
|
21
|
+
| name |
|
22
|
+
| xpath |
|
23
|
+
| css |
|
24
|
+
| tag_name |
|
25
|
+
|
26
|
+
@watir_only
|
27
|
+
Scenario Outline: Locating text fields on Watir only
|
28
|
+
When I search for the text field by "<search_by>"
|
29
|
+
|
30
|
+
Scenarios:
|
31
|
+
| search_by |
|
32
|
+
| index |
|
33
|
+
| text |
|
34
|
+
| value |
|
35
|
+
|
36
|
+
Scenario: Retrieve a text field
|
37
|
+
When I retrieve a text field
|
38
|
+
Then I should know it exists
|
39
|
+
And I should know it is visible
|
data/lib/page-object.rb
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
require 'page-object/version'
|
3
|
+
require 'page-object/accessors'
|
4
|
+
|
5
|
+
# Module that when included adds core functionality to a page object.
|
6
|
+
module PageObject
|
7
|
+
attr_reader :platform
|
8
|
+
|
9
|
+
# Construct a new page object. The browser parameter must be either a
|
10
|
+
# Watir::Browser or Selenium::WebDriver::Driver.
|
11
|
+
def initialize(browser)
|
12
|
+
include_platform_driver(browser)
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.included(cls)
|
16
|
+
cls.extend PageObject::Accessors
|
17
|
+
end
|
18
|
+
|
19
|
+
# navigate to the provided url
|
20
|
+
def navigate_to(url)
|
21
|
+
platform.navigate_to(url)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Returns the text of the current page
|
25
|
+
def text
|
26
|
+
platform.text
|
27
|
+
end
|
28
|
+
|
29
|
+
# Returns the html of the current page
|
30
|
+
def html
|
31
|
+
platform.html
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns the title of the current page
|
35
|
+
def title
|
36
|
+
platform.title
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def include_platform_driver(browser)
|
42
|
+
if browser.is_a? Watir::Browser
|
43
|
+
require 'page-object/watir_page_object'
|
44
|
+
@platform = PageObject::WatirPageObject.new(browser)
|
45
|
+
elsif browser.is_a? Selenium::WebDriver::Driver
|
46
|
+
require 'page-object/selenium_page_object'
|
47
|
+
@platform = PageObject::SeleniumPageObject.new(browser)
|
48
|
+
else
|
49
|
+
raise ArgumentError, "expect Watir::Browser or Selenium::WebDriver::Driver"
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
|
2
|
+
#
|
3
|
+
# Contains the class level methods that are inserted into your page objects
|
4
|
+
# when you include the PageObject module. These methods will generate another
|
5
|
+
# set of methods that provide access to the elements on the web pages.
|
6
|
+
#
|
7
|
+
module PageObject
|
8
|
+
module Accessors
|
9
|
+
#
|
10
|
+
# adds three methods to the page object - one to set text in a text field,
|
11
|
+
# another to retrieve text from a text field and another to return the text
|
12
|
+
# field element.
|
13
|
+
#
|
14
|
+
# Example: text_field(:first_name, {:id => "first_name"})
|
15
|
+
# will generate the 'first_name', 'first_name=' and 'first_name_text_field methods.
|
16
|
+
#
|
17
|
+
# @param the name used for the generated methods
|
18
|
+
# @param identifier how we find a text_field. The valid values are:
|
19
|
+
# :class => Watir and Selenium
|
20
|
+
# :css => Watir and Selenium
|
21
|
+
# :id => Watir and Selenium
|
22
|
+
# :index => Watir only
|
23
|
+
# :name => Watir and Selenium
|
24
|
+
# :tag_name => Watir and Selenium
|
25
|
+
# :text => Watir only
|
26
|
+
# :value => Watir only
|
27
|
+
# :xpath => Watir and Selenium
|
28
|
+
#
|
29
|
+
def text_field(name, identifier)
|
30
|
+
define_method(name) do
|
31
|
+
platform.text_field_value_for identifier
|
32
|
+
end
|
33
|
+
define_method("#{name}=") do |value|
|
34
|
+
platform.text_field_value_set(identifier, value)
|
35
|
+
end
|
36
|
+
define_method("#{name}_text_field") do
|
37
|
+
platform.text_field_for identifier
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
#
|
42
|
+
# adds three methods - one to select an item in a drop-down,
|
43
|
+
# another to fetch the currently selected item and another
|
44
|
+
# to retrieve the select list element.
|
45
|
+
#
|
46
|
+
# Example: select_list(:state, {:id => "state"})
|
47
|
+
# will generate the 'state', 'state=' and 'state_select_list' methods
|
48
|
+
#
|
49
|
+
# @param the name used for the generated methods
|
50
|
+
# @param identifier how we find a select_list. The valid values are:
|
51
|
+
# :class => Watir and Selenium
|
52
|
+
# :id => Watir and Selenium
|
53
|
+
# :index => Watir only
|
54
|
+
# :name => Watir and Selenium
|
55
|
+
# :text => Watir only
|
56
|
+
# :value => Watir only
|
57
|
+
# :xpath => Watir and Selenium
|
58
|
+
#
|
59
|
+
def select_list(name, identifier)
|
60
|
+
define_method(name) do
|
61
|
+
platform.select_list_value_for identifier
|
62
|
+
end
|
63
|
+
define_method("#{name}=") do |value|
|
64
|
+
platform.select_list_value_set(identifier, value)
|
65
|
+
end
|
66
|
+
define_method("#{name}_select_list") do
|
67
|
+
platform.select_list_for identifier
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
#
|
72
|
+
# adds two methods - one to select a link and another
|
73
|
+
# to return a PageObject::Elements::Link object representing
|
74
|
+
# the link.
|
75
|
+
#
|
76
|
+
# Example: link(:add_to_cart, {:text => "Add to Cart"})
|
77
|
+
# will generate the 'add_to_cart' and 'add_to_cart_link'
|
78
|
+
# method.
|
79
|
+
#
|
80
|
+
# @param the name used for the generated methods
|
81
|
+
# @param identifier how we find a link. The valid values are:
|
82
|
+
# :class => Watir and Selenium
|
83
|
+
# :href => Watir only
|
84
|
+
# :id => Watir and Selenium
|
85
|
+
# :index => Watir only
|
86
|
+
# :link => Watir and Selenium
|
87
|
+
# :link_text => Watir and Selenium
|
88
|
+
# :name => Watir and Selenium
|
89
|
+
# :text => Watir and Selenium
|
90
|
+
# :xpath => Watir and Selenium
|
91
|
+
#
|
92
|
+
def link(name, identifier)
|
93
|
+
define_method(name) do
|
94
|
+
platform.click_link_for identifier
|
95
|
+
end
|
96
|
+
define_method("#{name}_link") do
|
97
|
+
platform.link_for identifier
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
#
|
102
|
+
# adds four methods - one to check, another to uncheck, another
|
103
|
+
# to return the state of a checkbox, and a final method to return
|
104
|
+
# a PageObject::Elements::CheckBox object representing the checkbox.
|
105
|
+
#
|
106
|
+
# Example: checkbox(:active, {:name => "is_active"})
|
107
|
+
# will generate the 'check_active', 'uncheck_active',
|
108
|
+
# 'active_checked?' and 'active_checkbox' methods.
|
109
|
+
#
|
110
|
+
# @param the name used for the generated methods
|
111
|
+
# @param identifier how we find a checkbox. The valid values are:
|
112
|
+
# :class => Watir and Selenium
|
113
|
+
# :id => Watir and Selenium
|
114
|
+
# :index => Watir only
|
115
|
+
# :name => Watir and Selenium
|
116
|
+
# :xpath => Watir and Selenium
|
117
|
+
#
|
118
|
+
def checkbox(name, identifier)
|
119
|
+
define_method("check_#{name}") do
|
120
|
+
platform.check_checkbox(identifier)
|
121
|
+
end
|
122
|
+
define_method("uncheck_#{name}") do
|
123
|
+
platform.uncheck_checkbox(identifier)
|
124
|
+
end
|
125
|
+
define_method("#{name}_checked?") do
|
126
|
+
platform.checkbox_checked?(identifier)
|
127
|
+
end
|
128
|
+
define_method("#{name}_checkbox") do
|
129
|
+
platform.checkbox_for identifier
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
#
|
134
|
+
# adds four methods - one to select, another to clear,
|
135
|
+
# another to return if a radio button is selected, and
|
136
|
+
# another method to return a PageObject::Elements::RadioButton
|
137
|
+
# object representing the radio button element
|
138
|
+
#
|
139
|
+
# Example: radio_button(:north, {:id => "north"})
|
140
|
+
# will generate 'select_north', 'clear_north',
|
141
|
+
# 'north_selected?' and 'north_radio_button' methods
|
142
|
+
#
|
143
|
+
# @param the name used for the generated methods
|
144
|
+
# @param identifier how we find a checkbox. The valid values are:
|
145
|
+
# :class => Watir and Selenium
|
146
|
+
# :id => Watir and Selenium
|
147
|
+
# :index => Watir only
|
148
|
+
# :name => Watir and Selenium
|
149
|
+
# :xpath => Watir and Selenium
|
150
|
+
#
|
151
|
+
def radio_button(name, identifier)
|
152
|
+
define_method("select_#{name}") do
|
153
|
+
platform.select_radio(identifier)
|
154
|
+
end
|
155
|
+
define_method("clear_#{name}") do
|
156
|
+
platform.clear_radio(identifier)
|
157
|
+
end
|
158
|
+
define_method("#{name}_selected?") do
|
159
|
+
platform.radio_selected?(identifier)
|
160
|
+
end
|
161
|
+
define_method("#{name}_radio_button") do
|
162
|
+
platform.radio_button_for identifier
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
def button(name, identifier)
|
167
|
+
define_method(name) do
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
|
2
|
+
require 'page-object/elements/element'
|
3
|
+
require 'page-object/elements/link'
|
4
|
+
require 'page-object/elements/text_field'
|
5
|
+
require 'page-object/elements/select_list'
|
6
|
+
require 'page-object/elements/check_box'
|
7
|
+
require 'page-object/elements/button'
|
8
|
+
require 'page-object/elements/radio_button'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module PageObject
|
2
|
+
module Elements
|
3
|
+
class Button < Element
|
4
|
+
|
5
|
+
def self.watir_identifier_for identifier
|
6
|
+
identifier_for identifier, watir_finders, watir_mapping
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.selenium_identifier_for identifier
|
10
|
+
identifier_for identifier, selenium_finders, selenium_mapping
|
11
|
+
return identifier.keys.first, identifier.values.first
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module PageObject
|
2
|
+
module Elements
|
3
|
+
class CheckBox < Element
|
4
|
+
|
5
|
+
def self.watir_identifier_for identifier
|
6
|
+
identifier_for identifier, watir_finders, watir_mapping
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.selenium_identifier_for identifier
|
10
|
+
identifier = identifier_for identifier, selenium_finders, selenium_mapping
|
11
|
+
return identifier.keys.first, identifier.values.first
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module PageObject
|
2
|
+
module Elements
|
3
|
+
|
4
|
+
#
|
5
|
+
# Contains functionality that is common across all elements.
|
6
|
+
#
|
7
|
+
class Element
|
8
|
+
|
9
|
+
def initialize(element, platform)
|
10
|
+
@element = element
|
11
|
+
include_platform_for platform
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.identifier_for identifier, find_by, find_by_mapping
|
15
|
+
how, what = identifier.keys.first, identifier.values.first
|
16
|
+
return how => what if find_by.include? how
|
17
|
+
return find_by_mapping[how] => what if find_by_mapping[how]
|
18
|
+
return nil => what
|
19
|
+
end
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def self.watir_finders
|
24
|
+
[:class, :id, :index, :name, :xpath]
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.watir_mapping
|
28
|
+
{}
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.selenium_finders
|
32
|
+
[:class, :id, :name, :xpath]
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.selenium_mapping
|
36
|
+
{}
|
37
|
+
end
|
38
|
+
|
39
|
+
private
|
40
|
+
|
41
|
+
def include_platform_for platform
|
42
|
+
if platform[:platform] == :watir
|
43
|
+
require 'page-object/watir_element'
|
44
|
+
self.class.send :include, PageObject::WatirElement
|
45
|
+
else
|
46
|
+
require 'page-object/selenium_element'
|
47
|
+
self.class.send :include, PageObject::SeleniumElement
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|