diff --git a/apps/desktop/e2e/boot-failure.spec.ts b/apps/desktop/e2e/boot-failure.spec.ts index 7862bc3bf93..295804f7759 100644 --- a/apps/desktop/e2e/boot-failure.spec.ts +++ b/apps/desktop/e2e/boot-failure.spec.ts @@ -9,7 +9,7 @@ * Prerequisite: `npm run build` must have been run so dist/ exists. */ -import { test } from './test' +import { allowErrorBanners, test } from './test' import { type DeadBackendFixture, @@ -26,6 +26,12 @@ test.afterAll(async () => { }) test.describe('boot failure with dead backend', () => { + test.beforeEach(() => { + // These tests deliberately trigger boot errors — error banners + // (notifyError → [role="alert"]) are expected, not failures. + allowErrorBanners() + }) + test('app shows error state', async () => { // Inject a fake boot error so the backend resolution "fails" with a // controlled error message. This is the only reliable way to trigger diff --git a/apps/desktop/e2e/large-session-reload.spec.ts b/apps/desktop/e2e/large-session-reload.spec.ts index 89243f4003d..f01c744b17b 100644 --- a/apps/desktop/e2e/large-session-reload.spec.ts +++ b/apps/desktop/e2e/large-session-reload.spec.ts @@ -337,11 +337,15 @@ test.describe('loading a large previous session', () => { expect(results, 'render count data should have been collected').not.toBeNull() if (results) { + // After the fix, the transcript should paint exactly once (1 burst). + // Before the fix, it painted 2-3 times (the "re-renders a few times + // as it loads" bug). This assertion proves the fix works — if it + // ever regresses to >= 2, the test will fail. expect( results.bursts, - `expected >= 2 mutation bursts (multiple re-renders during load), ` + + `expected exactly 1 mutation burst (single paint after fix), ` + `got ${results.bursts}: ${JSON.stringify(results.timeline)}`, - ).toBeGreaterThanOrEqual(2) + ).toBe(1) } }) }) diff --git a/apps/desktop/e2e/test.ts b/apps/desktop/e2e/test.ts index 4ed4121d3e2..659e641c11d 100644 --- a/apps/desktop/e2e/test.ts +++ b/apps/desktop/e2e/test.ts @@ -18,6 +18,18 @@ import { test as base, expect, type Page, type ElectronApplication, _electron } // Track error messages per test so afterEach can assert + report. const seenErrors: string[] = [] let activePage: Page | null = null +// When true, the afterEach guard skips the error-banner check. +// Set by tests that deliberately trigger error states (e.g. boot-failure). +let errorBannersAllowed = false + +/** + * Opt out of the error-banner guard for the current test. Call in + * test.beforeEach or at the top of a test body when error banners are + * expected (e.g. boot-failure tests that deliberately trigger errors). + */ +export function allowErrorBanners(): void { + errorBannersAllowed = true +} /** * Install the error-banner guard on a page. Watches for `[role="alert"]` @@ -125,6 +137,16 @@ export const test = base.extend({ // default `page` fixture — Electron tests create their own page via // app.firstWindow(), so the default `page` fixture is undefined. base.afterEach(async ({}, testInfo) => { + const wasAllowed = errorBannersAllowed + // Reset for the next test. + errorBannersAllowed = false + + if (wasAllowed) { + // Test opted out — clear any collected errors without asserting. + seenErrors.length = 0 + return + } + const errors = await collectErrorBanners(activePage) if (errors.length > 0) {