How To Add Visual Testing To Existing Selenium Tests

Sauce AI for Test Authoring: Move from purpose to performance in mo.|xBack to ResourcesBlogPosted February 26, 2015

How To Add Visual Testing To Existing Selenium Tests

quote

Thanks again to those of you who attended our recent webinar withon automated visual examination. If you want to share it or if you happened to miss it, you can catch the audio and slideshere. We also worked with Selenium expertDave Haeffnerto provide the how-to on the bailiwick. Enjoy his post below.

The Problem

In previous write-ups I covered what automated optical examination is and how to do it. Unfortunately, found on the examples demonstrated, it may be unclear how automated ocular testing fits into your be automated testing practice.

Do you need to compose and keep a separate set of tests? What about your existing Selenium tests? What do you do if there isn & # x27; t a sufficient library for the programming words you & # x27; re presently using?

A Solution

You can rest easy knowing that you can make machine-driven visual testing tabintoyour existing Selenium tests. By leverage a third-party program like, this is a simple feat.

And when coupled withSauce Labs, you can quickly add coverage for those difficult to reach browser, twist, and platform combinations.

Let & # x27; s pace through an exemplar.

An Example

NOTE: This example is written in Java withthe JUnit testing framework.

Let & # x27; s start with an subsist Selenium tryout. A simple one that logs into a website.

