O Safari representa 27% do tráfego web mobile. Todo navegador iOS, incluindo o Chrome no iPhone, roda em WebKit por baixo, o que significa que pular o WebKit é pular seus usuários de iPhone. Chrome e Edge compartilham a mesma engine Chromium, então juntos cobrem aproximadamente 78% do tráfego desktop com um único projeto de navegador.
Por que os navegadores ainda diferem
Navegadores modernos (Chrome, Firefox, Safari, Edge) todos suportam os mesmos padrões de HTML, CSS e JavaScript. Mas as diferenças persistem:
Renderização de CSS: Gaps de flexbox, comportamentos de grid, renderização de fonte, shadow DOM: os navegadores implementam as specs de forma levemente diferente. APIs JavaScript: Algumas APIs mais recentes não são suportadas em versões mais antigas do Safari.Array.at(), structuredClone(), ResizeObserver: todos têm suporte variável.
Elementos de formulário: Date pickers, inputs de arquivo, elementos select: os navegadores têm estilos e comportamentos diferentes.
Renderização de PDF: O Safari lida com PDFs diferente do Chrome.
Específico do WebKit: O iOS usa WebKit para todos os navegadores (sim, o Chrome no iPhone é WebKit por baixo). Safari no Mac = Safari no iPhone.
Participação de mercado dos navegadores (2025)
| Navegador | Desktop | Mobile |
|-----------|---------|--------|
| Chrome | ~65% | ~66% |
| Safari | ~12% | ~27% |
| Firefox | ~3% | ~1% |
| Edge | ~13% | ~3% |
Ponto-chave: Safari é crítico para mobile (iPhone é WebKit). Edge é baseado em Chrome (Chromium). Firefox tem baixa participação de mercado mas é importante para enterprise e regiões específicas.A estratégia pragmática
Você não pode testar tudo em todo navegador. Uma hierarquia prática:
Camada 1: Sempre testar (todo sprint)
- Chrome — maior participação de mercado, navegador principal de desenvolvimento
- Safari — crítico para usuários iOS/macOS
Camada 2: Testar antes de releases maiores
- Firefox — menor participação de mercado mas renderização distinta
- Edge — baseado em Chromium, risco adicional baixo
Camada 3: Testar para features específicas
- Safari iOS — ao testar fluxos específicos de mobile
- Chrome Android — comportamentos específicos de mobile
- Versões específicas de navegador — quando clientes enterprise as exigem
Configuração cross-browser no Playwright
O Playwright suporta Chrome, Firefox e WebKit (a engine do Safari) nativamente:
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
// Navegadores desktop
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] },
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] },
},
// Navegadores mobile
{
name: 'mobile-chrome',
use: { ...devices['Pixel 7'] },
},
{
name: 'mobile-safari',
use: { ...devices['iPhone 14'] },
},
],
});Rodar um navegador específico:
npx playwright test --project=webkitRodar todos os navegadores:
npx playwright testO que testar cross-browser (e o que não testar)
Teste cross-browser:- Fluxos principais do usuário (login, checkout, workflows principais)
- Formulários, especialmente date pickers, uploads de arquivo, selects
- Layout CSS, especialmente designs com flex/grid intenso
- Features com muito JavaScript (interações complexas)
- Fluxos específicos de mobile (touch, viewport, orientação)
- Testes unitários: independentes de navegador
- Testes de API: sem navegador envolvido
- Testes de lógica de backend
- Ferramentas admin internas que só seu time usa
Lidando com falhas específicas de navegador
Quando um teste falha em apenas um navegador:
test('file upload', async ({ page, browserName }) => {
// Pular no WebKit — o comportamento de file input difere significativamente
test.skip(browserName === 'webkit', 'WebKit handles file inputs differently');
await page.goto('/upload');
await page.setInputFiles('[data-testid="file-input"]', 'test-file.pdf');
await expect(page.getByTestId('upload-success')).toBeVisible();
});Quando você precisa de comportamento específico por navegador:
test('date picker works', async ({ page, browserName }) => {
await page.goto('/book-appointment');
if (browserName === 'webkit') {
// O date picker do Safari exige interação diferente
await page.fill('[data-testid="date-input"]', '2026-06-15');
} else {
await page.click('[data-testid="date-input"]');
await page.click('[data-date="2026-06-15"]');
}
await expect(page.getByTestId('selected-date')).toContainText('June 15');
});BrowserStack e Sauce Labs
Os navegadores integrados do Playwright usam versões open-source. Para testar no Chrome real (não Chromium), Safari real e versões específicas de navegador, use serviços de teste em nuvem.
BrowserStack
// playwright.config.ts para BrowserStack
const capabilities = {
'browserstack.user': process.env.BROWSERSTACK_USERNAME,
'browserstack.key': process.env.BROWSERSTACK_ACCESS_KEY,
};
export default defineConfig({
projects: [
{
name: 'chrome@latest-mac',
use: {
connectOptions: {
wsEndpoint: `wss://cdp.browserstack.com/playwright?caps=${encodeURIComponent(JSON.stringify({
...capabilities,
browserName: 'chrome',
browserVersion: 'latest',
'bstack:options': {
os: 'OS X',
osVersion: 'Sonoma',
}
}))}`,
},
},
},
],
});Quando serviços em nuvem valem a pena
- Você precisa do Safari real (não WebKit) em macOS real
- Versão específica do Chrome (clientes enterprise travados no Chrome 110)
- Testes em dispositivos iOS reais (não simulador)
- Suporte a IE11 (raro, mas ainda existe em finanças/governo)
Testes responsivos
Teste em múltiplos tamanhos de viewport, não apenas mobile vs desktop:
// playwright.config.ts
projects: [
{
name: 'desktop',
use: { viewport: { width: 1920, height: 1080 } },
},
{
name: 'laptop',
use: { viewport: { width: 1280, height: 720 } },
},
{
name: 'tablet',
use: { viewport: { width: 768, height: 1024 } },
},
{
name: 'mobile',
use: { viewport: { width: 375, height: 667 } }, // iPhone SE
},
],Dentro de um teste:
test('navigation works on mobile', async ({ page }) => {
await page.setViewportSize({ width: 375, height: 667 });
await page.goto('/');
// Mobile: menu hamburger em vez de barra de nav
await expect(page.getByTestId('hamburger-menu')).toBeVisible();
await expect(page.getByTestId('desktop-nav')).not.toBeVisible();
await page.getByTestId('hamburger-menu').click();
await expect(page.getByTestId('mobile-nav')).toBeVisible();
});Gerenciando falhas cross-browser no CI
Rode navegadores em paralelo para manter o CI rápido:
# Estratégia de matrix no GitHub Actions
strategy:
matrix:
browser: [chromium, firefox, webkit]
steps:
- run: npx playwright test --project=${{ matrix.browser }}Ou faça sharding de testes cross-browser:
strategy:
matrix:
include:
- browser: chromium
shard: 1/2
- browser: chromium
shard: 2/2
- browser: firefox
shard: 1/1 # Menos testes Firefox
- browser: webkit
shard: 1/1Testes visuais cross-browser
Diferenças de renderização CSS são frequentemente sutis. A comparação manual é trabalhosa. Use Percy ou a comparação de screenshots do Playwright:
test('homepage renders correctly', async ({ page }) => {
await page.goto('/');
await expect(page).toHaveScreenshot('homepage.png', {
maxDiffPixelRatio: 0.02, // 2% de diferença de pixel permitida
});
});Screenshots são armazenados por projeto: cada navegador tem seu próprio baseline.
Resumo
Estratégia prática de cross-browser:1. Rode a suite completa no Chrome em todo commit
2. Rode Chrome + Safari antes de todo release
3. Rode todos os navegadores (incluindo Firefox, Edge) antes de releases maiores
4. Teste viewports mobile para features responsivas
O Playwright torna o cross-browser fácil:- Defina projetos para cada navegador
- Fixture
browserNamepara código específico de navegador test.skip()para incompatibilidades conhecidas- WebKit integrado = Safari sem precisar de macOS
O objetivo não é testar tudo em todo navegador: é pegar os bugs específicos de navegador que realmente afetam seus usuários, usando o tempo que você tem.
→ Veja também: Testes Cross-Browser com Playwright: Chrome, Firefox, Safari | Emulação Móvel no Playwright: Testes Responsivos e Táteis | Execução Paralela no Playwright: Workers, Shards e Sharding para Velocidade