Integrate functional and visual tests

This guide explains how to integrate functional and visual tests.

Introduction

Integrating functional and visual testing can greatly enhance your ability to catch UI regressions and ensure the visual consistency of your application. By integrating Percy with your functional testing pipeline, you can seamlessly capture screenshots during your functional test runs and compare them to baseline images.

Browser selection management

Browser selection management enables you to select from a single place all the browsers you want to run your visual tests on. The more the browsers, the higher your visual test coverage.

Users can create a Web Percy project and decide how the browsers should be handled. Percy offers two options listed below:

To select the browsers to test on, first, create a Web project in Percy. You have two ways to select browsers:

  • Percy(Default) - This is Percy's native cross-browser testing functionality and is selected by default. To know about how this works, see Cross-browser visual testing.

    • If you want to run visual tests only on the latest browsers, select Percy. Your tests run at a high processing speed. If you want twice the speed, purchase the enterprise plan for Percy.
  • Automate - You manage browsers with Automate capabilities. When the functional tests run, Percy directly captures the required screenshots.

    • If you want to run visual tests on a variety of desktop OS, Mobile OS, Mobile devices, and browser combinations, select Automate. If you want to boost the test processing speed, consider purchasing parallels in Automate.

Note:

  • A unique Percy token is generated for every project created on Percy.
  • Each selected browser consumes an additional screenshot from your subscription.

Percy on Automate

If you choose the "Automate" option when creating a Percy project, the "browsers selection" option will not appear in the project settings. Instead, the selection of browsers will be based on the capabilities specified in the Automate session.

You can use the Percy Screenshot command to capture a screenshot when a page is rendered during an Automate session. This screenshot is directly sent to the Percy build for comparison.

🚧

Things you must know

  • Supported languages and frameworks.
  • Set the browser height and width to get consistent screenshots.
  • Percy on Automate currently only supports single tile screenshots.
  • For Apple devices, close the tag for smart app banners before taking screenshots.
  • Samsung Internet Browser is coming soon.
  • Percy on Automate currently only supports w3c protocol.

Prerequisite

Before you begin, ensure your Automate script's capabilities are using Selenium version 3.11.0 and above.

Integration steps

Step 1) Install the latest Percy CLI

npm install --save @percy/cli

Step 2) Install the relevant SDK

For Javascript based frameworks like WebdriverIO, or Mocha

npm install @percy/[email protected]
npm install @percy/[email protected]

🚧

For WebdriverIO

If you are using WebdriverIO, make sure to install percy selenium-webdriver as used in JS-Selenium and make sure WebdriverIO is configured to be used with BrowserStack.

For Python

pip install percy-selenium==2.0.0b0
pip install percy-appium-app==2.0.0b0

For Java

Update the pom.xml file as shown below:

<groupId>io.percy</groupId>
<artifactId>percy-java-selenium</artifactId>
<version>2.0.0-beta.0</version>
<groupId>io.percy</groupId>
<artifactId>percy-appium-app</artifactId>
<version>2.0.0-beta.1</version>

For C#

Update the .csproj file as shown below:

<PackageReference Include="PercyIO.Selenium" Version="2.0.0-beta.0"/>
<PackageReference Include="PercyIO.Appium" Version="3.0.0-beta.0"/>

Step 3) In the Percy dashboard make selections as below:

  • Select Web as the platform.
  • Select Automate to handle browser selection.
  • Click Create Project.

Step 4) Export the Percy token.

A Percy token will be generated when you create a project. Export this token environment variables.

$ export PERCY_TOKEN="<your token here>"
$ set PERCY_TOKEN="<your token here>"

# PowerShell
$ $Env:PERCY_TOKEN="<your token here>"

Note: For Percy on Automate projects, the project token starts with auto_xxxxxxx.

Step 5) Update your Automate test script.

a) Import percy_screenshot from Percy library using the below code:

For Selenium

from percy import percy_screenshot 
const { percyScreenshot } = require('@percy/selenium-webdriver');
import io.percy.selenium.Percy;
using PercyIO.Selenium;

For Appium

from percy import percy_screenshot 
const percyScreenshot = require('@percy/appium-app');
import io.percy.appium.PercyOnAutomate;
using PercyIO.Appium;

b) Use the Percy screenshot command to take required screenshots in your Automate session.

For example, in the following Python code, the percy_screenshot("name", "options") method is called twice. In the first instance, we are passing only the required argument which is "name". In the second instance, we are passing both the required and optional "options".

For Selenium:

percy_screenshot(driver, name = 'Screenshot 1')

options =  { 'freezeAnimation': True, 'percyCSS': 'h1{color:red;} a{color: red;font-size: 1rem;}', 'ignore_region_xpaths':['/html/body/div/p[2]/a']}
percy_screenshot(driver, name = 'Screenshot 2', options = options)
await percyScreenshot(driver, 'Screenshot 1');

options = { percyCSS: 'h1{color:red;} a{color: red;font-size: 1rem;}', ignore_region_xpaths: ['/html/body/div/p[2]/a']}
await percyScreenshot(driver, 'Screenshot 2', options);
Percy percy = new Percy(driver);
percy.screenshot("Screenshot 1");

HashMap<String, Object> options = new HashMap<String, Object>();
options.put("percyCSS", "h1{color:red;} a{color: red;font-size: 1rem;}");
options.put("ignore_region_xpaths", Arrays.asList("/html/body/div/p[2]/a"));
percy.screenshot("Screenshot 2", options);
Percy.Screenshot(driver, "Screenshot 1");

