Class: PageFactory

Inherits:
Object
  • Object
show all
Defined in:
lib/test-factory/page_factory.rb

Overview

The PageFactory class provides a set of methods that allow the rapid creation of page element definitions–known colloquially as “page objects”. These elements are defined using Watir syntax. Please see www.watir.com if you are not familiar with Watir.

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(browser, visit = false) ⇒ PageFactory

As the PageFactory will be the superclass for all your page classes, having this initialize method here means it’s only written once.



8
9
10
11
12
13
# File 'lib/test-factory/page_factory.rb', line 8

def initialize browser, visit = false
  @browser = browser
  goto if visit
  expected_element if respond_to? :expected_element
  has_expected_title? if respond_to? :has_expected_title?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(sym, *args, &block) ⇒ Object

Catches any “missing” methods and passes them to the browser object–which means that Watir will take care of parsing them, so the assumption is that the method being passed is a valid method for the browser object.



18
19
20
# File 'lib/test-factory/page_factory.rb', line 18

def method_missing sym, *args, &block
  @browser.send sym, *args, &block
end

Class Method Details

.action(method_name, &block) ⇒ Object

The basic building block for interacting with elements on a page, such as links and buttons. Methods that take one or more parameters can be built with this as well.

Examples:

action(:continue) { |b| b.frm.button(:value=>"Continue").click } #=> Creates a #continue method that clicks the Continue button
action(:select_style) { |stylename, b| b.div(:text=>/#{Regexp.escape(stylename)}/).link(:text=>"Select").click } #=> #select_style(stylename)


71
72
73
74
75
# File 'lib/test-factory/page_factory.rb', line 71

def action method_name, &block
  define_method method_name.to_s do |*thing|
    Proc.new(&block).call *thing, self
  end
end

.button(button_text) ⇒ Object

Use this for buttons that are safe to define by their value attribute. This method will return two methods for interacting with the button: one that refers to the button itself, and one that clicks on it. Since it’s assumed that the most common thing done with a button is to click it, the method for clicking it will be named according to the value of the button, and the method for the button itself will have “_button” appended to it. Any special characters are stripped from the string. Capital letters are made lower case. And spaces and dashes are converted to underscores.

Examples:

button("Click Me For Fun!") #=> Creates the methods #click_me_for_fun and #click_me_for_fun_button


104
105
106
107
# File 'lib/test-factory/page_factory.rb', line 104

def button(button_text)
  element(damballa(button_text+"_button")) { |b| b.button(:value=>button_text) }
  action(damballa(button_text)) { |b| b.button(:value=>button_text).click }
end

.damballa(text) ⇒ Object

A helper method that converts the passed string into snake case. See the StringFactory module for more info.



111
112
113
# File 'lib/test-factory/page_factory.rb', line 111

def damballa(text)
  StringFactory::damballa(text)
end

.element(element_name) ⇒ Object Also known as: value

The basic building block of the page object classes. Use in conjunction with Watir to define all elements on a given page that are important to validate.

Examples:

element(:title) { |b| b.text_field(:id=>"title-id") }
value(:page_header) { |b| b.h3(:class=>"page_header").text }


56
57
58
59
60
61
# File 'lib/test-factory/page_factory.rb', line 56

def element element_name
  raise "#{element_name} is being defined twice in #{self}!" if self.instance_methods.include?(element_name.to_sym)
  define_method element_name.to_s do
    yield self
  end
end

.expected_element(element_name, timeout = 30) ⇒ Object

Define this in a page class and when that class is instantiated it will wait until that element appears on the page before continuing with the script.



34
35
36
37
38
# File 'lib/test-factory/page_factory.rb', line 34

def expected_element element_name, timeout=30
  define_method 'expected_element' do
    self.send(element_name).wait_until_present timeout
  end
end

.expected_title(expected_title) ⇒ Object

Define this in a page class and when the class is instantiated it will verify that the browser’s title matches the expected title. If there isn’t a match, it raises an error and halts the script.



43
44
45
46
47
48
# File 'lib/test-factory/page_factory.rb', line 43

def expected_title expected_title
  define_method 'has_expected_title?' do
    has_expected_title = expected_title.kind_of?(Regexp) ? expected_title =~ @browser.title : expected_title == @browser.title
    raise "Expected title '#{expected_title}' instead of '#{@browser.title}'" unless has_expected_title
  end
end

Use this for links that are safe to define by their text string. This method will return two methods for interacting with the link: one that refers to the link itself, and one that clicks on it. Since it’s assumed that the most common thing done with a link is to click it, the method for clicking it will be named according to the text of the link, and the method for the link itself will have “_link” appended to it. Any special characters are stripped from the string. Capital letters are made lower case. And spaces and dashes are converted to underscores.

Examples:

link("Click Me For Fun!") #=> Creates the methods #click_me_for_fun and #click_me_for_fun_link


88
89
90
91
# File 'lib/test-factory/page_factory.rb', line 88

def link(link_text)
  element(damballa(link_text+"_link")) { |b| b.link(:text=>link_text) }
  action(damballa(link_text)) { |b| b.link(:text=>link_text).click }
end

.page_url(url) ⇒ Object

Define this in a page class and when you use the “visit” method to instantiate the class it will enter the URL the browser’s address bar.



26
27
28
29
30
# File 'lib/test-factory/page_factory.rb', line 26

def page_url url
  define_method 'goto' do
    @browser.goto url
  end
end