• Automation
  • Home
  • /
  • Learning Hub
  • /
  • Cypress Snapshot Testing: Getting Started Tutorial
  • -
  • July 01, 2024

Cypress Snapshot Testing: Getting Started Tutorial

Learn how Cypress snapshot testing monitors website interfaces, ensuring appearance and functionality across browsers and operating systems.

OVERVIEW

Cypress snapshot testing allows you to capture snapshots of your websites or web applications during tests to visually compare each snapshot with the previous version of your website or web application to ensure everything looks correct, and there are no visual inconsistencies.

As website interfaces evolve, it's crucial to monitor their appearance and functionality. This includes checking for differences between updates and addressing any issues promptly, particularly across various web browsers on different operating systems.

Even minor problems like broken images or text overlapping on any web page can significantly impact user experience. Cypress, a widely used automation testing framework for end-to-end and component testing, is invaluable for addressing these issues. It allows you to capture screenshots of failed test cases and customize them to capture specific actions during your Cypress screenshot testing process.

What is Snapshot Testing in Cypress?

To understand the importance of snapshotting in the Cypress automation framework, we need to understand what snapshotting is.

Snapshot testing or screenshot testing is an effective technique to identify unintended changes in the visual appearance of an application, ensuring that codebase modifications do not negatively impact the User Interface (UI). This method is particularly useful for maintaining the integrity of the UI and ensuring consistent rendering across different browsers. It achieves accuracy by comparing generated screenshots with reference images, detecting any differences pixel by pixel.

The process involves comparing the current state of a UI component with a reference screenshot taken under identical conditions. Any discrepancies between the two trigger an assertion failure, indicating a failed test and a potential issue.

Below is a sample snapshot of an image displaying the visual differences between the latest and baseline images.

sample snapshot

In the screenshot above, the baseline image displays the Click me button in grey, while the latest image is green.

Through snapshot or screenshot testing, you can easily compare the baseline image. This image captures the UI or specific components in the expected state. You can compare it against the latest screenshot and identify any potential differences.

These differences may concern color change or rendering text, ensuring visual consistency across iterations.

The Importance of Cypress Snapshot Testing

Cypress snapshot testing has rapidly gained popularity due to its unique ability to capture the state of a UI and verify it against the stored screenshot.

During each test run, snapshots are compared to detect discrepancies. This method proves invaluable during product releases. For instance, it can detect overlapping text or changes in text color. This straightforward process ensures visual consistency and identifies UI regressions.

Consider an eCommerce website that receives regular updates. If a developer accidentally introduces a visual difference on the product details page, screenshot testing can quickly identify the issue.

Without configured snapshot or screenshot tests, visual differences might go unnoticed in traditional functional testing, which focuses only on functionality. However, you can capture these exact changes early with automated screenshot testing. This helps the team quickly identify and address UI issues. Snapshot testing is also done to ensure browser compatibility. In a multi-browser environment, there can be variations in visual appearance.

For example, your web application might appear fine in Chrome but could have unexpected display problems in Firefox. Each browser has its unique rendering engine, which means every browser interprets web pages differently on a user’s screen. Therefore, running snapshot tests across different browsers helps identify these differences early, ensuring a smooth user experience across various browsers.

Below are some of the key benefits of Cypress snapshot testing:

  • Streamlined Testing Workflow: It significantly reduces the manual effort and streamlines the testing process, making it more efficient and accurate. This approach adds extra value to your test execution, especially when utilizing automation.
  • Early Detection Of Visual Mismatch: It accurately identifies visual regressions that traditional functional testing may overlook. This ensures your application maintains its intended visual consistency. It checks pixel-perfect reference images and highlights if there is any mismatch in the image.
  • Seamless Cross-Browser and Cross-Device Compatibility: It ensures your application appears consistent and functions correctly across various browsers and devices, reducing the risk of visual issues that may arise on specific browsers.
  • Integration with CI/CD: It seamlessly integrates with the CI/CD pipeline, you can automate the process, allowing you to catch visual issues as soon as code changes are introduced and inform developers about the visual impact of their code changes, enabling them to make necessary adjustments quickly. This efficiency contributes to a smoother development process.
  • UI Consistency and Integrity: It ensures your application's UI remains consistent across development iterations. Comparing the current UI state with a previously accepted snapshot helps catch unexpected changes, maintaining consistency and integrity.
  • Time-Efficiency: Cypress screenshot tests are quick to write and run, making them more time-efficient than other tests. Manual updates are needed only for intentional UI changes, saving valuable development time.
  • Detecting Unexpected UI Changes: It helps detect unintended UI changes early in development, ensuring quicker bug detection and faster fixes.

However, Cypress snapshot testing is not meant to replace the other forms of testing in Cypress; it is just another tool in your toolkit that you can use whenever you think it is required.

The main purpose of visual screenshot testing is to ensure visual consistency and complement the other testing methods.

...

Types of Snapshots in Cypress

