diff --git a/tests-js/install-process-close.test.ts b/tests-js/install-process-close.test.ts index 2134b810b8..ce8b83c9b9 100644 --- a/tests-js/install-process-close.test.ts +++ b/tests-js/install-process-close.test.ts @@ -6,11 +6,14 @@ import { expect, it, vi } from 'vitest' const { observeProcessClose } = createRequire(import.meta.url)('../tests/install/e2e-assets/process-close.cjs') it('waits for native close, not exit, and retains a close observed before hand-off', async () => { - const child = new EventEmitter() + const pipe = { destroy: vi.fn() } + const child = Object.assign(new EventEmitter(), { stdio: [null, pipe], exitCode: null, signalCode: null }) const waitForClose = observeProcessClose(child) + expect(pipe.destroy).not.toHaveBeenCalled() let finished = false const completion = waitForClose().then(() => { finished = true }) child.emit('exit', 0) + expect(pipe.destroy).toHaveBeenCalledOnce() await Promise.resolve() expect(finished).toBe(false) child.emit('close', 0) @@ -22,7 +25,7 @@ it('waits for native close, not exit, and retains a close observed before hand-o it('fails if the launched process never closes', async () => { vi.useFakeTimers() try { - const waitForClose = observeProcessClose(new EventEmitter()) + const waitForClose = observeProcessClose(Object.assign(new EventEmitter(), { stdio: [], exitCode: null, signalCode: null })) const completion = expect(waitForClose(2_000)).rejects.toThrow('Electron process did not close') await vi.advanceTimersByTimeAsync(2_000) await completion diff --git a/tests/install/e2e-assets/process-close.cjs b/tests/install/e2e-assets/process-close.cjs index 6ee30767c7..e0aca5ae5a 100644 --- a/tests/install/e2e-assets/process-close.cjs +++ b/tests/install/e2e-assets/process-close.cjs @@ -6,6 +6,13 @@ function observeProcessClose(child) { closed = true resolve() })) + // Windows descendants can inherit pipe handles and postpone 'close' after + // the launch process exits. Release our handles, never kill descendants. + const releasePipes = () => { + for (const stream of child.stdio) stream?.destroy() + } + child.once('exit', releasePipes) + if (child.exitCode !== null || child.signalCode !== null) releasePipes() return async function waitForClose(timeoutMs = 120_000) { if (closed) return let timer