100% found this document useful (1 vote)
129 views52 pages

Cypress Vs Playwright 220527005559 F81b9cee PDF

The document compares the testing frameworks Cypress and Playwright. It outlines a matchup between the two frameworks, with 5 rounds comparing how common tasks are implemented in each framework. The rounds cover element interaction, working with iframes, waiting for elements, handling alerts, and navigating to new windows. Code examples are provided for each task in both Cypress and Playwright.

Uploaded by

Mizael Nazareno
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (1 vote)
129 views52 pages

Cypress Vs Playwright 220527005559 F81b9cee PDF

The document compares the testing frameworks Cypress and Playwright. It outlines a matchup between the two frameworks, with 5 rounds comparing how common tasks are implemented in each framework. The rounds cover element interaction, working with iframes, waiting for elements, handling alerts, and navigating to new windows. Code examples are provided for each task in both Cypress and Playwright.

Uploaded by

Mizael Nazareno
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 52

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Why compare
Cypress against Playwright?

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


The Matchup

🥊 10 rounds of code challenges


💻 Show implementations in Cypress and Playwright
🗣 Compare and discuss the code
🗳 You vote!

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Round 1:
Element Interaction
Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda
Element Interaction in Cypress
cy.visit('https://demo.applitools.com/')

cy.get('#username').type('filip')
cy.get('#password').type('i<3slovakia!')
cy.get('#log-in').click()

cy.contains('.element-header', 'Financial Overview')

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Element Interaction in Playwright
await page.goto("https://demo.applitools.com/");

await page.locator("id=username").fill("andy");
await page.locator("id=password").fill("panda<3");
await page.locator("id=log-in").click();

await expect(page.locator(".element-header").first())
.toHaveText("Financial Overview");

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Element Interaction Head-to-Head
Cypress Playwright

cy.visit('https://demo.applitools.com/') await page.goto("https://demo.applitools.com/");

cy.get('#username').type('filip') await page.locator("id=username").fill("andy");


cy.get('#password').type('i<3slovakia!') await page.locator("id=password").fill("panda<3");
cy.get('#log-in').click() await page.locator("id=log-in").click();

cy.contains('.element-header', 'Financial Overview') await expect(page.locator(".element-header").first())


.toHaveText("Financial Overview");

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Round 2:
Inline Frames
Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda
Inline Frames in Playwright
await page.goto("https://kitchen.applitools.com/ingredients/iframe");

const iframe = page.frameLocator("id=the-kitchen-table");


const table = iframe.locator("id=fruits-vegetables");

await expect(table).toBeVisible();

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Inline Frames in Cypress
cy.visit('https://kitchen.applitools.com/ingredients/iframe')

cy.iframe('#the-kitchen-table')
.find('#fruits-vegetables')
.should('be.visible')

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Inline Frames Head-to-Head
Cypress Playwright

cy.visit( await page.goto(


'https://kitchen.applitools.com/ingredients/iframe') "https://kitchen.applitools.com/ingredients/iframe");

cy.iframe('#the-kitchen-table') const iframe = page.frameLocator("id=the-kitchen-table");


.find('#fruits-vegetables') const table = iframe.locator("id=fruits-vegetables");
.should('be.visible')
await expect(table).toBeVisible();

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Round 3:
Waiting
Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda
Waiting in Cypress
cy.visit('https://automationbookstore.dev/')

cy.get('#searchBar').type('testing')
cy.get('li:visible').should('have.length', 1)

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Waiting in Playwright
await page.goto("https://automationbookstore.dev/");

await page.locator("id=searchBar").fill("testing");
await expect(page.locator("li:visible")).toHaveCount(1);

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Waiting Head-to-Head
Cypress Playwright

cy.visit('https://automationbookstore.dev/') await page.goto("https://automationbookstore.dev/");

cy.get('#searchBar').type('testing') await page.locator("id=searchBar").fill("testing");


cy.get('li:visible').should('have.length', 1) await expect(page.locator("li:visible")).toHaveCount(1);

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Round 4:
Alerts
Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda
Alerts in Playwright
// Accept alert
page.on('dialog', dialog => {
expect(dialog.message()).toBe("Airfryers can make anything!");
dialog.accept();
});
await page.goto("https://kitchen.applitools.com/ingredients/alert");
await page.locator("id=alert-button").click();

