Add comprehensive tests for Alt+- keyboard handling
Co-authored-by: Tyriar <2193314+Tyriar@users.noreply.github.com>
This commit is contained in:
co-authored by
Tyriar
parent
dc2ac0b78b
commit
9a64c2cb63
@@ -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 };
|
||||
@@ -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');
|
||||
});
|
||||
});
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user