Os testes de regressão visual comparam capturas de tela das suas páginas com imagens de referência aprovadas e falham quando os pixels mudam. Para layouts mobile, eles pegam o que os testes funcionais não veem: um botão de menu empurrado para fora de uma tela de 360px, um título que quebra em três linhas, uma grade de cards que colapsa errado na largura de tablet. Você pode rodá-los de graça com o toHaveScreenshot() do Playwright em viewports de celular e de tablet, e depois decidir se vale pagar por um serviço para fluxos de revisão e renderização em vários navegadores na nuvem.
Como funcionam os testes de regressão visual
Um teste visual tem quatro etapas: capturar uma referência, capturar de novo depois de uma mudança, comparar as duas imagens e deixar uma pessoa aceitar ou rejeitar a diferença. As mudanças aceitas viram a nova referência.
A comparação é onde as ferramentas se diferenciam. A comparação de pixels (Playwright, BackstopJS) conta os pixels alterados e falha acima de um limite que você define. O Applitools compara com a própria IA visual, em vez de contar pixels de forma estrita, e o Percy e o Chromatic são serviços hospedados com painel de revisão. Todos precisam de páginas estáveis: se um relógio, um anúncio ou uma animação mudar entre duas execuções, o teste falha sem motivo real. A maior parte do trabalho de configuração abaixo consiste em eliminar esse ruído.

