fix(e2e): detect update hand-off via marker file, not Playwright close event
Attempt 8 drove the ENTIRE GUI update click-path successfully: onboarding dismissed, Settings opened, About opened, Update now clicked, updating overlay shown. The hand-off log proves the real update then ran: desktop (pid 8880) exited, venv unlocked, 'hermes update --yes --gateway --force --branch main' fetched from serve.git, found 1 new commit, pulled, and restored. Everything worked. The only failure was the driver waiting on Playwright's app 'close' event, which doesn't fire reliably when the Electron app self-quits for the hand-off. Switch to the authoritative signal: poll for the HERMES_HOME/.hermes-update-in-progress marker (or the result JSON, or a genuine window-gone), which the hand-off writes ~4s after the click. The PowerShell driver still owns asserting the OUTCOME (target sha, marker cleanup, working hermes, relaunched app) after the driver returns.
This commit is contained in:
@@ -201,20 +201,64 @@ async function main() {
|
||||
await page.waitForTimeout(1200)
|
||||
await shot(page, '05-updating-overlay')
|
||||
|
||||
// ── Wait for the app to quit for the hand-off ─────────────────────────
|
||||
await new Promise((resolve, reject) => {
|
||||
const t = setTimeout(
|
||||
() => reject(new Error('app did not quit within 120s of Update now — hand-off did not start')),
|
||||
120_000
|
||||
)
|
||||
// ── Wait for the hand-off to take over ────────────────────────────────
|
||||
// Clicking Update now spawns the detached updater (desktop-update.ps1 or
|
||||
// the staged binary), which claims HERMES_HOME/.hermes-update-in-progress
|
||||
// and then the desktop quits. We do NOT rely on Playwright's app 'close'
|
||||
// event: when the app self-quits for the hand-off that event is
|
||||
// unreliable (attempt 8 timed out on it even though the hand-off log
|
||||
// proved the desktop had exited and `hermes update` was already running).
|
||||
//
|
||||
// The authoritative "hand-off started" signal is the marker file (or the
|
||||
// result JSON, if the whole update finished fast). Poll for either, and
|
||||
// also accept a genuine app close. Any one is success — the PowerShell
|
||||
// driver owns asserting the update's OUTCOME (sha, marker cleanup,
|
||||
// relaunch) after we return.
|
||||
const hermesHome = process.env.HERMES_HOME
|
||||
const markerPath = hermesHome ? path.join(hermesHome, '.hermes-update-in-progress') : null
|
||||
const resultPath = hermesHome ? path.join(hermesHome, '.hermes-update-result.json') : null
|
||||
|
||||
app.on('close', () => {
|
||||
clearTimeout(t)
|
||||
resolve()
|
||||
})
|
||||
let appClosed = false
|
||||
app.on('close', () => {
|
||||
appClosed = true
|
||||
})
|
||||
|
||||
log('app quit for updater hand-off — success, the detached updater owns the rest')
|
||||
const handoffDeadline = Date.now() + 150_000
|
||||
let handoffStarted = false
|
||||
|
||||
while (Date.now() < handoffDeadline) {
|
||||
if (markerPath && fs.existsSync(markerPath)) {
|
||||
log('hand-off marker present — updater has taken over')
|
||||
handoffStarted = true
|
||||
break
|
||||
}
|
||||
if (resultPath && fs.existsSync(resultPath)) {
|
||||
log('update result JSON already present — updater finished fast')
|
||||
handoffStarted = true
|
||||
break
|
||||
}
|
||||
if (appClosed) {
|
||||
log('app closed — hand-off in progress')
|
||||
handoffStarted = true
|
||||
break
|
||||
}
|
||||
// Secondary: if the renderer window is gone, evaluate throws.
|
||||
try {
|
||||
await page.evaluate(() => true)
|
||||
} catch {
|
||||
log('renderer window gone — app quit for hand-off')
|
||||
handoffStarted = true
|
||||
break
|
||||
}
|
||||
await new Promise(r => setTimeout(r, 2000))
|
||||
}
|
||||
|
||||
if (!handoffStarted) {
|
||||
await shot(page, 'ERROR-no-handoff')
|
||||
throw new Error('no hand-off within 150s of Update now (no marker, no result, app still alive)')
|
||||
}
|
||||
|
||||
log('hand-off confirmed — detached updater owns the rest')
|
||||
}
|
||||
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user