import { EventEmitter } from 'node:events'; import { describe, expect, it, vi } from 'vitest'; import { registerMainWindowClose } from '@electron/main/main-window-close'; class WindowStub extends EventEmitter { fullscreen = false; destroyed = false; hide = vi.fn(); setFullScreen = vi.fn(); isFullScreen = () => this.fullscreen; isDestroyed = () => this.destroyed; close = vi.fn(() => { const event = { defaultPrevented: false, preventDefault() { this.defaultPrevented = true; } }; this.emit('close', event); if (!event.defaultPrevented) { this.destroyed = true; this.emit('closed'); } }); leaveFullscreen(): void { this.fullscreen = false; this.emit('leave-full-screen'); } } function setup(fullscreen = false) { const window = new WindowStub(); window.fullscreen = fullscreen; let quitting = false; registerMainWindowClose(window as never, { platform: 'darwin', isQuitting: () => quitting, hideOnClose: false, }); return { window, quit: () => { quitting = true; window.close(); } }; } describe('native main window close', () => { it('really destroys a normal macOS window instead of hiding it', () => { const { window } = setup(); window.close(); expect(window.destroyed).toBe(true); expect(window.hide).not.toHaveBeenCalled(); expect(window.setFullScreen).not.toHaveBeenCalled(); }); it('waits for the fullscreen exit before closing, including repeated clicks', () => { const { window } = setup(true); const order: string[] = []; window.prependListener('leave-full-screen', () => order.push('left fullscreen')); window.on('closed', () => order.push('closed')); window.close(); window.close(); expect(window.destroyed).toBe(false); expect(window.hide).not.toHaveBeenCalled(); expect(window.setFullScreen).toHaveBeenCalledExactlyOnceWith(false); window.leaveFullscreen(); expect(window.destroyed).toBe(true); expect(order).toEqual(['left fullscreen', 'closed']); }); it('does not delay a real app quit while fullscreen exit is pending', () => { const { window, quit } = setup(true); window.close(); quit(); expect(window.destroyed).toBe(true); window.leaveFullscreen(); expect(window.close).toHaveBeenCalledTimes(2); }); it('lets Cmd+Q close a fullscreen window without starting another transition', () => { const { window, quit } = setup(true); quit(); expect(window.destroyed).toBe(true); expect(window.setFullScreen).not.toHaveBeenCalled(); }); it('cancels deferred closing if the window was destroyed externally', () => { const { window } = setup(true); window.close(); window.destroyed = true; window.emit('closed'); window.leaveFullscreen(); expect(window.close).toHaveBeenCalledTimes(1); }); it('preserves existing close-to-tray behavior on other platforms', () => { const window = new WindowStub(); registerMainWindowClose(window as never, { platform: 'win32', isQuitting: () => false, hideOnClose: true, }); window.close(); expect(window.destroyed).toBe(false); expect(window.hide).toHaveBeenCalledOnce(); }); });