diff --git a/apps/desktop/e2e/fixtures.ts b/apps/desktop/e2e/fixtures.ts index 1dabc674d04..3427d42c9bf 100644 --- a/apps/desktop/e2e/fixtures.ts +++ b/apps/desktop/e2e/fixtures.ts @@ -230,6 +230,10 @@ export function buildAppEnv(sandbox: Sandbox, extra: Record = {} HERMES_DESKTOP_IGNORE_EXISTING: '1', HERMES_DESKTOP_HERMES_ROOT: REPO_ROOT, HERMES_DESKTOP_APP_NAME: `HermesE2E-${Date.now()}`, + // `app.close()` in teardown must exit even when a spec leaves a turn + // mid-flight — otherwise the quit confirmation waits on a click that no + // one is there to make, and the worker dies on a teardown timeout. + HERMES_DESKTOP_SKIP_QUIT_CONFIRM: '1', // Clear dev-server override — we want the built dist/, not a vite server. // The dev-server check in main.ts looks for this env var; if it's set, // it loads from the vite URL instead of the local file. diff --git a/apps/desktop/electron/main.ts b/apps/desktop/electron/main.ts index 78157a3af79..7ac24c57f8e 100644 --- a/apps/desktop/electron/main.ts +++ b/apps/desktop/electron/main.ts @@ -608,6 +608,10 @@ const DESKTOP_LOG_DISCARD_BYTES = DESKTOP_LOG_MAX_BYTES * 4 const desktopLogBackupPath = n => `${DESKTOP_LOG_PATH}.${n}` const BOOT_FAKE_MODE = process.env.HERMES_DESKTOP_BOOT_FAKE === '1' const BOOT_FAKE_ERROR = process.env.HERMES_DESKTOP_BOOT_FAKE_ERROR || '' +// Automated teardown (Playwright's app.close(), harness scripts) quits with +// nobody to answer a modal, so the active-work confirmation would hang the +// caller instead of letting the process exit. Force quits set this. +const SKIP_QUIT_CONFIRM = process.env.HERMES_DESKTOP_SKIP_QUIT_CONFIRM === '1' const BOOT_FAKE_STEP_MS = (() => { const raw = Number.parseInt(String(process.env.HERMES_DESKTOP_BOOT_FAKE_STEP_MS || ''), 10) @@ -11424,7 +11428,7 @@ function configureSpellChecker() { // and the confirmation is on screen; "Quit Anyway" re-enters before-quit with // the latch set and falls straight through to the teardown below. function heldQuitForActiveWork(event: Electron.Event): boolean { - if (quitConfirmedWithActiveWork || quitPromptOpen) { + if (SKIP_QUIT_CONFIRM || quitConfirmedWithActiveWork || quitPromptOpen) { return false }