Add comprehensive tests for Alt+- keyboard handling

Co-authored-by: Tyriar <2193314+Tyriar@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2025-08-24 13:04:42 +00:00
co-authored by Tyriar
parent dc2ac0b78b
commit 9a64c2cb63
3 changed files with 297 additions and 0 deletions
+121
View File
@@ -0,0 +1,121 @@
/**
* Debug test to reproduce the Alt+- keyboard issue
*/
import { MockCompositionHelper, MockRenderer, MockViewport, TestTerminal } from 'browser/TestUtils.test';
import type { IBrowser } from 'browser/Types';
import { evaluateKeyboardEvent } from 'common/input/Keyboard';
// Create a test to simulate the keyboard event handling
function testAltMinusKeyHandling() {
const term = new TestTerminal({ cols: 80, rows: 24 });
(term as any).renderer = new MockRenderer();
(term as any).viewport = new MockViewport();
// Mock the composition helper to not intercept our events
const mockCompositionHelper = {
keydown: () => true,
isComposing: false
};
(term as any)._compositionHelper = mockCompositionHelper;
(term as any).element = {
classList: {
toggle: () => { },
remove: () => { }
}
};
// Mock browser detection for Linux
(term as any).browser = {
isMac: false,
isWindows: false,
isNode: false,
userAgent: 'Mozilla/5.0 (X11; Linux x86_64; rv:141.0) Gecko/20100101 Firefox/141.0',
platform: 'linux',
isFirefox: true,
isIpad: false,
isIphone: false
} as IBrowser;
// Mock textarea element
(term as any).textarea = {
value: ''
};
// Mock necessary services
(term as any).coreService = {
decPrivateModes: {
applicationCursorKeys: false
},
triggerDataEvent: () => {}
};
// Mock necessary options directly on term.options
(term as any).options.macOptionIsMeta = false;
(term as any).options.scrollOnUserInput = false;
(term as any).optionsService = {
rawOptions: {
screenReaderMode: false
}
};
let keyEventFired = false;
let capturedKey = '';
// Listen for onKey events
term.onKey((event) => {
keyEventFired = true;
capturedKey = event.key;
console.log('Key event fired:', event);
});
// Create a mock KeyboardEvent for Alt+-
const mockEvent = {
type: 'keydown',
keyCode: 189,
key: '-',
altKey: true,
ctrlKey: false,
shiftKey: false,
metaKey: false,
getModifierState: (modifier: string) => {
if (modifier === 'AltGraph') return false;
return false;
},
preventDefault: () => {},
stopPropagation: () => {}
} as KeyboardEvent;
console.log('Testing Alt+- key handling...');
console.log('Mock event:', mockEvent);
// Test the individual components
console.log('\n=== Testing evaluateKeyboardEvent directly ===');
const keyResult = evaluateKeyboardEvent(mockEvent, false, false, false);
console.log('evaluateKeyboardEvent result:', keyResult);
console.log('\n=== Testing _isThirdLevelShift ===');
const isThirdLevel = (term as any)._isThirdLevelShift((term as any).browser, mockEvent);
console.log('_isThirdLevelShift result:', isThirdLevel);
console.log('\n=== Testing full _keyDown method ===');
// Call the _keyDown method directly
const result = (term as any)._keyDown(mockEvent);
console.log('_keyDown result:', result);
console.log('Key event fired:', keyEventFired);
console.log('Captured key:', capturedKey);
console.log('Expected key: \\x1b-');
return {
keyEventFired,
capturedKey,
result,
keyResult,
isThirdLevel
};
}
export { testAltMinusKeyHandling };
+116
View File
@@ -0,0 +1,116 @@
/**
* Test for Alt+- keyboard handling specifically
* This tests both the evaluateKeyboardEvent function and potential browser integration issues
*/
import { assert } from 'chai';
import { evaluateKeyboardEvent } from 'common/input/Keyboard';
import { IKeyboardResult, IKeyboardEvent } from 'common/Types';
function createMockKeyboardEvent(partialEvent: Partial<IKeyboardEvent>): IKeyboardEvent {
return {
altKey: false,
ctrlKey: false,
shiftKey: false,
metaKey: false,
keyCode: 0,
code: '',
key: '',
type: 'keydown',
...partialEvent
};
}
describe('Alt+- keyboard handling', () => {
it('should return correct escape sequence for Alt+- on all platforms', () => {
const event = createMockKeyboardEvent({
altKey: true,
keyCode: 189,
key: '-',
type: 'keydown'
});
// Test on non-Mac (Linux/Windows)
const resultLinux = evaluateKeyboardEvent(event, false, false, false);
assert.equal(resultLinux.key, '\x1b-', 'Alt+- should produce \\x1b- on Linux');
assert.equal(resultLinux.cancel, false, 'Alt+- should not be cancelled on Linux');
// Test on Windows
const resultWindows = evaluateKeyboardEvent(event, false, false, false);
assert.equal(resultWindows.key, '\x1b-', 'Alt+- should produce \\x1b- on Windows');
// Test on Mac with macOptionIsMeta: true
const resultMacMeta = evaluateKeyboardEvent(event, false, true, true);
assert.equal(resultMacMeta.key, '\x1b-', 'Alt+- should produce \\x1b- on Mac with macOptionIsMeta');
// Test on Mac with macOptionIsMeta: false (third level shift)
const resultMacNoMeta = evaluateKeyboardEvent(event, false, true, false);
assert.equal(resultMacNoMeta.key, undefined, 'Alt+- should not produce escape sequence on Mac without macOptionIsMeta');
});
it('should handle Alt+- with shift key (underscore)', () => {
const event = createMockKeyboardEvent({
altKey: true,
shiftKey: true,
keyCode: 189,
key: '_',
type: 'keydown'
});
const result = evaluateKeyboardEvent(event, false, false, false);
assert.equal(result.key, '\x1b_', 'Alt+Shift+- should produce \\x1b_');
});
it('should verify keyCode 189 maps to minus character', () => {
// This test verifies that keyCode 189 is correctly mapped in KEYCODE_KEY_MAPPINGS
const event = createMockKeyboardEvent({
altKey: true,
keyCode: 189,
key: '-',
type: 'keydown'
});
const result = evaluateKeyboardEvent(event, false, false, false);
assert.isDefined(result.key, 'Result should have a key');
assert.equal(result.key, '\x1b-', 'Should produce the correct escape sequence');
});
it('should handle various browser scenarios for Alt+-', () => {
// Test with different keyCode values that might be used for minus
const keyCodes = [189, 109]; // 189 is standard minus, 109 is numpad minus
keyCodes.forEach(keyCode => {
const event = createMockKeyboardEvent({
altKey: true,
keyCode: keyCode,
key: '-',
type: 'keydown'
});
const result = evaluateKeyboardEvent(event, false, false, false);
if (keyCode === 189) {
assert.equal(result.key, '\x1b-', `keyCode ${keyCode} should produce \\x1b-`);
} else {
// For numpad minus or other codes, the behavior might be different
// but we should still handle them gracefully
assert.isDefined(result, `keyCode ${keyCode} should return a result`);
}
});
});
it('should not be affected by composition state for regular Alt combinations', () => {
// This tests that Alt+- is not treated as a composition character
const event = createMockKeyboardEvent({
altKey: true,
keyCode: 189,
key: '-',
type: 'keydown'
});
// Ensure the keyCode is not 229 (composition character)
assert.notEqual(event.keyCode, 229, 'Alt+- should not use composition keyCode');
const result = evaluateKeyboardEvent(event, false, false, false);
assert.equal(result.key, '\x1b-', 'Alt+- should work normally without composition interference');
});
});
+60
View File
@@ -0,0 +1,60 @@
<!DOCTYPE html>
<html>
<head>
<title>Alt+- Key Test</title>
<link rel="stylesheet" href="../css/xterm.css" />
<script src="../lib/xterm.js"></script>
</head>
<body>
<div id="terminal"></div>
<div id="output">
<h3>Key Events:</h3>
<div id="keyEvents"></div>
</div>
<script>
// Create terminal
const terminal = new Terminal({
cols: 80,
rows: 24
});
// Open terminal in DOM
terminal.open(document.getElementById('terminal'));
// Track key events
const keyEventsDiv = document.getElementById('keyEvents');
let eventCount = 0;
terminal.onKey((event) => {
eventCount++;
const eventInfo = document.createElement('div');
eventInfo.textContent = `${eventCount}: Key="${event.key}" (hex: ${event.key.split('').map(c => '\\x' + c.charCodeAt(0).toString(16).padStart(2, '0')).join('')}) - keyCode: ${event.domEvent.keyCode}, altKey: ${event.domEvent.altKey}`;
keyEventsDiv.appendChild(eventInfo);
console.log('onKey fired:', event);
});
// Also listen to raw DOM events for comparison
document.addEventListener('keydown', (event) => {
if (event.altKey && event.keyCode === 189) {
console.log('Raw keydown for Alt+- detected:', event);
const rawInfo = document.createElement('div');
rawInfo.style.color = 'blue';
rawInfo.textContent = `RAW: keydown Alt+- detected - keyCode: ${event.keyCode}, key: "${event.key}"`;
keyEventsDiv.appendChild(rawInfo);
}
});
// Instructions
const instructions = document.createElement('div');
instructions.innerHTML = `
<h3>Test Instructions:</h3>
<p>1. Click in the terminal area</p>
<p>2. Press Alt+- (Alt plus minus)</p>
<p>3. Check if key events are logged below</p>
<p style="color: red;">Expected: You should see a key event with key="\\x1b-"</p>
`;
document.body.insertBefore(instructions, document.getElementById('terminal'));
</script>
</body>
</html>