- Published on
Moving from Cypress to Playwright cheatsheet
- Authors
- Name
- Josh McCure
- @joshmccure
Cypress and Playwright
Cypress has been a great option for writing end-to-end and component tests for the last few years. With Playwright on the rise and being a genuine competitor with some incredible features and unmatched performance, I've started to use Playwright on some of my projects.
I wanted a mental model to work with so I could write Playwright tests in a similar style as I would write Cypress tests. There's some small differences in API and syntax that are worth knowing up front.
General differences
- Cypress uses chainables to control flow and defines context under the hood.
- Playwright uses async await to control flow and defines a
page
andbrowser
context - Both Cypress and Playwright allow to pass previous subjects (elements and others) on to other commands. However this is more extensive in Cypress.
Repository setup & scaffolding
Cypress
Cypress gives a more extensive but opinionated scaffold with project initiation, assuming you'll want fixtures and an opinion on how you structure your commands.
npm install cypress --save-dev && npx cypress open
├── cypress
│ ├── fixtures
│ │ └── example.json
│ ├── integration
│ │ ├── example.spec.js
│ ├── plugins
│ │ └── index.js
│ └── support
│ ├── commands.js
│ └── index.js
└── cypress.json
Playwright
Playwright gives you only the bare minimum to what you'll need, leaving it up to you how you structure your repository and additional features you might need.
npm install playwright --save-dev && npm init playwright
├── playwright.config.ts
└── tests
└── example.spec.ts
Finding Elements
You can find DOM elements in many ways with both Cypress and Playwright, but there's a few commands I used in Cypress for almost all scenarios. You wont have any trouble doing exactly what you're used to.
By id, class and attribute
// Cypress
cy.get('#foo') // #foo, .bar, [data-test="baz"]
// Playwright
await page.locator('#foo') // #foo, .bar, [data-test="baz"]
By text
// Cypress
cy.contains('foo')
// Playwright
await page.locator('text=foo')
By locator and text
// Cypress
cy.contains('#foo', 'bar')
// Playwright
await page.locator('#foo' { hasText: 'bar' })
Find nested element
// Cypress
cy.get('#foo').find('.bar')
// Playwright
await page.locator('#foo >> .bar')
await page.locator('#foo').locator('.bar')
Waiting
Both Cypress and Playwright have similar waiting behaviour including automatic waiting with retryability and actionability checks that are based on configurable timeouts. Playwright seems to have more events to wait for however.
In most use cases you wont need to specifically wait for anything in either framework until you hit an edgecase that exceeds the timeout or is a specific event like a new frame or tab.
Waiting for Elements
// Cypress
cy.get('#foo').should('be.visible')
// Playwright
await page.locator('#foo').waitFor()
Waiting for a Network Respose
// Cypress
cy.intecept('POST', 'https://example/getUsers').as('getUsers')
cy.get('#foo').click()
cy.wait('@getUsers')
// Playwright
const [response] = await Promise.all([
// Waits for the next response with the specified url
page.waitForResponse('https://example.com/getUsers'),
// Triggers the response
page.click('#foo'),
]);
Assertions
Cypress and Playwright both come with built in assertion libraries
- Cypress uses Chai and Sinon
- Playwright includes its own assertions including web-first assertions
Element visibility
// Cypress
cy.get('#foo').should('be.visible')
cy.get('#foo').should('not.be.visible')
// Playwright
await page.locator('#foo').toBeVisible()
await page.locator('#foo').not.toBeVisible()
Element enabled/disabled/checked
// Cypress
cy.get('#foo').should('be.enabled')
cy.get('#foo').should('be.disabled')
cy.get('#foo').should('be.checked')
// Playwright
await page.locator('#foo').toBeEnabled()
await page.locator('#foo').toBeDisabled()
await page.locator('#foo').toBeChecked()
Element count
// Cypress
cy.get('#foo').should('have.length', 2)
// Playwright
await page.locator('#foo').toHaveCount(2)
Overall
Transition from Cypress to Playwright is fairly straight forward as you can see. Many of the same features exist in Playwright (and more). There is a small learning curve for managing pages and difference in readadbility. Enjoy.