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!