Tuesday, October 22, 2013

Cross Browser/Cross Platform Automated Testing with Ruby


As developers, we’ve typically developed cross browser applications but now, with the advent of mobile devices, there’s a new plethora of devices to develop against.  How do we test against these? 
Cucumber + Watir-WebDriver + Appium = Cross Browser, Cross Platform Testing
We’ll walk through the highlights of setting up each browser and platform and also to capture screenshots.
The full code is available from my Github:  https://github.com/matthewbussa/watir-webdriver-demo
In order to start with, you’ll need the following software:
  • Ruby 1.9.3
    • Cucumber gem
    • Watir-WebDriver gem
  • Appium – please note that support for Appium in Windows is in “beta”
  • XCode
    • Install the Command Line tools (XCode –> Preferences –> Downloads –> Command Line Tools
    • Install the 6.1 Simulator in the same place
  • GenyMotion – free account is required.  Ensure you have Oracle VirtualBox installed before installing Genymotion

Cucumber Scenario to test:

Scenario: "Capture screenshot for one device and platform"
    Given I am on the home page
    Then a screenshot is captured

Setting up the Browser

With Watir-WebDriver it’s easy to setup in instance of a Watir Browser and initiate it for different browsers or platforms.  Below are some examples on how to utilize this feature:

FireFox

setup_firefox()
    browser = Watir::Browser.new :firefox
    browser.driver.manage.window.maximize
    browser
end

Chrome

For Chrome, you’ll need to download ChromeDriver v2.2  and place it in your class path.  Be sure to start the chromedriver before running your tests.  At the time of this writing, ChromeDriver v2.3 was not compatible.  The following is the Ruby code to setup an automated Chrome browser: 
setup_chrome()
    browser = Watir::Browser.new :chrome
    browser
end

For iPhone, iPad, and Android, ensure that Appium is up and running on the default port of 4723.  Appium will automatically load the iPhone and iPad devices however, it doesn’t automatically shut them down.  This can easily be done using the “kill ‘iPhone Simulator’” or kill ‘iPad Simulator’ commands from the terminal.

iPhone

setup_iphone()
    capabilities = 
    {
        'device' => "iPhone Simulator",
        'browserName' => 'iOS',
        'platform' => 'Mac',
        'version' => '6.1',
        'app' => 'safari'
    }

    server_url = "http://localhost:4723/wd/hub/"
    driver = Selenium::WebDriver.for(:remote,
                 :desired_capabilities => capabilities,
                 :url => server_url)
    browser = Watir::Browser.new driver
    browser

end

iPad

The iPad version is the same as the iPhone setup with the exception that the ‘device” capability is different. 
setup_ipad()
    capabilities = 
    {
        'device' => "iPad Simulator",
        'browserName' => 'iOS',
        'platform' => 'Mac',
        'version' => '6.1',
        'app' => 'safari'
    }

    server_url = "http://localhost:4723/wd/hub/"
    driver = Selenium::WebDriver.for(:remote, 
                 :desired_capabilities => capabilities, 
                 :url => server_url)
    browser = Watir::Browser.new driver
    browser

end

Android

In order for Android to work, ensure you have both Appium running and that you have an Android Emulator up using Genymotion. Also ensure that the Android Emulator you are using has the Chrome browser installed. This can be installed through the emulator's play store. A Gmail account will be needed to log into the Play Store.
setup_android()
  capabilities =
  {
  'app' => 'chrome',
  'device' => 'Android'
  }

  server_url = "http://localhost:4723/wd/hub/"
  driver = Selenium::WebDriver.for(:remote, 
               :desired_capabilities => capabilities, 
               :url => server_url)
  browser = Watir::Browser.new driver
  browser.driver.manage.timeouts.implicit_wait = 30
  browser

end

Capturing the Screenshot

The logic to capture a screenshot is fairly straightforward for non-Android devices.  However, Android devices are a bit tricky.  We need to save the screenshot to the sdcard on the emulator, then move the file to our location and finally, do some cleanup and delete the image on the sdcard.

def capture_screenshot()
  time = Time.now.to_i.to_s
  filename = time + '.png'
  if (platform == 'android')
    %x(adb shell /system/bin/screencap -p /sdcard/screenshot.png)
    %x(adb pull /sdcard/screenshot.png ./screenshots/screenshot.png)
    FileUtils.mv('./screenshots/screenshot.png', filename)
    %x(adb shell rm /sdcard/screenshot.png)
  else
    browser.driver.save_screenshot filename
  end

  filename
end

If you’re already using Cucumber and Watir-WebDriver for your automated web testing, Appium makes it easy extend your coverage utilizing the existing tool set and begin testing on mobile devices and if you’re not, here’s a framework to get you started!

Happy Testing!


Update 11/11/2013:  With the XCode 5.0, Apple removed the ability to launch built in applications.  This means that if you use XCode 5.0 or above, Appium will not launch Mobile safari, which is what the tests are setup to do.

No fear, the solution is to ensure you have XCode 4.6.3 and iOS Simulator 6.1.  You can download the older version here:  https://developer.apple.com/downloads/index.action#

There's some documentation on how to switch between versions of XCode from Appium here:  https://github.com/appium/appium/blob/master/docs/running-on-osx.md