We use different types of snapshots in our Cypress tests. Each has its differences and use cases; understanding these types will help us effectively capture the right moments for the best testing outcomes.

  • Document Object Model (DOM) Snapshot: This is a temporary copy of the test application’s DOM saved after every test step while running on GUI mode.
  • Snapshot: This is a more general term, which is any object stored on your disk using the cy.wrap(...).snapshot() command.
  • Element Snapshot: This type focuses more on specific elements in your DOM. It will store serialized versions of them on disk when executing the .snapshot() command in Cypress. The element could be any HTML element that exists in the DOM (e.g., a <div> or a <body>).

These three types of snapshots, each with their purpose and use, can be utilized effectively to enhance the resilience of your tests and their impact on your application.

Methods for Taking Snapshots in Cypress

Before writing code for Cypress snapshot testing, familiarize yourself with Cypress methods that help capture screenshots and enhance the effectiveness of your Cypress snapshot testing.

Taking Snapshots for Objects

Sometimes, we expect a large object to return from the API we use for our tests. The problem is that sometimes, the response we get from the API calls we make could be huge, and it would be very unreliable to write the object down in the test suite.

The best way to handle this is to save the object as a snapshot expected to be returned from the API call and compare it to the object returned in the subsequent test runs.

For example, let’s write a test to save a JavaScript object as a snapshot and compare it in the subsequent test runs.

To send API requests using Cypress, you must install the Axios library or fetch API in the browser.

Follow the below command to install the Axios library.


yarn add axios

Since this is a different test, we will create a spec file for this test called <cypress\e2e\api.cy.ts>

Below is the code for sending the API request with Axios.


import axios from "axios"
describe("API response snapshot tests", () => {
beforeEach(() => {
cy.visit("https://www.lambdatest.com/selenium-playground/simple-form-demo")
})
it("should match the snapshot", async () => {
const { data } = await axios.get(
"https://jsonplaceholder.typicode.com/todos"
)
})
})

Save the snapshot by using the .toMatchSnapshot() function that comes with the cypress-plugin-snapshots npm package.


import axios from "axios"
describe("API response snapshot tests", () => {
beforeEach(() => {
cy.visit("https://www.lambdatest.com/selenium-playground/simple-form-demo")
})
it("should match the snapshot", async () => {
const { data } = await axios.get(
"https://jsonplaceholder.typicode.com/todos"
)
cy.wrap(data).toMatchSnapshot()
})
})

Result:

simple form demo

The test successfully runs with the snapshot saved in the <cypresse2e__snapshots__> folder. It will save it in a snapshot file with the same name as the spec file with the suffix .snap, in this case, api.cy.ts.snap.

This is how the data is stored in the snapshot file <cypresse2e__snapshots__ api.cy.ts.snap>.


exports['API response snapshot tests > should match the snapshot #0'] =
[
{
"completed": false,
"id": 1,
"title": "delectus aut autem",
"userId": 1
},
{
"completed": false,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"userId": 1
},
];

This way, the snapshot is stored perfectly, and we can detect changes in the subsequent tests if there are any expected changes.

Let’s try to change the API response by changing the API endpoint to something that returns a different response.


import axios from "axios"
describe("API response snapshot tests", () => {
beforeEach(() => {
cy.visit("https://www.lambdatest.com/selenium-playground/simple-form-demo")
})
it("should match the snapshot", async () => {
// First API Call
// const { data } = await axios.get(
//   "https://jsonplaceholder.typicode.com/todos"
// )
// Second API Call
const { data } = await axios.get(
"https://jsonplaceholder.typicode.com/posts"
)
cy.wrap(data).toMatchSnapshot()
})
})

Result:

simple form demo result

As expected, we are getting an error message from Cypress because the snapshots didn’t match. Capturing objects in Cypress helps us easily detect changes, especially in API calls, without writing the expected values ourselves and making the code bloated.

Taking Snapshots for Elements

Now, let's write tests to capture element screenshots. This allows us to save a serialized version of the elements in the DOM and detect any unexpected changes in subsequent tests. Serializing an HTML element converts it to a string format for comparison with the same serialized element in future tests.

Below is the code for taking screenshots for elements:


describe("Element snapshot tests", () => {
    beforeEach(() => {
    cy.visit("https://www.lambdatest.com/selenium-playground/simple-form-demo")
    })
  it("Should match the snapshot of the element", () => {
   cy.get("h1").toMatchSnapshot()
   })
 })

This way, it will only get the h1 element in the DOM and save the serialized version as a snapshot.

Result:

element in the dom

Now, the screenshot is saved inside of the <cypresse2e__snapshots__> folder.

Below is the code for storing the Cypress screenshot.


exports['Element snapshot tests > Should match the snapshot of the element #0'] = '
<h1
class="text-size-48 font-bold text-black text-center leading-none text-shadow md:w-full leading-height-70 mx-auto smtablet:text-size-30 smtablet:leading-height-42"
>
Simple Form Demo
</h1>
';

Result:

result oneresult two

Now, anytime the <h1> element has changed, the Cypress snapshot testing test case will throw an error, and the test will fail.

Let’s replicate this scenario by getting another element from the DOM and comparing it to the stored element.


describe("Element snapshot tests", () => {
beforeEach(() => {
 cy.visit("https://www.lambdatest.com/selenium-playground/simple-form-demo")
 })
it("Should match the snapshot of the element", () => {
// First snapshot
// cy.get("h1").toMatchSnapshot()
// Second snapshot
 cy.get("h2")
.first()
.toMatchSnapshot()
})
})

