Cypress Halloween Theme

Back to Cypress blog

A good tool can become a great tool when users make it their own through customization. In this blog post I will explain how to customize the Cypress test runner’s appearance through user space color themes. Since it is the season, we have prepared a dark and spooky Halloween color theme that might scare all your bugs away!

When Cypress executes your end-to-end tests, the application under test is placed in an iframe element. The tests themselves are placed into another iframe to isolate them from the application’s context. While the test runner prevents the application from accessing the parent window reference, nothing stops the test code from doing so.

We can take a look at the parent element in a before hook in our tests

before(() => {
  console.log('parent.window.document.body is', parent.window.document.body)
})

And inspect it from the DevTools

If we have access to the parent.window.document we can easily inject new styles before the tests start, and we only need to do this once.

const { join } = require('path')
const isStyleLoaded = $head => $head.find('#cypress-dark').length > 0
before(() => {
  console.log('parent.window.document.body is', parent.window.document.body)
  // Cypress includes jQuery
  const $head = Cypress.$(parent.window.document.head)
  if (isStyleLoaded($head)) {
    return
  }

  const css = '' // new style
  $head.append(``)
})

CSS will be injected every time the runner is reloaded, but it won’t be injected twice if the tests are rerun when the source of the spec files changes. This might lead to a flash of the default style in the very first load, but the style should stay put throughout the rest of the session.

Now we can inspect each element and place the changed style into src/halloween.css. For example to change the failed test count color, find the element and copy the rule and change the color property to whatever you want.

Let’s make the counter orange

const css = `
.reporter .stats li.failed {
  /* orange */
  color: #f79109;
}
`

Reload the Cypress browser (Command-R) and see it become orange.

Hardcoding the CSS in a string quickly becomes boring. We can place it alongside our code and load it using the cy.readFile() command.

const { join } = require('path')
const isStyleLoaded = $head => $head.find('#cypress-dark').length > 0
before(() => {
  console.log('parent.window.document.body is', parent.window.document.body)
  // Cypress includes jQuery
  const $head = Cypress.$(parent.window.document.head)
  if (isStyleLoaded($head)) {
    return
  }
  const themeFilename = join(__dirname, 'halloween.css')
  cy.readFile(themeFilename, { log: false }).then(css => {
    $head.append(
      ``
    )
  })
})

It is important to add fun details, like spinning skulls, cobwebs and coffins of course. Even pinned commands that show DOM snapshots need a scary symbol

Try the Halloween theme for yourself! Install the cypress-dark module with npm i -D cypress-dark and tell Cypress to load it from your cypress/support/index.js file by adding this line at the end

require('cypress-dark/src/halloween')

Enjoy!

PS: you better NOT have any failing tests, otherwise some scary witches might laugh at you!