Playwright Applitools Integration


In the same way, we open our eyes and analyze if an image looks good; Applitools uses Visual AI to detect changes in our website so we can identify UI defects or validate expected new functionality. In this technical post, we will go over Applitools technology and how it can save us a ton of time in visual component validations. NOTE: If you need to know how to setup Playwright, please refer my previous post: Playwright Getting Started. Then add Applitools dependency:

npm install @applitools/eyes-playwright --save-dev

Now let’s create an applitools.util.ts under our ${PROJECT_HOME}/utils directory and add this content:

import { BatchInfo, Configuration, VisualGridRunner, BrowserType, DeviceName, ScreenOrientation, Eyes, Target } from "@applitools/eyes-playwright"
import { Page } from "@playwright/test"

const CHROME = {
  width: 1280,
  height: 768,
}
const FIREFOX = {
  width: 800,
  height: 600,
}
const EDGE = {
  width: 800,
  height: 600,
}
const SAFARI = {
  width: 1024,
  height: 768,
}

let configuration: Configuration
let runner: VisualGridRunner
let eyes: Eyes

function setUpConfiguration(batchName: string) {
  runner = new VisualGridRunner({ testConcurrency: 5 })
  configuration = new Configuration()
  configuration.setBatch(new BatchInfo(batchName))
  configuration.addBrowser(CHROME.width, CHROME.height, BrowserType.CHROME)
  configuration.addBrowser(FIREFOX.width, FIREFOX.height, BrowserType.FIREFOX)
  configuration.addBrowser(EDGE.width, EDGE.height, BrowserType.EDGE_CHROMIUM)
  configuration.addBrowser(SAFARI.width, SAFARI.height, BrowserType.SAFARI)
  configuration.addDeviceEmulation(DeviceName.iPhone_11, ScreenOrientation.PORTRAIT)
  configuration.addDeviceEmulation(DeviceName.Pixel_5, ScreenOrientation.PORTRAIT)
}

async function setUpTest(page: Page, appName: string, testName: string) {
  eyes = new Eyes(runner, configuration)
  await eyes.open(page, appName, testName)
}

async function checkWindowEyes(screenshot: string) {
  await eyes.check(screenshot, Target.window().layout())
}

async function closeEyes() {
  await eyes.close()
}

async function cleaning() {
  const results = await runner.getAllTestResults()
  console.log("Visual test results", results)
}

export default { setUpConfiguration, setUpTest, checkWindowEyes, closeEyes, cleaning }

On checkWindowEyes we are capturing a screenshot from the browser using eyes.check method, we can also capture from any region, UI element, or even entire window, you can know more about it here, and in our setUpTest we are initializing Applitools eyes with page, application name, and test information.

Running tests

Before running the visual test, you must find your Applitools API key and set it as an environment variable named APPLITOOLS_API_KEY

Linux / Mac

export APPLITOOLS_API_KEY=${YOUR_APPLITOOLS_API_KEY}

Windows:

$Env:APPLITOOLS_API_KEY="YOUR_APPLITOOLS_API_KEY"

This is how our home page looks like after integrating Applitools.

import { test, expect } from "@playwright/test"
import { Constants } from "../properties/test.properties"
import applitools from "../utils/applitools.util"

test.beforeAll(async () => {
  applitools.setUpConfiguration(Constants.BATCH_NAME)
})

test.beforeEach(async ({ page }) => {
  await applitools.setUpTest(page, Constants.APP, test.info().title)
})

test("should validate page title", async ({ page }) => {
  await page.goto(Constants.URL)
  await expect(page).toHaveTitle(Constants.TITLE)
  await applitools.checkWindowEyes("Home Page")
})

test.afterEach(async () => {
  await applitools.closeEyes()
})

test.afterAll(async () => {
  await applitools.cleaning()
})

To run the project:

npx playwright test --project chromium

As you can see here, I am using only the Chromium browser, and the reason why I am doing this is for having Applitools to manage different browsers and platforms to test across different devices. Here is the Playwright configuration file.

// @ts-check
const { defineConfig, devices } = require("@playwright/test")

module.exports = defineConfig({
  testDir: "./tests",
  fullyParallel: true,
  forbidOnly: !!process.env.CI,
  retries: process.env.CI ? 2 : 0,
  workers: process.env.CI ? 1 : undefined,
  reporter: "html",
  timeout: 60000,
  use: {
    trace: "on-first-retry",
  },

  projects: [
    {
      name: "chromium",
      use: { ...devices["Desktop Chrome"] },
    },
  ],
})

Go to the Applitools eyes dashboard and you should be able to see your batch images.

Vetlog

To browse the code go here, to download the project:

git clone git@github.com:josdem/playwright-applitools.git

To go to javascript version:

git fetch
git checkout javascript

To go to typescript version:

git fetch
git checkout typescript

Return to the main article