Testing CSS Print Media Styles

Set the browser to emulate the print media and test styles using Cypress.

Sometimes the users might need to print the website pages either in paper or to a PDF file. The site should look good and make sense. When the user clicks the "Print" option, the browser applies the screen CSS styles plus any specific media: print styles. For example, you might remove the underlines from the links when printing the page:

1
2
3
4
5
6
7
8
9
10
/* Remove Hyperlinks */
@media print {
a:link {
border-bottom: none !important;
text-decoration: none !important;
}
a[href]:after {
content: none !important;
}
}

Sometimes you want to hide the elements, like navigation, since they make no sense in the printed view. In the app below, the "Home" link should be hidden when the user prints the results:

The "Home" link does not belong in the print view

We can quickly check how the printed page is going to look by opening Chrome DevTools and running the "Emulate CSS print media type" command:

Emulate CSS print media DevTools command

Tip: once you emulate the CSS print media, it stays this way until you close the DevTools or disable the emulation by running the "Do not emulate CSS media type":

Stop emulating CSS print media

In this blog post I will show how to emulate the print media in Cypress tests.

The application changes

Instead of custom CSS classes, I used Tailwind for the project. Thus hiding the footer element was simple: I applied the print:hidden built-in class.

1
2
3
4
5
<footer class="pb-2 pt-2 print:hidden">
<a href=".." class="underline hover:text-sky-400">
Home
</a>
</footer>

The tests

We can set emulate CSS media in Cypress tests by sending Chrome Debugger Protocol commands from the Emulation domain. I wrote the cypress-cdp plugin to make running CDP commands simpler.

cypress/e2e/finish-page.cy.ts
1
2
3
4
5
6
7
8
9
10
11
12
// https://github.com/bahmutov/cypress-cdp
import 'cypress-cdp'

describe('Finish page', () => {
context('Print', () => {
it('hides the links when printing', () => {
cy.CDP('Emulation.setEmulatedMedia', { media: 'print' })
cy.get('table tbody').should('be.visible')
cy.get('footer').should('not.be.visible')
})
})
})

The footer is hidden when printing

Because the CSS print media remains in force, I reset it before each test since most of the tests in the spec assume the screen media.

cypress/e2e/finish-page.cy.ts
1
2
3
4
5
6
7
8
9
10
11
// https://github.com/bahmutov/cypress-cdp
import 'cypress-cdp'

describe('Finish page', () => {
beforeEach(() => {
// reset the CSS media emulation
cy.CDP('Emulation.setEmulatedMedia', { media: 'screen' })
})

...
})

Tip: if I wanted, I could use my OSS Cypress visual testing plugin bahmutov/cypress-toy-visual-testing to do even more testing of the printed styles.

See also