// @vitest-environment happy-dom // Billion's tab: first, fixed, and replaced in place by a restarted Billion. import { describe, it, expect, vi, beforeEach } from 'vitest'; vi.mock('../public/modules/ws.js', () => ({ send: vi.fn(() => true) })); import { agents, activeSessionId, setActiveSession, setBoardActive, setSelf, setBillionTabOpen, setWaitingActive } from '../public/modules/state.js'; import { handleSessionCreated, updateTabs } from '../public/modules/terminal.js'; beforeEach(() => { window.Terminal = class { open() {} loadAddon() {} attachCustomKeyEventHandler() {} onData() {} scrollToBottom() {} focus() {} dispose() {} }; document.body.innerHTML = '
' + '' + ''; agents.clear(); setActiveSession(null); setBoardActive(false); setSelf(null, false); setBillionTabOpen(false); }); const created = (sessionId, extra = {}) => handleSessionCreated({ type: 'session-created', sessionId, name: sessionId, state: 'IDLE', ...extra }); const tabIds = () => [...document.querySelectorAll('.terminal-tab[data-session-id]')].map(t => t.dataset.sessionId); describe('Billion\'s tab', () => { it('is hidden until opened, then comes first, cannot be dragged, and offers no rename', async () => { await created('w1'); await created('b1', { isBillion: true, name: 'Billion' }); expect(tabIds()).toEqual(['w1']); setBillionTabOpen(true); updateTabs(); expect(tabIds()).toEqual(['b1', 'w1']); const tab = document.querySelector('.terminal-tab[data-session-id="b1"]'); expect(tab.draggable).toBe(false); expect(tab.title).not.toBe('Double-click to rename'); expect(document.querySelector('.terminal-tab[data-session-id="w1"]').draggable).toBe(true); }); it('a restarted Billion replaces the stopped tab and keeps focus where it was', async () => { await created('b1', { isBillion: true }); expect(activeSessionId).toBe('b1'); await created('b2', { isBillion: true }); expect(agents.has('b1')).toBe(false); expect(activeSessionId).toBe('b2'); expect(tabIds()).toEqual(['b2']); }); it('takes Billion\'s notice from session-created, and a re-emit without one clears it', async () => { document.body.innerHTML += '