Rodar todos os testes contra Chromium, Firefox e WebKit em todo PR triplica o tempo de CI sem cobertura proporcional de bugs, porque a maioria das falhas não é específica de navegador. As diferenças que realmente importam entre engines são específicas: renderização de input de data, edge cases de CSS flexbox, permissões da Clipboard API, e comportamento de upload de arquivo.
Os três projetos de navegador
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
],
});Rodar todos os navegadores:
npx playwright testRodar um navegador específico:
npx playwright test --project=webkitChromium, Firefox e WebKit: o que é diferente
Chromium: engine JavaScript V8, renderização Blink. Chrome e Edge usam Chromium. Aproximadamente 65% do tráfego web desktop em 2026. Esse é seu alvo principal. Firefox: engine JavaScript SpiderMonkey, renderização Gecko. Aproximadamente 5% do tráfego desktop. Comportamento CSS diferente em edge cases, renderização diferente de elementos de formulário, tratamento diferente de algumas web APIs. WebKit: JavaScriptCore, renderização WebKit. Safari no Mac e iOS. O iOS é WebKit exclusivo. Todos os navegadores iOS são WebKit por baixo. Se seus usuários incluem usuários de iPhone (e incluem), testes WebKit são obrigatórios.O que realmente quebra nos testes cross-browser
A maioria dos apps web funciona igual nos três engines. As diferenças que importam:
CSS:gap em flexbox, subgrid, @container queries mais recentes, backdrop-filter, algumas funções de cor: todos se comportam levemente diferente entre engines ou não são suportados em versões mais antigas.
Input de data/hora: renderiza de forma muito diferente entre navegadores. WebKit e Firefox têm suas próprias UIs nativas de date picker.
Upload de arquivo: O diálogo de seleção de arquivo varia. O setInputFiles() do Playwright contorna isso, mas o tratamento do evento filechooser difere.
Comportamento de scrollbar: O WebKit (no Mac) oculta scrollbars por padrão. Testes que clicam em coordenadas próximas às scrollbars podem se comportar diferente.
Clipboard API: navigator.clipboard exige permissão do usuário. Funciona diferente em cada navegador sob automação de testes.
Elemento : Suporte completo em todos os navegadores modernos, mas diferenças de comportamento em versões mais antigas das engines.
WebRTC, WebSockets, Service Workers: Geralmente consistentes agora, mas historicamente tinham diferenças cross-browser.
Estratégia cross-browser: testes em camadas
Rodar todos os testes em todos os navegadores triplica o tempo de CI. A abordagem prática é em camadas:
Camada 1: todo PR (apenas Chromium):- Suite completa de regressão
- Testes de feature
- Testes de API
- Smoke tests em todos os navegadores
- Testes em áreas com risco cross-browser conhecido (inputs de data, upload de arquivo, interações dependentes de CSS)
- Regressão cross-browser completa
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
const isCIFullRun = process.env.CROSS_BROWSER === 'true';
export default defineConfig({
projects: [
// Sempre roda Chromium
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
// Só roda Firefox e WebKit no modo cross-browser
...(isCIFullRun ? [
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
] : []),
],
});# .github/workflows/tests.yml
- name: Run cross-browser tests
if: github.event_name == 'schedule' # Apenas no agendamento noturno
run: CROSS_BROWSER=true npx playwright testInstalando navegadores
O Playwright baixa os binários dos navegadores separadamente. Instale os três:
npx playwright installInstalar navegadores específicos:
npx playwright install chromium firefox webkitNo CI, use a imagem Docker que inclui todos os navegadores:
- run: npx playwright install --with-deps--with-deps também instala dependências de sistema (fontes, codecs) que os navegadores do Playwright precisam.
Lidando com comportamento específico de navegador nos testes
Quando um teste precisa se comportar diferente por navegador:
import { test, expect } from '@playwright/test';
test('date input behavior', async ({ page, browserName }) => {
await page.goto('/book-appointment');
if (browserName === 'webkit') {
// O date picker nativo do WebKit exige interação diferente
await page.getByLabel('Date').fill('2026-06-15');
} else {
await page.getByLabel('Date').type('06/15/2026');
}
await expect(page.getByLabel('Date')).toHaveValue('2026-06-15');
});browserName é um de 'chromium', 'firefox', 'webkit'.
Pular um teste em um navegador específico:
test('uses clipboard API', async ({ page, browserName }) => {
test.skip(browserName === 'firefox', 'Clipboard API requires permissions in Firefox');
// ...
});Navegador real vs. emulação
O Playwright roda contra engines de navegador reais, não ambientes simulados. Testes WebKit rodam contra a engine WebKit real (a mesma que alimenta o Safari), não um simulador Safari imitando Chrome.
Isso importa: bugs cross-browser que você encontrar no projeto WebKit do Playwright vão se reproduzir no Safari real. Não é 100% idêntico (o Playwright usa um build WebKit ligeiramente mais recente que o Safari em produção), mas é próximo o suficiente para pegar problemas reais.
→ Veja também: Estratégias de Testes Cross-Browser: Quando e Como Testar em Múltiplos Navegadores | Emulação Móvel no Playwright: Testes Responsivos e Táteis | Execução Paralela no Playwright: Workers, Shards e Sharding para Velocidade