# Teste Visual das Telas Principais — Design

**Data:** 2026-07-15
**Branch de trabalho:** `feat/fechamento-ajustes-v1` (ou uma branch dedicada de QA)

## Objetivo

Exercitar visualmente, num navegador real, as três telas centrais do Citrus —
**Cadastro de Profissional**, **Lançamento de Efetivo** e **Card / Financeiro** —
simulando entradas válidas (caminho feliz) e inválidas (valores fora do esperado),
observando o **retorno em tela**, e produzindo ao final um **relatório de checklist**
com o que funcionou (✅) e os problemas a resolver (❌).

Não é uma suíte automatizada versionada nem um roteiro manual: é um **passe
exploratório dirigido por automação de navegador**, executado uma vez, com relatório.

## Decisões (fechadas no brainstorming)

| Decisão | Escolha |
|---|---|
| Mecanismo | Passe exploratório dirigido por navegador (não vira suíte, não é roteiro manual) |
| Ferramenta | **Playwright + Chromium** (navegador real, executa JS) |
| Ambiente | App de **dev** atual (`http://localhost:8082`), sem limpeza dos dados criados |
| Login | `admin` / `citrus@2026` (perfil `administrativo`, acesso total) |
| Relatório | Markdown **enxuto**: checklist por tela + lista de problemas |
| Screenshots | **Somente nas falhas** (❌), como prova visual |

## Por que navegador real

Boa parte do valor está no **financeiro (card)**, cujo comportamento é client-side:
bônus/despesas adicionados dinamicamente, máscara monetária, recálculo de totais ao
vivo, upload de arquivo com badge, alerta de linha meio-preenchida (`alert()` no
`card.js`), e `confirm()` de exclusão. Um cliente HTTP puro não executa esse JS. O
Playwright dirige o Chromium de verdade, então esses casos ficam observáveis.

## Arquitetura do harness

Script único em Node (Playwright), sem framework de teste, rodando no host contra o
container de dev já no ar.

**Componentes:**

1. **`login()`** — abre `/site/login`, preenche `admin`/`citrus@2026`, submete. Em dev
   o reCAPTCHA v3 fica desativado quando `RECAPTCHA_SECRET_KEY` está vazio, então o
   login segue normal. Reaproveita a sessão para todos os cenários (um `context`).
2. **Cenários como dados** — um array por tela. Cada cenário é um objeto
   `{ id, tela, tipo, entrada, esperado, passos }`. O runner é genérico; adicionar
   cenário = adicionar um objeto.
3. **Runner** — para cada cenário: navega à tela, executa os `passos` (preencher,
   clicar "+ adicionar", `setInputFiles`, disparar `blur`/`input` para máscara e
   `recompute`), e então **assere sobre o que o usuário vê**: mensagens de validação
   (`.help-block-error` / error-summary), flashes (`.alert-success` / `.alert-danger`),
   badges (ex.: "NF"), totais recalculados lidos do DOM, e o texto capturado de
   `dialog` (`alert`/`confirm`).
4. **Coletor de resultados** — acumula `{ tela, cenário, entrada, esperado, obtido,
   status: ✅|❌, screenshot? }`. Em ❌, tira screenshot da tela naquele momento.
5. **Gerador de relatório** — emite o markdown enxuto (ver abaixo).

**Interações reais que o harness cobre:** máscara `R$ x.xxx,xx`, add/remove de linhas
de bônus e desconto, recálculo de total líquido, `alert()` do item 6, upload de
documento + badge de tipo, `confirm()` de exclusão, dropdown AJAX de profissional.

**Requisito de setup:** `npx playwright install chromium` (download único). App de dev
precisa estar no ar (`docker compose up -d`).

## Matriz de cenários

Legenda: **HP** caminho feliz · **INV** inválido/erro esperado · **CS** client-side.

### Tela 1 — Cadastro de Profissional (`create`/`update`)

| # | Tipo | Entrada | Retorno esperado em tela |
|---|---|---|---|
| P1 | HP | Profissional puro válido (nome, CPF, nasc, endereço, whatsapp, função, status ativo, perfil `profissional`, diária) | Salva, redireciona à lista, aparece na grid |
| P2 | HP | Líder válido (perfil `lider` + login + senha ≥6 + bônus mensal) | Salva |
| P3 | HP | Administrativo válido (login+senha, sem diária) | Salva |
| P4 | INV | Todos obrigatórios vazios | Erros "não pode ficar em branco" em nome/CPF/nasc/endereço/whatsapp/função |
| P5 | INV | Nenhum perfil marcado | "Selecione ao menos um perfil." |
| P6 | INV | CPF duplicado (`000.000.000-00` do admin) | "CPF já cadastrado." |
| P7 | INV | E-mail inválido (`abc@`) | Erro de e-mail |
| P8 | INV | Perfil `profissional` sem diária | "Informe o valor da diária." |
| P9 | INV | Perfil `lider` sem bônus mensal | "Informe o bônus mensal do líder." |
| P10 | INV | Perfil com login (`lider`) sem login | "Login é obrigatório para perfis com acesso." |
| P11 | INV | Perfil com login, novo, sem senha | "Senha é obrigatória para perfis com acesso." |
| P12 | INV | Senha com 3 chars | Erro de mínimo 6 |
| P13 | INV | Login duplicado (`admin`) | Erro de login já em uso |
| P14 | INV | Data de nascimento inválida (`31/31/2000`) | Erro de data |
| P15 | CS | Máscaras: CPF `12345678901`, whatsapp, diária `123456` | Formata p/ `123.456.789-01`, `R$ 1.234,56` em tela |
| P16 | CS | Selecionar função → valor sugerido (`valor-funcao`) | Campo diária/base reflete a função escolhida |