Result:

element snapshot

As expected, Cypress shows the difference between the snapshots beautifully.

Capturing screenshots is a fundamental practice when validating the visual aspects of the web application during Cypress tests. Cypress offers various commands to achieve this. Below, we will learn more about using the cy.screenshot() command to take screenshots.

Syntax:

syntax screenshot

Note: We will use the latest version of Cypress 13.6.6, which is compatible with the most recent features and enhancements.

Taking Snapshots Using cy.screenshot()

Using the cy.screenshot() command allows you to easily capture a full-page screenshot at the end of your test, which will be saved with the same name as your test case. By default, these screenshots are stored in the cypress/screenshots folder, but you can customize the folder using the Cypress configuration.

To gain a better understanding of how to utilize cy.screenshot() in your test script, let's consider the following test scenario:

Test Scenario:


  • OpenURL: LambdaTest Selenium Playground using cy.visit().
  • Enter username and password using cy.get().type().
  • Click the Submit button using cy.get().click().

Let's enhance our understanding of cy.visit(), cy.get().type(), and cy.get().click() by executing the test scenario mentioned above.

Code Implementation:

Below is the code implementation for the test scenarios that must be added to your test script.


describe('Cypress Screenshot Testing', function () {


   it('cy.screenshot() - take a screenshot', () => {
       cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
       cy.get('#input-email').type("lambdatest.Cypress@disposable.com");
       cy.get('#input-password').type("Cypress123!!");
       cy.get('[value="Login"]').click()
       cy.screenshot()


   })
})

Before jumping to the test result, let's understand the code details below.

Code Walkthrough:

  • Open the website using the cy.visit() command.
  • open the website
  • Enter your username and password and click on the Submit button. The following code uses the Cypress command cy.get() to interact with a login form.

    It locates the email and password input fields by their unique IDs, namely "input-email" and "input-password”, enters the values “lambdatest.Cypress@disposable.com" into the email field and "Cypress123!!" into the password field and triggers the form submission by clicking the Login button by using the command cy.get('[value="Login"]').click().

  • username and password

    As shown below, you can locate elements using attribute names and utilize them in a Cypress test case using the cy.get() command.

    attribute names
  • The code below lets you capture a full-page screenshot at the end of your test and save it with the same name as your test case. By default, these screenshots are stored in the cypress/screenshots folder, but you can also customize the folder in the Cypress configuration.
  • capture full page screenshot

Output:

Go to the terminal and run the following command:


npx cypress run
cypress run

After the successful execution of your test scenario, the screenshot will be stored in the folder cypress/screenshots/<name of the test> just like shown below in the screenshot.

screenshot in folder

Let us learn another method offered by Cypress that allows you to store and save the screenshot images with custom names.

Taking Snapshots for Custom Filename Using cy.screenshot(filename)

With the cy.screenshot(filename) command, you can capture a full-page screenshot at the end of your test run, and it will be saved with the name as passed in the cy.screenshot(filename).

To better understand how to use the cy.screenshot(filename) command, we will use the same test scenario for the above Cypress method cy.screenshot().

Code Implementation:

Below is the code implementation for the test scenarios mentioned earlier, where you can use cy.screenshot(filename) to provide names for your captured screenshots.


describe('Cypress Screenshot Testing', function () {
   it('cy.screenshot() - take a screenshot', () => {
       cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
       cy.get('#input-email').type("lambdatest.Cypress@disposable.com");
       cy.get('#input-password').type("Cypress123!!");
       cy.get('[value="Login"]').click()
       cy.screenshot('Test')
   })
})

Before jumping to the test result, let's understand the code details below.

Code Walkthrough:

  • The only step that has changed is storing the screenshot in the folder. In the code below, it captures a screenshot of the entire page and saves it with the name provided in the command cy.screenshot('Test').
  • changed step

Output:

To run your testing go to the terminal and run the following command:


npx cypress run
run the following command

After successfully executing the test scenario, the screenshot will be stored in the folder cypress/screenshots/Test.png, as specified in the test.

screenshot will be saved

Taking Snapshots for Behavioural Change Using cy.screenshot(options)

You can customize the default behavior of Cypress by passing an options object to the cy.screenshot() command.

Below are some commonly used options that allow you to modify the default behavior:


