Exploring Playwright TypeScript Visual Comparison Testing
Tags: playwright
Published: 2023-08-10 05:27:41

In the world of software automation testing, ensuring the visual consistency of web applications is paramount. Imagine a scenario where a tiny code change inadvertently leads to a visual glitch in your application's UI. To prevent such mishaps, visual comparison testing comes to the rescue. In this blog post, we'll dive into the realm of Playwright and TypeScript for effective visual comparison testing.

## **Unveiling Visual Comparison Possibilities**

Visual comparison testing with Playwright and TypeScript opens up a realm of possibilities. You can conduct visual comparisons at different levels to capture and analyze potential visual discrepancies:

**Page Comparison:**

By capturing screenshots of entire web pages, you can easily identify any unexpected visual changes caused by code alterations. Consider the following code snippet that encapsulates this approach:

```
test("Page compare", async ({ page }) => {
  await expect(page).toHaveScreenshot(['Login', 'starter.png']);
});
```

The default screenshot name is autogenerated. However, if you want more control, you can optimize the toHaveScreenshot or toMatchSnapshot function by passing an array parameter. Here, 'Login' refers to a folder name created under a specific test.

**Text or Image Comparison:**

Dive deeper into the UI by comparing specific text content or images within elements. The following code demonstrates how you can achieve this:

```
test('Text content compare', async ({ page }) => {
  expect(await page.textContent('p[class="intro-subtitle"]')).toMatchSnapshot(['Login','hero.txt'])
});
```

**Element Comparison:** 

Sometimes, focusing on specific UI elements is crucial. Here's how you can compare elements like a pro:

```
test('Element compare', async ({ page }) => {
  expect(await page.locator('div[class="starter-logo-box"]').screenshot()).toMatchSnapshot(['Login', 'ncsclogo.png']);
});
```

## Taming Pixel Differences


To account for minor visual discrepancies due to various factors, you can configure pixel differences in Playwright's config file or at the test level:

In the Playwright config file:

```
expect: {
  toHaveScreenshot: { maxDiffPixels: 500 },
  toMatchSnapshot: { maxDiffPixels: 500 },
}

```

At the test level:

```
await expect(page).toHaveScreenshot({ maxDiffPixels: 100 });
```


## Challenges and CI Integration


However, there's a challenge that emerges when executing tests across different platforms and Continuous Integration (CI) environments. Snapshot naming conventions can vary, leading to inconsistencies. For instance, while running tests locally, a snapshot name might look like `example-test-1-chromium-darwin.png`. But if you pass a snapshot name as "Image," on a Windows machine, it could become `Image-win32.png`.

When executing tests through CI on a Linux environment, the discrepancy in snapshot naming can lead to failures. This is where Docker comes to the rescue. By containerizing your code and ensuring consistent naming conventions, you can avoid this issue altogether.

However, if you're determined to run tests locally without Docker, a nifty workaround exists:

By creating a fixture that removes the snapshot suffix, you can achieve uniform snapshot names across all platforms. Here's how you can implement it:

```
_autoSuffix: [
  async ({}, use, testInfo) => {
    testInfo.snapshotSuffix = `${testInfo.title}`;
    await use();
  },
  { auto: true },
],
```


This fixture modifies the snapshot suffix based on the test title, ensuring uniformity in snapshot names.


## Conclusion


Visual comparison testing with Playwright and TypeScript is a powerful approach to maintain the visual integrity of your web applications. Armed with the ability to compare entire pages, specific elements, and text or images, you can catch visual discrepancies with precision. By configuring pixel differences and tackling challenges like snapshot naming, you pave the way for more reliable and robust automated testing practices.