If you are a tester and deal with automation, you will likely at some point have to run your tests on SauceLabs or some similar remote platform. In talking with some testers, this tends to make them a little nervous and I’ve found this comes down to them thinking it’s more difficult than it really is. So here I’ll cover how to do this with two popular automation libraries in Ruby and then I’ll show how to do the same thing using my Symbiont framework.
The first thing to do, if you want to play along and practice for yourself, is to head on over to SauceLabs. You’ll need to create an account by signing up. You can sign up for a free account, either the one marked “Free $0” or “Open Sauce $0”. The Sauce Plan portion that shows on the page explains the differences.
Since this is a post about running automated tests on the SauceLabs platform, I’m not going to go into setting up your local development environment. That means I’m going to assume that you have Ruby installed (or can do so) and have installed the selenium-webdriver and watir-webdriver gems as well as my own symbiont gem.
Selenium on Sauce
Let’s first create a test using Selenium WebDriver. This first example will not use SauceLabs at all. Instead, this script will simply go to a web site (my own Symbiote sample app) and log in.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
require 'selenium-webdriver' driver = Selenium::WebDriver.for(:firefox) driver.get('http://symbiote-app.herokuapp.com/') open = driver.find_element(id: 'open') open.click username = driver.find_element(id: 'username') username.send_keys 'admin' password = driver.find_element(id: 'password') password.send_keys 'admin' login = driver.find_element(id: 'login-button') login.click driver.quit |
You should be able to run this and see that it works just fine. Now let’s make that script run against SauceLabs.
When you created your account on SauceLabs, you effectively set up a set of authentication credentials. You have your account name and you have an access key. You will need both of these in order to connect up your script with SauceLabs. You’re going to need those in a moment.
In order to get your script to run on SauceLabs, you have to pass in a set of desired capabilities to the Selenium driver. These capabilities will indicate the platform OS to run on and the browser to run on that platform. So let’s add this to the top of the script:
1 2 3 4 5 6 7 8 9 |
caps = Selenium::WebDriver::Remote::Capabilities.new caps['platform'] = "Windows 8.1" caps['browserName'] = "internet explorer" caps['version'] = "11" caps['name'] = "Testing with Sauce" def sauce_url "http://USERNAME:ACCESSKEY@ondemand.saucelabs.com:80/wd/hub" end |
Here I’m indicating I want to run my test on Windows 8.1, using version 11 of the Internet Explorer browser. The ‘name’ property is there to provide a name for the running session on SauceLabs. This is a way you could distinguish your tests if you are running multiple test scripts.
Do note that you’ll want to replace the USERNAME and the ACCESSKEY with your own credentials in the sauce_url() method.
Once you have that in place, you need to make just a slight change to your existing script, as such:
1 2 3 4 5 6 7 8 |
require 'selenium-webdriver' ... driver = Selenium::WebDriver.for(:remote, url: sauce_url, desired_capabilities: caps) driver.get('http://symbiote-app.herokuapp.com/') ... |
Here instead of calling for the :firefox browser as I did originally, I’m indicating I want to run on a :remote browser. Doing this requires you to pass in two further parameters: the :url that you want to use to connect to the remote browser and the :desired_capabilities, which specify details about the operating system and browser. You’ll notice here that I’ve indicated the :url is the return value of my sauce_url() method. The :desired_capabilities will be the caps instance I have established.
Make sure you are signed in to your SauceLabs account so that you are on your jobs page. This way you will be able to verify that the script is running on SauceLabs. Now run the test just as you did before. You should notice that, after a moment or two, you’ll see the job appear in the SauceLabs jobs page and see the test running in real time.
Execution on SauceLabs captures a lot of information, such as screenshots, logs from various things (like Selenium and the browser itself), and so on. This is something you can experiment with on your own. The SauceLabs UI is fairly intuitive.
Watir on Sauce
Let’s try the same test, but using Watir-WebDriver. For that you’re going to keep the caps instance and sauce_url() method in place. But change the script to read as such:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
require 'watir-webdriver' driver = Watir::Browser.new(:remote, url: sauce_url, desired_capabilities: caps) # driver = Watir::Browser.new(:firefox) driver.goto('http://symbiote-app.herokuapp.com/') driver.p(id: 'open').click driver.text_field(id: 'username').set('admin') driver.text_field(id: 'password').set('admin') driver.button(id: 'login-button').click driver.quit |
The commented line 4 shows the statement you would use to run the test locally against a Firefox browser, similar to what was done with the Selenium script earlier. The uncommented driver line, however, is what I’m using here to run remotely. Again, very similar to the Selenium script. In fact, you should find this script works just as the Selenium one did, running against SauceLabs.
Symbiont on Sauce
Finally, let’s see how this works with my own Symbiont tool. Keep in mind that Symbiont is a wrapper for Watir-WebDriver (which in turn wraps Selenium-WebDriver). The goal of Symbiont is to force you to use a page object pattern. So here is a listing for a Symbiont script:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
require 'symbiont' include Symbiont::Factory class Login attach Symbiont url_is 'http://symbiote-app.herokuapp.com/' title_is 'Symbiote' p :login_form, id: 'open' text_field :username, id: 'username' text_field :password, id: 'password' button :login, id: 'login-button' div :message, class: 'notice' def login_as_admin login_form.click username.when_present.set 'admin' password.set 'admin' login.click end end Symbiont.set_browser(:remote, url: sauce_url, desired_capabilities: caps) on_view(Login).login_as_admin Symbiont.browser.quit |
This script seems more involved with the page definition there but notice that the actual working script is only three lines (24, 26, 28), particularly since you are using the Symbiont factory and a method on the page object itself.
That’s All There Is To It!
Not too hard, right? While I’ve shown Ruby here since it’s my language of choice, do note that SauceLabs allows you to run tests written in various languages, such as PHP, JavaScript, Java, Python, and so on. As long as there are bindings for Selenium in that language you should be able to run your tests against SauceLabs.
Hopefully this brief post gives some testers confidence that running your tests against SauceLabs isn’t all that hard.
The main thing you’ll need to focus on is figuring out how you can run a series of tests against different browsers on SauceLabs. For example, you will probably want to run against various Firefox, Internet Explorer, Chrome, and Safari browsers. What that means is you won’t just have one caps instance as I set up here but rather a list of browsers that get passed into your test runner.
Also, if you are looking at running against mobile applications (native or hybrid), you’ll want to look at including Appium, which is sponsored by SauceLabs and is another driver that you can use against the SauceLabs platform to run your tests.
Happy (Cross Browser) Testing!