Pular para o conteúdo principal

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:

  1. Backend: Endpoints para executar testes Playwright e servir documentação markdown
  2. Frontend: Interface admin para clicar e ver testes acontecer em tempo real
  3. 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 }
  • GET /api/testing/status/{run_id} — Obtém status + logs (polling)

    • Response: { run_id, status, log_tail (200 lines), exit_code }
  • GET /api/testing/runs — Lista 10 execuções mais recentes

    • Response: { runs: [TestRun, ...] }

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 }, ...]
  • GET /api/docs/guides/{slug} — Obtém conteúdo markdown completo

    • Response: { slug, title, content, path }

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 test remotamente

  • Real-time Logs: Polling a cada 2 segundos getStatus(runId)

    • Mostra log_tail (últimas 200 linhas)
    • Auto-scroll se running
  • 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
  • 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)

  1. Starta backend com flag:

    cd backend
    ENABLE_TEST_RUNNER=true python -m uvicorn src.main:app --reload
  2. Starta frontend:

    cd frontend
    npm run dev
  3. Acede à interface:

    http://localhost:3000/admin/testing
  4. 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
  5. 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):

  1. load-login-page — Valida URL /auth/login e elementos visíveis
  2. login-success — Email + password válidos → redirect /admin
  3. login-invalid — Email/password inválidos → erro exibido

Credentials:

  • Email: admin.test@example.com
  • Password: TestPass123!

Fixtures:

  • adminUser — Credenciais reutilizáveis
  • locationSamples — 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 .md files
  • 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.ts se HTML mudou
  • Usar npx playwright codegen para 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/testing sem 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/docs sem 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


Documento criado: 26 de Fevereiro de 2026
Próxima atualização: Após testes funcionar 100% no dev