Cypress is a popular automation tool known for features like easy debugging, an interactive Test Runner, and developer-friendly syntax. Version 10 simplifies Component Testing, streamlining configuration and execution while integrating it with End-to-End Testing.
It allows developers to test components directly in the browser, seamlessly integrating with APIs. Cypress also supports Visual Testing, validating UI elements at both application and component levels.
This guide explores how to perform visual validation testing using Cypress Component Testing, including Visual Regression Testing with the Cypress Image Diff Plugin and component-level visual testing with Percy.
Steps to Perform Visual Component Testing in Cypress
Visual Component Testing in Cypress is an effective way to validate UI elements and ensure they render as expected across various states. By integrating component testing with visual validation tools, developers can detect even the smallest UI inconsistencies early in the development cycle.
This process works seamlessly with modern frameworks like React, Angular, or VueJS, making it adaptable for diverse projects.
Pre-requisites
Before proceeding, ensure you have a development framework such as React, Angular, or VueJS set up as a prerequisite.
Also Read: Cypress Installation for Test Automation
Below are the key steps to perform Visual Testing in Cypess
Step 1: Install Cypress to your project
Using the command
npm install cypress -D
Step 2: Open Cypress
Open Cypress with command
npx cypress open
The above command will create the default directory structure for Cypress tests.
Step 3: Configure Cypress Component Testing
- Once you open Cypress, you will see the window, E2E and Component Testing.
- Choose Component Testing.
- Using the on-screen instruction, configure your project with Cypress Component Testing.
Step 4: Install the cypress-image-diff-js plugin
For the Visual Testing, you need to install cypress-image-diff-js, Use the below command to install the image comparison node package.
npm i cypress-image-diff-js
Step 5: Configure the Image Diff package
Navigate to your cypress.config.js usually located in your root project.
Import the cypress-image-diff-js/dist/plugin into your config file as shown below.
const setupNodeEvents = require('cypress-image-diff-js/dist/plugin')
Navigate to component section in cypress.config.js file add the setupNodeEvents
The full cypress.config.js file looks like below.
const { defineConfig } = require("cypress"); const setupNodeEvents = require('cypress-image-diff-js/dist/plugin') module.exports = defineConfig({ component: { devServer: { framework: 'react', bundler: 'vite', }, setupNodeEvents }, e2e: {} });
Step 6: Configure the Support file
Navigate to cypress/support/component.js and add the below code
const compareSnapshotCommand = require('cypress-image-diff-js/dist/command') compareSnapshotCommand()
Ensure that import ‘./commands’, is already present in the component.js file, if it doesn’t exist, then add it.
Optional Step: Create Simple React Component
This step is optional, if you are already having a component created then you can skip this step.
Below is the sample component created for Demo Purpose
We have created DemoComponent.jsx in my-react-app/src folder
The code looks like the below
import { useState } from 'react' import {Button, Alert} from 'react-bootstrap'; import './App.css' import 'bootstrap/dist/css/bootstrap.min.css'; export default function DemoComponent() { return ( <div data-testid="demo-page"> <div data-testid="demoButton"> <Button variant="primary" size="lg"> Demo Page </Button> <p></p> </div> <div data-testid="infoalert"> <Alert key="info" variant="info"> This is a test Alert! </Alert> </div> </div> ) }
The above is a simple component that has a button and simple alert like the below.
Step 7: Create Visual Test for Component
Let’s create a simple visual test for the above component,
Navigate to cypress/component folder and create a simple .jsx file name it as visual-test.jsx
Also Read: How to run UI tests in Cypress
The code looks like the below:
import { mount } from 'cypress/react' import DemoComponent from '../../src/DemoComponent' const demoButton = '[data-testid=demoButton]' describe('Demo Component', () => { it('Visual Testing Cypress', () => { mount(<DemoComponent />) cy.get(demoButton).should('contain.text', 'Demo Component Button') cy.compareSnapshot('component-testing', 0.2) }) })
- In the above code, mount(<Stepper />): Mounting DemoCompenent for testing, which is imported using import DemoComponent from ‘../../src/DemoComponent’
- cy.get(demoButton).should(‘contain.text’, ‘Demo Component Button’),: This line is an assertion to ensure that our component button is rendered correctly.
- cy.compareSnapshot(‘component-testing’, 0.2): This line takes the screenshot and compares it against the base screenshot, 0.2 is the threshold which is the tolerance of pixel difference of the screenshot.
Try Visual Testing using Percy
Step 8: Execute the test
You can execute the Cypress test, using both the command line and Cypress Test Runner window.
Using the Cypress Test Runner window
- Use npx cypress open command
- Choose the Component Testing and Browser
- Click on the test name in our case it is visual-test.cy.jsx
- Once you execute the test, Cypress shows the output pass or fail
- For cypress CLI execution you can use the below command
npx cypress run –component
Note: You need to execute the test at least two times, the first run captures the base screenshot, and the subsequent run captures the actual screenshot and compares it against the base screenshot.
In our case there was no difference, so tests are marked as passes.
Let’s modify the component by changing the button background color from blue to red
Execute the test again.
You can see that the test has failed since there is a difference between the base screenshot and the actual screenshot.
You can view the difference, by navigating to the diff folder under the cypress-visual-screenshots folder
Cypress Component Visual Testing using Percy
The Percy is the most popular cloud based visual testing tool. Percy provides a dedicated dashboard to compare the visual differences. One of the unique features of Percy is you can visually check how the components are rendered across multiple browsers such as Edge, Chrome, Safari, etc. Percy provides a feature to accept, and reject the changes.
Use Step 1 to Step 3 to configure Cypress to your project, after that follow the below instructions
Install Percy for Cypress
- Using the command below install Percy for Cypress
npm install --save-dev @percy/cli @percy/cypress
- Configure cypress/support folder
Navigate to cypress/support/command.js file and add the import statement
import '@percy/cypress';
Create a component (Optional, if you have already created a simple component skip this step). Below is a simple react component to test the Percy visual testing.
import { useState } from 'react' import {Button, Alert} from 'react-bootstrap'; import './App.css' import 'bootstrap/dist/css/bootstrap.min.css'; export default function DemoComponent() { //style={{background: "red"}} return ( <div data-testid="demo-page"> <div data-testid="demoButton"> <Button variant="primary" size="lg" > Demo Component Button </Button> <p></p> </div> <div data-testid="infoalert"> <Alert key="info" variant="info"> This is a test Alert! </Alert> </div> </div> ) }
- Write a simple Percy Visual Test for Component using Cypress
- Navigate to cypress/component folder create a visual-test.cy.jsx file
import { mount } from 'cypress/react' import DemoComponent from '../../src/DemoComponent' const demoButton = '[data-testid=demoButton]' describe('Demo Component Testing Percy', () => { it('Visual Testing Cypress Percy', () => { mount(<DemoComponent />) cy.get(demoButton).should('contain.text', 'Demo Component Button') cy.percySnapshot('percy-component-visual-test'); }) })
In the above code,
- mount(<Stepper />): Mounts the DemoCompenent for testing, which is imported using import DemoComponent from ‘../../src/DemoComponent’
- cy.get(demoButton).should(‘contain.text’, ‘Demo Component Button’): This line is an assertion to ensure that our component button is rendered correctly.
- cy.percySnapshot(); : This is a Percy command to take the DOM snapshot and then Percy CLI uploads the snapshots to the Percy dashboard.
Set the PERCY_TOKEN Environment Variable:
- Navigate to Percy Project. Refer to this help documentation to know more.
Copy the PERCY_TOKEN. Read more.
Set the Environment Variable # Unix $ export PERCY_TOKEN="<your-project-token>" # Windows $ set PERCY_TOKEN="<your-project-token>" # Powershell $ $Env:PERCY_TOKEN="<your-project-token>"
Run Component Tests using Percy Cypress
npx percy exec -- cypress run –component
Once the execution is complete, the command line output will have the Percy build URL, you can navigate to the build URL to check the difference.
Note: you need to execute the Percy test at least two times to check the result, as you need to have a base screenshot and an actual screenshot to compare.
If there are no changes then Percy displays “No Changes.”
Let’s modify our code, change the button background color to Red from Blue and execute the test again.
You can see in the above image, that the difference is shown side by side.
Best Practices for Cypress Visual Testing
Adopting best practices ensures the reliability and efficiency of your visual tests. Here are some key guidelines to follow:
- Identify the Need for Visual Testing: Use visual testing when UI appearance is critical or when end-to-end tests rely heavily on verifying style properties like visibility, color, and layout.
- Ensure the Application is Fully Loaded: Capture visual snapshots only after confirming that all dynamic content, animations, and rendering processes are complete.
- Standardize Timestamps: Freeze timestamps during tests to maintain consistency in visual outputs, especially for components displaying date or time-sensitive information.
- Control Application State: Use consistent test data and mock external dependencies to ensure the application behaves predictably during visual testing.
- Focus on Targeted Elements: Test individual components or specific sections of the UI to avoid unrelated changes affecting the results.
- Combine with Component Testing: Perform visual testing alongside component testing to validate the appearance and functionality of individual UI elements in isolation.
- Update Snapshots Strategically: Regularly review and update snapshots to reflect intentional UI changes while avoiding unnecessary updates that could mask regressions.
- Integrate Visual Tests with CI/CD: Include visual testing in continuous integration pipelines to catch regressions early and maintain consistent visual quality across releases.
Conclusion
The modern development framework encourages the development of the components in isolation. Visual Testing is the most popular method for testing the Visual Changes in UI. Cypress and Percy make the visual testing much easier and effectively bring the visual testing to the component level. The component-level visual testing helps faster development.