Options Description
captureBy default, the application under test is captured from top to bottom. But you can also change it from the other available options - Valid values are viewport, full-page, or runner. Using the capture option, you can define what part of the AUT you want to take a screenshot of.
paddingThis is used to alter the dimensions of a screenshot of an element. Example => cy.get('.click).first().screenshot({ padding: 10 })
overwriteBy default, the overwrite is false, but if you want to overwrite duplicate screenshot files with the same file name, pass it as true.
screenshotOnRunFailureBy default, Cypress automatically takes a screenshot when a test fails during execution in cypress run.

In addition to the options mentioned above, one of the most commonly used options is log. By default, Cypress logs the cy.screenshot() command in the command log, but you can hide it by passing log: false.

To better understand the most commonly used Cypress option, let's consider how to use the log option with cy.screenshot() in the test scenario.

We will use the same test scenarios as in the first method, which is cy.screenshot(), but with a modification: cy.screenshot({ log: false }).

Below is the code implementation for the test scenarios mentioned earlier, where you can use cy.screenshot(options).

Code Implementation:


describe('Cypress Screenshot Testing', function () {
   it('cy.screenshot() - take a screenshot', () => {
       cy.visit("https://ecommerce-playground.lambdatest.io/index.php?route=account/login");
       cy.get('#input-email').type("lambdatest.Cypress@disposable.com");
       cy.get('#input-password').type("Cypress123!!");
       cy.get('[value="Login"]').click()
       cy.screenshot({ log: false })
   })  })

Code Walkthrough:

  • The only change you need to make is to pass the options in cy.screenshot(). The code captures a screenshot of the entire page but does not display it in the command logs.
  • no display in command logs

Result

no display in command logs result

As shown above, the cy.screenshot() command will not appear in the command logs. However, the screenshot will still be captured and stored in the cypress/screenshots folder, as shown below.

screenshot captured and stored

We have learned how to take screenshots using Cypress commands and understood their functionality by running each command with a test scenario.

Prerequisites for Cypress Snapshot Testing

Here, we will learn how to install the necessary plugins for Cypress to run snapshot tests. We will also try out all snapshots, including visual screenshot testing.

Once we've completed that step, you can leverage Cypress's robust cloud testing capability. This will allow us to automate and execute our tests in the cloud, streamlining the delivery process and enabling compatibility across various browsers.

First, let’s initialize a Node.js project by running the following command:


   npm init -y

This will create a package.json file with the following configurations:


    {
        "name": "cypress-snapshot-testing",
        "version": "1.0.0",
        "description": "",
        "main": "index.js",
        "scripts": {
          "test": "echo "Error: no test specified" && exit 1"
        },
        "keywords": [],
        "author": "",
        "license": "ISC"
      }

Install TypeScript

  • If you want to use TypeScript with Cypress, then run the following commands to install TypeScript with Yarn.
  •  yarn add -D typescript
    
  • Once you have installed the TypeScript, you must then initialize it by using the following command:
  •  npx tsc --init
    

    After you have initiated the TypeScript, a tsconfig.json file will be created in your root directory.

  • Now to install Cypress with the latest version, run the following command:
  •  yarn add -D cypress@latest
    
  • Once you have installed the Cypress, update the package.json file, as shown below.
  •  ...
    "scripts": {
      "test": "cypress open"
    },
    ...
    
  • Once the Cypress is installed, run the following command to open the Cypress test runner
  •  yarn test 
    

    Or

     npm run test 
    
  • Select the E2E Testing option > Click on the Continue button > Choose the browser of your choice > Click on the Create new spec option.
  • create new spec

    Now that Cypress has created the spec file, it is ready to be modified, and the tests run.

    run cypress tests

For this Cypress tutorial, all our tests will be run on the LambdaTest Selenium PlaygroundLambdaTest Selenium Playground for testing purposes.

To make things easier, we can update the Cypress config file and add the website as the baseUrl key.


// ./cypress.config.ts
import { defineConfig } from "cypress"
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
baseUrl: "https://www.lambdatest.com/selenium-playground/simple-form-demo",
},
})

Install the Cypress Screenshot Plugins

To utilize the snapshotting features with Cypress, we need to install the cypress-plugin-snapshots plugin. It helps integrate snapshot testing into Cypress, allowing developers to easily capture and compare UI states, objects, and DOM elements, ensuring consistency across your application.

To get started with the Cypress screenshot plugin, follow the below steps:

  • Install the plugin by running the following command:
  • yarn add -D cypress-plugin-snapshots
  • Import it to the commands.js/ts file.
  • import 'cypress-plugin-snapshots/commands';
  • Add as a plugin in cypress.config.js or cypress.config.ts file:
  • import { defineConfig } from "cypress"
    import { initPlugin } from "cypress-plugin-snapshots/plugin"import the plugin
    export default defineConfig({
    e2e: {
    setupNodeEvents(on, config) {
    // implement node event listeners here
    initPlugin(on, config)// ← initialize the plugin
    },
    baseUrl: "https://www.lambdatest.com/selenium-playground/simple-form-demo",
    },
    })

How To Perform Cypress Snapshot Testing?

Now that we’ve set up the Cypress environment with the necessary Cypress snapshot testing plugins and other libraries, it’s time to execute real-time Cypress snapshot testing. We'll use the LambdaTest Selenium Playground website to run the tests, mimicking real-time scenarios by changing the application's state rather than altering the code.

Below is the code modified to perform Cypress snapshot testing.


describe("Snapshot testing", () => {
beforeEach(() => {
cy.visit("https://www.lambdatest.com/selenium-playground/simple-form-demo")
})
it("should match the snapshot", () => {
cy.get("input#user-message").type(
"Lambdatest is a cloud-based platform enhancing testing with its scalable, reliable, and secure global infrastructure. It offers cross-browser testing capabilities and continuous integration tools."
)
cy.get("button#showInput").click()
cy.get("div.mt-30.rounded")
.first()
.toMatchImageSnapshot()
})
>})
LambdaTest

