Mobilify
We don't like to maintain a lot of test code. Which means, we don't want to rewrite the same tests for the same web application on different platforms. It's easy when those different platforms are browsers, because the site doesn't change much (at all?).
But, it's a challenge to reuse code when the different platforms are desktop and mobile browsers. The elements move, and their identifiers change. We could create separate page objects for desktop and mobile, with a mixin object for the shared stuff. Or we could create one page object with all the elements, and write two different tests. Seems like a waste both ways.
Mobilify allows you to create one page object and write one test. You write tests for the desktop, and it will grab mobile elements when necessary. Just define the context during page initialization.
Usage
To Mobilify your page objects, include Mobilify
in the page class. For each method requiring a mobile replacement, create an element definition with mobile_
prepended to the original's name.
# method
text_field(:password, :id => "user-pw")
# replacement
text_field(:mobile_password, :id => "mobile-pw")
Mobilify will replace called methods with their mobile_
counterparts if two conditions are met. First, a hash with a key-value pair of :agent => :mobile
is passed to the page object constructor. And second, the page object responds to a mobile_
version of the called method.
# constructor
my_page = Page.new(@browser, :agent => :mobile)
To navigate to your page object during initialization, pass the key-value pair :visit => true
to the constructor.
# visiting
my_page = Page.new(@browser, :visit => true)
my_page = Page.new(@browser, :visit => true, :agent => :mobile)
Example
You're testing a responsive page with a link to your registration form. But you can only identify the link with XPath, and the XPath changes between your desktop-sized application and your mobile-sized application. You could:
- Call two different methods in two different specs, each pointing to its own XPath
- Call two different methods in one spec, using logic to determine the call correctly
- Call the same method in one spec and Mobilify the page object for mobile testing
# spec/page.rb
require 'mobilify'
class Page
include Mobilify
page_url "http://my-page.com"
link(:to_registration, :xpath => '//xpath/to/desktop/register/link')
link(:mobile_to_registration, :xpath => '//xpath/to/mobile/register/link')
end
# spec/spec_helper.rb
require 'watir-webdriver'
require 'webdriver-user-agent'
RSpec.configure do |config|
config.before :all do
case ENV['BROWSER']
when 'desktop'
@browser = Watir::Browser.new :firefox
@agent = :desktop
when 'mobile'
driver = Webdriver::UserAgent.driver(:browser => :firefox, :agent => :iphone)
@browser = Watir::Browser.new driver
@agent = :mobile
end
end
end
# spec/registration_link_spec.rb
require 'spec_helper'
require 'page'
describe Page do
let(:page) { Page.new(@browser, :agent => @agent, :visit => true) }
describe "#to_registration" do
it "takes me to the registration form" do
page.to_registration
@browser.url.should == "http://my-page.com/registration"
end
end
end
Installation
Add this line to your application's Gemfile:
gem 'mobilify'
And then execute:
$ bundle
Or install it yourself as:
$ gem install mobilify
Contributing
- Fork it
- Create your feature branch (
git checkout -b my-new-feature
) - Commit your changes (
git commit -am 'Add some feature'
) - Push to the branch (
git push origin my-new-feature
) - Create new Pull Request
Questions, Comments, Concerns
Easiest place to reach me is Twitter, @jpdenen