QA Learning / Playwright

Módulo 1: Preparar e primeiro teste

O que é automação de navegador, instalar o Playwright, o alvo já publicado, e rodar o primeiro teste de login.

Curioso de onde vem cada arquivo do projeto desta trilha? O Módulo 0 (bônus) monta um do zero, sem nada pronto. É opcional e pode ser pulado.

O que é automação de navegador

Até agora suas verificações rodaram contra banco (SQL), API ou um processo de linha de comando. Automação web é diferente: o script abre um navegador de verdade (ou uma versão sem interface dele) e interage com a página como um usuário faria: clica, digita, espera a tela mudar, lê o que apareceu.

O Playwright é a ferramenta que faz isso hoje com menos dor: controla Chromium, Firefox e WebKit com a mesma API, espera sozinho um elemento existir/estar visível antes de interagir (sem sleep() arbitrário espalhado pelo teste) e vem com um corretor de testes embutido (@playwright/test), que é o que esta trilha usa.

O alvo: um site feito pra isso

Testar contra um site de produção de verdade é ruim pra aprender: qualquer mudança visual quebra o seu seletor, e você não controla os cenários de erro. Por isso esta trilha usa o QA Treino, um site fake, separado do QA Learning, com um data-testid="pagina-elemento-papel" em cada elemento importante. É a mesma convenção que Playwright e Testing Library recomendam: o seletor testa comportamento, não aparência.

Ele tem uma loja com login obrigatório, cadastro com validação, lista de produtos com carregamento assíncrono e paginação, modal, upload de arquivo, drag-and-drop, carrinho em localStorage, e uma página que força erro 500 sob demanda. É tudo o que esta trilha (e as próximas, de Cypress) vai usar.

1. Instalar o Node.js (se ainda não tem)

Confira se já tem:

node --version

Se não tiver, baixe o instalador LTS em nodejs.org e reabra o terminal depois.

2. Pegar o código da trilha

Baixe, descompacte, e pronto. Não precisa de Git nem de conta no GitHub:

Baixar só esta trilha (.zip) 19 KB · 23 arquivos, sem mais nada junto

Dentro do ZIP vem só uma pasta, exatamente a que esta trilha precisa:

trilha-7/     o projeto Playwright que você vai usar em todos os módulos

Se preferir clonar com Git, um aviso: isso baixa o repositório inteiro (o site, as outras trilhas e todo o histórico de commits), não só esta trilha.

git clone https://github.com/ezequiel-dawud/HardSkillsQA.git

Só vale a pena se você for fazer a Trilha 6 (CI/CD), que precisa do repositório de verdade pra rodar o pipeline, ou se quiser praticar o que a Trilha 2 ensina. Nesse caso a pasta se chama HardSkillsQA e o projeto fica em HardSkillsQA/trilha-7/. Para só fazer esta trilha, o botão acima basta.

No Windows, atenção a uma pegadinha: o "Extrair Tudo" cria uma pasta com o nome do arquivo e mantém o que vem dentro dele, às vezes você acaba com qa-learning-playwright\qa-learning-playwright\. A pasta certa é a que tem trilha-7 logo dentro. Se você baixar duas vezes, o Windows ainda acrescenta (1) no nome, não tem problema, só confira onde você está antes de rodar os comandos.

3. O alvo já está no ar

Diferente de outras trilhas que rodam tudo local, o QA Treino está publicado em https://qa-learning-treino-production.up.railway.app. Não precisa clonar nada nem subir servidor: o playwright.config.js da trilha-7/ já aponta pra lá por padrão.

