Implementing Visual Testing With Cypress
Tags: webdev, cypress, visualtesting
Published: 2024-02-22 15:22:22

With the evolution of technology, web applications are becoming increasingly interactive as well as complex. With the growth of user-centric applications, be it design or user-interface, all the aspects of software development aim to deliver customer satisfaction. In such a scenario, the traditional approach to testing is not sufficient to handle the huge test coverage. Visual testing has stood out as a technique to validate the visual presentation and UI layout in addition to just the functionality.
 
In this article we will be discussing testing the visual aspects of a web application using Cypress. We will look at the importance of visual testing and then look at the automation of Visual tests using Cypress.

**What is Visual Testing?**

Visual Testing, also known as [Visual regression Testing](https://testgrid.io/blog/visual-regression-testing-guide/), validates that the visual appearance of an application matches the expected design. It is all about checking the application beyond functional aspects. Some of the attributes that are validated as a part of Visual Testing 

- Images: Logos, icons, graphics being displayed correctly.
- Layout: Alignment and spacing of web elements.
- Typography: Correctness of fonts, sizes and colours.
- Responsiveness: Adaptiveness to different screen views.
- No unintended changes in the application UI compared to the previous version

Visual testing checks that the pixels on the screen match the intended design specifications. It helps in uncovering bugs that are easily missed in QA processes, like, misaligned elements, inconsistent fonts, overlapped elements, etc. Visual Testing acts as a final layer of protection against not just functional bugs, but visual bugs as well.

**Why is Visual Testing important?**

Testing modern web applications manually can be time-consuming, prone to errors/oversights, and even inconsistent sometimes, all due to the extensive UI code and complex front-end logic.

Automated visual testing effectively addresses many of the challenges faced in manual runs.. Some of the key benefits are listed below:

- Prevents visual regression – If there are changes in the HTML or CSS, there can be unintentional bugs that can be detected visually. Visual automation tests help in uncovering these issues.
- Automating visual tests helps in creating a safety net for responsive web designs.
- Visual differences across browsers are caught easily using visual automated testing.
- Style guide and pixel-perfect matching to designs is validated.
- It is easy to reproduce reported visual defects.
- The test coverage is broadened beyond functional aspects only.
- Visual integration of new features can be tested quickly.
- Visual automation testing adds an extra layer of protection against regression issues, hence boosting confidence before releases.

**How to implement Visual Testing using Cypress?**

Cypress is a powerful tool for end-to-end testing which comes with a lot of extensible features. One such feature is Visual Testing, which can be achieved using some plugins available in Cypress. Let us implement one such plugin, called the cypress-image-diff. To begin with, we need to ensure the following prerequisites to be fulfilled-

- Install NodeJS in your system
- Install Visual Studio Code in your system
- Install Cypress in your system

Let us now begin the steps to automate visual testing.
1.Create a project directory in your system, I have created one by the name 

**CypressVisualTesting.**
2.Now, install cypress by running below command:

npm install cypress –save -dev


3. Next, we will navigate to project directory on the terminal and then install the cypress image diff package using the command below:

npm i -D cypress-image-diff-js


Execution will show you console output like below:
4.Now we will open Cypress using the command below:

npx cypress open


5. Select e2e test configuration and continue with the configuration files. Once done, you will see cypress folder being added to project structure:
6.We will now configure the plugin we just installed. Open the cypress.config.js file present in the project directory and add below lines of code in the setUpNodeEvents method as shown below:
const { defineConfig } = require("cypress");


module.exports = defineConfig({
 e2e: {
   setupNodeEvents(on, config) {
     //Requires and imports the main plugin function from the cypress-image-diff-js NPM package
     const getCompareSnapshotsPlugin = require("cypress-image-diff-js/dist/plugin");
     //Calls the plugin's getCompareSnapshotsPlugin function, passing Cypress' on and config objects, to intialize and register the plugin with Cypress
     getCompareSnapshotsPlugin(on, config);
   },
 },
});

7.Now, navigate to command.js file in e2e > support folder and write below lines of code:
//Imports the compareSnapshotCommand function from the cypress-image-diff-js plugin module
const compareSnapshotCommand = require("cypress-image-diff-js/dist/command");

//This registers the cy.compareSnapshot() custom command provided by the plugin
compareSnapshotCommand();

8.Now, open the e2e.js file within the same support folder to ensure that either import ‘./commands’  or require(‘./commands’) is present. In our case, below is enabled:
// Import commands.js using ES2015 syntax:
import './commands'

9. Now, within the same file add the below lines of code to generate a report after test execution using the after() hook:
// Import commands.js using ES2015 syntax:
import './commands'


// Alternatively you can use CommonJS syntax:
// require('./commands')
after(() => {
   //custom task to generate report
   cy.task("generateReport");
 });


10. Now look at the project structure, you will notice that there are two folders, viz, cypress-visual-report and cypress-visual-screenshots.

cypress-visual-report: will contain the reports of execution, which are generally the html files of screenshot comparisons.
cypress-visual-screenshots: will consist of subfolding having screenshots of:

baseline, will have the baseline screenshots that will be used to compare to other images.
comparison, will contain the images that will be compared to the baseline images.

diff, will contain the resulting differences of baseline and comparison.

11.Now look at the project structure, you will notice that there are two folders, viz, cypress-visual-report and cypress-visual-screenshots.
12.Now, start E2E testing in Chrome or any other browser of your choice from the Cypress window.



// Alternatively you can use CommonJS syntax:
// require('./commands')

13. Now, select Create New Spec and enter the path or the name of your file.

14. Now go back to the spec file and write the code as below:
describe('Visual Testing',() => {
 it('should be comparing the screenshots of the landing page',() => {


   //Navigation to google.com url
     cy.visit('www.google.com');
     //takes the screenshot of current page and compares with baseline screenshot with name google-home-page
     cy.compareSnapshot('google-home-page');
  })
})

When you execute the above code for the first time, it will pass and capture the baseline screenshot by the name google-home-page. Execute the test using below command:
npx cypress run --spec "cypress/e2e/first_visual_test.cy.js"


Upon execution you will see the results as below in the VS Code console:
15. Next, we will edit our code to see how visual testing works if there is a difference in the images. I am simply changing the url and adding the search parameter to the earlier url so that the snapshots vary and the test fails.
describe('Visual Testing',() => {
 it('should be comparing the screenshots of the landing page',() => {


   //Navigation to testgrid.io url
     cy.visit('https://www.google.com/search?q=testgrid');
     //takes the screenshot of current page and compares with baseline screenshot with name google-home-page
     cy.compareSnapshot('google-home-page');
  })
})

16. Now, you can execute this test similar to the way we did above and see the results:

This is how you can easily find out the visual differences in your applications and bring down the time it might have taken with manual executions.

**Best Practices for Visual Testing**

- Visual Testing should be added during the early development phase, so that baseline screenshots can be captured, and further development be done by keeping a check on the baseline design.
- Visual tests should be run on every build and production release to detect regression issues.
- Naming conventions for screenshots should be relevant.
- CI/CD pipelines should be leveraged to capture visual testing issues.
- Try to implement small modular tests to focus on key components.
- Visual testing should be used with functional testing to maximise test coverage.

**Conclusion**

- Visual Testing is as important as Functional testing in modern web applications.
- Cypress offers a powerful tool for automating visual tests with minimal efforts.
- Using cypress plugins to test the visual appearance of web apps can marginally reduce bugs creeping into the production environment.
- When implemented with a modular approach, visual testing in Cypress can result in bulletproof software that satisfies functionality and maintains visual appearance across every user journey.

This blog is originally published at [testgrid](https://testgrid.io/blog/cypress-visual-testing/
)