7a0da7932b
OSV-Scanner (Scheduled) / scan-scheduled (push) Failing after 0s
Create Release / test-gate (push) Has been cancelled
Create Release / release-gate (push) Has been cancelled
Create Release / ci-gate (push) Has been cancelled
Create Release / version-check (push) Has been cancelled
Create Release / e2e-test-gate (push) Has been cancelled
Create Release / responsive-test-gate (push) Has been cancelled
Create Release / compat-test-gate (push) Has been cancelled
Create Release / compose-integration-gate (push) Has been cancelled
Create Release / vulture-gate (push) Has been cancelled
Create Release / build (push) Has been cancelled
Create Release / provenance (push) Has been cancelled
Create Release / prerelease-docker (push) Has been cancelled
Create Release / publish-docker (push) Has been cancelled
Create Release / create-release (push) Has been cancelled
Create Release / cleanup-changelog (push) Has been cancelled
Create Release / trigger-pypi (push) Has been cancelled
Create Release / monitor-pypi (push) Has been cancelled
Create Release / Clean up orphan prerelease tags and signatures (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-form] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-metrics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [research-workflow] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-core] (push) Has been cancelled
CodeQL Advanced / Analyze (javascript-typescript) (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [history-news] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [library] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [link-analytics] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-core] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [chat-lifecycle] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [error-benchmark] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [settings-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) (push) Has been cancelled
Docker Tests (Consolidated) / Accessibility Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Unit Tests (push) Has been cancelled
Docker Tests (Consolidated) / LLM Example Tests (push) Has been cancelled
Docker Tests (Consolidated) / Production Image Smoke Test (push) Has been cancelled
Docker Tests (Consolidated) / Infrastructure Tests (push) Has been cancelled
OSSF Scorecard / OSSF Security Scorecard Analysis (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [mobile] (push) Has been cancelled
Backwards Compatibility / Verify Encryption Constants (push) Has been cancelled
Backwards Compatibility / PyPI Version Compatibility (push) Has been cancelled
Backwards Compatibility / Database Migration Tests (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Docker Tests (Consolidated) / detect-changes (push) Has been cancelled
Docker Tests (Consolidated) / Build Test Image (push) Has been cancelled
Docker Tests (Consolidated) / All Pytest Tests + Coverage (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [accessibility] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [api-crud] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-login] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-pages] (push) Has been cancelled
Docker Tests (Consolidated) / UI Tests (Puppeteer) [auth-register] (push) Has been cancelled
118 lines
3.8 KiB
JavaScript
118 lines
3.8 KiB
JavaScript
/**
|
|
* Tests for services/keyboard.js
|
|
*
|
|
* Tests the keyboard shortcut matching logic and service API.
|
|
* We can't test the full initialization (which binds to document),
|
|
* but we can test the shortcut matching and public API.
|
|
*/
|
|
|
|
// Stub URLS needed by keyboard.js handlers
|
|
window.URLS = {
|
|
PAGES: {
|
|
HOME: '/',
|
|
HISTORY: '/history/',
|
|
METRICS: '/metrics/',
|
|
SETTINGS: '/settings/',
|
|
}
|
|
};
|
|
|
|
import '@js/services/keyboard.js';
|
|
|
|
const KS = window.KeyboardService;
|
|
|
|
describe('KeyboardService', () => {
|
|
describe('shortcuts registry invariants', () => {
|
|
it('every registered shortcut has a callable handler', () => {
|
|
// Catches accidental refactors that drop the handler field.
|
|
const shortcuts = KS.shortcuts();
|
|
for (const [name, shortcut] of Object.entries(shortcuts)) {
|
|
expect(shortcut.handler, `${name} missing handler`).toBeTypeOf('function');
|
|
expect(shortcut.keys, `${name} missing keys`).toBeInstanceOf(Array);
|
|
expect(shortcut.keys.length, `${name} has empty keys`).toBeGreaterThan(0);
|
|
}
|
|
});
|
|
});
|
|
|
|
describe('addShortcut / removeShortcut', () => {
|
|
afterEach(() => {
|
|
KS.removeShortcut('testShortcut');
|
|
});
|
|
|
|
it('adds a custom shortcut', () => {
|
|
KS.addShortcut('testShortcut', {
|
|
keys: ['ctrl+t'],
|
|
description: 'Test shortcut',
|
|
handler: () => {}
|
|
});
|
|
const shortcuts = KS.shortcuts();
|
|
expect(shortcuts.testShortcut).toBeDefined();
|
|
expect(shortcuts.testShortcut.keys).toEqual(['ctrl+t']);
|
|
});
|
|
|
|
it('removes a custom shortcut', () => {
|
|
KS.addShortcut('testShortcut', {
|
|
keys: ['ctrl+t'],
|
|
description: 'Test',
|
|
handler: () => {}
|
|
});
|
|
KS.removeShortcut('testShortcut');
|
|
const shortcuts = KS.shortcuts();
|
|
expect(shortcuts.testShortcut).toBeUndefined();
|
|
});
|
|
});
|
|
|
|
describe('keyboard event handling', () => {
|
|
it('Escape key triggers newSearch shortcut', () => {
|
|
// The shortcut sets window.location.href, which we can spy on
|
|
const originalHref = window.location.href;
|
|
|
|
// Create a keydown event for Escape
|
|
const event = new KeyboardEvent('keydown', {
|
|
key: 'Escape',
|
|
code: 'Escape',
|
|
bubbles: true,
|
|
});
|
|
|
|
// We can verify the event doesn't throw
|
|
expect(() => document.dispatchEvent(event)).not.toThrow();
|
|
});
|
|
|
|
it('ignores shortcuts when typing in input fields', () => {
|
|
const input = document.createElement('input');
|
|
input.type = 'text';
|
|
document.body.appendChild(input);
|
|
input.focus();
|
|
|
|
const event = new KeyboardEvent('keydown', {
|
|
key: 'Escape',
|
|
code: 'Escape',
|
|
bubbles: true,
|
|
});
|
|
|
|
// Should not throw or cause navigation when typing
|
|
expect(() => input.dispatchEvent(event)).not.toThrow();
|
|
input.remove();
|
|
});
|
|
|
|
it('allows Ctrl+Shift navigation shortcuts even in input', () => {
|
|
const input = document.createElement('input');
|
|
input.type = 'text';
|
|
document.body.appendChild(input);
|
|
input.focus();
|
|
|
|
const event = new KeyboardEvent('keydown', {
|
|
key: '1',
|
|
code: 'Digit1',
|
|
ctrlKey: true,
|
|
shiftKey: true,
|
|
bubbles: true,
|
|
});
|
|
|
|
// Should not throw
|
|
expect(() => input.dispatchEvent(event)).not.toThrow();
|
|
input.remove();
|
|
});
|
|
});
|
|
|
|
});
|