Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Cypress or Playwright?

Cypress or Playwright?

Avatar for Rainer Hahnekamp

Rainer Hahnekamp

April 26, 2024
Tweet

More Decks by Rainer Hahnekamp

Other Decks in Technology

Transcript

  1. 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
  2. RainerHahnekamp Goal • Discuss both Frameworks from different Perspectives •

    Provide enough information for a founded decision • Present my own opinion
  3. RainerHahnekamp Agenda 1. Technological Approach 2. Developer Experience 3. CI

    4. Coding 5. Architecture & Extensibility 6. Misc. Features 7. Summary
  4. RainerHahnekamp Browser Support • Browsers ◦ Chromium Family ◦ Firefox

    ◦ Webkit • Languages ◦ JavaScript/TypeScript ◦ .NET ◦ Java ◦ Python Playwright • Browsers ◦ Chromium Family ◦ Firefox ◦ Webkit • Languages ◦ JavaScript/TypeScript
  5. RainerHahnekamp CI • Traceview • Parallelization • Sharding Playwright •

    Video Recording per Test • Screenshot for failed Test • Commercial Cypress Cloud
  6. 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"
  7. RainerHahnekamp Architecture & Extensibility • Recommends Page Objects • Fixtures

    as DI Playwright • Page Objects possible • Recommendation to extend cy ◦ Mind the Query!
  8. 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(); } }
  9. 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); }, };
  10. RainerHahnekamp Playwright Usage in Test const test = base.extend<SidemenuFixtures>(sidemenuFixtures); test('rename

    Latitia to Laetitia', async ({ page, sidemenuPage }) => { await page.goto(''); await sidemenuPage.select('customers'); // ... });
  11. RainerHahnekamp Cypress Commands declare namespace Cypress { interface Chainable<Subject> {

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

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

    openMenu(item: 'Customers' | 'Holidays'): void; testid(selector: string): Chainable<JQuery<HTMLElement>>; } } 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<Chainable<JQuery>>; return () => getFn(); });
  14. RainerHahnekamp Miscellaneous Features • Network: Stubbing, Verifying, Requesting • Visual

    Regression • A11y: User-Facing Selectors, Axe Plugin • Recorder: Chrome Extensions • Session Storage
  15. RainerHahnekamp Browser Support ✅ Performance ✅ More Control over the

    Browser ✅ Tracing ✅ Backed by Microsoft Playwright ✅ Developer Experience ✅ Mature ✅ Component Testing