Depois de anos automatizando com Selenium, migrar parte das suítes para o Playwright mudou a forma como o time encara testes end-to-end. Não é só uma ferramenta nova — é uma forma mais estável e rápida de validar o comportamento real da aplicação.
Por que Playwright?
O grande diferencial é o auto-waiting: o Playwright espera automaticamente o elemento ficar visível, habilitado e estável antes de interagir. Isso elimina boa parte dos sleep() e dos testes "flaky" que tanto atrapalham a confiança na suíte.
- Multi-browser real: Chromium, Firefox e WebKit com a mesma API.
- Execução paralela por padrão, com isolamento por contexto de browser.
- Trace Viewer: grava cada passo com screenshots, DOM e network — depurar uma falha de CI vira algo trivial.
- Auto-wait e web-first assertions que reduzem drasticamente a flakiness.
Um teste na prática
import { test, expect } from '@playwright/test';
test('usuário faz login com sucesso', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('E-mail').fill('qa@exemplo.com');
await page.getByLabel('Senha').fill('s3nh4-segura');
await page.getByRole('button', { name: 'Entrar' }).click();
await expect(page.getByRole('heading', { name: 'Bem-vindo' })).toBeVisible();
});
Repare no uso de getByRole e getByLabel: localizadores baseados em acessibilidade, mais resistentes a mudanças de layout do que seletores CSS frágeis.
Boas práticas que adotei
- Usar Page Object Model para encapsular telas e reduzir duplicação.
- Preferir localizadores acessíveis (
getByRole,getByText) a XPaths longos. - Rodar com
--trace on-first-retrypara capturar evidências só quando falha. - Isolar dados de teste e usar fixtures para setup/teardown.
Teste E2E bom não é o que cobre tudo — é o que falha só quando o produto realmente quebrou.
Conclusão
Playwright não substitui testes unitários nem de integração; ele coroa a pirâmide validando os fluxos críticos do ponto de vista do usuário. Combinado a um bom pipeline de CI, dá ao time a confiança de entregar mais rápido sem medo de regressões.
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-retryto 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.