Quer rodar o alvo na sua própria máquina mesmo assim (offline, ou pra mexer no código do site de treino)? Clone qa-learning-treino, rode npm run dev ali dentro (sobe em http://localhost:3000) e aponte os testes pra ele com BASE_URL=http://localhost:3000. Pra seguir a trilha normalmente, pode pular direto pro próximo passo.

4. Instalar o Playwright na trilha

De dentro de trilha-7/ (no repositório do QA Learning), um comando de cada vez (espera o primeiro terminar antes de rodar o segundo):

npm install

Instala as dependências do projeto (o próprio Playwright). Só depois que esse terminar:

npx playwright install chromium

Esse baixa o navegador que o Playwright controla (só a primeira vez; são uns 150 MB). Instalamos só o Chromium aqui pra ficar leve; Firefox e WebKit entram depois, se você quiser testar em mais de um motor.

Se o VS Code sublinhar de vermelho require("@playwright/test") com "Cannot find module", mesmo depois do npm install terminar: é falso alarme. O editor analisou o arquivo antes do node_modules/ existir e não percebeu sozinho que a pasta apareceu. Ctrl+Shift+P → digite "Reload Window" → Enter resolve. Confirme rodando o teste de verdade no terminal antes de se preocupar: se ele passar, o módulo está lá, é só o editor que está desatualizado.

🎥 Prefere ver antes de ler?

Esse vídeo (2min23) mostra onde o data-testid vive de verdade na página, explica o código do primeiro teste linha por linha, e termina com o teste rodando no navegador. Não substitui o texto abaixo, mas ajuda a visualizar antes de praticar.

5. data-testid e locators

A forma de "achar" um elemento na página chama-se locator. Dá pra localizar por texto, por CSS, por papel de acessibilidade, mas o mais estável pra teste automatizado é por data-testid, porque não muda quando o design muda:

await page.getByTestId("login-email-input").fill("maria@exemplo.com");
await page.getByTestId("login-submit-button").click();

No login do QA Treino: login-email-input, login-password-input, login-submit-button, e login-error-message quando a credencial está errada. A lista completa fica no README.md do repositório do site de treino.

Não quer depender só do README? Com o site de treino aberto, aperta F12 pra abrir o DevTools do navegador, clica no ícone de seta/cursor (ou Ctrl+Shift+C) e depois clica em qualquer elemento da página: o painel Elements mostra o HTML dele, incluindo o data-testid. É assim que QA de verdade descobre seletor numa tela que não tem documentação nenhuma — vale praticar isso aqui, numa tela que tem.

6. O primeiro teste

O arquivo já vem pronto no projeto. Isto aqui é só pra você ver o conteúdo, não precisa digitar nem colar isto no terminal:

📄 arquivo já existe em tests/01_primeiro_teste.spec.js, não cole no terminal

const { test, expect } = require("@playwright/test");

test("a pagina de login carrega", async ({ page }) => {
  await page.goto("/login.html");
  await expect(page.getByTestId("login-form")).toBeVisible();
});

test("login com credenciais validas entra na loja", async ({ page }) => {
  await page.goto("/login.html");
  await page.getByTestId("login-email-input").fill("maria@exemplo.com");
  await page.getByTestId("login-password-input").fill("SenhaForte123");
  await page.getByTestId("login-submit-button").click();

  await expect(page).toHaveURL(/index\.html/);
  await expect(page.getByTestId("nav-account-name")).toHaveText("Maria");
});

Repare que page.goto("/login.html") usa um caminho relativo, não a URL inteira. Isso funciona porque todo teste já recebe um page pronto, apontando pro baseURL configurado em playwright.config.js (o site de treino publicado): o Playwright gruda esse baseURL na frente de qualquer caminho relativo que você passar pro goto(). Na prática, page.goto("/login.html") e page.goto("https://qa-learning-treino-production.up.railway.app/login.html") abrem a mesma página; a primeira forma só evita repetir a URL inteira em todo teste, e facilita trocar de alvo no futuro (como no Módulo 0, que usa outro baseURL) sem precisar editar teste por teste. E não existe nenhum sleep() antes de ler o nome "Maria" no header: o expect() do Playwright espera sozinho até uns 5 segundos até a condição ficar verdadeira, ou falha com uma mensagem clara.

De dentro de trilha-7/:

npx playwright test tests/01_primeiro_teste.spec.js

Por padrão isso roda headless (sem abrir janela de navegador) — mais rápido, mas você não vê nada acontecendo. Pra ver o navegador de verdade clicando e preenchendo, acrescente --headed:

npx playwright test tests/01_primeiro_teste.spec.js --headed

Como os dois testes rodam em paralelo, podem abrir duas janelas ao mesmo tempo — não é erro. Vale usar --headed enquanto você está aprendendo um cenário novo, e depois voltar pro padrão (headless) no dia a dia, que é mais rápido e é como o CI roda.

7. Ler o resultado

O Playwright imprime cada teste com ok ou failed e grava um relatório (resultado.json, configurado em playwright.config.js) que o corretor lê:

Running 2 tests using 2 workers

  ok 1 [chromium] › a pagina de login carrega (712ms)
  ok 2 [chromium] › login com credenciais validas entra na loja (2.0s)

  2 passed (5.2s)

Quando um teste falha, o Playwright mostra os dois lados: o que o expect() esperava e o que achou, e, por padrão, guarda um trace (configurado como retain-on-failure) que dá pra abrir depois com npx playwright show-trace e ver a página exatamente no momento da falha, passo a passo. É o equivalente ao "print na tela na hora que quebrou", só que automático.

Rode o corretor pra conferir os critérios do módulo:

python verificar.py 1

Exercício

Em tests/01_primeiro_teste.spec.js, escreva um terceiro teste chamado "login com senha errada mostra mensagem de erro": vai em /login.html, preenche o e-mail certo e uma senha errada, clica em login-submit-button e confere que login-error-message fica visível. Rode npx playwright test tests/01_primeiro_teste.spec.js e depois python verificar.py 1 até dar 4 [ok]. O gabarito está em trilha-7/GABARITO.md.

Pegadinha clássica: um teste sem nenhum expect() sempre passa, não importa o que aconteça na tela — o Playwright só reprova quando uma asserção falha, e sem asserção não tem o que falhar. Faça os passos (goto, fill, click) sem a linha final de expect() e rode de novo: o relatório mostra "1 passed" mesmo assim. É fácil escrever uma suíte inteira "verde" que não testa nada — o python verificar.py 1 também cairia nessa, porque só confere se o teste existe e se passou, não se ele tem asserção de verdade. Depois de ver isso acontecer, acrescente o expect(...).toBeVisible() de volta.

📁 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
│   ├── CadastroPage.js
│   ├── ProdutosPage.js
│   ├── ProdutoPage.js
│   └── RedePage.js
└── tests/
    ├── 01_primeiro_teste.spec.js   ← este exercício
    ├── 02_selecionadores.spec.js
    ├── 03_cenarios.spec.js
    └── 04_rede_ci.spec.js

Repare que os locators (page.getByTestId(...)) ficaram espalhados direto nos testes acima. Pra um arquivo com dois testes, tudo bem, mas isso não escala. O Módulo 2 mostra como organizar isso com Page Object Model, o padrão que o resto da trilha usa daqui pra frente.

Olhar de QA

Automação de UI é a camada mais lenta e mais frágil da pirâmide de testes: qualquer mudança de layout pode quebrar um seletor ruim, e cada teste abre um navegador de verdade. Por isso ela não substitui os testes de API e unitários que você já viu: ela cobre o que só existe no navegador (JavaScript do cliente, CSS que esconde algo, um formulário que não submete). A pergunta antes de automatizar uma tela é a mesma de sempre: esse cenário já está coberto numa camada mais barata e mais rápida? Se não, UI é o lugar certo.

Terminou este módulo? Marque: o ✓ aparece no índice da trilha e a barra de progresso anda no começo do site. Fica salvo só no seu navegador.