Testes E2E com Cypress
Introdução ao documento
Este documento descreve a estrutura, configuração e execução dos testes end-to-end (E2E) utilizando Cypress no projeto Dhedalos Dashboard.
Versionamento
- Versão do documento: 1.0.0
- Última atualização: 2026-03-09
- Responsável: Marivaldo Vinicius
Referencial teórico
Objetivo dos testes
Os testes Cypress validam fluxos end-to-end críticos do dashboard administrativo, incluindo:
- Autenticação e controle de acesso
- Funcionalidades de CRUD (usuários, manutenção)
- Validação de cache e atualização de dados
- Dashboard e visualizações de dados
- Integrações com APIs externas (AoVivo, WordPress)
- Exportação de dados
- Gestão de permissões e roles
Os testes garantem que a interface administrativa funcione corretamente do ponto de vista do usuário final, complementando os testes unitários e de feature do Pest PHP.
Estrutura de pastas
cypress/
├── e2e/ # Especificações de testes E2E
│ ├── 01-cache-validation.cy.js
│ ├── aovivo.cy.js
│ ├── crud-user.cy.js
│ ├── dashboard.cy.js
│ ├── exportacao-cadastros.cy.js
│ ├── manutencao.cy.js
│ ├── perfil-inscritos.cy.js
│ ├── permissoes.cy.js
│ ├── produtos.cy.js
│ └── forms/ # Page Objects para formulários
│ ├── LoginForm.js
│ ├── MaintenanceForm.js
│ └── UserForm.js
└── support/ # Arquivos de suporte
├── commands.js # Comandos customizados
├── e2e.js # Configuração global e handlers
└── helpers.js # Funções auxiliares
Evidências:
- Estrutura de pastas:
cypress/e2e/,cypress/support/ - Arquivos de teste: 12 arquivos
.cy.jsemcypress/e2e/ - Page Objects: 3 arquivos em
cypress/e2e/forms/
Configuração
Arquivo de configuração
O arquivo cypress.config.js define as configurações principais:
{
chromeWebSecurity: false,
baseUrl: process.env.CYPRESS_BASE_URL || "http://localhost:8000",
specPattern: "cypress/e2e/**/*.cy.{js,jsx,ts,tsx}",
supportFile: "cypress/support/e2e.js",
testIsolation: false,
viewportHeight: 960,
viewportWidth: 1536,
video: true,
videoCompression: true,
retries: {
runMode: 1,
openMode: 1,
}
}
Configurações principais:
- chromeWebSecurity: false: Desabilita segurança do Chrome para permitir testes com iframes e cross-origin
- baseUrl: URL base da aplicação (configurável via
CYPRESS_BASE_URL) - testIsolation: false: Testes compartilham estado (sessão, cookies) entre specs
- viewport: Resolução padrão 1536x960
- video: true: Grava vídeos dos testes para debugging
- retries: 1 tentativa adicional em caso de falha (runMode e openMode)
Evidências:
- Configuração:
cypress.config.js:3-45
Variáveis de ambiente
Variáveis utilizadas pelos testes Cypress:
| Variável | Obrigatória | Descrição | Evidência |
|---|---|---|---|
CYPRESS_BASE_URL | Não | URL base da aplicação (default: http://localhost:8000) | cypress.config.js:30 |
CYPRESS_PROJECT_ID | Não | ID do projeto no Cypress Cloud (para recording) | cypress.config.js:7 |
CYPRESS_RECORD_KEY | Não | Chave para gravar testes no Cypress Cloud | .github/workflows/cypress.yml:149 |
CYPRESS_USER_EMAIL | Sim (CI) | Email do usuário de teste | .github/workflows/cypress.yml:108 |
CYPRESS_USER_PASSWORD | Sim (CI) | Senha do usuário de teste | .github/workflows/cypress.yml:108 |
Variáveis de ambiente da aplicação (necessárias para testes):
REDSHIFT_DB_HOST,REDSHIFT_DB_DATABASE,REDSHIFT_DB_USERNAME,REDSHIFT_DB_PASSWORDWORDPRESS_API_URL,WORDPRESS_API_TOKENAO_VIVO_API,AO_VIVO_TOKENGEMINI_API_KEY
Evidências:
- Variáveis Cypress:
cypress.config.js:7,30 - Variáveis de aplicação:
.github/workflows/cypress.yml:50-62
Comandos de execução
Local (desenvolvimento)
Pré-requisitos:
- Aplicação Laravel rodando em
http://localhost:8000 - Dependências Node instaladas (
npm install) - Usuário de teste criado no banco de dados
Comandos disponíveis:
# Abrir Cypress Test Runner (interface gráfica)
npm run cypress:open
# Executar testes em modo headless
npm run cypress:run
Evidências:
- Scripts:
package.json:4-9(na branchorigin/feat/cypress)
Execução passo a passo:
-
Iniciar aplicação:
docker compose up -
Criar usuário de teste (se necessário):
docker compose exec laravel php artisan tinker
# Criar usuário com email e senha conhecidos -
Executar testes:
npm run cypress:open # Interface gráfica
# ou
npm run cypress:run # Headless
CI/CD (GitHub Actions)
Os testes Cypress são executados automaticamente no pipeline CI/CD:
Workflow: .github/workflows/cypress.yml
Triggers:
- Pull requests
- Push para branches
mainedevelop
Processo:
- Setup PHP 8.3 e Node.js 22
- Instalação de dependências (Composer e npm)
- Configuração de ambiente (
.envcom variáveis de secrets) - Build de assets frontend (
npm run build) - Execução de migrações e seeders
- Criação de usuário de teste via Tinker
- Inicialização do servidor Laravel (
php artisan serve) - Execução dos testes Cypress com recording no Cypress Cloud
- Upload de artifacts (vídeos e screenshots)
Evidências:
- Workflow:
.github/workflows/cypress.yml:1-155 - Recording:
.github/workflows/cypress.yml:140-150
Fixtures e mocks
Status: Não há fixtures ou mocks configurados explicitamente.
Os testes utilizam:
- Dados reais da aplicação: Testes interagem com banco de dados real (SQLite no CI, MySQL local)
- APIs externas reais: Testes dependem de integrações com Redshift, WordPress API, AoVivo API e Gemini API
- Usuários de teste: Criados via seeders ou Tinker antes da execução
Pendências:
- Considerar uso de fixtures para dados de teste isolados
- Avaliar mocks para APIs externas em testes de integração
Custom commands
getIframeBody(selector)
Comando customizado para acessar conteúdo de iframes:
Cypress.Commands.add("getIframeBody", (selector) => {
return cy
.get(selector, { timeout: 15000 })
.should(($el) => {
expect($el.contents().find("body")).to.not.be.empty;
})
.then(($el) => {
return cy.wrap($el.contents().find("body"));
});
});
Uso: Acessar elementos dentro de iframes (ex.: gráficos embutidos, widgets externos).
Evidências:
- Definição:
cypress/support/commands.js:20-30
Helpers
Funções auxiliares em cypress/support/helpers.js:
deleteItems(searchTerm, escapedTerm)
Remove todas as linhas de uma tabela CRUD que correspondem ao termo de busca, clicando em "Excluir" iterativamente.
Parâmetros:
searchTerm: Texto para buscar na tabelaescapedTerm: Versão regex-safe do termo para matching
Uso: Limpar dados de teste após execução de testes de CRUD.
Evidências:
- Definição:
cypress/support/helpers.js:8-35
anoAtualLabel() e anoAnteriorLabel()
Retornam labels de ano atual e anterior para filtros de data.
Uso: Testes que precisam filtrar dados por ano (ex.: dashboard, relatórios).
Evidências:
- Definições:
cypress/support/helpers.js:37-47
Page Objects
Page Objects organizados em cypress/e2e/forms/:
LoginForm.js
Classe para encapsular ações de login:
- Método
makeLogin(user): Realiza login com credenciais fornecidas
Evidências:
- Uso:
cypress/e2e/01-cache-validation.cy.js:3,8 - Uso:
cypress/e2e/dashboard.cy.js:3,8
MaintenanceForm.js e UserForm.js
Page Objects para formulários de manutenção e usuários (estrutura similar).
Evidências:
- Arquivos:
cypress/e2e/forms/MaintenanceForm.js,cypress/e2e/forms/UserForm.js
Convenções observadas
-
Nomenclatura de arquivos:
- Arquivos de teste:
*.cy.js - Page Objects:
*Form.js(PascalCase) - Helpers:
helpers.js(camelCase)
- Arquivos de teste:
-
Estrutura de testes:
- Uso de
describe()para agrupar testes relacionados - Testes descritivos em português (BDD-style)
- Page Objects para encapsular interações com formulários
- Uso de
-
Isolamento:
testIsolation: falsepermite compartilhamento de sessão entre specs- Testes dependem de estado compartilhado (login, cookies)
-
Aguardar elementos:
- Uso de
cy.wait()com delays fixos (não ideal, mas presente) - Timeouts customizados quando necessário (ex.:
getIframeBodycom 15s)
- Uso de
-
Tratamento de erros:
- Handler global em
e2e.jsignora erros de hidratação React e classList null - Evidências:
cypress/support/e2e.js:18-28
- Handler global em
Limitações e pendências
Limitações conhecidas
-
Dependência de APIs externas:
- Testes falham se Redshift, WordPress API, AoVivo API ou Gemini API estiverem indisponíveis
- Não há fallback ou mocks para APIs externas
-
Dados de teste:
- Testes dependem de dados reais no banco de dados
- Não há isolamento completo de dados entre execuções
- Usuários de teste precisam ser criados manualmente ou via seeders
-
Performance:
- Uso de
cy.wait()com delays fixos pode tornar testes lentos testIsolation: falsepode causar efeitos colaterais entre specs
- Uso de
-
Ambiente local:
- Requer aplicação rodando localmente
- Requer configuração manual de variáveis de ambiente
Pendências
-
Fixtures e mocks:
- Implementar fixtures para dados de teste isolados
- Avaliar mocks para APIs externas (opcional, para testes mais rápidos)
-
Melhorias de performance:
- Substituir
cy.wait()fixos por esperas baseadas em condições (cy.get().should()) - Avaliar uso de
testIsolation: truepara maior isolamento
- Substituir
-
Cobertura:
- Expandir cobertura de testes para mais funcionalidades
- Adicionar testes de edge cases e cenários de erro
-
Documentação:
- Documentar padrões de escrita de novos testes
- Criar guia de troubleshooting comum
-
CI/CD:
- Avaliar execução paralela de testes (atualmente sequencial)
- Considerar retry automático apenas para testes flaky específicos
Troubleshooting
Problemas comuns
1. Testes falham com "Element not found":
- Verificar se aplicação está rodando em
http://localhost:8000 - Verificar se viewport está correto (1536x960)
- Aumentar timeout se elemento demora para aparecer
2. Erros de autenticação:
- Verificar se usuário de teste existe no banco de dados
- Verificar credenciais em
CYPRESS_USER_EMAILeCYPRESS_USER_PASSWORD - Limpar cookies antes de executar testes:
cy.clearAllCookies()
3. Testes falham no CI mas passam localmente:
- Verificar logs do servidor Laravel no CI
- Verificar se todas as variáveis de ambiente estão configuradas
- Verificar se migrações e seeders foram executados corretamente
4. Vídeos não são gerados:
- Verificar se
video: trueestá configurado emcypress.config.js - Verificar espaço em disco (vídeos podem ser grandes)
- Verificar permissões de escrita na pasta
cypress/videos
5. Erros de iframe:
- Verificar se
chromeWebSecurity: falseestá configurado - Usar comando customizado
getIframeBody()para acessar conteúdo de iframes
Integração com outros testes
Os testes Cypress complementam:
- Testes Pest PHP: Testes unitários e de feature do backend
- Storybook: Testes de componentes React isolados
Cobertura:
- Pest PHP: Lógica de negócio, controllers, services, jobs
- Cypress: Fluxos end-to-end, interface do usuário, integrações completas
- Storybook: Componentes React isolados
Evidências:
- Testes Pest:
tests/Unit/,tests/Feature/ - Storybook:
stories/