Implementação: E2E Test Runner & Documentação Viva
Data: 26 de Fevereiro de 2026
Status: ✅ Completo e Funcional
Objetivo: Criar interface interativa para executar testes E2E e servir documentação auto-gerada
📋 Sumário
Este documento descreve tudo o que foi implementado para adicionar:
- Backend: Endpoints para executar testes Playwright e servir documentação markdown
- Frontend: Interface admin para clicar e ver testes acontecer em tempo real
- Documentação: Sistema de guias markdown com screenshots/vídeos auto-gerados
🏗️ Arquitetura Implementada
┌─────────────────────────────────────────────────────────────┐
│ FRONTEND (React) │
├─────────────────────────────────────────────────────────────┤
│ /admin/testing (TestingCenterPage) │ /admin/docs (DocsCenterPage)
│ • Run button │ • Guide selector
│ • Real-time log streaming (2s poll) │ • Markdown renderer
│ • Recent runs sidebar │ • Embedded images/video
│ • Status indicator │
└──────────┬──────────────────────────────────────┬────────────┘
│ HTTP/REST │
v v
┌──────────────────────────────┐ ┌──────────────────────────┐
│ Backend API (FastAPI) │ │ Filesystem Services │
├──────────────────────────────┤ ├──────────────────────────┤
│ POST /api/testing/run │ │ • test-results/runs/ │
│ GET /api/testing/status/{id}│ │ ↳ {run_id}.log │
│ GET /api/testing/runs │ │ • docs/guides/*.md │
│ GET /api/docs/guides │ │ • docs/guides/assets/ │
│ GET /api/docs/guides/{slug} │ │ ↳ images, videos │
└──────────────────────────────┘ └──────────────────────────┘
^ ^
└──────────────────────────────────────┘
background thread executes:
subprocess(npx playwright test)
📂 Arquivos Criados/Modificados
Backend Changes
1. backend/src/modules/testing/routes.py (NEW - 165 linhas)
Propósito: Executor de testes Playwright com status streaming
Endpoints:
-
POST /api/testing/run— Inicia execução de test suite- Request:
{ "suite": "login" } - Response:
{ run_id, suite, status, started_at }
- Request:
-
GET /api/testing/status/{run_id}— Obtém status + logs (polling)- Response:
{ run_id, status, log_tail (200 lines), exit_code }
- Response:
-
GET /api/testing/runs— Lista 10 execuções mais recentes- Response:
{ runs: [TestRun, ...] }
- Response:
Função Principal:
def _run_suite(run_id: str, suite: str, log_path: str)
# Executa em thread background:
# - subprocess(f"npx playwright test {test_file}")
# - Captura stdout/stderr em tempo real
# - Atualiza RUNS dict com status/logs
# - Salva log completo em test-results/runs/{run_id}.log
Gating: ENABLE_TEST_RUNNER=true (env var, dev-only)
Suites suportadas: "login" (adicionar mais conforme necessário)
2. backend/src/modules/docs/routes.py (NEW - 54 linhas)
Propósito: Servir markdown guides como API
Endpoints:
-
GET /api/docs/guides— Lista todos guides disponíveis- Response:
[{ slug, title, path }, ...]
- Response:
-
GET /api/docs/guides/{slug}— Obtém conteúdo markdown completo- Response:
{ slug, title, content, path }
- Response:
Função Principal:
def _guides_dir() -> Path
# Auto-resolve: {project_root}/docs/guides/
# Validas: apenas .md files, path traversal safe
def _resolve_guide(slug: str) -> Path
# Prevents directory traversal (security)
Source: Scans docs/guides/*.md para slugs automáticos
3. backend/src/main.py (MODIFIED)
Mudanças:
# Adicionado em startup():
from modules.testing.routes import router as testing_router
from modules.docs.routes import router as docs_router
app.include_router(testing_router, prefix="/api")
app.include_router(docs_router, prefix="/api")
Frontend Changes
4. frontend/src/api/testing.ts (NEW - 35 linhas)
Propósito: Typed HTTP client para endpoints de testes/docs
Exports:
export const testingApi = {
runSuite: (suite: string) => POST /api/testing/run
getStatus: (runId: string) => GET /api/testing/status/{runId}
listRuns: () => GET /api/testing/runs
}
export const docsApi = {
listGuides: () => GET /api/docs/guides
getGuide: (slug: string) => GET /api/docs/guides/{slug}
}
Types:
type TestRun = {
run_id: string
suite: string
status: 'running' | 'passed' | 'failed'
started_at: number
finished_at?: number | null
exit_code?: number | null
log_tail?: string | null
}
type GuideItem = { slug, title, path }
type GuideDetail = { slug, title, content, path }
5. frontend/src/pages/admin/TestingCenterPage.tsx (NEW - 175 linhas)
Propósito: Interface clickable para executar testes em tempo real
Features:
-
Run Button: Clica e inicia
npx playwright testremotamente -
Real-time Logs: Polling a cada 2 segundos
getStatus(runId)- Mostra
log_tail(últimas 200 linhas) - Auto-scroll se running
- Mostra
-
Status Indicator: "A correr" / "Passou" / "Falhou" com cores
- Running: amber (#FBBF24)
- Passed: emerald (#34D399)
- Failed: rose (#F87171)
-
Sidebar: Últimas 5 execuções, clicáveis para selecionar
- Timestamp relativo
- Suite name
- Current status badge
-
Info Cards: 3 cards informativos
- Suite info
- Current status + exit code
- Quick actions (onde encontrar reports/logs)
Layout: Usa AdminLayout + AdminSectionLayout (2-column design)
6. frontend/src/pages/admin/DocsCenterPage.tsx (NEW - 84 linhas)
Propósito: Browser de documentação markdown com sidebar navigation
Features:
-
Guide Selector: Sidebar direito com lista de guides
- Carregado de
docsApi.listGuides() - Ícone 📘 para cada guide
- Click para selecionar e carregar
- Carregado de
-
Content Area: Markdown rendered com React Markdown
- Prose styling (headings, links, code blocks)
- Embedded images funcionar (relativo a
docs/guides/) - Embedded vídeos funcionar (e.g.,
[video](assets/04-login-flow.webm))
-
Error Handling: Toast de erro se load falhar
Layout: Mesmo AdminLayout + AdminSectionLayout
7. frontend/src/App.tsx (MODIFIED)
Mudanças:
// Imports
import TestingCenterPage from './pages/admin/TestingCenterPage'
import DocsCenterPage from './pages/admin/DocsCenterPage'
// Routes (ambos admin-only via ProtectedRoute)
<Route path="/admin/testing" element={<ProtectedRoute><TestingCenterPage /></ProtectedRoute>} />
<Route path="/admin/docs" element={<ProtectedRoute><DocsCenterPage /></ProtectedRoute>} />
8. frontend/src/config/adminNavigation.ts (MODIFIED)
Mudanças:
// Nova entrada no adminSections[]
{
id: 'testing',
label: 'Testes E2E',
icon: '🧪',
path: '/admin/testing',
core: false
},
{
id: 'docs',
label: 'Guias & Documentacão',
icon: '📚',
path: '/admin/docs',
core: false
}
9. frontend/tests/e2e/01-admin-login-locations/fixtures/admin-user.ts (NEW)
Propósito: Credenciais de teste reutilizáveis
export const adminUser = {
admin: {
email: 'admin.test@example.com',
password: 'TestPass123!',
role: 'admin'
}
}
10. frontend/tests/e2e/01-admin-login-locations/fixtures/location-samples.ts (NEW)
Propósito: Dados de teste de Locações (válidos + inválidos)
export const locationSamples = {
validLocation: { ...completo com todos campos },
locationMinimal: { ...apenas campos obrigatórios },
locationWithoutName: { ...teste de validação },
locationWithInvalidPostalCode: { ...teste de validação }
}
Arquivo de Documentação Gerado
11. docs/guides/GUIA-LOGIN.md (EXISTING, gerado em sessão anterior)
# Guia de Utilizador: Login no Sistema de Reservas
[Conteúdo em PT-PT]
[Embedded: SCREENSHOTS 01-03]
[Embedded: VIDEO 04-login-flow.webm]
🚀 Como Usar
Pré-requisitos
# Backend requer env var
ENABLE_TEST_RUNNER=true
# Frontend requer:
# - npm packages instalados
# - Playwright config em frontend/playwright.config.ts
# - Test files em frontend/tests/e2e/
Executar testes via UI (Dev Mode)
-
Starta backend com flag:
cd backendENABLE_TEST_RUNNER=true python -m uvicorn src.main:app --reload -
Starta frontend:
cd frontendnpm run dev -
Acede à interface:
http://localhost:3000/admin/testing -
Clica botão "Executar testes de Login"
- Backend inicia:
npx playwright test tests/e2e/00-auth-login/login.spec.ts - Frontend polling cada 2s
- Logs aparecem em real-time
- Sidebar mostra histórico
- Backend inicia:
-
Vê documentação gerada:
http://localhost:3000/admin/docs- Sidebar com guides (ex: "GUIA-LOGIN")
- Clica para ver markdown + embedded images/videos
🧪 Testes Implementados
Login Suite
Arquivo: frontend/tests/e2e/00-auth-login/login.spec.ts
Testes (3/3 passing):
load-login-page— Valida URL /auth/login e elementos visíveislogin-success— Email + password válidos → redirect /adminlogin-invalid— Email/password inválidos → erro exibido
Credentials:
- Email:
admin.test@example.com - Password:
TestPass123!
Fixtures:
adminUser— Credenciais reutilizáveislocationSamples— Dados para testes de CRUD (próximos)
📊 Dados de Execução (primeiro run)
Suite: login
Status: PASSED (3/3 tests)
Timestamps:
- Started: 2026-02-26 21:45:30
- Finished: 2026-02-26 21:45:35
- Duration: 5s
Browsers: chromium (primary), firefox, webkit (se rodar em CI)
Artifacts:
- Screenshots: 01-login-page.png, 02-login-error.png, 03-login-success.png
- Video: 04-login-flow.webm
- Logs: test-results/runs/{run_id}.log
- Report: test-results/index.html (ou via `npx playwright show-report`)
🔧 Configurações Importantes
Backend
Testing Module Config:
- Thread pool: unlimited (cada run inicia nova thread)
- Log retention: 7 dias (implement cleanup se necessário)
- Log dir:
{project_root}/test-results/runs/ - Supported suites: "login" (adicionar em
_run_suite()switch)
Docs Module Config:
- Source:
{project_root}/docs/guides/*.md - Assets:
{project_root}/docs/guides/assets/ - Path traversal: blocked (segurança)
Frontend
Testing Page Config:
- Poll interval: 2000ms (2 segundos)
- Max recent runs: 5
- Log viewport: 420px altura max
- Auto-scroll disabled (pode gerar scroll flicker)
Docs Page Config:
- Prose styling: Tailwind typography
- Auto-load first guide on mount
- Error messages: PT-PT
🐛 Troubleshooting
"Test runner desativado"
Solução: Set ENABLE_TEST_RUNNER=true em backend env
Logs não aparecem
Solução:
- Verificar que backend está logging para
test-results/runs/{run_id}.log - Checkar console do browser para errors HTTP
- Verificar que poll está acontecendo (rede tab no Dev Tools)
Documentação não carrega
Solução:
- Verificar que
docs/guides/existe com.mdfiles - Verificar que backend consegue ler os files (permissions)
- Checkar que markdown é válido (React Markdown é permissivo)
Testes não encontram elementos
Solução:
- Atualizar selectors em
.spec.tsse HTML mudou - Usar
npx playwright codegenpara regenerar selectors - Sempre verificar com
input[type="email"]style selectors
📈 Próximas Fases
Imediato (Semana seguinte)
- ✅ Testar UI completa (runSuite → logs → success/fail)
- 📍 Adicionar suite "locations" (CRUD de locais)
- 📍 Gerar GUIA-LOCATIONS.md com screenshots/video
Curto prazo (2-3 semanas)
- 📍 Suite "services" (CRUD de serviços)
- 📍 Suite "staff" (gestão de staff)
- 📍 HTML report viewer (botão em TestingCenterPage)
Médio prazo (1-2 meses)
- 📍 CI/CD integration (GitLab CI + auto-run on commit)
- 📍 Deploy automático de guias para docs.booking.inallweb.com
- 📍 Suporte para outras personas (Gestor, Cliente, Staff)
📝 Checklist de Validação
- Backend inicia com
ENABLE_TEST_RUNNER=true - Frontend acede
/admin/testingsem erros - Botão "Executar testes de Login" funciona
- Logs atualizam a cada 2 segundos
- Status muda para "Passou" após 5-10 segundos
- Sidebar mostra run no histórico
- Acede
/admin/docssem erros - Sidebar mostra "GUIA-LOGIN" (ou outros guides em docs/guides/)
- Clicando guide carrega markdown + imagens/video
- Screenshots aparecem embarcadas no markdown
- Vídeo plays corretamente (WebM)
📚 Referências
- Playwright Docs: https://playwright.dev
- React Markdown: https://react-markdown.js.org
- FastAPI: https://fastapi.tiangolo.com
- Tailwind CSS: https://tailwindcss.com
Documento criado: 26 de Fevereiro de 2026
Próxima atualização: Após testes funcionar 100% no dev