diff --git a/web/e2e/document-revision-runtime.spec.ts b/web/e2e/document-revision-runtime.spec.ts index 30310f6d..b0ad0562 100644 --- a/web/e2e/document-revision-runtime.spec.ts +++ b/web/e2e/document-revision-runtime.spec.ts @@ -23,6 +23,11 @@ import { currentProjectBannerName, visibleProjectEntry, } from '../src/lib/currentProjectRestore'; +import { + SHARED_PHASE_SECRETS_FILE, + SHARED_PHASE_STATE_FILE, + playwrightResultsFileName, +} from '../src/lib/playwrightPhaseArtifacts'; /** * Document revision runtime — real UI acceptance (UI-01..UI-16). @@ -45,10 +50,10 @@ const ASSETS = path.resolve( const SCREENSHOTS = path.join(ASSETS, 'screenshots'); const TRACES = path.join(ASSETS, 'traces'); const VIDEOS = path.join(ASSETS, 'videos'); -const RESULTS_FILE = path.join(ASSETS, 'ui-acceptance-results.json'); -const PHASE_STATE_FILE = path.join(ASSETS, 'phase-state.json'); +const RESULTS_FILE = path.join(ASSETS, playwrightResultsFileName(uiPhase)); +const PHASE_STATE_FILE = path.join(ASSETS, SHARED_PHASE_STATE_FILE); /** Local-only secrets for post-restart login — never copied into results JSON. */ -const PHASE_SECRETS_FILE = path.join(ASSETS, 'phase-secrets.local.json'); +const PHASE_SECRETS_FILE = path.join(ASSETS, SHARED_PHASE_SECRETS_FILE); for (const d of [SCREENSHOTS, TRACES, VIDEOS]) { fs.mkdirSync(d, { recursive: true }); diff --git a/web/src/lib/playwrightPhaseArtifacts.test.ts b/web/src/lib/playwrightPhaseArtifacts.test.ts index d92bc377..6e70d289 100644 --- a/web/src/lib/playwrightPhaseArtifacts.test.ts +++ b/web/src/lib/playwrightPhaseArtifacts.test.ts @@ -1,6 +1,14 @@ import { describe, it } from 'node:test'; import assert from 'node:assert/strict'; -import { playwrightArtifactDirNames, playwrightPhaseSlug } from './playwrightPhaseArtifacts'; +import { + MAIN_RESULTS_FILE, + POST_RESTART_RESULTS_FILE, + SHARED_PHASE_SECRETS_FILE, + SHARED_PHASE_STATE_FILE, + playwrightArtifactDirNames, + playwrightPhaseSlug, + playwrightResultsFileName, +} from './playwrightPhaseArtifacts'; describe('playwrightPhaseArtifacts', () => { it('defaults unknown or empty UI_PHASE to main', () => { @@ -19,4 +27,21 @@ describe('playwrightPhaseArtifacts', () => { assert.notEqual(main.outputDirName, restart.outputDirName); assert.notEqual(main.reportDirName, restart.reportDirName); }); + + it('keeps main results at the historical filename and isolates post-restart recordPass', () => { + assert.equal(playwrightResultsFileName('main'), MAIN_RESULTS_FILE); + assert.equal(playwrightResultsFileName(undefined), 'ui-acceptance-results.json'); + assert.equal(playwrightResultsFileName('post-restart'), POST_RESTART_RESULTS_FILE); + assert.equal(playwrightArtifactDirNames('main').resultsFileName, 'ui-acceptance-results.json'); + assert.equal( + playwrightArtifactDirNames('post-restart').resultsFileName, + 'ui-acceptance-results-post-restart.json', + ); + assert.notEqual(playwrightResultsFileName('main'), playwrightResultsFileName('post-restart')); + }); + + it('shares phase-state and secrets across phases', () => { + assert.equal(SHARED_PHASE_STATE_FILE, 'phase-state.json'); + assert.equal(SHARED_PHASE_SECRETS_FILE, 'phase-secrets.local.json'); + }); }); diff --git a/web/src/lib/playwrightPhaseArtifacts.ts b/web/src/lib/playwrightPhaseArtifacts.ts index 7a2f4660..a60ad323 100644 --- a/web/src/lib/playwrightPhaseArtifacts.ts +++ b/web/src/lib/playwrightPhaseArtifacts.ts @@ -1,18 +1,32 @@ export type PlaywrightUiPhase = 'main' | 'post-restart'; +/** Shared across phases so post-restart can resume the main project/login. */ +export const SHARED_PHASE_STATE_FILE = 'phase-state.json'; +export const SHARED_PHASE_SECRETS_FILE = 'phase-secrets.local.json'; + +/** Main keeps the historical ledger name so existing evidence/docs stay valid. */ +export const MAIN_RESULTS_FILE = 'ui-acceptance-results.json'; +export const POST_RESTART_RESULTS_FILE = 'ui-acceptance-results-post-restart.json'; + export function playwrightPhaseSlug(uiPhase?: string): PlaywrightUiPhase { return uiPhase?.trim() === 'post-restart' ? 'post-restart' : 'main'; } +export function playwrightResultsFileName(uiPhase?: string): string { + return playwrightPhaseSlug(uiPhase) === 'post-restart' ? POST_RESTART_RESULTS_FILE : MAIN_RESULTS_FILE; +} + export function playwrightArtifactDirNames(uiPhase?: string): { outputDirName: string; reportDirName: string; + resultsFileName: string; slug: PlaywrightUiPhase; } { const slug = playwrightPhaseSlug(uiPhase); return { outputDirName: `playwright-output-${slug}`, reportDirName: `playwright-report-${slug}`, + resultsFileName: playwrightResultsFileName(uiPhase), slug, }; }