From 2fec6a407efa61526d2ea298bcf5de041372e6c2 Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Tue, 11 Aug 2026 13:14:24 -0300 Subject: [PATCH 1/3] test(OPS39): prewarm POST /campanha/home-search e GET /campanha/acoes/mudar-tendencia no setup e2e (Closes #645) --- ...-rotas-home-search-mudar-tendencia-impl.md | 71 +++++++++++++++++++ tests/e2e/setup.e2e.spec.ts | 2 + 2 files changed, 73 insertions(+) create mode 100644 docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md diff --git a/docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md b/docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md new file mode 100644 index 00000000..ea9886f2 --- /dev/null +++ b/docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md @@ -0,0 +1,71 @@ +# Impl: Prewarm e2e: adicionar /campanha/home-search (POST) e /campanha/acoes/mudar-tendencia (GET) ao setup spec + +Status: aprovado +Atualizado em: 2026-08-11 +Issue: #645 +Intenção: docs/plans/prewarm-rotas-home-search-mudar-tendencia.md +Appetite restante: ~1 hora eng (herdado) + +## Leitura da intenção + +- **Outcome:** o `setup.e2e.spec.ts` preaquece as duas rotas que ficaram de fora, + para o 1º hit em dev não compilar no meio de um journey (B48/B97 flakearam 2/2 + sob load ≥40 na sessão OPS36). +- **O que NÃO negociar:** setup continua em dev-mode-only, sem mudança de + asserções ou de CI; POST sem auth com `.catch(() => undefined)` — padrão das + entradas existentes. +- **O que reavaliar:** nada material — as rotas existem e o padrão do setup é + uniforme. + +## Abordagem recomendada + +```mermaid +flowchart LR + A[setup.e2e.spec.ts] --> B[GET /campanha/acoes/mudar-tendencia] + A --> C[POST /campanha/home-search] +``` + +**Opções consideradas:** A — duas linhas nas listas existentes | B — subir um +webServer `waitOn` prewarm +**Recomendação:** A — o setup spec já é o dono do prewarm dev; a intenção diz +"seguindo o padrão das entradas existentes". Custo ~2 linhas, zero risco. +**Rejeitadas:** B — duplica o mecanismo, fora do appetite. + +### Componentes / mudanças + +- **`tests/e2e/setup.e2e.spec.ts`**: na lista de GETs, adicionar + `/campanha/acoes/mudar-tendencia` ao lado de `/campanha/acoes/atualizar-votos` + (mesma família de wizard; GET anônimo → 307 para `/campanha/login`, seguido + pelo client → `response.ok()` true — mesmo contrato das entradas vizinhas). + Na lista de POSTs, adicionar `/campanha/home-search` (route handler em + `src/app/(campaign)/campanha/(app)/home-search/route.ts`; POST anônimo falha, + `.catch(() => undefined)` absorve — compila o handler, que é o objetivo). +- **Migration:** sem migration. +- **Access / Consent:** sem mudança — as rotas não são tocadas. + +## Fases verificáveis + +1. **Setup spec** — 2 linhas; gate rápido local. +2. **Gates** — `pnpm gate:fast` (ou lint/tsc); e2e direcionado: rodar o projeto + `setup` + B48 (`campaignMunicipalities` home-search) e B97 + (`campaignHomeActions` mudar-tendencia) em dev a load ≥40, primeiro hit verde. + +## Rabbit holes / Não escopo (engenharia) + +- Hardening geral do prewarm em dev é dono da OPS30 (#586) — não reabrir aqui. +- Flakes de render sob carga em geral (B24, B176, demand) — fora. + +## Riscos e mitigação + +- GET `mudar-tendencia` sem auth poderia não compilar o bundle da página se o + redirect pular o render: mitigação — o GET segue o redirect (login), mas o + compile da rota `[slug]` acontece no primeiro match de rota, independente do + redirect; mesma família que `atualizar-votos` já prewarms com sucesso. +- Medição sob load ≥40 é cara: mitigação — verificação local direcionada + (workers ≥2, setup primeiro), sem CI novo. + +## Aceite de engenharia + +- [x] Aceite de produto da intenção ainda coberto +- [x] Invariantes AGENTS/engineering-standards (nenhum código runtime tocado) +- [x] Testes de domínio previstos (unit/int): não se aplica — mudança só em spec e2e diff --git a/tests/e2e/setup.e2e.spec.ts b/tests/e2e/setup.e2e.spec.ts index c6f7f52d..0b09eeb0 100644 --- a/tests/e2e/setup.e2e.spec.ts +++ b/tests/e2e/setup.e2e.spec.ts @@ -17,6 +17,7 @@ test('prewarms shared Next route bundles sequentially', async ({ request }) => { '/campanha/liderancas', '/campanha/conceitos', '/campanha/acoes/atualizar-votos', + '/campanha/acoes/mudar-tendencia', '/campanha/convite/e2e-prewarm', '/', ]) { @@ -42,6 +43,7 @@ test('prewarms shared Next route bundles sequentially', async ({ request }) => { '/campanha/webauthn/login', '/campanha/webauthn/register-options', '/campanha/webauthn/register', + '/campanha/home-search', ]) { await request.post(`${baseURL}${path}`, { data: {} }).catch(() => undefined) } From 21b4b4d0c630e179e1eac6434b943c0fc52ab804 Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Tue, 11 Aug 2026 15:23:50 -0300 Subject: [PATCH 2/3] =?UTF-8?q?fix(gate):=20sele=C3=A7=C3=A3o=20e2e=20cont?= =?UTF-8?q?endo=20apenas=20o=20spec=20setup=20vira=20none=20(setup=20?= =?UTF-8?q?=C3=A9=20dev-only;=20OPS39)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...arm-rotas-home-search-mudar-tendencia-impl.md | 14 +++++++++++++- scripts/lib/test-affected-core.mjs | 14 ++++++++++++++ tests/unit/testAffected.unit.spec.ts | 16 ++++++++++++++++ 3 files changed, 43 insertions(+), 1 deletion(-) diff --git a/docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md b/docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md index ea9886f2..432f5e40 100644 --- a/docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md +++ b/docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md @@ -64,8 +64,20 @@ webServer `waitOn` prewarm - Medição sob load ≥40 é cara: mitigação — verificação local direcionada (workers ≥2, setup primeiro), sem CI novo. +## Desvio da intenção (aprovado 2026-08-11) + +A intenção dizia "sem mudança de asserções ou de CI", mas o gate:ci falhou com +"No tests found" — **falha pré-existente do classificador** (OPS39 é a primeira +PR setup-only): o `setup` só existe em dev mode (projeto dropado sob `CI=1`, +playwright.config.ts OPS34), e `selectE2eSpecs` o selecionava sozinho para o +e2e prod-mode. Fix no dono (`scripts/lib/test-affected-core.mjs`): seleção +contendo **apenas** `setup` → `mode: 'none'` (spec dev-only; sets mistos seguem +inalterados — o spec simplesmente não casa projeto). 2 testes de unidade novos +em `tests/unit/testAffected.unit.spec.ts`. + ## Aceite de engenharia - [x] Aceite de produto da intenção ainda coberto - [x] Invariantes AGENTS/engineering-standards (nenhum código runtime tocado) -- [x] Testes de domínio previstos (unit/int): não se aplica — mudança só em spec e2e +- [x] Testes de domínio previstos (unit/int): 2 unit novos no classificador + (`testAffected.unit.spec.ts`); runtime intocado diff --git a/scripts/lib/test-affected-core.mjs b/scripts/lib/test-affected-core.mjs index de841b63..c02383a3 100644 --- a/scripts/lib/test-affected-core.mjs +++ b/scripts/lib/test-affected-core.mjs @@ -232,6 +232,20 @@ export function selectE2eSpecs(files, manifest) { unmapped, } } + // The `setup` spec is dev-mode-only: the setup project is dropped under + // CI/prod (playwright.config.ts), so a selection containing ONLY it would + // run `playwright test -- tests/e2e/setup.e2e.spec.ts` against zero projects + // and fail with "No tests found" (OPS39 — first setup-only PR hit it). In a + // mixed set the spec is harmless (it just matches no project), so only the + // setup-only case drops out. + if (specs.size === 1 && specs.has('setup')) { + return { + mode: 'none', + specs: [], + reason: 'setup spec is dev-mode-only; prod-mode e2e cannot run it', + unmapped, + } + } return { mode: 'selected', specs: [...specs].sort(), diff --git a/tests/unit/testAffected.unit.spec.ts b/tests/unit/testAffected.unit.spec.ts index 4a899969..b5a88abb 100644 --- a/tests/unit/testAffected.unit.spec.ts +++ b/tests/unit/testAffected.unit.spec.ts @@ -136,6 +136,22 @@ describe('selectE2eSpecs (OPS5)', () => { const result = selectE2eSpecs([changed('docs/AGENT-OPS.md')], manifest) expect(result).toMatchObject({ mode: 'none', specs: [], unmapped: [] }) }) + + it('drops a setup-only selection (setup runs only in dev mode, OPS39)', () => { + const result = selectE2eSpecs([changed('tests/e2e/setup.e2e.spec.ts')], manifest) + expect(result).toMatchObject({ mode: 'none', specs: [], unmapped: [] }) + expect(result.reason).toContain('dev-mode-only') + }) + + it('keeps setup in a mixed selection (it matches no project, harmless)', () => { + const result = selectE2eSpecs( + [changed('tests/e2e/setup.e2e.spec.ts'), changed('src/app/(payload)/api/x.ts')], + manifest, + ) + expect(result.mode).toBe('selected') + expect(result.specs).toContain('setup') + expect(result.specs).toContain('admin') + }) }) describe('e2eShardConfig (OPS34)', () => { From fdca8ff9c4716f9e93aa25f1e38dc8e0cd93b2b0 Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Tue, 11 Aug 2026 15:27:23 -0300 Subject: [PATCH 3/3] format: prettier no impl plan OPS39 --- docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md b/docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md index 432f5e40..e424ae50 100644 --- a/docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md +++ b/docs/plans/prewarm-rotas-home-search-mudar-tendencia-impl.md @@ -80,4 +80,4 @@ em `tests/unit/testAffected.unit.spec.ts`. - [x] Aceite de produto da intenção ainda coberto - [x] Invariantes AGENTS/engineering-standards (nenhum código runtime tocado) - [x] Testes de domínio previstos (unit/int): 2 unit novos no classificador - (`testAffected.unit.spec.ts`); runtime intocado + (`testAffected.unit.spec.ts`); runtime intocado