// Dismiss alert
page.on('dialog', dialog => dialog.dismiss());
await page.goto("https://kitchen.applitools.com/ingredients/alert");
await page.locator("id=confirm-button").click();

// Answer prompt
page.on('dialog', dialog => dialog.accept("nachos"));
await page.goto("https://kitchen.applitools.com/ingredients/alert");
await page.locator("id=prompt-button").click();

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Alerts in Cypress
// Accept alert
cy.visit('https://kitchen.applitools.com/ingredients/alert')
cy.get('#alert-button').click()
cy.on('window:alert', (alert) => {
expect(alert).to.eq('Airfryers can make anything!')
})

// Dismiss alert
cy.visit('https://kitchen.applitools.com/ingredients/alert')
const dismiss = () => false
cy.get('#confirm-button').click()
cy.on('window:confirm', dismiss)

// Answer prompt
cy.visit('https://kitchen.applitools.com/ingredients/alert', {
onLoad(win: Window) {
cy.stub(win, 'prompt').returns('Hi mom!');
}
})
cy.get('#prompt-button').click()

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Alerts Head-to-Head
Cypress Playwright

// Accept alert // Accept alert


cy.visit('https://kitchen.applitools.com/ingredients/alert') page.on('dialog', dialog => {
cy.get('#alert-button').click() expect(dialog.message()).toBe("Airfryers can make anything!");
cy.on('window:alert', (alert) => { dialog.accept();
expect(alert).to.eq('Airfryers can make anything!') });
}) await page.goto("https://kitchen.applitools.com/ingredients/alert");
await page.locator("id=alert-button").click();

// Dismiss alert // Dismiss alert


cy.visit('https://kitchen.applitools.com/ingredients/alert') page.on('dialog', dialog => dialog.dismiss());
const dismiss = () => false await page.goto("https://kitchen.applitools.com/ingredients/alert");
cy.get('#confirm-button').click() await page.locator("id=confirm-button").click();
cy.on('window:confirm', dismiss)

// Answer prompt // Answer prompt


cy.visit('https://kitchen.applitools.com/ingredients/alert', { page.on('dialog', dialog => dialog.accept("nachos"));
onLoad(win: Window) { await page.goto("https://kitchen.applitools.com/ingredients/alert");
cy.stub(win, 'prompt').returns('nachos'); await page.locator("id=prompt-button").click();
}
})
cy.get('#prompt-button').click()

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Round 5:
Navigation to New Windows
Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda
Navigation to New Windows in Cypress
cy.visit('https://kitchen.applitools.com/ingredients/links')

cy.get('#button-the-kitchen-table')
.invoke('removeAttr', 'target')
.click()

cy.location('pathname')
.should('eq', '/ingredients/table')

cy.get('#fruits-vegetables:visible')
.should('have.length', 1)

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Navigation to New Windows in Playwright
await page.goto("https://kitchen.applitools.com/ingredients/links");

let [newPage] = await Promise.all([


context.waitForEvent('page'),
page.locator("id=button-the-kitchen-table").click()
]);

await newPage.waitForLoadState();
expect(newPage.url()).toContain('/ingredients/table');

await expect(newPage.locator("id=fruits-vegetables")).toBeVisible();

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Navigation to New Windows Head-to-Head
Cypress Playwright

cy.visit( await page.goto(


'https://kitchen.applitools.com/ingredients/links') "https://kitchen.applitools.com/ingredients/links");

cy.get('#button-the-kitchen-table') let [newPage] = await Promise.all([


.invoke('removeAttr', 'target') context.waitForEvent('page'),
.click() page.locator("id=button-the-kitchen-table").click()
]);

cy.location('pathname') await newPage.waitForLoadState();


.should('eq', '/ingredients/table') expect(newPage.url()).toContain('/ingredients/table');

cy.get('#fruits-vegetables:visible') await expect(newPage.locator("id=fruits-vegetables"))


.should('have.length', 1) .toBeVisible();

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Round 6:
API Requests
https://kitchen.applitools.com/api/recipes
Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda
API Requests in Playwright
const requestContext = await request.newContext(
{baseURL: 'https://kitchen.applitools.com'});

const response = await requestContext.get('api/recipes');


await expect(response).toBeOK();