Dictionary<string, object> options = new Dictionary<string, object>();
options.Add("percyCSS", "h1{color:red} a{color: red;font-size: 1rem;}");
List<string> xpaths = new List<string>();
xpaths.Add("/html/body/div/p[2]/a");
options.Add("ignore_region_xpaths", xpaths);
Percy.Screenshot(driver, "Screenshot 2", options);

For Appium:

percy_screenshot(driver, name = 'Screenshot 1')

options =  { 'freezeAnimation': True, 'percyCSS': 'h1{color:red;} a{color: red;font-size: 1rem;}', 'ignore_region_xpaths':['/html/body/div/p[2]/a']}
percy_screenshot(driver, name = 'Screenshot 2', options = options)
await percyScreenshot(driver, 'Screenshot 1');

options = { percyCSS: 'h1{color:red;} a{color: red;font-size: 1rem;}', ignore_region_xpaths: ['/html/body/div/p[2]/a']}
await percyScreenshot(driver, 'Screenshot 2', options);
PercyOnAutomate percy = new PercyOnAutomate(driver);
percy.screenshot("Screenshot 1");

HashMap<String, Object> options = new HashMap<String, Object>();
options.put("percyCSS", "h1{color:red;} a{color: red;font-size: 1rem;}");
options.put("ignore_region_xpaths", Arrays.asList("/html/body/div/p[2]/a"));
percy.screenshot("Screenshot 2", options);
PercyOnAutomate Percy = new PercyOnAutomate(driver);
Percy.Screenshot("Screenshot 1");

Dictionary<string, object> options = new Dictionary<string, object>();
options.Add("percyCSS", "h1{color:red} a{color: red;font-size: 1rem;}");
List<string> xpaths = new List<string>();
xpaths.Add("/html/body/div/p[2]/a");
options.Add("ignore_region_xpaths", xpaths);
Percy.Screenshot("Screenshot 2", options);
ArgumentsDescription
name(String)(Required)The screenshot name must be unique for each screenshot captured.
for ex: name = Screenshot 1.
options()(Optional) freezeAnimation(Boolean) -To determine whether Percy will perform stabilization on the DOM. By default set to false, set to true if stabilization needs to be performed by Percy.
(Optional) percyCSS - Apply Percy-specific CSS to stabilize screenshots.
(Optional) ignoreRegions - To ignore a particular set of elements or sections in DOM. There are four ways to pass it.
1. ignore_region_xpaths.
2. ignore_region_selectors.
3. ignore_region_selenium_elements / ignore_region_appium_elements.
4. custom_ignore_regions.

Step 6) Run the build.

npx percy exec -- <command to run the automate script file>

Results

You can view the visual comparison results on the generated Percy builds.

Percy on Automate Features

  • If there are more than five screen widths, a dropdown menu will show up with different width options. The dropdown will display a maximum of ten entries.
  • The build generation panel now includes a new device selection filter on the left pane.
  • You can easily switch between the Percy and the Automate session.

Debug in Automate Session

  • The generated Percy builds have a redirect link to your builds on the Automate session.
  • The generated builds on the Automate session have a redirect link to your Percy builds.
  • Once the Automate builds are generated, you can use various logging options such as Text Logs, Network Logs, Other Logs, Issues Detected, and many more to review your builds.
  • To determine the timestamp of a screenshot taken, you can search for the Percy Screenshot command within your Automate session.
  • The Percy screenshot command displays the screenshot name besides it, as shown:

Handle dynamic elements

If you have dynamic JavaScript elements or carousels in your test, stabilize the DOM first and then invoke percyScreenshot. To ensure stable screenshots for dynamic JavaScript or carousel elements in your test, it is recommended to stabilize the DOM first and then invoke percyScreenshot. This allows for capturing consistent and accurate screenshots.
For example, if you are using bootstrap carousel, handle it as shown below:

# before taking screenshot we force the carousel to be at 1st tile
driver.execute_script(`var carousel = $('.carousel');
  carousel.carousel(0);
  carousel.carousel('pause');`)

percy_screenshot(driver, name = 'Screenshot 1')

Another example is how to handle sticky elements. Suppose the website you're testing has the cookie banner. You can either accept or reject it. In the following snippet, we're accepting the cookie:

# before taking screenshot please close the sticky elements
cookie_banner = wait.until(EC.presence_of_element_located((By.ID, 'cookie-banner')))

# Find the accept button and click it
accept_button = cookie_banner.find_element(By.XPATH, '//button[text()="Accept"]')
accept_button.click()

percy_screenshot(driver, name = 'Screenshot 1')

Benefits

  • Using Percy on Automate is cost-effective and performant.
    • It supports a single pipeline for functional and visual testing.
    • It saves lot of network traffic as we are directly uploading screenshots from BrowserStack terminal to Percy cloud.
  • Tell us the capture movement and Percy will take screenshot of that movement as it supports css pseudo classes.
  • It supports third party automated testing platforms including in-house setups.
  • Exposure to highest browser and devices coverage while using BrowserStack Automate.

Limitations

  • Internet Explorer is not supported.
  • For Mozilla Firefox, Google Chrome, and Microsoft Edge, browser versions less than 91 are not supported.
  • Mojave and older versions of macOS are not supported.

Compatibility Matrix

Refer the below matrix to check what frameworks are supported by Percy on Automate.

Note: Write us at [email protected] to raise a feature request.

LanguagesFrameworks
JavaJava
Cucumber
Gauge
JBehave
JUnit 4
JUnit 5
Selenide
Serenity
TestNG
NodeJSNodeJS
Cucumber JS
Jest
Mocha JS
Protractor
WD
WebdriverIO
PythonPython
Behave
Pytest
.NetC#
MBUnit
NUnit
PNUnit
SpecFlow
XUnit