# Plano — E2E de verificação: login real + relatório de turno > **ESTADO: IMPLEMENTADO E VERIFICADO (2026-05-30).** `pnpm test:e2e` 3/3 (happy-path + relatório) e `pnpm test:e2e:auth` 4/4 (login real, autologin OFF). A implementação destapou o problema do `AUTH_URL` per-app — corrigido de raiz via `apps/admin-web/.env.admin` (ver [auth-v0.2.md] e a secção de config no project_phase da memory). > > Autor: Opus 4.8 (sessão de design, 2026-05-30). Destinado a implementação pelo Sonnet. > Pré-requisitos: MAI CALL v0.1 + Auth v0.2 + v0.3 (relatório), todos implementados e verificados ao nível de lógica/build. Estado do código verificado contra o repo. > **Motivo:** Pedro escolheu "travar features e verificar". Três camadas de interação nunca foram exercitadas por um browser: (a) a UI do relatório, (b) o **login real** (o E2E atual usa `AUTH_DEV_AUTOLOGIN=true` e **contorna** o login), (c) offline. Este plano fecha (a) e (b) com Playwright. (c) fica para um smoke manual. ## Objetivo numa frase Acrescentar testes E2E que provem que **o relatório de turno renderiza e reage** e que o **login real funciona no browser** (operador PIN + admin password), sem depender do back door de autologin. ## Decisões fixadas (não revisitar sem motivo forte) 1. **Dois configs Playwright.** O atual ([`e2e/playwright.config.ts`](../../e2e/playwright.config.ts)) arranca ambos os servidores com `AUTH_DEV_AUTOLOGIN: 'true'` — mantém-se para os testes que não precisam de login (happy-path + **relatório**). Um **segundo config** arranca os servidores com o autologin **desligado** para os testes de **login real**. 2. **Porquê dois servidores e não um:** o autologin é decidido server-side (`resolveUser()` + `middleware.ts`). Com o flag ligado no servidor, apagar cookies no browser não chega — o middleware volta a deixar entrar. A única forma de testar o login real é um servidor com o flag desligado. 3. **Como desligar o flag no servidor de teste:** passar `AUTH_DEV_AUTOLOGIN: 'false'` em `webServer[].env`. Funciona porque o script de dev usa `dotenv -e ../../.env`, e **`dotenv` não sobrepõe variáveis já presentes** no processo — o valor do Playwright ganha. (É o mesmo mecanismo pelo qual o config atual força `'true'`.) 4. **Mesmas portas (3000/3001), `reuseExistingServer: false` no config de auth.** Consequência: **`test:e2e:auth` não pode correr com servidores já a correr nessas portas** (dá "port in use"). Documentar. Em CI corre isolado, sem problema. 5. **Não testar o lockout no E2E.** Já está coberto pelo `auth-smoke` (11/11). Testar lockout no browser exigiria 5 tentativas e deixaria `failedAttempts`/`lockedUntil` sujos por 5 min, podendo partir outros testes. O E2E de login cobre **sucesso** + **credencial errada mostra erro** (1 tentativa), e o **sucesso reseta** `failedAttempts`. 6. **Asserções tolerantes a dados acumulados.** O DB é partilhado e sequencial (`workers: 1`); o happy-path cria pedidos extra. O teste do relatório usa asserções **estruturais** (elementos existem, valores não-vazios) e **≥**, nunca números exatos — mesma postura do `report-smoke`. ## Estrutura de ficheiros (nova) ``` e2e/ playwright.config.ts (existe — autologin ON, testDir ./tests) playwright.auth.config.ts (NOVO — autologin OFF, testDir ./tests-auth, reuseExistingServer:false) tests/ mai-call.spec.ts (existe) report.spec.ts (NOVO — Passo 1) tests-auth/ login.spec.ts (NOVO — Passo 2) ``` > O config atual tem `testDir: './tests'`, por isso os specs em `./tests-auth` **não** são apanhados por ele. Sem colisão. ## Selectores confirmados (lidos do código — usar exatamente) **Operador (operator-pwa, `/select-operator`):** - Lista: `