1
// filename: Login.java
2
import org.junit.After;
3
meaning org.junit.Assert;
4
import org.junit.Before;
5
importation org.junit.Test;
6
import org.openqa.selenium.By;
7
import org.openqa.selenium.WebDriver;
8
meaning org.openqa.selenium.firefox.FirefoxDriver;
9
10
public class Login {
11
12
individual WebDriver driver;
13
14
@Before
15
public void setup () {
16
driver = new FirefoxDriver ();
17
}
18
19
@Test
20
public void succeeded () {
21
driver.get (& quot; http: //the-internet.herokuapp.com/login & quot;);
22
driver.findElement (By.id (& quot; username & quot;)) .sendKeys (& quot; tomsmith & quot;);
23
driver.findElement (By.id (& quot; password & quot;)) .sendKeys (& quot; SuperSecretPassword! & quot;);
24
driver.findElement (By.id (& quot; login & quot;)) .submit ();
25
Assert.assertTrue (& quot;; success message should be present after logging in & quot;,
26
driver.findElement (By.cssSelector & quot; .flash.success & quot;)) .isDisplayed ());
27
}
28
29
@After
30
public void teardown () {
31
driver.quit ();
32
}

In it we & # x27; re load an instance of Firefox, visiting the login page onthe-internet, inputting the username & amp; password, submitting the form, asserting that we gain a logged in state, and closing the browser.

Now let & # x27; s add in Applitools Eyes support.

If you haven & # x27; t already done so, you & # x27; ll need to make (no credit-card ask). You & # x27; ll then necessitate to instal the Applitools Eyes Java SDK and import it into the trial.

1
// filename: pom.xml
2
<dependency>
3
<groupId>com.applitools</groupId>
4
<artifactId>eyes-selenium-java</artifactId>
5
<version>RELEASE</version>
6
</addiction>
7
// filename: Login.java
8
9
import com.applitools.eyes.Eyes;
10
...

Next, we & # x27; ll need to add a varying (to store the instance of Applitools Eyes) and modify our test frame-up.

1
individual WebDriver driver;
2
private Eyes oculus;
3
4
@Before
5
public nothingness apparatus () {
6
WebDriver browser = new FirefoxDriver ();
7
eye = new Eyes ();
8
eyes.setApiKey (& quot; YOUR_APPLITOOLS_API_KEY & quot;);
9
driver = eyes.open (browser, & quot; the-internet & quot;, & quot; Login succeed & quot;);
10
}

Rather than store the Selenium representative in thedrivervariable, we & # x27; re now storing it in a localbrowservariable and legislate it intoeyes.open-- storing the WebDriver object thateyes.openreturns in thedrivervariable instead.

This way the Eyes platform will be capable to capture what our test is doing when we ask it to enchant a screenshot. The Selenium actions in our test willnotneed to be alter.

Before callingeyes.openwe provide the API key (which can be found on). When callingeyes.open, we pass it the Selenium instance, the gens of the app we & # x27; re testing (e.g.,& quot; the-internet & quot;), and the name of the tryout (e.g.,& quot; Login succeed & quot;).

Now we & # x27; re ready to add some optic checks to our test.

1
// filename: Login.java
2
...
3
@ Test public vacancy succeeded () {
4
driver.get (& quot; http: //the-internet.herokuapp.com/login & quot;);
5
eyes.checkWindow (& quot; Login & quot;);
6
driver.findElement (By.id (& quot; username & quot;)) .sendKeys (& quot; tomsmith & quot;);
7
driver.findElement (By.id (& quot; password & quot;)) .sendKeys (& quot; SuperSecretPassword! & quot;);
8
driver.findElement (By.id (& quot; login & quot;)) .submit (); eyes.checkWindow (& quot; Logged In & quot;);
9
Assert.assertTrue (& quot; success substance should be present after logging in & quot;,
10
driver.findElement (By.cssSelector (& quot; .flash.success & quot;)) .isDisplayed ());
11
eyes.close ();
12
}
13
...

With eyes.checkWindow ();we are specifying when in the test & # x27; s workflow we & # x27; d like Applitools Eyes to capture a screenshot (along with some description schoolbook). For this test we want to check the page before logging in, and then the blind just after lumber in -- so we useeyes.checkWindow ();two times.

NOTE: These visual cheque are effectively doing the same employment as the pre-existing assertion (e.g., where we & # x27; re enquire Selenium if a success notice is displayed and asserting on the Boolean result) -- in improver to reviewing other optical aspects of the page. So once we verify that our test is working correctly we can remove this assertion and however be cover.

We end the test witheyes.close. You may feel the urge to put this inteardown, but in increase to shut the session with Eyes, it behave like an assertion. If Eyes finds a failure in the app (or if a baseline image approval is required), theneyes.closewill throw an elision; failing the test. So it & # x27; s best accommodate to live in the test.

NOTE: An exceptions fromeyes.closewill include a URL to the Applitools Eyes job in your examination output. The job will include screenshots from each test stride and enable you to play back the keystrokes and mouse movements from your Selenium tests.

When an exception gets thrown byeyes.close, the Eyes session will close. But if an exclusion occurs beforeeyes.closecan fire, the session will remain open. To handle that, we & # x27; ll need to add an extra command to ourteardown.

1
// filename: Login.java
2
...
3
@After
4
public nothingness teardown () {
5
eyes.abortIfNotClosed ();
6
driver.quit ();
7
}
8
}

For autonomous testing across multiple user personas, check out SUSATest — it explores your app like 10 different real users.

eyes.abortIfNotClosed ();will make sure the Eyes session terminates properly irrespective of what happens in the exam.

Now when we run the test, it will execute topically while also do visual checks in Applitools Eyes.

What About Former Browsers?

If we desire to run our examination with its newly added visual checks against other browsers and operating systems, it & # x27; s mere enough to run your cross-browser exam on Sauce Labs.

NOTE: If you don & # x27; t already feature a Sauce Labs story, sign up for a free trial chroniclehere.

First we & # x27; ll need to import the relevant classes.

1
// filename: Login.java
2
... significance org.openqa.selenium.Platform;
3
import org.openqa.selenium.remote.DesiredCapabilities;
4
import org.openqa.selenium.remote.RemoteWebDriver;
5
importation java.net.URL;
6
...

We & # x27; ll then need to modify the test setup to load a Sauce browser instance (via Selenium Remote) alternatively of a local Firefox one.

1
// filename: Login.java
2
...
3
@ Before public void apparatus () cast Exception {
4
DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer ();
5
capabilities.setCapability (& quot; platform & quot;, Platform.XP);
6
capabilities.setCapability (& quot; version & quot;, & quot; 8 & quot;);
7
capabilities.setCapability (& quot; name & quot;, & quot; Login succeeded & quot;);
8
String sauceUrl = String.format (
9
& quot; http: // % s: % s @ ondemand.saucelabs.com:80/wd/hub & quot;,
10
& quot; YOUR_SAUCE_USERNAME & quot;,
11
& quot; YOUR_SAUCE_ACCESS_KEY & quot;);
12
WebDriver browser = new RemoteWebDriver (new URL (sauceUrl), capabilities);
13
eye = new Eyes ();
14
eyes.setApiKey (System.getenv (& quot; APPLITOOLS_API_KEY & quot;));
15
driver = eyes.open (browser, & quot; the-internet & quot;, & quot; Login follow & quot;);
16
}
17
...

We tell Sauce what we need in our test representative throughDesiredCapabilities. The main things we want to specify are the browser, browser adaptation, operating system (OS), and name of the test.

In order to join to Sauce, we necessitate to provide an history username and access key. The access key can be found on your account page. These values get concatenated into a URL that charge to the Sauce Labs on-demand grid.

Once we feature theDesiredCapabilitiesand concatenated URL, we create a Selenium Remote instance with them and store it in a localbrowservariable. Just like in our former representative, we feedbrowser to eyes.openand store the homecoming objective in thedriver variable.

Now when we run this test, it will execute against Internet Explorer 8 on Windows XP. You can see the test while it & # x27; s lam in your Sauce Labs account dashboard. And you can see the persona captured on.

A Small Bit Of Cleanup

Both Applitools and Sauce Labs require you to specify a test name. Up until now, we & # x27; ve been hard-coding a value. Let & # x27; s change it so it gets set automatically.

We can do this by leverage a JUnitTestWatcherand a public variable.

1
// filename: Login.java
2
...
3
import org.junit.rules.TestRule;
4
import org.junit.rules.TestWatcher;
5
import org.junit.runner.Description;
6
...
7
public class Login {
8
private WebDriver driver;
9
private Eyes oculus;
10
public String testName;
11
@Rule
12
public TestRule watcher = new TestWatcher () {
13
protect void starting (Description description) {
14
testName = description.getDisplayName ();
15
}
16
};
17

Each time a test starts, theTestWatcher startingfunction will snaffle the show gens of the test and store it in thetestName variable.

Let & # x27; s clean up our setup to use this variable instead of a hard-coded value.

1
// filename: Login.java
2
...
3
@Before
4
public void setup () cast Exception {
5
DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer ();
6
capabilities.setCapability (& quot; platform & quot;, Platform.XP);
7
capabilities.setCapability (& quot; version & quot;, & quot; 8 & quot;);
8
capabilities.setCapability (& quot; name & quot;, testName);
9
String sauceUrl = String.format (
10
& quot; http: // % s: % s @ ondemand.saucelabs.com:80/wd/hub & quot;,
11
System.getenv (& quot; SAUCE_USERNAME & quot;),
12
System.getenv (& quot; SAUCE_ACCESS_KEY & quot;));
13
WebDriver browser = new RemoteWebDriver (new URL (sauceUrl), capabilities);
14
eyes = new Eyes ();
15
eyes.setApiKey (System.getenv (& quot; APPLITOOLS_API_KEY & quot;));
16
driver = eyes.open (browser, & quot; the-internet & quot;, testName);
17
}
18
...

Now when we run our exam, the name will mechanically appear. This will arrive in handy with additional tests.

One More Thing

When a job fails in Applitools Eyes, it automatically return a URL for it in the examination yield. It would be decent if we could also get the Sauce Labs job URL in the output. So let & # x27; s add it.

First, we & # x27; ll need a public variable to store the session ID of the Selenium job.

1
// filename: Login.java
2
...
3
public class Login {
4
private WebDriver driver;
5
private Eyes oculus;
6
public String testName;
7
public String sessionId;
8
...
9

Next we & # x27; ll add an extra function toTestWatcherthat will activate when there & # x27; s a failure. In it, we & # x27; ll display the Sauce job URL in standard output.

1
// filename: Login.java
2
...
3
@Rule
4
public TestRule watcher = new TestWatcher () {
5
protect emptiness starting (Description description) {
6
testName = description.getDisplayName ();
7
}
8
9
@Override
10
protect void miscarry (Throwable e, Description description) {
11
System.out.println (String.format (& quot; https: //saucelabs.com/tests/ % s & quot;, sessionId));
12
}
13
};
14
...

Lastly, we & # x27; ll grab the session ID from the Sauce browser instance just after it & # x27; s create.

1
// filename: Login.java
2
...
3
WebDriver browser = new RemoteWebDriver (new URL (sauceUrl), capabilities);
4
sessionId = ((RemoteWebDriver) browser) .getSessionId () .toString ();
5
...

Now when we run our exam, if there & # x27; s a Selenium failure, a URL to the Sauce job will be returned in the test yield.

Expected Outcome

  • Connect to Applitools Eyes

  • Load an example of Selenium in Sauce Labs

  • Run the trial, performing visual checks at specified points

  • Close the Applitools session

  • Close the Sauce Labs session

  • Return a URL to a failed job in either Applitools Eyes or Sauce Labs

Outro

Glad Testing!

About Dave Haeffner:Dave is the author ofPrimary Selenium(a free, once weekly Selenium tip newsletter that is read by century of testing professionals) as well as a new record, The Selenium Guidebook. He is also the creator and sustainer ofChemistryKit(an open-source Selenium fabric). He has helped legion companies successfully implement automated acceptance examine; including The Motley Fool, ManTech International, Sittercity, and Animoto. He is a founder and co-organizer of theSelenium Hangoutand has spoken at numerous conferences and meetups about acceptance examination.

Published:
Feb 26, 2015
Share this post
Copy Share Link
LinkedIn
© 2026 Sauce Labs Inc., all rights reserved. SAUCE and SAUCE LABS are registered trademarks possess by Sauce Labs Inc. in the United States, EU, and may be register in other jurisdictions.
robot
quote

Automate This With SUSA

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts needed.

Try SUSA Free

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free