page-object 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/.gitignore +6 -0
  2. data/Gemfile +3 -0
  3. data/LICENSE +20 -0
  4. data/README.md +87 -0
  5. data/Rakefile +51 -0
  6. data/cucumber.yml +5 -0
  7. data/features/check_box.feature +39 -0
  8. data/features/html/static_elements.html +34 -0
  9. data/features/link.feature +42 -0
  10. data/features/page_level_actions.feature +19 -0
  11. data/features/radio_button.feature +40 -0
  12. data/features/select_list.feature +40 -0
  13. data/features/step_definitions/accessor_steps.rb +88 -0
  14. data/features/step_definitions/element_steps.rb +28 -0
  15. data/features/step_definitions/page_level_actions_steps.rb +12 -0
  16. data/features/step_definitions/page_traversal_steps.rb +5 -0
  17. data/features/support/env.rb +18 -0
  18. data/features/support/page.rb +45 -0
  19. data/features/support/url_helper.rb +16 -0
  20. data/features/text_field.feature +39 -0
  21. data/lib/page-object.rb +52 -0
  22. data/lib/page-object/accessors.rb +171 -0
  23. data/lib/page-object/elements.rb +8 -0
  24. data/lib/page-object/elements/button.rb +15 -0
  25. data/lib/page-object/elements/check_box.rb +15 -0
  26. data/lib/page-object/elements/element.rb +52 -0
  27. data/lib/page-object/elements/link.rb +34 -0
  28. data/lib/page-object/elements/radio_button.rb +15 -0
  29. data/lib/page-object/elements/select_list.rb +21 -0
  30. data/lib/page-object/elements/text_field.rb +33 -0
  31. data/lib/page-object/selenium_element.rb +12 -0
  32. data/lib/page-object/selenium_page_object.rb +190 -0
  33. data/lib/page-object/version.rb +3 -0
  34. data/lib/page-object/watir_element.rb +12 -0
  35. data/lib/page-object/watir_page_object.rb +190 -0
  36. data/page-object.gemspec +29 -0
  37. data/spec/page-object/accessors_spec.rb +297 -0
  38. data/spec/page-object/elements/button_spec.rb +23 -0
  39. data/spec/page-object/elements/check_box_spec.rb +21 -0
  40. data/spec/page-object/elements/element_spec.rb +54 -0
  41. data/spec/page-object/elements/link_spec.rb +34 -0
  42. data/spec/page-object/elements/radio_button_spec.rb +21 -0
  43. data/spec/page-object/elements/select_list_spec.rb +22 -0
  44. data/spec/page-object/elements/text_field_spec.rb +32 -0
  45. data/spec/page-object/page-object_spec.rb +78 -0
  46. data/spec/spec_helper.rb +31 -0
  47. 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,5 @@
1
+
2
+ Given /^I am on the static elements page$/ do
3
+ @page = Page.new(@browser)
4
+ @page.navigate_to(UrlHelper.static_elements)
5
+ 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,16 @@
1
+ module UrlHelper
2
+ class << self
3
+ def html
4
+ File.expand_path("#{File.dirname(__FILE__)}/../html")
5
+ end
6
+
7
+ def files
8
+ "file://#{html}"
9
+ end
10
+
11
+
12
+ def static_elements
13
+ "#{files}/static_elements.html"
14
+ end
15
+ end
16
+ 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
@@ -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