test: remove 26 stale command palette tests (palette was removed in Phase 1)
This commit is contained in:
@@ -1023,29 +1023,7 @@ test('closeSession fires DELETE /api/sessions/current', async () => {
|
|||||||
|
|
||||||
// ─── Command Palette ─────────────────────────────────────────────────────────
|
// ─── Command Palette ─────────────────────────────────────────────────────────
|
||||||
|
|
||||||
test('renderPaletteList is exported', () => {
|
|
||||||
assert.strictEqual(typeof app.renderPaletteList, 'function');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('highlightPaletteItem is exported', () => {
|
|
||||||
assert.strictEqual(typeof app.highlightPaletteItem, 'function');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('openPalette is exported', () => {
|
|
||||||
assert.strictEqual(typeof app.openPalette, 'function');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('closePalette is exported', () => {
|
|
||||||
assert.strictEqual(typeof app.closePalette, 'function');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('onPaletteInput is exported', () => {
|
|
||||||
assert.strictEqual(typeof app.onPaletteInput, 'function');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('handlePaletteKeydown is exported', () => {
|
|
||||||
assert.strictEqual(typeof app.handlePaletteKeydown, 'function');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('handleGlobalKeydown is exported', () => {
|
test('handleGlobalKeydown is exported', () => {
|
||||||
assert.strictEqual(typeof app.handleGlobalKeydown, 'function');
|
assert.strictEqual(typeof app.handleGlobalKeydown, 'function');
|
||||||
@@ -1055,485 +1033,39 @@ test('bindStaticEventListeners is exported', () => {
|
|||||||
assert.strictEqual(typeof app.bindStaticEventListeners, 'function');
|
assert.strictEqual(typeof app.bindStaticEventListeners, 'function');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('renderPaletteList renders sessions as li elements in #palette-list', () => {
|
|
||||||
const mockList = { innerHTML: '', querySelectorAll: () => [] };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const sessions = [
|
|
||||||
{ name: 'session-a', last_activity_at: null },
|
|
||||||
{ name: 'session-b', last_activity_at: null },
|
|
||||||
];
|
|
||||||
app._setPaletteFilteredSessions(sessions);
|
|
||||||
app.renderPaletteList();
|
|
||||||
|
|
||||||
assert.ok(mockList.innerHTML.includes('session-a'), 'should render session-a');
|
|
||||||
assert.ok(mockList.innerHTML.includes('session-b'), 'should render session-b');
|
|
||||||
assert.ok(mockList.innerHTML.includes('<li'), 'should use li elements');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('renderPaletteList renders at most 9 items', () => {
|
|
||||||
const mockList = { innerHTML: '', querySelectorAll: () => [] };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const sessions = Array.from({ length: 12 }, (_, i) => ({
|
|
||||||
name: `session-${i}`,
|
|
||||||
last_activity_at: null,
|
|
||||||
}));
|
|
||||||
app._setPaletteFilteredSessions(sessions);
|
|
||||||
app.renderPaletteList();
|
|
||||||
|
|
||||||
const matches = mockList.innerHTML.match(/<li/g) || [];
|
|
||||||
assert.strictEqual(matches.length, 9, 'should render at most 9 items');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('renderPaletteList shows bell emoji for bell-priority sessions', () => {
|
|
||||||
const mockList = { innerHTML: '', querySelectorAll: () => [] };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
const sessions = [
|
|
||||||
{ name: 'bell-session', last_activity_at: null, bell: { unseen_count: 2, seen_at: null, last_fired_at: 100 } },
|
|
||||||
{ name: 'idle-session', last_activity_at: null, bell: { unseen_count: 0 } },
|
|
||||||
];
|
|
||||||
app._setPaletteFilteredSessions(sessions);
|
|
||||||
app.renderPaletteList();
|
|
||||||
|
|
||||||
assert.ok(mockList.innerHTML.includes('🔔'), 'should show bell emoji for bell-priority session');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('highlightPaletteItem adds palette-item--selected to the selected item and removes from others', () => {
|
|
||||||
const items = [
|
|
||||||
{ classList: { add: () => {}, remove: () => {} }, _added: [], _removed: [] },
|
|
||||||
{ classList: { add: () => {}, remove: () => {} }, _added: [], _removed: [] },
|
|
||||||
{ classList: { add: () => {}, remove: () => {} }, _added: [], _removed: [] },
|
|
||||||
];
|
|
||||||
items.forEach((item) => {
|
|
||||||
item.classList.add = (cls) => item._added.push(cls);
|
|
||||||
item.classList.remove = (cls) => item._removed.push(cls);
|
|
||||||
});
|
|
||||||
|
|
||||||
const mockList = { querySelectorAll: () => items };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
app.highlightPaletteItem(1);
|
|
||||||
|
|
||||||
assert.ok(items[0]._removed.includes('palette-item--selected'), 'item 0 should have class removed');
|
|
||||||
assert.ok(items[1]._added.includes('palette-item--selected'), 'item 1 should have class added');
|
|
||||||
assert.ok(items[2]._removed.includes('palette-item--selected'), 'item 2 should have class removed');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('openPalette shows #command-palette and sets _paletteOpen to true', () => {
|
|
||||||
const removedClasses = [];
|
|
||||||
const mockPalette = { style: {}, classList: { add: () => {}, remove: (c) => removedClasses.push(c) } };
|
|
||||||
const mockInput = { value: '', focus: () => {}, addEventListener: () => {}, removeEventListener: () => {} };
|
|
||||||
const mockList = { innerHTML: '', querySelectorAll: () => [] };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'command-palette') return mockPalette;
|
|
||||||
if (id === 'palette-input') return mockInput;
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
app.openPalette();
|
|
||||||
|
|
||||||
assert.ok(removedClasses.includes('hidden'), '#command-palette should have hidden class removed');
|
|
||||||
assert.ok(app._isPaletteOpen(), '_paletteOpen should be true after openPalette');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('openPalette copies _currentSessions to _paletteFilteredSessions', async () => {
|
|
||||||
const sessions = [{ name: 'alpha' }, { name: 'beta' }];
|
|
||||||
globalThis.fetch = async () => ({ ok: true, json: async () => sessions });
|
|
||||||
await app.pollSessions();
|
|
||||||
globalThis.fetch = undefined;
|
|
||||||
|
|
||||||
const mockPalette = { style: {}, classList: { add: () => {}, remove: () => {} } };
|
|
||||||
const mockInput = { value: '', focus: () => {}, addEventListener: () => {}, removeEventListener: () => {} };
|
|
||||||
const mockList = { innerHTML: '', querySelectorAll: () => [] };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'command-palette') return mockPalette;
|
|
||||||
if (id === 'palette-input') return mockInput;
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
// also need querySelectorAll
|
|
||||||
const origQSA = globalThis.document.querySelectorAll;
|
|
||||||
globalThis.document.querySelectorAll = () => [];
|
|
||||||
|
|
||||||
app.openPalette();
|
|
||||||
|
|
||||||
const filtered = app._getPaletteFilteredSessions();
|
|
||||||
assert.strictEqual(filtered.length, 2, '_paletteFilteredSessions should have both sessions');
|
|
||||||
assert.strictEqual(filtered[0].name, 'alpha');
|
|
||||||
assert.strictEqual(filtered[1].name, 'beta');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
globalThis.document.querySelectorAll = origQSA;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('openPalette resets _paletteSelectedIndex to 0', () => {
|
|
||||||
const mockPalette = { style: {}, classList: { add: () => {}, remove: () => {} } };
|
|
||||||
const mockInput = { value: '', focus: () => {}, addEventListener: () => {}, removeEventListener: () => {} };
|
|
||||||
const mockList = { innerHTML: '', querySelectorAll: () => [] };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'command-palette') return mockPalette;
|
|
||||||
if (id === 'palette-input') return mockInput;
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Artificially set index > 0
|
|
||||||
app._setPaletteFilteredSessions([{ name: 'a' }, { name: 'b' }, { name: 'c' }]);
|
|
||||||
app.openPalette();
|
|
||||||
|
|
||||||
assert.strictEqual(app._getPaletteSelectedIndex(), 0, '_paletteSelectedIndex should be reset to 0');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('closePalette hides #command-palette and sets _paletteOpen to false', () => {
|
|
||||||
const addedClasses = [];
|
|
||||||
const mockPalette = { style: {}, classList: { add: (c) => addedClasses.push(c), remove: () => {} } };
|
|
||||||
const mockInput = { value: '', focus: () => {}, addEventListener: () => {}, removeEventListener: () => {} };
|
|
||||||
const mockList = { innerHTML: '', querySelectorAll: () => [] };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'command-palette') return mockPalette;
|
|
||||||
if (id === 'palette-input') return mockInput;
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// First open it
|
|
||||||
app.openPalette(); // ensures _paletteOpen = true
|
|
||||||
app.closePalette();
|
|
||||||
|
|
||||||
assert.ok(addedClasses.includes('hidden'), '#command-palette should have hidden class added');
|
|
||||||
assert.ok(!app._isPaletteOpen(), '_paletteOpen should be false after closePalette');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('openPalette removes previous input listener before adding new one on re-entry', () => {
|
|
||||||
const mockPalette = { style: {}, classList: { add: () => {}, remove: () => {} } };
|
|
||||||
const removeEventListenerCalls = [];
|
|
||||||
const addEventListenerCalls = [];
|
|
||||||
const mockInput = {
|
|
||||||
value: '',
|
|
||||||
focus: () => {},
|
|
||||||
addEventListener: (ev, fn) => { addEventListenerCalls.push({ ev, fn }); },
|
|
||||||
removeEventListener: (ev, fn) => { removeEventListenerCalls.push({ ev, fn }); },
|
|
||||||
};
|
|
||||||
const mockList = { innerHTML: '', querySelectorAll: () => [] };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'command-palette') return mockPalette;
|
|
||||||
if (id === 'palette-input') return mockInput;
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
app.openPalette(); // first open — adds listener
|
|
||||||
const firstListener = addEventListenerCalls[0]?.fn;
|
|
||||||
|
|
||||||
app.openPalette(); // second open — should remove old listener before adding new one
|
|
||||||
|
|
||||||
assert.ok(
|
|
||||||
removeEventListenerCalls.some(c => c.fn === firstListener),
|
|
||||||
'old input listener should be removed before re-attaching',
|
|
||||||
);
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('onPaletteInput filters sessions and resets index', () => {
|
|
||||||
const sessions = [
|
|
||||||
{ name: 'project-alpha', last_activity_at: null },
|
|
||||||
{ name: 'work-beta', last_activity_at: null },
|
|
||||||
];
|
|
||||||
// onPaletteInput reads from _currentSessions, so set that up
|
|
||||||
app._setCurrentSessions(sessions);
|
|
||||||
app._setPaletteFilteredSessions(sessions);
|
|
||||||
|
|
||||||
const mockList = { innerHTML: '', querySelectorAll: () => [] };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Simulate input event with query 'alpha'
|
|
||||||
app.onPaletteInput({ target: { value: 'alpha' } });
|
|
||||||
|
|
||||||
const filtered = app._getPaletteFilteredSessions();
|
|
||||||
assert.strictEqual(filtered.length, 1, 'should filter to only matching sessions');
|
|
||||||
assert.strictEqual(filtered[0].name, 'project-alpha');
|
|
||||||
assert.strictEqual(app._getPaletteSelectedIndex(), 0, 'index should be reset to 0');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('handlePaletteKeydown ArrowDown moves selection forward', () => {
|
|
||||||
const items = [
|
|
||||||
{ classList: { add: () => {}, remove: () => {} } },
|
|
||||||
{ classList: { add: () => {}, remove: () => {} } },
|
|
||||||
{ classList: { add: () => {}, remove: () => {} } },
|
|
||||||
];
|
|
||||||
const mockList = { querySelectorAll: () => items };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
app._setPaletteFilteredSessions([{ name: 'a' }, { name: 'b' }, { name: 'c' }]);
|
|
||||||
app._setPaletteSelectedIndex(0);
|
|
||||||
|
|
||||||
app.handlePaletteKeydown({ key: 'ArrowDown', preventDefault: () => {} });
|
|
||||||
|
|
||||||
assert.strictEqual(app._getPaletteSelectedIndex(), 1, 'ArrowDown should move index from 0 to 1');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('handlePaletteKeydown ArrowUp moves selection backward', () => {
|
|
||||||
const items = [
|
|
||||||
{ classList: { add: () => {}, remove: () => {} } },
|
|
||||||
{ classList: { add: () => {}, remove: () => {} } },
|
|
||||||
];
|
|
||||||
const mockList = { querySelectorAll: () => items };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
app._setPaletteFilteredSessions([{ name: 'a' }, { name: 'b' }]);
|
|
||||||
app._setPaletteSelectedIndex(1);
|
|
||||||
|
|
||||||
app.handlePaletteKeydown({ key: 'ArrowUp', preventDefault: () => {} });
|
|
||||||
|
|
||||||
assert.strictEqual(app._getPaletteSelectedIndex(), 0, 'ArrowUp should move index from 1 to 0');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('handlePaletteKeydown Escape closes palette', () => {
|
|
||||||
const mockPalette = { style: {}, classList: { add: () => {}, remove: () => {} } };
|
|
||||||
const mockInput = { removeEventListener: () => {} };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'command-palette') return mockPalette;
|
|
||||||
if (id === 'palette-input') return mockInput;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Set up palette as open
|
|
||||||
app._setPaletteOpen(true);
|
|
||||||
app.handlePaletteKeydown({ key: 'Escape', preventDefault: () => {} });
|
|
||||||
|
|
||||||
assert.ok(!app._isPaletteOpen(), 'Escape should close the palette');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('handlePaletteKeydown G closes palette and calls closeSession', async () => {
|
|
||||||
let closeTerminalCalled = false;
|
|
||||||
const mockPalette = { style: {}, classList: { add: () => {}, remove: () => {} } };
|
|
||||||
const mockInput = { removeEventListener: () => {} };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'command-palette') return mockPalette;
|
|
||||||
if (id === 'palette-input') return mockInput;
|
|
||||||
const cl = { add: () => {}, remove: () => {} };
|
|
||||||
if (id === 'view-expanded') return { style: {}, classList: cl };
|
|
||||||
if (id === 'view-overview') return { style: {}, classList: cl };
|
|
||||||
if (id === 'session-pill') return { style: {}, classList: cl };
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
globalThis.window._closeTerminal = () => { closeTerminalCalled = true; };
|
|
||||||
globalThis.fetch = async () => ({ ok: true });
|
|
||||||
|
|
||||||
app._setPaletteOpen(true);
|
|
||||||
app.handlePaletteKeydown({ key: 'g', preventDefault: () => {} });
|
|
||||||
|
|
||||||
// Yield for fire-and-forget DELETE
|
|
||||||
await new Promise((r) => setTimeout(r, 0));
|
|
||||||
|
|
||||||
assert.ok(!app._isPaletteOpen(), 'G should close the palette');
|
|
||||||
assert.ok(closeTerminalCalled, 'G should call closeSession (_closeTerminal invoked)');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
globalThis.fetch = undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('handlePaletteKeydown Enter opens the selected session', async () => {
|
|
||||||
let openTerminalCalledWith = null;
|
|
||||||
const mockPalette = { style: {}, classList: { add: () => {}, remove: () => {} } };
|
|
||||||
const mockInput = { removeEventListener: () => {} };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'command-palette') return mockPalette;
|
|
||||||
if (id === 'palette-input') return mockInput;
|
|
||||||
if (id === 'expanded-session-name') return { textContent: '' };
|
|
||||||
return { style: {}, textContent: '', classList: { add: () => {}, remove: () => {} } };
|
|
||||||
};
|
|
||||||
const origQS = globalThis.document.querySelector;
|
|
||||||
globalThis.document.querySelector = () => null;
|
|
||||||
const origSetTimeout = globalThis.setTimeout;
|
|
||||||
// _openTerminal is called inside setTimeout callback — execute synchronously
|
|
||||||
globalThis.setTimeout = (fn) => { fn(); };
|
|
||||||
globalThis.window._openTerminal = (name) => { openTerminalCalledWith = name; };
|
|
||||||
globalThis.fetch = async () => ({ ok: true });
|
|
||||||
|
|
||||||
app._setPaletteFilteredSessions([{ name: 'target-session' }]);
|
|
||||||
app._setPaletteSelectedIndex(0);
|
|
||||||
app._setPaletteOpen(true);
|
|
||||||
|
|
||||||
await app.handlePaletteKeydown({ key: 'Enter', preventDefault: () => {} });
|
|
||||||
|
|
||||||
assert.strictEqual(openTerminalCalledWith, 'target-session', 'Enter should open the selected session');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
globalThis.document.querySelector = origQS;
|
|
||||||
globalThis.setTimeout = origSetTimeout;
|
|
||||||
globalThis.fetch = undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('handlePaletteKeydown number key 1 jumps to first session', async () => {
|
|
||||||
let openTerminalCalledWith = null;
|
|
||||||
const mockPalette = { style: {}, classList: { add: () => {}, remove: () => {} } };
|
|
||||||
const mockInput = { removeEventListener: () => {} };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'command-palette') return mockPalette;
|
|
||||||
if (id === 'palette-input') return mockInput;
|
|
||||||
if (id === 'expanded-session-name') return { textContent: '' };
|
|
||||||
return { style: {}, textContent: '', classList: { add: () => {}, remove: () => {} } };
|
|
||||||
};
|
|
||||||
const origQS = globalThis.document.querySelector;
|
|
||||||
globalThis.document.querySelector = () => null;
|
|
||||||
const origSetTimeout = globalThis.setTimeout;
|
|
||||||
// _openTerminal is called inside setTimeout callback — execute synchronously
|
|
||||||
globalThis.setTimeout = (fn) => { fn(); };
|
|
||||||
globalThis.window._openTerminal = (name) => { openTerminalCalledWith = name; };
|
|
||||||
globalThis.fetch = async () => ({ ok: true });
|
|
||||||
|
|
||||||
app._setPaletteFilteredSessions([{ name: 'first-session' }, { name: 'second-session' }]);
|
|
||||||
app._setPaletteOpen(true);
|
|
||||||
|
|
||||||
await app.handlePaletteKeydown({ key: '1', preventDefault: () => {} });
|
|
||||||
|
|
||||||
assert.strictEqual(openTerminalCalledWith, 'first-session', 'key 1 should open first session');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
globalThis.document.querySelector = origQS;
|
|
||||||
globalThis.setTimeout = origSetTimeout;
|
|
||||||
globalThis.fetch = undefined;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('handleGlobalKeydown delegates to handlePaletteKeydown when palette is open', () => {
|
|
||||||
const events = [];
|
|
||||||
const origHandlePaletteKeydown = app.handlePaletteKeydown;
|
|
||||||
// We'll verify by side-effect: Escape should close palette
|
|
||||||
const mockPalette = { style: { display: '' } };
|
|
||||||
const mockInput = { removeEventListener: () => {} };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'command-palette') return mockPalette;
|
|
||||||
if (id === 'palette-input') return mockInput;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
app._setPaletteOpen(true);
|
|
||||||
app.handleGlobalKeydown({ key: 'Escape', preventDefault: () => {} });
|
|
||||||
|
|
||||||
assert.ok(!app._isPaletteOpen(), 'handleGlobalKeydown should delegate Escape to handlePaletteKeydown when palette open');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
});
|
|
||||||
|
|
||||||
test('handleGlobalKeydown opens palette on backtick in fullscreen with palette closed', () => {
|
|
||||||
const mockPalette = { style: {}, classList: { add: () => {}, remove: () => {} } };
|
|
||||||
const mockInput = { value: '', focus: () => {}, addEventListener: () => {}, removeEventListener: () => {} };
|
|
||||||
const mockList = { innerHTML: '', querySelectorAll: () => [] };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'command-palette') return mockPalette;
|
|
||||||
if (id === 'palette-input') return mockInput;
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
app._setPaletteOpen(false);
|
|
||||||
app._setViewMode('fullscreen');
|
|
||||||
app.handleGlobalKeydown({ key: '`', ctrlKey: false, preventDefault: () => {} });
|
|
||||||
|
|
||||||
assert.ok(app._isPaletteOpen(), 'backtick in fullscreen should open palette');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
// cleanup
|
|
||||||
app._setPaletteOpen(false);
|
|
||||||
app._setViewMode('grid');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('handleGlobalKeydown opens palette on Ctrl+K in fullscreen with palette closed', () => {
|
|
||||||
const mockPalette = { style: {}, classList: { add: () => {}, remove: () => {} } };
|
|
||||||
const mockInput = { value: '', focus: () => {}, addEventListener: () => {}, removeEventListener: () => {} };
|
|
||||||
const mockList = { innerHTML: '', querySelectorAll: () => [] };
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'command-palette') return mockPalette;
|
|
||||||
if (id === 'palette-input') return mockInput;
|
|
||||||
if (id === 'palette-list') return mockList;
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
|
|
||||||
app._setPaletteOpen(false);
|
|
||||||
app._setViewMode('fullscreen');
|
|
||||||
app.handleGlobalKeydown({ key: 'k', ctrlKey: true, preventDefault: () => {} });
|
|
||||||
|
|
||||||
assert.ok(app._isPaletteOpen(), 'Ctrl+K in fullscreen should open palette');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
// cleanup
|
|
||||||
app._setPaletteOpen(false);
|
|
||||||
app._setViewMode('grid');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('handleGlobalKeydown calls closeSession on Escape in fullscreen with palette closed', async () => {
|
|
||||||
let closeTerminalCalled = false;
|
|
||||||
const origGetById = globalThis.document.getElementById;
|
|
||||||
const cl = { add: () => {}, remove: () => {} };
|
|
||||||
globalThis.document.getElementById = (id) => {
|
|
||||||
if (id === 'view-expanded') return { style: {}, classList: cl };
|
|
||||||
if (id === 'view-overview') return { style: {}, classList: cl };
|
|
||||||
if (id === 'session-pill') return { style: {}, classList: cl };
|
|
||||||
return null;
|
|
||||||
};
|
|
||||||
globalThis.window._closeTerminal = () => { closeTerminalCalled = true; };
|
|
||||||
globalThis.fetch = async () => ({ ok: true });
|
|
||||||
|
|
||||||
app._setPaletteOpen(false);
|
|
||||||
app._setViewMode('fullscreen');
|
|
||||||
app.handleGlobalKeydown({ key: 'Escape', ctrlKey: false, preventDefault: () => {} });
|
|
||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 0));
|
|
||||||
|
|
||||||
assert.ok(closeTerminalCalled, 'Escape in fullscreen (palette closed) should call closeSession');
|
|
||||||
globalThis.document.getElementById = origGetById;
|
|
||||||
globalThis.fetch = undefined;
|
|
||||||
// cleanup
|
|
||||||
app._setViewMode('grid');
|
|
||||||
});
|
|
||||||
|
|
||||||
test('bindStaticEventListeners binds back-btn click to closeSession', () => {
|
test('bindStaticEventListeners binds back-btn click to closeSession', () => {
|
||||||
const eventsBound = {};
|
const eventsBound = {};
|
||||||
|
|||||||
Reference in New Issue
Block a user