Ferramentas comparadas
A asserção embutida do Playwright cobre o caso gratuito e autogerenciado. Em outubro de 2026:
| Ferramenta | Método de comparação | Custo | Onde é mais forte |
|---|---|---|---|
Playwright toHaveScreenshot |
Comparação de pixels, local | Gratuito, código aberto | Chromium, Firefox e WebKit em um único runner, referências no seu repositório |
| BackstopJS | Comparação de pixels, local | Gratuito, código aberto | Cenários só por configuração (sem código de teste), relatório HTML, opção --docker |
| Percy (BrowserStack) | Comparação na nuvem e interface de revisão | Plano gratuito: 5.000 capturas por mês | Fluxo de revisão e aprovação hospedado, em vários navegadores e larguras |
| Chromatic | Comparação na nuvem, baseada em Storybook | Plano gratuito: 5.000 snapshots por mês, só Chrome | Testes em nível de componente para projetos com Storybook |
| Applitools Eyes | IA visual | Plano inicial a partir de US$ 667 por mês, cobrado anualmente; teste gratuito | Comparação por IA que visa ignorar o ruído de renderização que a comparação de pixels acusa; grandes grades entre navegadores |
O Percy conta cada página em cada navegador e largura como uma captura: duas páginas em três larguras de celular e tablet em dois navegadores já somam doze. Os preços e limites dos planos vêm da página de preços de cada fornecedor em 25 de outubro de 2026, e mudam com frequência.
Configure testes visuais em viewports de celular
Esta configuração usa o @playwright/test 1.64 (a versão atual em 25 de outubro de 2026). Ela precisa de Node.js e de um site acessível a partir da máquina de testes, local ou publicado.
-
Instale o Playwright e os navegadores:
npm init playwright@latest -
Adicione projetos mobile em
playwright.config.ts. Cada descritor de dispositivo define o viewport, a densidade de pixels, o user agent e o suporte a toque, e escolhe o motor (iPhone 15roda no WebKit,Pixel 7no Chromium).import { defineConfig, devices } from '@playwright/test'; export default defineConfig({ testDir: './visual', use: { baseURL: 'http://localhost:4321' }, expect: { toHaveScreenshot: { maxDiffPixelRatio: 0.01 }, }, projects: [ { name: 'pixel-7', use: { ...devices['Pixel 7'] } }, { name: 'iphone-15', use: { ...devices['iPhone 15'] } }, { name: 'tablet', use: { browserName: 'chromium', viewport: { width: 820, height: 1180 } } }, ], });No Playwright 1.64, o descritor
Pixel 7tem viewport de 412 × 839 com densidade de pixels de 2,625, e oiPhone 15tem 393 × 659 com 3. OmaxDiffPixelRatiode 1% é um valor inicial que você ajusta, não um padrão. -
Escreva o teste. Limite-o às páginas cujo layout mais importa:
// visual/pages.spec.ts import { test, expect } from '@playwright/test'; const pages = ['/', '/pricing', '/blog']; for (const path of pages) { test(`layout ${path}`, async ({ page }) => { await page.goto(path); await page.evaluate(async () => { await document.fonts.ready; }); await expect(page).toHaveScreenshot({ fullPage: true, mask: [page.locator('[data-testid="live-date"]')], }); }); } -
Crie as referências e confirme-as no repositório:
npx playwright test --update-snapshotsO Playwright salva um PNG por teste e por projeto, com o nome do projeto e a plataforma no fim do nome do arquivo (por exemplo
...-iphone-15-linux.png). Faça commit das pastas*-snapshots. -
Rode
npx playwright testem cada pull request. Uma comparação que falha derruba o teste; abra o relatório HTML comnpx playwright show-reportpara ver a falha. Se a mudança for intencional, atualize as referências com--update-snapshotse faça commit junto com a mudança de código.
Os padrões ajudam: o toHaveScreenshot() espera até que duas capturas consecutivas coincidam antes de comparar, desativa animações e transições CSS e oculta o cursor de texto (documentação da API do Playwright). Sua opção scale tem o padrão "css", um pixel de imagem por pixel CSS, então uma referência de iPhone tem 393 px de largura em vez de 1179, e as comparações ficam rápidas.
Veja o layout antes de criar as referências
Uma referência registra como a página estava quando você a capturou. Se a primeira captura já mostra um layout mobile quebrado, todas as execuções seguintes vão defender esse erro. Antes de criar as referências, olhe cada página nas larguras que você testa:
- Abra a página em uma largura de celular. O Mobile View Extension recarrega a aba com o user agent, o tamanho de tela e a densidade de pixels de um celular, e pode mostrar dois dispositivos lado a lado, então você confere juntos os layouts de celular e tablet de uma mesma URL. Ele funciona em localhost.
- Role a página inteira e confira a navegação, os títulos que quebram linha, as tabelas e os elementos fixos.
- Corrija o que encontrar e rode
--update-snapshots.
A extensão renderiza com o motor do Chrome de desktop e com mouse, então mostra o layout, não a renderização do Safari nem o comportamento de toque. O projeto WebKit do Playwright cobre parte dessa diferença, e um iPhone real cobre o resto. Uma rotina mais ampla para verificações manuais está em como testar um design responsivo, e as capturas pontuais para tickets em como fazer uma captura de tela mobile de um site.
Corrija diferenças de captura instáveis
As diferenças instáveis vêm do que muda entre as execuções, então a solução é deixar essas coisas sempre iguais. Estas são as causas comuns e o que fazer com cada uma:
| Causa | Correção |
|---|---|
| Sistema operacional ou versão de navegador diferentes | Gere e compare as referências no mesmo tipo de máquina; no CI, uma imagem Docker fixada que corresponda à sua versão do Playwright, como mcr.microsoft.com/playwright:v1.64.0-noble |
| Fontes web que chegam atrasadas ou usam a fonte de reserva | Espere por document.fonts.ready; hospede as fontes você mesmo para que um atraso do CDN não mude a renderização |
| Datas, contadores, anúncios, embeds | Aplique mask aos localizadores, ou oculte-os com uma folha de estilo stylePath |
| Carrosséis e animações em JavaScript | Pare-os com um sinalizador só para testes; o toHaveScreenshot só congela CSS e Web Animations |
| Estados de hover | Tire o mouse de cima antes: page.mouse.move(-1, -1) |
| Imagens preguiçosas em capturas de página inteira | Role até o fim ou espere as imagens carregarem antes de capturar |
| Ruído de antisserrilhado | Aumente o threshold (padrão 0,2) ou defina maxDiffPixels |
A primeira linha explica as falhas que parecem aleatórias. A documentação do Playwright alerta que a renderização pode variar conforme o sistema operacional do host, a versão, as configurações e o hardware, e a plataforma faz parte do nome da captura por esse motivo: uma referência criada em um Mac (-darwin.png) não é usada em um runner Linux de CI (-linux.png). Escolha um único ambiente para as referências. Rodar npx playwright test --update-snapshots dentro da mesma imagem Docker usada pelo CI elimina essa fonte de diferença.
Um arquivo stylePath é o lugar mais limpo para ocultar ruído em todos os testes:
/* visual/screenshot.css */
iframe, [data-testid="cookie-banner"] { visibility: hidden; }
import path from 'node:path';
await expect(page).toHaveScreenshot({
stylePath: path.join(__dirname, 'screenshot.css'),
});
A mesma opção pode ir em expect.toHaveScreenshot na configuração para valer em todos os testes.
O que os testes visuais não detectam
Uma comparação de capturas verifica pixels nos motores que você executa. Ela não verifica se um botão funciona, se uma área de toque tem tamanho suficiente, nem como a página se comporta no navegador real de um celular, com a barra do navegador e o teclado. O WebKit do Playwright é parecido com o Safari, mas não é o Safari no iPhone. Mantenha testes funcionais ao lado dos visuais, e cubra os navegadores reais com a lista de testes entre navegadores.
Mantenha a suíte pequena. Cada página, projeto e estado multiplica o número de imagens para revisar. De três a dez modelos-chave (início, uma listagem, uma página de detalhe, um formulário) em dois tamanhos de celular e um de tablet mantêm a revisão em poucas dezenas de imagens por execução. Esse número é um ponto de partida para ajustar (uma decisão de design), não uma regra.
Perguntas frequentes
Testes de regressão visual são gratuitos?
Sim, com ferramentas de código aberto. O toHaveScreenshot() do Playwright e o BackstopJS rodam localmente e no seu CI sem custo. Serviços pagos como Percy, Chromatic e Applitools acrescentam renderização hospedada e painéis de revisão, e o Percy e o Chromatic têm planos gratuitos de 5.000 capturas ou snapshots por mês em outubro de 2026.
Qual é a diferença entre teste visual e teste de captura de tela?
Os dois tiram uma captura e a comparam com uma referência aprovada. A diferença está na comparação: o Playwright e o BackstopJS contam pixels alterados, enquanto o Applitools usa IA visual (veja a tabela de ferramentas acima).
Por que as minhas capturas do Playwright falham no CI mas passam localmente?
Porque as referências foram feitas em outro sistema operacional ou com outra versão de navegador. O Playwright inclui a plataforma no nome do arquivo de captura, e as fontes e o antisserrilhado são diferentes no macOS e no Linux. Crie as referências na mesma imagem Docker usada pelo CI.
Como ignoro conteúdo dinâmico nos testes visuais?
Use a opção mask para cobrir elementos como datas e anúncios, ou oculte-os com uma folha de estilo stylePath. Para regiões inteiras que mudam, capture um elemento estável em vez da página completa.