In this visual testing example using Cypress, we visited the LambdaTest Selenium Playground website, selected the input, submitted the form, and observed the message appearing next to the text input. Then, we capture a snapshot of the user message element using the toMatchImageSnapshot() function from the cypress-plugin-snapshots plugin.

If you have noticed, we have used the .toMatchImageSnapshot() method in the above code; this code is provided by TypeScript and is an autocomplete feature. To use this, you must first update your commands.js/ts file and add the following code given below:


declare global {
namespace Cypress {
interface Chainable {
toMatchImageSnapshot(args?: {
imageConfig?: {
createDiffImage?: boolean
threshold?: number
thresholdType?: "pixel" | "percent"
}
name?: string
separator?: string
}): Chainable<Element>


toMatchSnapshot(args?: {
ignoreExtraFields: boolean
ignoreExtraArrayItems: boolean
normalizeJson: boolean
replace: {
[key: string]: string | number | boolean | null | undefined
}
}): Chainable<Element>

}
}
}

Here is a quick explanation of each property that you can provide for the toMatchImageSnapshot() method:

  • createDiffImage: When set to true, this option generates a "diff image" highlighting the differences between reference and new snapshots. It's a visual tool for identifying changes, but it can be set to false to skip this process and improve performance.
  • threshold: This parameter sets the tolerance level for differences between the reference and new snapshots. The snapshot is considered invalid if the differences exceed this amount (in pixels or percentages).
  • thresholdType: Specifies whether the threshold is measured in "pixel" or "percent." It defines the unit for the threshold parameter, helping to fine-tune the sensitivity of the comparison.

