📚 Módulo 13: QA - Garantia de Qualidade com Testes E2E (Cypress) no React e NestJS
Neste módulo avançado de Garantia de Qualidade (QA) da TecLoja 03, implementaremos testes ponta a ponta (End-to-End - E2E) utilizando o framework Cypress.
Para garantir a estabilidade do nosso ecossistema de nível corporativo escrito em TypeScript (NestJS e React 18), configuraremos o Cypress para simular o comportamento de um usuário real no navegador: fazendo login seguro, navegando pelas categorias do catálogo React, adicionando produtos de tecnologia ao carrinho global, faturando o pedido e validando o tratamento transacional ACID no backend NestJS.
🗺️ 1. Arquitetura do Fluxo de Testes E2E com Cypress
O diagrama abaixo ilustra a esteira integrada de testes simulando o tráfego do frontend React para a API NestJS no banco Neon PostgreSQL:
flowchart TD
%% Styling
classDef cy fill:#00b48a,stroke:#005c45,stroke-width:2px,color:#fff;
classDef browser fill:#2088ff,stroke:#005cc5,stroke-width:2px,color:#fff;
classDef react fill:#61dafb,stroke:#20232a,stroke-width:2px,color:#000;
classDef nest fill:#e0234e,stroke:#9f1239,stroke-width:2px,color:#fff;
subgraph Cypress_Runner ["⚙️ Cypress Test Suite"]
A[Cypress Test Script]:::cy -->|Interagir via automação| B[Navegador de Teste Chrome]:::browser
end
subgraph Application_Stack ["💻 Ecossistema da Aplicação"]
B -->|Eventos de Click & Input| C[React Vite SPA - localhost:5173]:::react
C -->|Chamadas HTTP Rest| D[NestJS API - localhost:3000]:::nest
end
⚙️ 2. Instalação e Configuração do Cypress no React
Acesse o diretório raiz da sua aplicação frontend React (tecloja-frontend ou correspondente) e instale o Cypress como dependência de desenvolvimento:
# Instalar o Cypress
npm install -D cypress
Após instalar, rode o assistente visual para criar a estrutura padrão de diretórios:
npx cypress open
- Selecione E2E Testing na tela do assistente.
- Clique em Continue para aceitar a criação dos arquivos de suporte padrão.
- Escolha o navegador desejado e finalize clicando em Start E2E Testing.
- Feche a janela gráfica do navegador para retornar ao código.
Configurando o arquivo cypress.config.ts
Edite o arquivo de configurações cypress.config.ts na raiz do projeto React para definir as dimensões de tela padrão e o endereço de escuta do Vite:
import { defineConfig } from "cypress";
export default defineConfig({
e2e: {
baseUrl: "http://localhost:5173", // URL padrão de desenvolvimento do React
viewportWidth: 1280,
viewportHeight: 720,
video: true,
screenshotOnRunFailure: true,
},
});
🧪 3. Escrevendo o Teste do Fluxo de Checkout (checkout.cy.ts)
Criaremos o cenário principal cobrindo a adição de produtos e o fluxo transacional de faturamento.
Crie o arquivo de testes em cypress/e2e/checkout.cy.ts:
describe('Fluxo Completo de Compra - TecLoja 03', () => {
beforeEach(() => {
// Garantir que nenhuma sessão antiga de login permaneça ativa no navegador
cy.clearLocalStorage();
cy.visit('/');
});
it('Deve carregar o catálogo React, adicionar itens e exigir login para faturar', () => {
// 1. Validar interface principal
cy.get('h1').should('contain', 'TecLoja 03');
cy.get('.produtos-lista').should('be.visible');
// 2. Adicionar o primeiro eletrônico ao carrinho
cy.get('.produto-card').first().within(() => {
cy.get('.produto-titulo').then(($el) => {
cy.wrap($el.text()).as('tituloItem');
});
cy.contains('Comprar').click();
});
// 3. Validar se o balão flutuante do carrinho incrementou
cy.get('.cart-badge').should('contain', '1');
// 4. Navegar para a tela do carrinho de compras
cy.get('.cart-nav-button').click();
cy.url().should('include', '/carrinho');
// 5. Validar consistência do nome do produto no carrinho
cy.get('@tituloItem').then((titulo) => {
cy.get('.carrinho-itens-lista').should('contain', titulo);
});
// 6. Clicar no botão para faturar sem autenticação
cy.contains('Finalizar Pedido').click();
// 7. Esperado: Redirecionamento forçado para a tela de autenticação
cy.url().should('include', '/login');
});
it('Deve logar com credenciais válidas e concluir o checkout com sucesso', () => {
// 1. Visitar a tela de Login
cy.visit('/login');
// 2. Preencher formulário de login (credenciais populares de semente)
cy.get('input[name="email"]').type('maria@gmail.com');
cy.get('input[name="password"]').type('123456');
cy.get('button[type="submit"]').click();
// 3. Validar redirecionamento pós-login bem-sucedido para a Home
cy.url().should('eq', Cypress.config().baseUrl + '/');
cy.get('.navbar-username').should('contain', 'Maria');
// 4. Adicionar produto ao carrinho
cy.get('.produto-card').first().within(() => {
cy.contains('Comprar').click();
});
// 5. Ir ao carrinho e finalizar compra
cy.get('.cart-nav-button').click();
cy.contains('Finalizar Pedido').click();
// 6. Validar mensagem de sucesso emitida pela API NestJS
cy.get('.checkout-sucesso-container').should('be.visible')
.and('contain', 'Pedido processado e faturado!');
});
});
🚀 4. Executando os Testes E2E
Modo Interativo
Abra a interface interativa do Cypress para ver a reprodução visual dos testes:
npx cypress open
Modo Automático (CI/CD)
Execute a suíte completa no terminal (headless mode):
npx cypress run
✅ Pré-Requisitos deste Módulo
Antes de iniciar a simulação com Cypress, garanta que:
- A API NestJS está ativa localmente na porta 3000 (
npm run start:dev). - O banco de dados PostgreSQL foi populado com a massa de dados padrão (
maria@gmail.comcom senha123456) usando a CLI do Prisma (npx prisma db seed). - O frontend React está respondendo localmente na porta 5173 (
npm run dev).
🤔 Por que fizemos assim?
- Por que escolher testes E2E com Cypress para o React? Componentes React com múltiplos hooks de estado (
useState,useContext) interagem entre si em tempo real. Testar isso isoladamente com Jest e React Testing Library (RTL) exige mockar o navegador completo e o Axios, o que oculta falhas em eventos assíncronos. O Cypress roda sobre o motor real do Chromium/Webkit, garantindo que eventos de renderização e acessos à memória local de contexto ocorram exatamente como na máquina do cliente. - Por que validar o redirecionamento de rotas virtuais? Em SPAs React com
react-router-dom, as trocas de rotas ocorrem no lado do cliente por manipulação do histórico do navegador (History API). Se o roteamento estiver com problemas de configuração, a tentativa de finalizar compras sem login pode resultar em telas brancas ou loops infinitos de redirecionamento. Testes E2E garantem que a guarda global de rotas funcione corretamente.
🔍 Checkpoint
- Sucesso na CLI: Rode
npx cypress runno terminal e certifique-se de que todos os specs terminem com o status verde “All specs passed!”. - Massa de Dados Persistida: Após a execução do teste de faturamento com sucesso, abra o Prisma Studio (
npx prisma studio) e confirme se um novo registro de pedido foi criado na tabelaPedidocom oclienteIdcorrespondente à Maria.
⚠️ Erros Comuns
| Erro | Causa | Solução |
|---|---|---|
AxiosError: Network Error ao rodar os testes |
A API NestJS não está rodando ou o endereço configurado no frontend React não bate com o backend. | Certifique-se de iniciar a API NestJS com npm run start:dev e confirme as portas de comunicação de ambos. |
| O Cypress tenta clicar em um botão de comprar que está desativado | O estoque do produto selecionado no banco está zerado e o botão de compras foi desativado dinamicamente no React. | Execute o comando npx prisma db seed para resetar os valores de estoque originais do banco de dados de testes. |
| Erros de CORS no console do Cypress | O backend NestJS não habilitou a porta do React para fazer requisições cruzadas (CORS). | Verifique se você chamou a instrução app.enableCors({ origin: 'http://localhost:5173' }) no arquivo main.ts da API NestJS. |