Módulo 4: Rede e preparo pra CI
page.route pra mock/intercept de rede, um atalho de login mais rápido, e o que muda quando os testes rodam no CI.
🎥 Prefere ver antes de ler?
Esse vídeo (6min18) explica o que é um status code, o que significa "mockar" uma resposta,
como o page.route intercepta a rede antes dela sair do navegador, o que são
addInitScript e localStorage, a diferença entre um método
static e um método de instância, o que é CI e o que significa rodar
headless, e termina explicando linha por linha o workflow do GitHub Actions.
Fecha com os dois erros (real e mockado) e o login pulado acontecendo de verdade no site de
treino. Não substitui o texto abaixo, mas ajuda a visualizar antes de praticar.
1. Erro de verdade vs. erro mockado
O QA Treino tem uma rota que sempre responde 500
(/api/erro), pra testar como a tela reage a um erro de servidor sem
depender de derrubar nada de verdade. Mais uma Page Object nova,
pages/RedePage.js:
const rede = new RedePage(page);
await rede.goto();
await rede.forceErrorButton.click();
await expect(rede.errorMessage).toContainText("500");
Isso testa o servidor real. Mas às vezes você quer
testar como a tela reage a um erro que o servidor não produz hoje: um timeout,
um 503 de manutenção, um corpo de resposta estranho. É aí que entra
page.route: ele intercepta a requisição antes dela sair do navegador e
você decide a resposta:
await page.route("**/api/erro", (route) =>
route.fulfill({
status: 503,
contentType: "application/json",
body: JSON.stringify({ erro: "Fora do ar pra manutencao (mock)." }),
})
);
await rede.goto();
await rede.forceErrorButton.click();
await expect(rede.errorMessage).toContainText("503");
O padrão (**/api/erro) usa glob: **
casa qualquer coisa antes, então funciona não importa a origem exata
(localhost:3000 hoje, outra coisa amanhã).
2. Pular o login com addInitScript
O login em si já foi testado no Módulo 1. Repetir a tela de
login em todo teste que só precisa estar logado custa tempo (e é mais um
lugar pra flakiness acontecer). page.addInitScript injeta um script que
roda antes de qualquer script da página, em toda navegação. Dá pra escrever a sessão
direto. Como isso não pertence a nenhuma página específica (é sobre a sessão, não sobre
o login.html), virou um método estático na própria LoginPage:
// dentro de pages/LoginPage.js
static async pularLogin(page, nome = "Maria") {
await page.addInitScript((nomeInjetado) => {
localStorage.setItem("qa-treino-sessao", JSON.stringify({ nome: nomeInjetado }));
}, nome);
}
No teste:
await LoginPage.pularLogin(page, "Maria");
await page.goto("/index.html");
await expect(page.getByTestId("nav-account-name")).toHaveText("Maria");
Quando usar qual: se o teste é sobre o login (Módulo 1), passe pela UI de verdade. Se o login é só um pré-requisito pra testar outra coisa (carrinho, paginação, mock de produto), pular direto é mais rápido e mais estável: menos passos, menos chance de um deles falhar por motivo que não tem nada a ver com o que você está testando.
Fora desta trilha: o addInitScript funciona porque aqui a sessão
é só um item no localStorage. Em projetos reais o Playwright tem um jeito
oficial pra isso: storageState. A ideia é fazer o login pela UI
uma vez, salvar cookies e localStorage num arquivo JSON
(await page.context().storageState({ path: "sessao.json" })) e depois
reaproveitar esse arquivo em todos os testes via playwright.config.js
(use: { storageState: "sessao.json" }). É o padrão usado em produção
porque funciona com qualquer mecanismo de sessão (cookie de verdade, token, o que
for), não só localStorage manual como fizemos acima.
3. Os testes deste módulo
Arquivo já existe em
tests/04_rede_ci.spec.js. Não precisa digitar, só rodar:
npx playwright test tests/04_rede_ci.spec.js
4. O que muda pra rodar em CI
Os comandos que você já roda (npx playwright test)
já executam headless por padrão (sem abrir janela de navegador), então já
funcionam num servidor de CI sem alteração nenhuma. Como o alvo (QA Treino) já está
publicado, o CI nem precisa subir nada: só instalar os navegadores do Playwright na
máquina do runner e rodar. Um workflow do GitHub Actions pra isso, pra ler (não precisa
rodar agora, depende do repositório estar público, que ainda não é o caso):
name: Playwright
on: [push, pull_request]
jobs:
testes:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: 20 }
- run: npm ci
working-directory: trilha-7
- run: npx playwright install --with-deps chromium
working-directory: trilha-7
- run: npx playwright test
working-directory: trilha-7
É a mesma lógica da Trilha 6: o pipeline só automatiza os mesmos comandos que você já roda à mão, um atrás do outro. Se tiver curiosidade de como isso se encaixa num workflow de verdade, vale revisar aquela trilha.
Exercício
Em tests/04_rede_ci.spec.js, escreva um teste
chamado "produto mockado aparece na lista" que combina as duas técnicas do
módulo: pule o login com LoginPage.pularLogin(page, "Maria") e use
page.route em
"**/api/produtos*" pra devolver um produto inventado
({ id: 999, nome: "Produto Mockado", preco: 9.9, emoji: "🧪" }), depois
confira que product-card-999 aparece com esse nome. Rode
python verificar.py 4 até dar 5 [ok]. Gabarito em
trilha-7/GABARITO.md.
📁 Ver estrutura de pastas da trilha-7/
trilha-7/
├── playwright.config.js
├── package.json
├── verificar.py
├── GABARITO.md
├── README.md
├── fixtures/
│ └── exemplo.png
├── pages/
│ ├── LoginPage.js ← pularLogin() usado neste exercício
│ ├── CadastroPage.js
│ ├── ProdutosPage.js
│ ├── ProdutoPage.js
│ └── RedePage.js
└── tests/
├── 01_primeiro_teste.spec.js
├── 02_selecionadores.spec.js
├── 03_cenarios.spec.js
└── 04_rede_ci.spec.js ← este exercício
Olhar de QA
Mockar rede é uma faca de dois gumes. Pra baixo: testa como a tela reage a um cenário (erro, vazio, dado estranho) sem precisar reproduzir esse cenário no servidor de verdade: mais rápido, mais estável, cobre casos difíceis de forçar. Pra cima: se você mockar tudo, nunca testa se o front-end e o back-end ainda concordam sobre o formato da resposta, e um contrato quebrado passa despercebido. A prática mais segura: ter alguns testes de ponta a ponta contra o servidor real (como os Módulos 1 a 3 fizeram) e usar mock pontualmente pros cenários que o servidor real não reproduz de forma confiável.