toMatchSnapshot() properties:

  • ignoreExtraFields: In subsequent tests, if the new version of the object has extra fields (that weren't present in the first snapshot) and ignoreExtraFields is set to true, the test will not fail because of these additional fields.
  • ignoreExtraArrayItems: If set to true, for array types of snapshots, the test will not fail if there are additional items at the end of the array in the current test data compared to the snapshot.
  • normalizeJson: Alphabetically sorts keys in JSON.
  • replace: Replaces a key inside of the snapshot with the provided value.

Result:

the cypress-plugin-snapshots will save the image snapshot

The first time the test is run, the cypress-plugin-snapshots will save the image snapshot in the folder <cypress/e2e/__image_snapshot__>.

We can change the name of the snapshot by adding the name property, for example:


cy.get("div.mt-30.rounded")
.first()
.toMatchImageSnapshot({
name: "User message",
})

The screenshot will then be saved in the <cypress/e2e/__image_snapshot__/User message #0.png> file.

Let’s change the UI to get a mismatched screenshot error from the Cypress snapshots plugin. We will change the text in the input just a bit to see if we get the snapshot error.

Here’s the next test:


describe("Snapshot testing", () => {
beforeEach(() => {
cy.visit("https://www.lambdatest.com/selenium-playground/simple-form-demo")
})
it("should match the snapshot", () => {
cy.get("input#user-message").type(
"Another website is a cloud-based platform enhancing testing with its scalable, reliable, and secure global infrastructure. It offers cross-browser testing capabilities and continuous integration tools."
)
cy.get("button#showInput").click()
cy.get("div.mt-30.rounded")
.first()
.toMatchImageSnapshot({
name: "User message",
})
})
})

The only thing that changed is that the text LambdaTest was changed to another website.

Result:

change is that the text LambdaTest was changed to another website

Weird, isn’t it? It should have thrown an error instead of passing the test because we changed the text, and thus, the UI should have changed as well.

This test passed because the cypress-plugin-snapshots plugin has a default threshold property set to 0.01. This means Cypress will only throw an error if there is at least a one percent change in the UI. The change was minimal, less than one percent, so no error was thrown.

Let's tweak the threshold property to 0. This way, the test will only pass if the images are 100% identical.


cy.get("div.mt-30.rounded")
.first()
.toMatchImageSnapshot({
name: "User message",
imageConfig: {
threshold: 0,
},
})

Result:

 Look at the <cypress/e2e/__image_snapshot__> directory and the generated images

As you can see, the test is failing as expected. Look at the <cypress/e2e/__image_snapshot__> directory and the generated images.

The snapshot image directory looks like this now:

the snapshot image directory looks like this now:
  • actual.png: Represents the latest snapshot.
  • .diff.png: Represents the difference between the new and old snapshots.
  • .png: The initial snapshot.

Look at the <.diff.png> image file and see how it looks.

Look at the <.diff.png> image file and see how it looks

As seen above, the cypress-plugin-snapshots does a pretty good job of spotting the differences between the two snapshots.

This is a reliable way to write tests to make the UI match your expectations. Without visual screenshot testing, it would be impossible to write tests for the aesthetics of your website.

But that is not the only plugin that Cypress screenshot testing offers. We are looking into other plugins to help you perform screenshot testing using the powerful cypress-image-snapshot plugin.

This plugin, available under the MIT License, has more than nine releases, making it a reliable choice. It enables you to capture specific snapshots during tests and compare them to reference screenshots. Doing so lets you identify differences in the DOM, layout, or visual appearance, ensuring your website looks perfect.

For example, if the text has a padding issue or a color change. This plugin immediately highlights it after the test execution.

Below are some of the examples.

 key features of the cypress-image-snapshot plugin

Below are the key features of the cypress-image-snapshot plugin:

  • Specific Snapshots: Capture It captures targeted snapshots of specific parts of your website during test execution and checks for an existing snapshot in <rootDir>/cypress/snapshots.
  • Smart Comparisons: The plugin intelligently compares new snapshots with existing ones, considering changes to the DOM, layout, font, or any visual appearance.
  • Saving Differences: If differences are detected, the plugin saves them in <rootDir>/cypress/snapshots/diff_output.

Before using the cypress-image-snapshot plugin, let's understand how it works and how to set it up to implement Cypress snapshot testing in detail.

Plugin Set-Up Process

  • Go to the terminal and install the plugin by using the following command.
  • npm install --save-dev @simonsmith/cypress-image-snapshot

    After the installation, you should see a dependency added in package.json, as shown below.

    see a dependency added in package.json, as shown
  • Import and initialize the cypress-image-snapshot plugin. For Cypress version 10 and above, add the following code to file cypress.config.js file:
  • The code to be added to the cypress.config.js file looks as shown below.

    const { addMatchImageSnapshotPlugin } = require('@simonsmith/cypress-image-snapshot/plugin')
    const { defineConfig } = require('cypress')
    module.exports = defineConfig({
    e2e: {
    setupNodeEvents(on) {
       addMatchImageSnapshotPlugin(on)
    },
    },
    })
  • To import and add the Cypress image command for Cypress version 10 and above, go to cypress/support/commands.js and add the following code:
  • import { addMatchImageSnapshotCommand } from '@simonsmith/cypress-image-snapshot/command'
    addMatchImageSnapshotCommand()
    // can also add any default options to be used
    // by all instances of `matchImageSnapshot`
    addMatchImageSnapshotCommand({
       failureThreshold: 0.2 
    })
    

To understand the functionality and usage of this dependency, we will start by initiating a request to the sample index.html ( which displays a simple text on the page with a grey button), followed by capturing a snapshot.

Test Scenario:

  • Open the URL by using cy.visit().
  • Take a screenshot of the page.

Code Implementation:


  describe('Cypress Screenshot Testing', function () {


it('cy.screenshot() - take a screenshot', () => {
cy.visit("index.html");
cy.matchImageSnapshot();


})
})
LambdaTest

Code Walkthrough:

Step 1: Open the website using the cy.visit() command.

Open the website using the cy.visit() command

Step 1: The code cy.matchImageSnapshot() captures a snapshot of the test and checks for a stored snapshot in <rootDir>/cypress/snapshots. If a snapshot is found, it compares the current screenshot against the stored one.

Any differences are saved in <rootDir>/cypress/snapshots/diff_output. If no snapshot is found, it captures and stores the new snapshot in <rootDir>/cypress/snapshots.

 code cy.matchImageSnapshot() captures

In this case, during the first test, the snapshot will be stored in <rootDir>/cypress/snapshots, and the test will execute without any failures.

Output:

To run the test, use the following command.


npx cypress run
To run the test, use the following command: npx cypress run

After the test execution, the snapshot will be stored in the folder <rootDir>/cypress/snapshots with the same name as the test case title, just as shown below:

stored in the folder <rootDir>/cypress/snapshots with the same name as the test case title

Above is the result without any design implementation using the Click me button.

To perform Cypress snapshot testing and to design the Click me button, let’s modify the index.html ( changing the Click me button to green color and update the href="styles-font2.css"> from href="styles-font1.css">) and rerun the test to observe the differences in output.

rerun the test to observe the differences in output
LambdaTest

Output:

Execute the test using the following command <npx cypress run>, and this time, the snapshot will differ because the latest screenshot varies from the previous one, as the Click me button will be displayed in green, differing from the prior test, where it had a white background.

differing from the prior test, where it had a white background

Navigate to the cypress/snapshots folder, and you will find the differing snapshots stored inside <rootDir>/cypress/snapshots/__diff_output__ .

The snapshot below shows that the left side displays the base image (captured during the initial test case execution), the center highlights the differences (the color of the Click me button), and the right side shows the newly taken snapshot.

 Click me button), and the right side shows the newly taken snapshot

Let's understand this with another test scenario where the latest release includes a space in the text compared to the baseline test.

Test Scenario:

  • Execute a test case with `index.html` to capture the baseline image.
  • Make modifications to the design (e.g., add extra space).
  • Run the Cypress test to check for differences.
  • Identify if the test case fails.
  • Highlight the differences and save them as a screenshot.

Before executing the test scenario, you will get the result as shown below.

Before executing the test scenario, you will get the result as shown below

After executing the test scenario, you will get the result as shown below.

After executing the test scenario, you will get the result as shown below After executing the test scenario, the results will appear
LambdaTest

Output:

irectory cypress/snapshots/screenshotTest-Plugin.cy.js/diff_output updated screenshot will be saved there

Go to the directory cypress/snapshots/screenshotTest-Plugin.cy.js/diff_output_. The updated screenshot will be saved there, displaying the highlighted differences in red, similar to the one shown below in the screenshot.

 displaying the highlighted differences in redthe difference is highlighted even with a slight change in the design

