Sign inSign up

Introducing Chromatic’s integration for Cypress visual testing

Extend Chromatic’s visual tests into your Cypress workflow

loading
Joe Vaughan
@joevaugh4n
💡
tl;dr: We’re building an integration that brings Chromatic’s visual tests into Cypress. That gives you all of Chromatic’s visual testing capabilities, scanning every possible state of UI, within your E2E tests. All it takes to get started is a couple lines of code. Learn more

Every team needs the confidence that their apps work and look great for their users.

Today, we’re sharing how you gain get that through Chromatic’s new integration for Cypress: E2E Visual Tests. This lets you bring Chromatic’s visual testing into your existing E2E workflow, and all it takes to get started is two tiny changes to your code.

Read on for an overview of how E2E Visual Tests for Cypress works, and how you can try it now in early access.

Using Playwright? You’ll want to head here 👉

Why integrate Chromatic and Cypress?

As a visual testing tool, Chromatic doesn’t just capture an image of each page you test. Instead, E2E Visual Test snapshots are living re-creations of a page’s DOM, styling, and assets. Whenever you’re reviewing test results, you receive high-fidelity renderings that are fully inspectable. This makes it painless to reproduce and confirm changes, because you’re seeing exactly the same UI as your users.

Snapshots are taken in a controlled cloud environment, using consistently-versioned, modern browsers. Whether you’re testing in one browser or four, they run in parallel so your test suite stays fast.

Every snapshot taken is saved to Chromatic’s CDN. Having your snapshots on Chromatic’s servers, rather than in your local filesystem, means that you’re not tracking and pushing up to your repo what can grow to be an enormous set of images!

Finally, by integrating Chromatic into your E2E tests, you gain all the benefits of the Chromatic platform. This includes visual testing down to the pixel, a single location for designers and other stakeholders to sign-off on work, plus a published library of all your snapshots. All of this happens out of the box just by integrating Chromatic into Cypress—without any other changes to your tests.

Get started with two small steps

⚠️
At the time of publication, this API and all implementation details are still in active development and are liable to change. Please refer to the Chromatic E2E Visual Tests documentation for up to date code and process details.

Firstly: in cypress/support/e2e.js, import Chromatic’s test-archiver for Cypress:

// cypress/support/e2e.js

import '@chromaui/test-archiver/cypress/support';

Then, in cypress.config.js, add our archiveCypress task:

// cypress.config.js

const { defineConfig } = require("cypress");
const { archiveCypress } = require('@chromaui/test-archiver/cypress');

module.exports = defineConfig({  
  e2e: {
    setupNodeEvents(on, config) {
      // implement node event listeners here
      on('task', {        
        archiveCypress
      })
    },
  },
});

That’s it! You’re now set up to start benefiting from Chromatic in all of your Cypress tests, without adding any more code! Chromatic will now take a snapshot at the end of every Cypress E2E test.

Here’s how it works

Imagine you’re a developer on an online shopping product. You’re tasked with verifying how data flows from the backend to the frontend for a critical product detail page.

A search for tungsten cube on Amazon

To begin, let’s just make sure we can successfully visit the page. We’ll use Cypress’s built-in cy.visit() command to navigate to the product page. Then, we’ll use cy.title().should() to verify that the page title renders as expected:

describe('My First Test', () => {
  it('Visits product page', () => {
		// 👇 go to the Amazon product page
    cy.visit('https://www.amazon.com/Tungsten-Cube-Biggest-Size/dp/B07WK9WLZ8/')
		// 👇 verify the page title
		cy.title().should('eq', 'Amazon.com: The 4" Tungsten Cube - Biggest Size : Toys & Games')
  })
})

There’s not much to this test. So, presumably, the page will render and the test will pass. However, in addition to the test being green, you now also gain a visual snapshot of the page taken at the completion of the test. You can view that snapshot in Chromatic’s UI:

The same Amazon page as above, now in Chromatic

Remember, though, that you were tasked with verifying how data flows from the backend to the frontend, not just that the page loads. To do that, we could add to the initial test and write new assertions to ensure every value on the page—price, description, product title, etc.—match our expectations. But that would quickly grow verbose.

Instead, you can verify all those details in a single glance with the snapshot you just created. And if the data ever changes, Chromatic will catch it and highlight it in a visual diff for you to verify or deny. Now you’re testing that the data flows correctly and that the appearance of the page is correct, too. And with much less code!

Diffs of the same Amazon page above

Now, another example. This time, we want to test the interaction of the search bar on the product page.

To begin, you start again by visiting the product page URL in Cypress. But once there, you find the main search field on the page and type in a search:

describe('My First Test', () => {
  it('Searches from product page 1', () => {
		// 👇 go to the product page
    cy.visit('https://www.amazon.com/Tungsten-Cube-Biggest-Size/dp/B07WK9WLZ8/')
		// 👇 verify the page title
		cy.title().should('eq', 'Amazon.com: The 4" Tungsten Cube - Biggest Size : Toys & Games')
		// 👇 find the main search field and type in it
    cy.get('.nav-search-field > input').type('rubik’s cube')
  })
})

Ok, cool. We should get some passing tests again and a snapshot of the final state of the UI, showing ‘rubik’s cube’ typed into the search field.

But what if we want some snapshots taken during that process? Easy! You can use cy.takeChromaticArchive() to take a manual snapshot at specific points during your tests. So let’s use this method to take a snapshot when we first focus the search field to see what that looks like:

describe('My First Test', () => {
  it('Searches from product page 2', () => {
		// 👇 go to the product page
    cy.visit('https://www.amazon.com/Tungsten-Cube-Biggest-Size/dp/B07WK9WLZ8/')
		// 👇 verify the page title
		cy.title().should('eq', 'Amazon.com: The 4" Tungsten Cube - Biggest Size : Toys & Games')
		// 👇 find & focus the search field
    cy.get('.nav-search-field > input').focus()
		// 👇 tell Chromatic to take a snapshot here
    cy.takeChromaticArchive()
		// 👇 finish the test as before
    cy.get('.nav-search-field > input').type('rubik’s cube')
  })
})

When this test runs, Chromatic will capture two snapshots: the one we’ve manually taken of the focused search field and the one automatically taken at the end of the test.

Multiple tests within Chromatic of the Amazon page

One line of code to snapshot two different states of the page, plus the functional tests you already had? Not bad.

Sign up for early access

Help us bring Chromatic’s Cypress integration over the finish line by signing up for early access! Try it out and give feedback so that we can ship the best package possible.

👉 Sign up here 👈

Did this article help you?

Get free UI development guides and tutorials like this emailed to you.

4,472 developers and counting

We’re hiring!

Join the team behind Storybook and Chromatic. Build tools that are used in production by 100s of thousands of developers. Remote-first.

View jobs

Popular posts

Chromatic’s 2023 Wrapped

Our 2023 highlights include Story Modes, E2E Visual Tests, 70% faster time to first result, and more
loading
Dominic Nguyen
Product
PricingAboutJobsTerms of ServicePrivacyStatusSecurity • SOC 2Contact Sales
Chromatic
© Chroma Software Inc. Made by the maintainers of Storybook.