diff --git a/src/main/startup/ensure-virtual-display.test.ts b/src/main/startup/ensure-virtual-display.test.ts index f66d79fefea..e22f7fb87f9 100644 --- a/src/main/startup/ensure-virtual-display.test.ts +++ b/src/main/startup/ensure-virtual-display.test.ts @@ -42,7 +42,11 @@ describe('ensureVirtualDisplayForHeadlessServe', () => { delete process.env.DISPLAY }) - afterEach(() => { + afterEach(async () => { + const { stopVirtualDisplay } = await import('./ensure-virtual-display') + process.removeListener('exit', stopVirtualDisplay) + stopVirtualDisplay() + vi.restoreAllMocks() setPlatform(ORIGINAL_PLATFORM) if (ORIGINAL_DISPLAY === undefined) { delete process.env.DISPLAY @@ -97,7 +101,9 @@ describe('ensureVirtualDisplayForHeadlessServe', () => { // First existsSync (stale-socket check) false; later (socket-ready poll) true. existsSyncMock.mockReturnValueOnce(false).mockReturnValue(true) spawnMock.mockReturnValue({ once: vi.fn(), kill: vi.fn(), killed: false }) - const { ensureVirtualDisplayForHeadlessServe } = await import('./ensure-virtual-display') + const processOnceSpy = vi.spyOn(process, 'once') + const { ensureVirtualDisplayForHeadlessServe, stopVirtualDisplay } = + await import('./ensure-virtual-display') expect(ensureVirtualDisplayForHeadlessServe({ isServeMode: true })).toBe(true) expect(spawnMock).toHaveBeenCalledWith( @@ -109,6 +115,8 @@ describe('ensureVirtualDisplayForHeadlessServe', () => { expect(appMock.disableHardwareAcceleration).toHaveBeenCalled() expect(appMock.commandLine.appendSwitch).toHaveBeenCalledWith('disable-dev-shm-usage') expect(appMock.commandLine.appendSwitch).toHaveBeenCalledWith('disable-gpu') + expect(processOnceSpy).toHaveBeenCalledWith('exit', stopVirtualDisplay) + expect(appMock.once).not.toHaveBeenCalledWith('will-quit', stopVirtualDisplay) }) it('reuses an existing virtual display only when its X server is alive', async () => { diff --git a/src/main/startup/ensure-virtual-display.ts b/src/main/startup/ensure-virtual-display.ts index a4adfed6113..6d1606687d9 100644 --- a/src/main/startup/ensure-virtual-display.ts +++ b/src/main/startup/ensure-virtual-display.ts @@ -163,8 +163,8 @@ export function ensureVirtualDisplayForHeadlessServe(options: { isServeMode: boo process.env.DISPLAY = VIRTUAL_DISPLAY - // Why: don't leave a stray Xvfb process behind when serve exits. - app.once('will-quit', stopVirtualDisplay) + // Why: Electron can cancel will-quit for async teardown and still needs X11 until its event loop stops. + process.once('exit', stopVirtualDisplay) return true }