As shown in the snapshot above, the difference is highlighted even with a slight change in the design. Cypress snapshot testing is not limited to color changes; it can also detect any design changes on the page. This can be achieved with minimal lines of code in your test automation framework.

With Cypress screenshot testing, managing the snapshot directory structure is always challenging, especially when replicating the folder structure of test files.

To overcome such a challenge, a cloud platform for Cypress screenshot testing, like LambdaTest, can help manage the snapshot directory structure. It also includes advanced visual regression testing features that can detect subtle differences in UI snapshots, which might not be possible with basic image comparison techniques.

LambdaTest offers scalability for parallel testing, centralized storage for screenshots, and the ability to replicate local folder structures in the cloud storage. This streamlines test management and ensures efficient storage and access to screenshots.

LambdaTest is an AI-powered test execution platform that lets you run manual and automated screenshot tests at scale with over 3000+ real devices, browsers, and OS combinations. This platform offers a scalable approach to testing web applications across various OS/browser combinations and helps identify visual UI bugs through the SmartUI testing feature.

Its SmartUI testing platform helps testers validate the visual appearance of web applications. It compares screenshots to detect visual pixel differences, compares PDF files, and identifies DOM rendering issues across browsers, ensuring UI consistency and seamless integration with functional tests.

Key Features of SmartUI testing are:

  • Pixel-to-Pixel Comparison: It allows for a thorough pixel-to-pixel comparison of screenshots. This ensures any UI issues are immediately identified by visually comparing how web pages look.
  • Multi-browser and Resolution Tests: It simultaneously enables testing across different browsers and screen resolutions. This ensures a consistent user experience regardless of the browser or device used.
  • Project Collaboration: It can easily collaborate on projects by adding up to 5 approvers/tags. This feature streamlines teamwork and facilitates smoother project management.
  • Real-time Notifications: It receives immediate updates on test status changes, allowing quick responses to any issues arising during testing. This ensures efficient troubleshooting and resolution of problems as they occur.

How To Perform Cypress Snapshot Testing at Scale?

Here, we will provide a step-by-step guide on performing Cypress screenshot testing on the LambdaTest using SmartUI. I’ll walk you through the process, from setting up your testing environment to executing and analyzing results.

Ensure you have set up the account on LambdaTest and have all the config details (username and access key). Once you have signed up and have all the details, follow the below steps to run your test.

  • To install the LambdaTest Cypress CLI, navigate to your Cypress project directory and open the terminal. Then, use the following command to install the LambdaTest CLI:
  • npm i lambdatest-cypress-cli@3.0.26 --save-exact. 

    Download the latest version using lambdatest-cypress-cli to access its newest features.

  • After completing the installation, you can double-check the version to ensure it matches the one you specified in the command using the below syntax:
  • npx lambdatest-cypress init --version
  • Once the LambdaTest Cypress CLI is installed, the next step is to set up the configuration using the below command:
  • lambdatest-cypress init
  • After running the previous step command, a file will be created in your project named lambdatest-config.json.
  • To set up the configuration for running test cases on different browsers on LambdaTest with Cypress version 10 and above, you can create a lambdatest-config.json file in your project's root directory with the following content:
  • { 
    "lambdatest_auth": {
    "username": "<user.name>",
    "access_key": "<access_key"
    },
    "browsers": [
    {
    "browser": "Chrome",
    "platform": "Windows 10",
    "versions": ["latest-1"]
    },
    {
    "browser": "Firefox",
    "platform": "Windows 10",
    "versions": ["latest-1"]
    }
    ],
    "run_settings": {
    "config_file": "cypress.config.js",
    "reporter_config_file": "base_reporter_config.json",
    "build_name": "screenshot-test-build",
    "parallels": 1,
    "specs": "./cypress/e2e/screenshot.cy.js",
    "ignore_files": "",
    "network": false,
    "visual": true,
    "headless": false,
    "npm_dependencies": {
    "cypress": "13.2.0"
    },
    "smart_ui": {
    "project": "screenshotTest",
    "baseline": true
    }
    }
    }
    
LambdaTest

Code Walkthrough:

  • Set up LambdaTest credentials in lambdatest-config.json to run your test on the cloud platform.
  • Specify the browser and OS version for your test case.
  • Configure settings in run_settings, including the config name (varies with Cypress Versions) and the spec file.
  • For SmartUI, configure the settings in the smart_ui section of your configuration file. Provide a meaningful project name under the project setting. When setting the baseline parameter:
    • Setting the baseline to true indicates that the current test case is the baseline for your test. If any future test case does not match this baseline image, it will fail.
    • Setting the baseline to false indicates this test is not the baseline. The baseline can be a previously chosen image.

In the shared configuration file, you can set the baseline to true to execute your initial test case. When you run this test case on SmartUI, it will be recognized as a baseline image.

To better understand how to run the test on SmartUI, let's consider the same test case mentioned in the initial section of the tutorial.

Code Implementation:


 describe('Cypress Screenshot Testing', function () {
it('Cypress Screenshot Test - take a screenshot', () => {
cy.visit('index.html')
cy.screenshot('Test');
})
})
LambdaTest

Output:

Once the config is done and you have added the test case, now you can execute the Cypress test case on the SmartUI using the below command:


npx lambdatest-cypress run
cypress-test-case-on-the-smartui

