page-objectify

Build Status

A Ruby page class generator (for use with the page-object gem)

Why?

Normally, I’d advise against using a gem like this, because the page class shouldn't necessarily contain methods for every single HTML element on the page. In fact, if the page we are modeling is anything like the Google home page, our page class should only have one or 2 methods (a.k.a. PageObject::Accessors) for HTML elements: the search box and the submit button.

However, recently, almost all of the tests I have been writing have been for non-public facing sites, used by specialized, internal users who are trained on the platform. As a result, we end up with fairly dense webpages, with multiple different features and HTML elements that need interacting with, all on a single page.

Ultimately, this is the specific use case I am writing this gem for. Also, I wanted to learn a bit more about how a Ruby AST -- abstract syntax tree -- works and how the unparser gem allows me to generate working Ruby code from a dynamically generated AST.

Changes

This gem will follow semantic versioning. See changelog for changes in each version.

Installation

Ensure this gem and watir-webdriver are both in your Gemfile:

gem "page-objectify"
gem "watir-webdriver"

And then execute:

$ bundle

Usage

The supported usage of this gem is to:

  • create a SomethingPageGenerator class that inherits from PageObjectify::Generator
  • write a SomethingPageGenerator#visit method that opens a browser and navigates to the page you want to generate a page class for.
  • initialize the generator class & call #generate! in some kind of Rake task (that is typically executed manually.)

Here's a complete example (using the Google homepage, which, as I mention above, is a horrible use case, but it works for a demo):

# Gemfile
gem "chromedriver-helper", "~> 1.0"
gem "page-objectify"
gem "watir-webdriver", "~> 0.9.1"
# /generators/google_page_generator.rb
require "page-objectify/generator"
require "watir-webdriver"

class GooglePageGenerator < PageObjectify::Generator
  def visit
    @browser = Watir::Browser.new :chrome
    @browser.goto "www.google.com"
    sleep 1 # Use `wait_for_ajax` instead of `sleep`, if jQuery is available on the page!
  end
end
# Rakefile
require "generators/google_page_generator"

namespace :generate do
  task :po do
    # Specifying file path is optional
    GooglePageGenerator.new(file: "path/to/pages-dir/google_page.rb").generate!
    # and any other pages you want to generate programmatically
  end
end

Then, upon executing the rake task $ bundle exec rake generate:po, the following file will be generated:

class GooglePage < BasePage
  div(:viewport, id: "viewport")
  div(:"doc-info", id: "doc-info")
  div(:cst, id: "cst")
  text_area(:csi, id: "csi")
  div(:searchform, id: "searchform")
  # etc.
end

Currently, only those HTML elements with a non-empty id attribute will have PageObject accessors generated for them.

For another example (using watir-webdriver and phantomjs via the phantomjs gem), see this integration test.

Debugging & Development

The default log level is 2. Set this to a lower level to see helpful DEBUG level prints, i.e.

PageObjectify::Logging.logger.level = 0

After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install.

Releasing

To release a new version, I must:

  1. Update the version number in version.rb.
  2. Run rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.
  3. Run rake changelog, which will auto-generate a changelog of the PRs merged/Issues resolved in the newest release.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/smoll/page-objectify.