Automation

Playwright in practice: modern E2E testing

After years of automating with Selenium, migrating part of the suites to Playwright changed how the team approaches end-to-end tests. It's not just a new tool; it's a more stable and faster way to validate the real behavior of the application.

Why Playwright?

The big differentiator is auto-waiting: Playwright automatically waits for the element to be visible, enabled, and stable before interacting. That eliminates a good share of sleep() calls and the "flaky" tests that so undermine confidence in the suite.

  • Real multi-browser: Chromium, Firefox, and WebKit with the same API.
  • Parallel execution by default, with isolation per browser context.
  • Trace Viewer: records every step with screenshots, DOM, and network, so debugging a CI failure becomes trivial.
  • Auto-wait and web-first assertions that drastically reduce flakiness.

A test in practice

import { test, expect } from '@playwright/test';

test('user logs in successfully', async ({ page }) => {
  await page.goto('/login');
  await page.getByLabel('Email').fill('qa@example.com');
  await page.getByLabel('Password').fill('s3cure-p4ss');
  await page.getByRole('button', { name: 'Sign in' }).click();

  await expect(page.getByRole('heading', { name: 'Welcome' })).toBeVisible();
});

Notice the use of getByRole and getByLabel: accessibility-based locators, more resilient to layout changes than brittle CSS selectors.

Best practices I adopted

  • Use the Page Object Model to encapsulate screens and reduce duplication.
  • Prefer accessible locators (getByRole, getByText) over long XPaths.
  • Run with --trace on-first-retry to capture evidence only when something fails.
  • Isolate test data and use fixtures for setup/teardown.
A good E2E test isn't the one that covers everything; it's the one that fails only when the product has really broken.

Conclusion

Playwright doesn't replace unit or integration tests; it crowns the pyramid by validating the critical flows from the user's point of view. Combined with a good CI pipeline, it gives the team the confidence to ship faster without fearing regressions.

Read also

Back to the blog