Playwright Vs Cypress For Frontend Test Automation
In this blog post I'm sharing some really cool key features of Playwright over Cypress. When working in our project on a Single Page Application (SPA) we were already using Cypress.
We wanted to leverage our test automation in terms of Cross browser testing, Developing Test code and Parallelisation.
Here are some of the key points listed below to consider Playwright over Cypress.
I've used both Playwright with Jest and Playwright test runner in our project.
What is Playwright?
- Autowaits - Waits automatically for the elements in the DOM to be available.
- Scenarios - Deals with multiple pages, tabs, pop-up's, Iframes
- Intercept - Performs stubbing and handles network activity
- Browser versions - runs tests on latest versions of browsers and no need to download browsers on your computer. npm i -D playwright will install the browsers with latest versions for you on Node.js and JavaScript/TypeScript Environment
- Webkit - Runs your tests on the safari browser on Mac, Linux and Windows
- Emulate - Mobile devices with geo locations and permissions
- Inbuilt - Native Test runner called Playwright Test runner available now. It also supports Test recording, Video recording and Screenshot capture
- Official Website - https://playwright.dev/docs/intro
- Shadow DOM - Good support for handling shadow DOM selectors
- Test Runners - Supports you to choose your own test runners like Jest, AVA and Mocha. Mostly, recommended to use Playwright's native test runner - "Playwright test"
Fixtures: Playwright Test is based on the concept of the test fixtures. Test fixtures are used to establish environment for each test, giving the test everything it needs and nothing else.
Playwright's own inbuilt fixtures are:-
- Browser - Browser instance is shared between all tests in the same worker - this makes testing efficient. However, each test runs in an isolated BrowserContext and gets a fresh environment.
All tests run in worker processes. These processes are OS processes, running independently, orchestrated by the test runner. All workers have identical environments and each starts its own browser.
You can't communicate between the workers. Playwright Test reuses a single worker as much as it can to make testing faster, so multiple test files are usually run in a single worker one after another.
A worker is an object created using a constructor that runs a named JavaScript file and this file contains the code that will run in the worker thread.
- Context - Isolated BrowserContext instance, created for each test. Since contexts are isolated between each other, every test gets a fresh environment, even when multiple tests run in a single Browser for maximum efficiency.
BrowserContexts provide a way to operate multiple independent browser sessions.If a page opens another page, e.g. with a
window.open
call, the popup will belong to the parent page's browser context.Playwright allows creating "incognito" browser contexts with browser.newContext([options]) method. "Incognito" browser contexts don't write any browsing data to disk.
- Page - Isolated Page instance, created for each test. Pages are isolated between tests due to fixtures.context isolation. Page provides methods to interact with a single tab in a Browser in Chromium for example. One Browser instance might have multiple Page instances.
Using cypress dashboards make cypress a paid tool to achieve parallelisation test run but videos, screenshots and retries of tests are well supported by cypress.Coming to cross browser testing cypress supports Electron, Chrome, Firefox and Microsoft edge browsers.
Type: Cypress.Commands.add('typeText', (selector, text) => {
cy.get(selector).click()
return cy.get(selector).type(text, { timeout: 1000 })
})
Click: Cypress.Commands.add ('selectorClick', selector => {
return cy.get(selector).click({ force: true })
})
We get the element first and do the respective operation.
In playwright we don’t really need to get the element and perform operation on it. Playwright automatically waits for the element to be available until the operation is performed.
In Playwright :
Type: async waitAndFill(selector, text) {
await page.waitForSelector(selector)
return await page.fill(selector, text)
}
Click : await page.click(selector)
These are called actionability checks in Playwright. It waits for the element to be attached to DOM, available and visible and then only it performs the type or click operation on the element.
Fill is a Type operation in Playwright but with clearing the existing text and then types the text needed.Playwright's actionability check of element includes whether element is Visible, stable, attached to DOM and whether is it Enabled and after all these checks then only it performs the Type(Fill) or Click operation on an element for instance.
More or less almost same rule applies to actions like check, dblclick, tap, uncheck, hover, scrollintoViewIfNeeded, screenshot.
2. Selectors
When getting the selectors for Cypress if we want to check if an element is visible when writing test automation framework, it can be three or four functions we write for example below for the same function for 4 different types of locators
CSS or Classname: Cypress.Commands.add('isVisible', selector => {
return cy.get(selector).should('be.visible')
})
With XPATH: Cypress.Commands.add('isXpathVisible', selector => {
return cy.xpath(selector).should('be.visible')
})
With data-cy: Cypress.Commands.add('isdata-cyVisible', selector => {
return cy.get(`[data-cy="${selector}"]`).).should('be.visible')
})
With data-test-id : Cypress.Commands.add('isdata-test-idVisible', selector => {
return cy.get(`[data-testid="${selector}"]`).).should('be.visible')
})
When getting the selectors with Playwright it is more hassle free. Just one function to define like below when developing test automation framework for any selector.
you can find a specific element with it's selector of type id, data-cy, data-test-id, css, xpath and text and return Visible
async isElementVisible(selector) {
let isVisible = true
await page.waitForSelector(selector)
await page
.locator(selector, { visible: true, timeout: this.timeout })
.catch(() => {
isVisible = false
})
return isVisible
}
3. Custom Waits: Playwright has custom wait option for lazy loading of the page or certain network conditions are met.
async waitForPageLoad() {
const isPageLoaded = await page.waitForLoadState('domcontentloaded')
return isPageLoaded
}
4. Choice of Test Runner: With Cypress we are restricted to Mocha. With Playwright we can use our own choice of test runners like Jest, AVA, Mocha and Playwright’s own native Test runner available now. Most popular ones are playwright's inbuilt native test runner and Jest with playwright.
For ex: cy.contains(text).click()
With Playwright it is click the element grabbed as a selector with text like below: -
Put all the locators in one locators.js file like below
export const newButton = 'text=New'
Selector In the Code,
await page.click(newButton) Selector is ‘text=New’
Playwright with Jest Execution in Headless Mode (Locally):
Total Time for 41 tests: 14.419 seconds
Playwright Native Test Runner in Headless Mode (Locally):
Cypress Headless run (Locally):
Total Time for 40 tests: 35.0 seconds
Playwright with Jest : Total Time for 41 tests in Parallel: 02 mins 05 seconds
Playwright Native Test Runner on GitLab CI parallel execution:
Playwright Test Runner : Total Time for 41 tests in Parallel: 01 min 35 seconds
Cypress on Gitlab CI (Parallel Execution with cypress dashboards):
Cypress : Total time for 40 tests: 3 mins and 05 seconds
15. Test Reporting Options: With Playwright we can use jest-stare, html-test-report, Allure reporting and playwright's own inbuilt test report. With Cypress, we have Allure or Mochawesome
reporting.
16. Folio and Fixtures from Playwright: Folio comes with only Playwright's inbuilt native test runner and makes your
tests run in parallel and handles the re-try of flaky failures.
Fixtures are a basic set up for our tests to runThere are two types of fixtures called Test fixtures and Worker fixtures.
For reference Please see https://github.com/microsoft/folio
Folio and Playwright-CLI is now deprecated and archived by the owner link below.
This is replaced now with Playwright test runner V1.12.0. Playwright Test Runner
17. Playwright Test runner is definitely a worth to try and blown away my mind when I tried myself. It's test execution is so fast and kind of similar to Jest in terms like assertions with expect, hooks. However, there is much more in the store to explore with it. You have everything needed for the test run defined in playwright.config.js or playwright.config.ts.
18. Docker Images: With Cypress we may use three different types of docker images when integrating with CI in yaml file. we use three kind of docker images depending on our requirement Cypress-docker-images it can be cypress/base, cypress/browsers (OR) cypress/included. With Playwright, It is just one Docker Image Playwright-Docker-Image can be mcr.microsoft.com/playwright:focal for instance.
19. Drivers and Browsers Installation: With Selenium, you have to install drivers like geckodriver, chromedriver and browsers like firefox, chrome. With Cypress, you have to at-least install browsers on your PC. With Playwright, You don't have to install both.
20. Visual Regression Testing: With Cypress we have to use third party tool like percy.io to achieve the Visual regression testing. Playwright with Jest gives you the best option for Visual regression testing as Jest comes with wonderful feature of Image snapshot with npm package Jest-Image-Snapshot.
All you need to do is to run the npm install command npm i --save-dev jest-image-snapshot.Visual Regression testing is very easy to setup and run tests with Playwright-Jest.
With Playwright Test runner version starting from 1.12, we can also do now the visual comparisons with snapshots just like jest. Playwright visual testing: Playwright Visual Testing
9 comments:
Usefull information
Super, your information is always useful. Clear and Crisp. Keep it up 👍
Superb comparison between Playwright and Cypress and one outweighs the another 👌🏼
Another informative blog covering the key concepts and their usage in Playwright & Cypress. The awesome part is timelines mentioned for the test parts that reflects your hands on experience. I believe this blog helps the team members to assess the scope of testing & the time lines.. Looking forward for many such valuable blogs.
Awesome Real time comparison. And also I heard in Cypress we cannot hover. But Playwright has added this feature
Great writings, I decided to use Wright in my upcoming project after reading this one!
Very thoughtful info. Thanks for sharing your findings!!
Thank you Mahen!
Cypress is still a cool tool to use and very useful
Post a Comment