From 7ca0efc95c422893a3a08a9afb343d49870063e3 Mon Sep 17 00:00:00 2001 From: Francisco Solla Date: Sun, 16 Aug 2026 01:25:06 -0300 Subject: [PATCH] fix(ci): isola bundle e2e do servidor de desenvolvimento --- .gitignore | 1 + playwright.config.ts | 9 +++------ scripts/gate-ci.mjs | 4 ++-- scripts/run-e2e-affected.mjs | 4 ++-- tests/unit/ciSkipInvariants.unit.spec.ts | 13 +++++++++++++ tsconfig.json | 2 +- 6 files changed, 22 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index ef5f47b8..b3555f34 100644 --- a/.gitignore +++ b/.gitignore @@ -21,6 +21,7 @@ # next.js /.next/ +/.next-e2e/ /out/ # production diff --git a/playwright.config.ts b/playwright.config.ts index de3e1d94..92bfa52c 100644 --- a/playwright.config.ts +++ b/playwright.config.ts @@ -154,12 +154,9 @@ export default defineConfig({ * e2e states stay deterministic (see `googleCalendarTestKey.ts`). */ [GOOGLE_CALENDAR_SERVICE_ACCOUNT_KEY_ENV_NAME]: GOOGLE_CALENDAR_TEST_KEY, - // Fixed dist dir: Next dev appends `/types/**/*.ts` to - // tsconfig.json's include with an EXACT-string check, so per-process - // names polluted tsconfig with one entry per run. A prior Playwright - // process tearing down late can, rarely, delete files of the next run's - // server — if a boot flakes, rerun (dev-only trade-off). - NEXT_DIST_DIR: '.next/e2e', + // Keep e2e artifacts outside `.next`: a concurrent development server + // owns that entire directory and may clear nested production bundles. + NEXT_DIST_DIR: process.env.NEXT_DIST_DIR ?? '.next-e2e', PAYLOAD_SECRET: process.env.PAYLOAD_SECRET ?? 'test-only-secret-not-used-in-production', NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL ?? baseURL, }, diff --git a/scripts/gate-ci.mjs b/scripts/gate-ci.mjs index 2c8972a8..4d8e34f9 100644 --- a/scripts/gate-ci.mjs +++ b/scripts/gate-ci.mjs @@ -149,9 +149,9 @@ const main = async () => { run('playwright install chromium', 'pnpm', ['exec', 'playwright', 'install', 'chromium']) run('e2e migrate', 'pnpm', ['migrate'], dbEnv) run('e2e seed:minimal', 'pnpm', ['db:seed:minimal'], dbEnv) - run('e2e build', 'pnpm', ['build'], { ...dbEnv, NEXT_DIST_DIR: '.next/e2e' }) + run('e2e build', 'pnpm', ['build'], { ...dbEnv, NEXT_DIST_DIR: '.next-e2e' }) - const e2eEnv = { ...dbEnv, E2E_PROD: '1', CI: '1', NEXT_DIST_DIR: '.next/e2e' } + const e2eEnv = { ...dbEnv, E2E_PROD: '1', CI: '1', NEXT_DIST_DIR: '.next-e2e' } if (scope.e2e.mode === 'full') { run('test:e2e (full)', 'pnpm', ['test:e2e'], e2eEnv) } else { diff --git a/scripts/run-e2e-affected.mjs b/scripts/run-e2e-affected.mjs index 1df1c734..f7297ea5 100644 --- a/scripts/run-e2e-affected.mjs +++ b/scripts/run-e2e-affected.mjs @@ -3,7 +3,7 @@ * run-e2e-affected — local mirror of the CI (PR) e2e job: * 1. `e2e-affected.mjs` picks full vs manifest-selected vs skip (same base ref). * 2. migrate + db:seed:minimal when anything would run. - * 3. optional production build into `.next/e2e` when `E2E_PROD=1`. + * 3. optional production build into `.next-e2e` when `E2E_PROD=1`. * 4. `pnpm test:e2e` (set `CI=1` and `E2E_PROD=1` together for prod mode). * * Extra Playwright args after `--` are forwarded (e.g. a single spec while debugging). @@ -48,7 +48,7 @@ const run = (command, args, env = {}) => { run('pnpm', ['migrate']) run('pnpm', ['db:seed:minimal']) if (process.env.E2E_PROD === '1') { - run('pnpm', ['build'], { NEXT_DIST_DIR: '.next/e2e' }) + run('pnpm', ['build'], { NEXT_DIST_DIR: '.next-e2e' }) } const playwrightArgs = ['test:e2e'] diff --git a/tests/unit/ciSkipInvariants.unit.spec.ts b/tests/unit/ciSkipInvariants.unit.spec.ts index 8c150518..d82c14d0 100644 --- a/tests/unit/ciSkipInvariants.unit.spec.ts +++ b/tests/unit/ciSkipInvariants.unit.spec.ts @@ -75,6 +75,19 @@ describe('ciSkipInvariants', () => { expect(CANONICAL_E2E_SPEC_SUFFIX).toBe('.e2e.spec.ts') }) + it('keeps local e2e build artifacts outside the development dist directory', () => { + for (const file of [ + 'playwright.config.ts', + 'scripts/gate-ci.mjs', + 'scripts/run-e2e-affected.mjs', + 'tsconfig.json', + ]) { + const source = readFileSync(join(repoRoot, file), 'utf8') + expect(source, file).not.toContain('.next/e2e') + expect(source, file).toContain('.next-e2e') + } + }) + it('skip classifiers and invariant specs are high-risk (force full suite)', () => { for (const path of [ 'scripts/lib/test-affected-core.mjs', diff --git a/tsconfig.json b/tsconfig.json index d65296d2..c733c52b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -30,7 +30,7 @@ "next-env.d.ts", ".next/types/**/*.ts", ".next/dev/types/**/*.ts", - ".next/e2e/types/**/*.ts" + ".next-e2e/types/**/*.ts" ], "exclude": ["node_modules"] }