// @vitest-environment happy-dom import { describe, it, expect, vi, beforeEach } from 'vitest'; vi.mock('../public/modules/ws.js', () => ({ send: vi.fn(() => true) })); import { agents, activeSessionId, setActiveSession, setBoardActive } from '../public/modules/state.js'; import { handleSessionCreated, handleSessionEnded, handleSessionRemoved } from '../public/modules/terminal.js'; // A new tab takes focus only in the window the server marked `focus` (the one // that spawned or re-adopted it), or in a window showing no tab at all. describe('session-created focus', () => { beforeEach(() => { window.Terminal = class { open() {} loadAddon() {} attachCustomKeyEventHandler() {} onData() {} scrollToBottom() {} focus() {} dispose() {} }; document.body.innerHTML = '
' + '' + ''; agents.clear(); setActiveSession(null); setBoardActive(false); }); const created = (sessionId, extra = {}) => handleSessionCreated({ type: 'session-created', sessionId, name: sessionId, state: 'IDLE', ...extra }); it('a window with no active tab switches to the new one', async () => { await created('s1'); expect(activeSessionId).toBe('s1'); }); it('someone else\'s spawn opens quietly beside the active tab', async () => { await created('s1'); await created('s2'); expect(activeSessionId).toBe('s1'); expect(agents.has('s2')).toBe(true); }); it('someone else\'s spawn leaves an open job board alone', async () => { setBoardActive(true); await created('s1'); expect(activeSessionId).toBe(null); }); it('the spawning window (focus) switches even with a tab already active', async () => { await created('s1'); await created('s2', { focus: true }); expect(activeSessionId).toBe('s2'); }); }); describe('session-removed', () => { beforeEach(() => { window.Terminal = class { open() {} loadAddon() {} attachCustomKeyEventHandler() {} onData() {} scrollToBottom() {} focus() {} dispose() {} }; document.body.innerHTML = '' + '' + ''; agents.clear(); setActiveSession(null); setBoardActive(false); }); it('drops the tab; a crash keeps it; removal after dispose is harmless', async () => { await handleSessionCreated({ type: 'session-created', sessionId: 's1', name: 's1', state: 'IDLE' }); await handleSessionCreated({ type: 'session-created', sessionId: 's2', name: 's2', state: 'IDLE' }); handleSessionEnded({ type: 'session-ended', sessionId: 's1' }); expect(agents.get('s1').state).toBe('DISCONNECTED'); handleSessionRemoved({ type: 'session-removed', sessionId: 's2' }); expect(agents.has('s2')).toBe(false); handleSessionRemoved({ type: 'session-removed', sessionId: 's2' }); expect(agents.has('s1')).toBe(true); }); });