### Tela 2 — Lançamento de Efetivo (`registrar` + `adicionar` + dropdown)

| # | Tipo | Entrada | Retorno esperado |
|---|---|---|---|
| E1 | HP | Obra + hoje + profissional + entrada `08:00` | Linha criada na lista do dia |
| E2 | HP | Entrada `08:00` + saída `17:00` | Linha criada |
| E3 | HP | Turno noturno: entrada `22:00`, saída `06:00` | Aceito (regra nova) |
| E4 | INV | Sem hora de entrada | "não pode ficar em branco" |
| E5 | INV | Hora em formato errado (`8h`) | "Use o formato HH:MM." |
| E6 | INV | Retroativo (ontem) sem saída | "Informe a hora de saída para lançamentos de dias anteriores." |
| E7 | HP | Retroativo (ontem) com saída | Aceito |
| E8 | INV | Dobra com 1ª entrada aberta (sem saída) | "Há um lançamento em aberto..." |
| E9 | INV | Dobra com entrada antes da saída anterior | "A nova entrada deve ser a partir de HH:MM..." |
| E10 | HP | Dobra válida (entrada ≥ saída anterior) | Aceito |
| E11 | CS | Dropdown de profissional (`buscar-profissional`) | Quem tem entrada **aberta** no dia some da lista; quem já fechou aparece |

### Tela 3 — Card / Financeiro (`fechar` + `salvar` + `mudar-status` + upload)

| # | Tipo | Entrada | Retorno esperado |
|---|---|---|---|
| C1 | HP | Abrir card de um profissional/quinzena | Página renderiza com diárias e totais |
| C2 | HP+CS | Adicionar bônus (desc + `R$ 100,00`), salvar | Total líquido recalcula em tela e persiste após salvar |
| C3 | HP+CS | Adicionar desconto (desc + valor), marcar "abate nota" | Total e valor de nota recalculam |
| C4 | CS | Bônus meio-preenchido: só valor, sem descrição, "Salvar" | `alert()` "Preencha descrição e valor..." e submit bloqueado (item 6) |
| C5 | CS | Adicionar 2 bônus + 1 desconto dinamicamente, remover 1 | Linhas add/remove corretas; total confere com a soma |
| C6 | CS | Editar quantidade de diária | Subtotal e total recalculam ao vivo |
| C7 | HP+CS | Marcar como Pago + anexar documento tipo **NF** | Badge "NF" ao lado do documento (item 7) |
| C8 | INV | Tentar salvar card fora do rascunho | "Só é possível editar um card em rascunho." |
| C9 | INV | Mudar para status inválido | Flash de erro de transição |
| C10 | CS | Anexo do desconto (clip) em largura mobile ~390px | Modal "Anexar comprovante" abre e aceita arquivo (item 5) |
| C11 | HP | Lista de cards: filtro "Somente sem NF" | Só cards **fechados/pagos** com nota>0 e sem NF; rascunho não conta (item 10 + commit c4d63fd) |

Total: **~38 cenários** (16 Profissional, 11 Efetivo, 11 Card).

## Formato do relatório

Arquivo markdown enxuto salvo em
`docs/superpowers/relatorios/2026-07-15-teste-visual-telas-principais.md`.

Estrutura:

1. **Cabeçalho** — data, ambiente, versão/commit, contagem ✅/❌.
2. **Uma seção por tela** com tabela: `# | Cenário | Entrada | Esperado | Obtido | ✅/❌`.
   Em ❌, uma coluna/linha com o caminho do screenshot.
3. **Seção final "Problemas a resolver"** — lista só os ❌, priorizados, cada um com:
   cenário, o que se esperava, o que aconteceu, e link do screenshot.

Screenshots das falhas em
`docs/superpowers/relatorios/assets/2026-07-15/<cenario-id>.png`.

## Dados e efeitos colaterais

O passe cria registros reais no banco de dev (profissionais `QA - ...`, lançamentos de
efetivo, itens de card) e **não os remove** (decisão do brainstorming). Nomes de teste
recebem prefixo identificável para facilitar limpeza manual futura, se desejada. CPFs de
teste usam valores fictícios distintos do admin, exceto no cenário P6 (que precisa do
CPF duplicado de propósito).

## Limitações conhecidas

- **PDF do card** (`actionPdf`) não faz parte do escopo — foco nas três telas de entrada.
- Cenários que dependem de **estado pré-existente** (ex.: C11 exige cards com nota>0 sem
  NF; E11 exige alguém com ponto aberto) são preparados pelo próprio harness antes da
  asserção, criando o estado necessário via a UI.
- O passe reflete o estado do app **no momento da execução**; não é reexecutado em CI.

## Fora de escopo

- Automatizar como suíte Codeception permanente.
- Telas fora das três alvo (Função, Obra, Relatórios, Dashboard, Controle de Efetivo).
- Testes de performance, carga ou segurança.
