fix(desktop): let automated teardown quit past the active-work prompt

Playwright closes the app with a turn still in flight, so the new quit
confirmation waited on a click nobody was there to make and the E2E
worker died on a 90s teardown timeout.
This commit is contained in:
Brooklyn Nicholson 2026-07-27 16:19:27 -05:00
parent c7ef4c192d
commit 579b66336f
2 changed files with 9 additions and 1 deletions

View file

@ -230,6 +230,10 @@ export function buildAppEnv(sandbox: Sandbox, extra: Record<string, string> = {}
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.

View file

@ -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
}