In the field of test automation, traditionally dominated by Selenium, two strong contenders have emerged in recent years, bringing a fresh approach to web application testing—Cypress and Playwright. Both tools are steadily gaining popularity within the QA community due to their advantages, such as ease of use, performance, and built-in automatic waiting for elements on the tested page. In this article, we will compare these frameworks and help you understand which one might be the best fit for your needs.
Playwright is an open-source framework developed by Microsoft for automating web application testing. It is written in TypeScript and is based on the Chrome DevTools Protocol. Playwright supports multiple programming languages and is completely free to use. Interestingly, the team behind Playwright previously worked at Google, where they created Puppeteer—a well-known and widely used testing framework.
Cypress is also an open-source test automation framework, but unlike Playwright, it only supports JavaScript/TypeScript and operates under a freemium model. In short, you can use it for free, but purchasing a subscription grants access to Cypress Cloud—a tool that enables parallel test execution and improves test reporting.
Both of these frameworks are often compared due to their similar functionalities that support writing and executing tests. These include automatic waiting for elements on web pages, advanced reporting capabilities, and robust debugging options.
How does the popularity of these two tools currently compare? According to npm trends, as of November 10, 2023, Cypress downloads are at around 5 million per day, with the framework having been in production since 2017. Playwright, released in 2020, is catching up to its competitor with approximately 2.5 million daily downloads, and this number continues to grow.

Arguments in favor of Cypress
Community support
Cypress was released in 2015 (private beta, then public beta in 2017), and over the years since its inception, a large community of specialists using this tool has built around it, also sharing knowledge about it. It’s not hard to find a course on writing tests in Cypress. There are plenty of discussions online about its various features. Cypress regularly appears at industry conferences, workshops, and has become well-established among QA engineers.
The situation is somewhat different when it comes to Playwright. It is a relatively newer tool, still actively developed, and considered a novelty in the industry. This powerhouse from Microsoft has not yet built a large community around it, and there aren’t as many knowledge resources available online as there are for its competitor. However, given the steadily increasing popularity of this framework, it’s likely that this will change soon.
Syntax simplicity
We’ll take a look at what a simple test written in Cypress looks like:
describe('fake shop', () => {
it('cypress can search products', () => {
const newItem = 'Shirt'
cy.visit('https://playground.quality-frontiers.pl/')
cy.get('.wc-block-product-search__field').type(`${newItem}{enter}`)
cy.get('.products li')
.should('have.length', 3)
.last()
.should('contain.text', newItem)
})
})
Cypress is based on JavaScript syntax, but it has its own DSL (Domain-specific language), so that we write tests using functions, usually combined one after another. The test ends with a function should
, which is a cypress assertion. The whole thing does not look complicated and anyone is able to understand the logic and steps of this test. Describing this syntax, it is safe to say that we “write in cypress” and not in JavaScript.
For comparison, let’s see what a similar test looks like at Playwright:
import { test, expect } from '@playwright/test';
test('playwright can search products', async ({ page }) => {
await page.goto('https://playground.quality-frontiers.pl/');
await page.getByPlaceholder('Search product...').click();
await page.getByPlaceholder('Search product...').fill('Shirt');
await page.getByPlaceholder('Search product...').press('Enter');
await expect(page.locator(".products li")).toHaveCount(3);
});
The syntax is simple, although not as simple as Cypress. Every method used in the test starts with await
and we can’t combine methods here like in the competing framework.
Personally, I am more inclined towards the approach taken by the creators of Playwright. The syntax requires some getting used to, and writing the first tests has a higher learning curve compared to Cypress, but I know what happens underneath – in Cypress, this is somewhat hidden. That said, the advantage of Cypress here is its simplicity of syntax, which is especially important for beginners.
Arguments in favor of Playwright
Parallel tests
Playwright runs test files in parallel by default, using so-called workers. We can also control parallelism of test execution in a single file (this is disabled by default). The user is also able to completely block parallelism in tests by manually setting the number of workers to 1.
The easiest way to control the number of workers in tests is to add a parameter in the command that runs the tests:
npx playwright test --workers 4
What does it look like for Cypress? This one does not support parallel testing, unless you pay for Cypress Cloud. Also in use are alternative, open-sourced plugins such as Sorry Cypress.
EDIT: Since version 13, Cypress has blocked support for the Sorry Cypress and Currents.dev plugins—thereby removing alternatives to its paid service.
Support for programming languages
This aspect is definitely in favor of Playwright, which supports JavaScript/TypeScript, Java, and C#. Cypress, on the other hand, only supports JavaScript/TypeScript.
Browsers
Both frameworks offer a wide range of browser support. In Cypress, we can run tests on Chrome, Electron, MS Edge and on Firefox – both in headless and headed modes. Playwright gives us a similar list, i.e. Chrome, Chromium, Firefox, Edge, Safari, also run in headless / headed modes.
Test Runners
Here in favor of Playwright – this one supports Mocha, Jest, Jasmine, while Cypress supports only Mocha.
Performance
Playwright uses a WebSockets-based architecture for communication between browser components and test code, which, in a nutshell, means that Playwright connects to a browser instance and then sends commands from the test to the browser via this communication channel. This connection is maintained throughout the test, allowing asynchronous communication between the test and the browser. When the test executes a specific command, such as clicking on a page element or entering data, Playwright sends these commands to the browser over the existing WebSocket connection.
With this architecture, Playwright is able to deliver sensational test performance.
Projects
In the configuration file, there is a projects
section – this is where Playwright allows you to group tests and assign them a shared configuration when running them, such as specifying the browser, device, URL, etc.
For example, if we wanted to have one test group, e.g., dev
, running in the development environment, and another, e.g., production
, running in the production environment, our code snippet in the projects
section of playwright.config.ts
could look like this:
export default defineConfig({
timeout: 60000,
projects: [
{
name: 'dev',
use: {
baseURL: 'dev.fake-client.com',
use: { ...devices['Desktop Chrome'] }
},
retries: 2,
},
{
name: 'production',
use: {
baseURL: 'production.fake-client.com',
use: { ...devices['Desktop Chrome'] }
},
retries: 0,
},
],
});
In addition, we also selected the number of repetitions of failed tests in each environment and assigned browsers.
This way of configuring test collections is very clear and convenient to use.
Support
Playwright has the backing of a major player—Microsoft. It is reasonable to assume that the tech giant from Redmond will provide Playwright with technical and financial support while keeping its promise that the tool will always remain free.
VS Code plug-in
A plug-in for Visual Studio Code dedicated to writing tests in Playwright has been created. From the editor, we can run and track tests, generate selectors, debug and even record tests.
The article is divided into two parts. The continuation can be found at this address.