Slide 1

Slide 1 text

RainerHahnekamp Cypress or Playwright? JAX, 25.4.2024 Rainer Hahnekamp

Slide 2

Slide 2 text

RainerHahnekamp About Me... Professional NgRx https://www.youtube.com/ @RainerHahnekamp https://www.ng-news.com https://github.com/softarc-consulting/sheriff ● Rainer Hahnekamp ANGULARarchitects.io ● Developer / Trainer / Speaker Modern Spring for Angular @RainerHahnekamp

Slide 3

Slide 3 text

RainerHahnekamp Goal ● Discuss both Frameworks from different Perspectives ● Provide enough information for a founded decision ● Present my own opinion

Slide 4

Slide 4 text

RainerHahnekamp

Slide 5

Slide 5 text

RainerHahnekamp

Slide 6

Slide 6 text

RainerHahnekamp Agenda 1. Technological Approach 2. Developer Experience 3. CI 4. Coding 5. Architecture & Extensibility 6. Misc. Features 7. Summary

Slide 7

Slide 7 text

RainerHahnekamp Technological Approach

Slide 8

Slide 8 text

RainerHahnekamp 2010 2005 2015 2020 Selenium RC Selenium 2 CDP Cypress Playwright

Slide 9

Slide 9 text

RainerHahnekamp Playwright: Outside browser testing Test CDP

Slide 10

Slide 10 text

RainerHahnekamp Cypress: Inside browser testing Cypress Test Browser

Slide 11

Slide 11 text

RainerHahnekamp 2 iFrames, same origin

Slide 12

Slide 12 text

RainerHahnekamp Browser Support ● Browsers ○ Chromium Family ○ Firefox ○ Webkit ● Languages ○ JavaScript/TypeScript ○ .NET ○ Java ○ Python Playwright ● Browsers ○ Chromium Family ○ Firefox ○ Webkit ● Languages ○ JavaScript/TypeScript

Slide 13

Slide 13 text

RainerHahnekamp Playwright Waiting Feature: Auto-Wait

Slide 14

Slide 14 text

RainerHahnekamp Cypress Waiting Feature: Actionability

Slide 15

Slide 15 text

RainerHahnekamp Dependencies ● Almost Zero dependencies ● Build everything on their own Mocha & Chai jQuery Playwright

Slide 16

Slide 16 text

RainerHahnekamp Developer Experience

Slide 17

Slide 17 text

RainerHahnekamp Cypress Test Runner Embedded Browser Test Code History with "Time Travel" Detailed Logging Info

Slide 18

Slide 18 text

RainerHahnekamp Playwright Native Debug Mode Playwright Inspector

Slide 19

Slide 19 text

RainerHahnekamp Playwright VSCode Integration Interactive Selector Highlighting Debugging Execution Management

Slide 20

Slide 20 text

RainerHahnekamp Playwright UI Mode Test Log Embedded Browser TraceView

Slide 21

Slide 21 text

RainerHahnekamp CI

Slide 22

Slide 22 text

RainerHahnekamp CI ● Traceview ● Parallelization ● Sharding Playwright ● Video Recording per Test ● Screenshot for failed Test ● Commercial Cypress Cloud

Slide 23

Slide 23 text

RainerHahnekamp Cypress Video Recording

Slide 24

Slide 24 text

RainerHahnekamp Cypress Screenshot on Error

Slide 25

Slide 25 text

RainerHahnekamp Playwright Trace Viewer

Slide 26

Slide 26 text

RainerHahnekamp Coding

Slide 27

Slide 27 text

RainerHahnekamp Coding: Selectors, Actions & Assertions ● Testing framework built-in ○ Different Selector Engines ○ Special Web Assertions ● Locators as Abstraction to DOM ● Async/Await Playwright ● Relies on External Libraries ○ Selection via jQuery ○ Assertion via Mocha & Chai ○ Explicit Assertions ● Retryability ● "Declarative Asynchrony"

Slide 28

Slide 28 text

RainerHahnekamp cy.visit() cy.get() cy.click() synchronous ● visit ● get ● click asynchronous

Slide 29

Slide 29 text

RainerHahnekamp Architecture & Extensibility

Slide 30

Slide 30 text

RainerHahnekamp Architecture & Extensibility ● Recommends Page Objects ● Fixtures as DI Playwright ● Page Objects possible ● Recommendation to extend cy ○ Mind the Query!

Slide 31

Slide 31 text

RainerHahnekamp Playwright Page Object import { Page } from '@playwright/test'; export class SidemenuPage { constructor(private page: Page) {} async select(menu: 'customers' | 'holidays') { await this.page.getByTestId(`btn-${menu}`).click(); } }

Slide 32

Slide 32 text

RainerHahnekamp Playwright Fixture import { SidemenuPage } from '../page-objects/sidemenu-page'; export interface SidemenuFixtures { sidemenuPage: SidemenuPage; } export const sidemenuFixtures = { sidemenuPage: async ({ page }, use) => { const sidemenuPage = new SidemenuPage(page); await use(sidemenuPage); }, };

Slide 33

Slide 33 text

RainerHahnekamp Playwright Usage in Test const test = base.extend(sidemenuFixtures); test('rename Latitia to Laetitia', async ({ page, sidemenuPage }) => { await page.goto(''); await sidemenuPage.select('customers'); // ... });

Slide 34

Slide 34 text

RainerHahnekamp Cypress Commands declare namespace Cypress { interface Chainable { openMenu(item: 'Customers' | 'Holidays'): void; } } Cypress.Commands.add('openMenu', (item: 'Customers' | 'Holidays') => { cy.findByRole('link', { name: item }).click(); });

Slide 35

Slide 35 text

RainerHahnekamp Cypress Commands declare namespace Cypress { interface Chainable { openMenu(item: 'Customers' | 'Holidays'): void; } } Cypress.Commands.add('openMenu', (item: 'Customers' | 'Holidays') => { cy.findByRole('link', { name: item }).click(); });

Slide 36

Slide 36 text

RainerHahnekamp Cypress Queries declare namespace Cypress { interface Chainable { openMenu(item: 'Customers' | 'Holidays'): void; testid(selector: string): Chainable>; } } Cypress.Commands.add('openMenu', (item: 'Customers' | 'Holidays') => { cy.findByRole('link', { name: item }).click(); }); Cypress.Commands.addQuery('testid', (selector: string) => { const getFn = cy.now('get', `[data-testid=${selector}]`) as () => Promise>; return () => getFn(); });

Slide 37

Slide 37 text

RainerHahnekamp Misc. Features

Slide 38

Slide 38 text

RainerHahnekamp Miscellaneous Features ● Network: Stubbing, Verifying, Requesting ● Visual Regression ● A11y: User-Facing Selectors, Axe Plugin ● Recorder: Chrome Extensions ● Session Storage

Slide 39

Slide 39 text

RainerHahnekamp Summary

Slide 40

Slide 40 text

RainerHahnekamp Browser Support ✅ Performance ✅ More Control over the Browser ✅ Tracing ✅ Backed by Microsoft Playwright ✅ Developer Experience ✅ Mature ✅ Component Testing

Slide 41

Slide 41 text

RainerHahnekamp Thanks!!!

Slide 42

Slide 42 text

RainerHahnekamp Contact Data @Rainer Hahnekamp https://www.youtube.com/@RainerHahnekamp https://www.youtube.com/@ng-news https://www.angulararchitects.io https://www.rainerhahnekamp.com https://github.com/softarc-consulting/sheriff