Class: Gamera::Page

Inherits:
Object
  • Object
show all
Includes:
Capybara::DSL
Defined in:
lib/gamera/page.rb

Overview

This is a base class which implements common methods for page object classes.

You can use this to create a Ruby class which wraps a web page, providing an API for automating elements or processes on the page

Examples:

Page Object class for registration page

class NewRegistrationPage < Gamera::Page
  def initialize
    @url = 'http://example.com/registration/new'
    @url_matcher = /registration\/new/
  end

  # page elements
  def name_field
    find_field('Name')
  end

  def email_field
    find_field('Email Address')
  end

  def password_field
    find_field('Password')
  end

  def password_confirmation_field
    find_field('Confirm Password')
  end

  def instructions
  def instructions
    find('#instructions')
  end

  # page processes
  def save
    find_button('Save').click
  end

  def register_user(name:, email:, password:)
    name_field.set(name)
    email_field.set(email)
    password_field.set(password)
    password_confirmation_field.set(password)
    save
  end
end

# This could be used in a test or automation script, e.g.
...
reg_page = NewRegistrationPage.new
reg_page.visit
reg_page.register_user(name: 'Laurence Peltier',
                       email: '[email protected]',
                       password: 'super_secret')
...

Page class for general Rails page with flash messages

class RailsPage < Gamera::Page
  def flash_error_css
    'div.flash.error'
  end

  def flash_notice_css
    'div.flash.notice'
  end

  def flash_error
    find(flash_error_css)
  end

  def flash_notice
    find(flash_notice_css)
  end

  def has_flash_message?(message)
    has_css?(flash_notice_css, text: message)
  end

  def has_flash_error?(error)
    has_css?(flash_error_css, text: error)
  end

  def has_no_flash_error?
    has_no_css?(flash_error_css)
  end

  def has_no_flash_message?
    has_no_css?(flash_notice_css)
  end

  def has_submission_problems?
    has_flash_error?('There were problems with your submission')
  end

  def fail_if_submission_problems
    fail(SubmissionProblemsError, flash_error.text) if has_submission_problems?
  end
end

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, url_matcher = nil) ⇒ Page

Returns a new instance of Page


137
138
139
140
# File 'lib/gamera/page.rb', line 137

def initialize(url, url_matcher = nil)
  @url = url
  @url_matcher = url_matcher
end

Instance Attribute Details

#urlObject (readonly)

Returns the value of attribute url


135
136
137
# File 'lib/gamera/page.rb', line 135

def url
  @url
end

#url_matcherObject (readonly)

Returns the value of attribute url_matcher


135
136
137
# File 'lib/gamera/page.rb', line 135

def url_matcher
  @url_matcher
end

Instance Method Details

#displayed?(wait_time_seconds = Capybara.default_wait_time) ⇒ Boolean

Check to see if we eventually land on the right page

Parameters:

  • wait_time_seconds (Integer) (defaults to: Capybara.default_wait_time)

    How long to wait for the correct page to load

Returns:

  • (Boolean)

    true if the url loaded in the browser matches the url_matcher pattern

Raises:


158
159
160
161
162
163
164
165
166
167
# File 'lib/gamera/page.rb', line 158

def displayed?(wait_time_seconds = Capybara.default_wait_time)
  fail Gamera::NoUrlMatcherForPage if url_matcher.nil?
  start_time = Time.now
  loop do
    return true if page.current_url.chomp('/') =~ url_matcher
    break unless Time.now - start_time <= wait_time_seconds
    sleep(0.05)
  end
  false
end

#path_join(*elements) ⇒ String

This is a utility method to clean up URLs formed by concatenation since we sometimes ended up with “//” in the middle of URLs which broke the url_matcher checks.

Parameters:

  • elements (String)

    duck types

Returns:

  • (String)

    of elements joined by single “/” characters.


201
202
203
# File 'lib/gamera/page.rb', line 201

def path_join(*elements)
  "/#{elements.join('/')}".gsub(%r(//+), '/')
end

#sparse?Boolean

This is a flag for tracking which page object classes don't cover all of the elements and/or controls on the target web page.

Returns:

  • (Boolean)

    true unless everything's been captured in the page object class


191
192
193
# File 'lib/gamera/page.rb', line 191

def sparse?
  false
end

#visit(fail_on_redirect = true) ⇒ Object

Open the page url in the browser specified in your Capybara configuration

Parameters:

  • fail_on_redirect (Boolean) (defaults to: true)

    Whether to fail if the site redirects to a page that does not match the url_matcher regex

Raises:

  • (WrongPageVisited)

    if the site redirects to URL that doesn't match the url_matcher regex and fail_on_redirect is true


146
147
148
149
150
151
# File 'lib/gamera/page.rb', line 146

def visit(fail_on_redirect = true)
  super(url)
  if fail_on_redirect
    fail WrongPageVisited, "Expected URL '#{url}', got '#{page.current_url}'" unless displayed?
  end
end

#with_refreshes(retries, allowed_errors = [RSpec::Expectations::ExpectationNotMetError], &block) ⇒ Object

A method to wait for slow loading data on a page. Useful, for example, when waiting on a page that shows the count of records loaded via a slow web or import.

Parameters:

  • retries (Integer)

    Number of times to reload the page before giving up

  • allowed_errors (Array) (defaults to: [RSpec::Expectations::ExpectationNotMetError])

    Array of errors that trigger a refresh, e.g., if an ExpectationNotMetError was raised during an acceptance test

  • block (Block)

    The block to execute after each refresh


176
177
178
179
180
181
182
183
184
# File 'lib/gamera/page.rb', line 176

def with_refreshes(retries, allowed_errors = [RSpec::Expectations::ExpectationNotMetError], &block)
  retries_left ||= retries
  visit
  block.call(retries_left)
rescue *allowed_errors => e
  retries_left -= 1
  retry if retries_left >= 0
  raise e
end