const body = await response.json();


expect(body.time).toBeGreaterThan(0);
expect(body.data.length).toBeGreaterThan(0);

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


API Requests in Cypress
cy.request('https://kitchen.applitools.com/api/recipes')
.then(({ status, body, duration }) => {
expect(status).to.eq(200)
expect(body.data).to.have.length.greaterThan(0)
expect(duration).to.be.greaterThan(0)
})

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


API Requests Head-to-Head
Cypress Playwright

cy.request('https://kitchen.applitools.com/api/recipes') const requestContext = await request.newContext(


.then(({ status, body, duration }) => { {baseURL: 'https://kitchen.applitools.com'});
expect(status).to.eq(200)
expect(body.data).to.have.length.greaterThan(0) const response = await requestContext.get('api/recipes');
expect(duration).to.be.greaterThan(0) await expect(response).toBeOK();
})
const body = await response.json();
expect(body.time).toBeGreaterThan(0);
expect(body.data.length).toBeGreaterThan(0);

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Round 7:
Page Objects
Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda
Page Objects in Cypress
export const loginPage = { loginPage
username: '#username', .load()
password: '#password', .login('filip', 'i<3slovakia!')
log_in: '#log-in',

load() {
cy.visit('https://demo.applitools.com/')
return this
},

login(username: string, pass: string) {


cy.get(this.username).type(username)
cy.get(this.password).type(pass)
cy.get(this.log_in).click()
return this
}
}

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Page Objects in Playwright
export class LoginPage { const loginPage = new LoginPage(page);
page: Page; await loginPage.load();
usernameInput: Locator; await loginPage.login("andy", "panda<3");
passwordInput: Locator;
loginButton: Locator;

constructor(page: Page) {
this.page = page;
this.usernameInput = page.locator("id=username");
this.passwordInput = page.locator("id=password");
this.loginButton = page.locator("id=log-in")
}

async load() {
await this.page.goto("https://demo.applitools.com/");
}

async login(username: string, password: string) {


await this.usernameInput.fill(username);
await this.passwordInput.fill(password);
await this.loginButton.click();
}
}

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Page Objects Head-to-Head
Cypress Playwright

export const loginPage = { export class LoginPage {


username: '#username', page: Page;
usernameInput: Locator;
password: '#password', passwordInput: Locator;
log_in: '#log-in', loginButton: Locator;

load() { constructor(page: Page) {


this.page = page;
cy.visit('https://demo.applitools.com/') this.usernameInput = page.locator("id=username");
return this this.passwordInput = page.locator("id=password");
}, this.loginButton = page.locator("id=log-in")
}
login(username: string, pass: string) {
async load() {
cy.get(this.username).type(username) await this.page.goto("https://demo.applitools.com/");
cy.get(this.password).type(pass) }
cy.get(this.log_in).click()
return this async login(username: string, password: string) {
await this.usernameInput.fill(username);
} await this.passwordInput.fill(password);
} await this.loginButton.click();
}
}
Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda
Round 8:
Language Support
Language Support Head-to-Head
Cypress Playwright

● TypeScript/JavaScript ● TypeScript/JavaScript
● Python
● Java
● .NET (C#)

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Round 9:
Browsers
Browsers Head-to-Head
Cypress Playwright

Supported browsers: Supported browsers:


● Chrome ● Chromium
● Edge ● Firefox
● Electron ● WebKit
● Firefox ● Chrome & Edge (browser channels)

Can only test one browser at a time. Can test multiple browsers in parallel.

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Round 10:
Speed
Speed Head-to-Head
Cypress Playwright

Command: Command:
npx cypress run --browser chrome npx playwright test –-project chromium

Execution times (s): Execution times (s):


23-24-24-24-24 5-4-5-5-5-4-4-7-7-6

Average time: Average time:


23.8s 5.2s (4.6x faster than Cypress)

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Which is the Winner?
Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda
filiphric.com/workshop
● 4 module online workshop
● learn by doing
● core principles and best
practices

starting on 31th May

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda
And the Winner is…

Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda


Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda
Continue the Conversation

#LetTheCodeSpeak
@filip_hric
@AutomationPanda
@applitools
Cypress | @filip_hric #LetTheCodeSpeak Playwright | @AutomationPanda

You might also like