After successfully executing the command and completing the test cases, you will receive a link to the LambdaTest SmartUI Dashboard. This link will navigate you to the SmartUI Dashboard, where you can review the test execution results.

Result:

Below is the screenshot of the execution status from the LambdaTest Dashboard.

execution-status-from-the-lambdatest-dashboard

Comparing Screenshots With Test Changes

To inspect the visual differences in the screenshot, we will modify the test by updating the index.html to change the click me button's color, producing a distinct final output. We will also update the lambdatest-config.json config file, setting the baseline to false.

comparing-screenshots-with-test-changes

Result:

Executing the test on different browsers is essential because each browser uses a different rendering engine, and it's impossible to predict which browser your audience will use. Therefore, testing on multiple browsers is always a good idea.

Will rerun the test case from the terminal using the following command:

<npx lambdatest-cypress run>, and this time, the snapshot will differ because of the color change in the Click me button.

Result on Firefox Browser:

Result on Firefox Browser

Result on Chrome Browser:

Result on Chrome Browser

The test case failed due to a difference in the images. On the left side, you can see the baseline image captured during the initial test case execution. The last screenshot is displayed on the right side, with the difference highlighted in blue.

Subscribe to the LambdaTest YouTube Channel for more video tutorials on other automation testing tools, such as Selenium testing, Cypress UI testing, and more.

Advanced Options for Snapshot Comparison

We will explain the advanced options that can be used for Screenshot comparison on the SmartUI Dashboard.


Feature Description
Build ConfigurationUsing the build configuration, You can update any chosen build as a new baseline by changing the build name and baseline value to true/false.build as a new baseline by changing the build name and baseline value to true/false
Advanced Test SettingsThere are many options that you can customize to compare baseline tests with the test output screenshots. One such option is the largeImageThreshold option from the advanced test settings, which allows you to set the pixel granularity at the rate at which pixel blocks are created. largeImageThreshold option from the advanced test settings
HTML DOM Config and OptionsThis is one of the coolest advanced settings options where you can ignore the dynamic elements or specify certain areas to exclude from the comparison. Refer to the support documentation for guidance on handling DOM configuration and options for SmartUI. This will help you start making your Cypress snapshot testing even smarter.

Conclusion

In conclusion, Cypress snapshot testing is a robust method for validating the visual aspects of your applications, fortifying the resilience of your comprehensive testing strategy. By capturing UI states, this method serves as an essential strategy for detecting unexpected visual changes, elevating the quality and reliability of your applications.

However, as with any testing tool, it's important to remember that Cypress snapshot testing isn't for all testing needs. It excels in providing visual validation and supplementing other types of testing, like unit and end-to-end tests. Hence, snapshot tests should be a part of a larger, comprehensive testing strategy that covers different layers of your application.

Now that you've got a solid grasp of Cypress snapshot testing and its potential impact, it's time to start experimenting. So set up Cypress, write your first snapshot test, and enhance your testing suite one snapshot at a time!

Enhance Test Management with AI

Streamline test authoring, management, execution, and reporting to boost efficiency throughout all testing phases.

Automate Accessibility Testing

Frequently asked questions

  • General ...
What is snapshot testing for?
Snapshot testing is employed to detect unintentional changes in the visual representation of an application's user interface (UI) over time. It captures and stores snapshots or baseline images of the UI during a stable state and compares them to subsequent snapshots taken after code changes. This method is particularly valuable for identifying unexpected alterations in an application's layout, styling, or content. By flagging discrepancies between baseline and updated snapshots, snapshot testing helps prevent visual regressions caused by code modifications. It is an essential quality assurance technique, ensuring the UI remains consistent and visually appealing with each development iteration. It is especially useful in projects with dynamic and frequently evolving UIs.
How to do screenshot testing in Cypress?
You can leverage the built-in cy.screenshot() command to perform screenshot testing in Cypress. First, ensure the Cypress Screenshot plugin is installed by running npm install --save-dev cypress-screenshot. Include the plugin in your Cypress commands by adding the import 'cypress-screenshot'; to your commands.js file. Once set up, you can capture screenshots at various points during your tests, such as after visiting a page or performing specific actions. Customize the screenshot names for better identification, and explore additional configuration options in your cypress.json file to tailor the behavior. With this straightforward implementation, Cypress enables you to visually verify the consistency of your web application's UI across different test scenarios.
How does Cypress screenshot testing detect visual changes in web apps?
Cypress screenshot testing detects visual changes by capturing baseline images of UI components and comparing them with subsequent screenshots, highlighting any differences that may indicate UI regressions.
Can Cypress screenshots be automatically saved and compared?
Yes, Cypress can automatically save screenshots and compare them against baseline images, making identifying and addressing visual inconsistencies easy.
Does Cypress support capturing screenshots across different browsers?
Cypress supports capturing screenshots across different browsers, allowing developers to ensure consistent UI appearance and behavior across various browser environments.
What is the benefit of integrating Cypress screenshots with CI/CD pipelines?
Integrating Cypress screenshots with CI/CD pipelines enables teams to automate visual regression testing, catching UI issues in the development process and ensuring a smoother deployment process.

Did you find this page helpful?

Helpful

NotHelpful

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud