Compare commits

..
Author SHA1 Message Date
Cursor AgentandDaniel Imms 16f5b8f533 Implement supported skipped InputHandler integration tests
Unskip CSI/OSC sequences that are safely ignored or no-op in xterm.js
using assertNoModeChange, following the pattern from prior commits.

Add window option integration tests for GetWinSizeChars (18t) and
PushTitle/PopTitle (22t/23t).

Keep skipped: XTHIMOUSE (parsed as scroll down), DECSLRM (parsed as
SCOSC), DECGPCS/DECGRPM aliases (covered by mode 45/47 tests), and
addon-only graphics sequences.

Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
2026-06-03 03:36:15 +00:00
ea75b99e2b fix(deps): override serialize-javascript to ^7.0.3 (#5989)
Mocha 11.7.x pulls in serialize-javascript 6.0.2, which is affected by
code injection via RegExp.flags and Date.toISOString (CVE incomplete fix).
Force the patched 7.x release via npm overrides.

Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Daniel Imms <Tyriar@users.noreply.github.com>
2026-06-02 13:34:19 +00:00
3 changed files with 284 additions and 155 deletions
+167 -64
View File
@@ -4700,18 +4700,22 @@
}
},
"node_modules/glob": {
"version": "13.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
"integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
"deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
"dev": true,
"license": "BlueOak-1.0.0",
"license": "ISC",
"dependencies": {
"minimatch": "^10.2.2",
"minipass": "^7.1.3",
"path-scurry": "^2.0.2"
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"engines": {
"node": "18 || 20 || >=22"
"bin": {
"glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
@@ -4737,6 +4741,39 @@
"dev": true,
"license": "BSD-2-Clause"
},
"node_modules/glob/node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT"
},
"node_modules/glob/node_modules/brace-expansion": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
"integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/glob/node_modules/minimatch": {
"version": "9.0.9",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
"integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.2"
},
"engines": {
"node": ">=16 || 14 >=14.17"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/gopd": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -5758,44 +5795,15 @@
"license": "MIT"
},
"node_modules/mocha/node_modules/brace-expansion": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.1.tgz",
"integrity": "sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
"integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
}
},
"node_modules/mocha/node_modules/glob": {
"version": "10.5.0",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
"integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
"deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
"dev": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
"jackspeak": "^3.1.2",
"minimatch": "^9.0.4",
"minipass": "^7.1.2",
"package-json-from-dist": "^1.0.0",
"path-scurry": "^1.11.1"
},
"bin": {
"glob": "dist/esm/bin.mjs"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/mocha/node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true,
"license": "ISC"
},
"node_modules/mocha/node_modules/minimatch": {
"version": "9.0.9",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
@@ -5812,23 +5820,6 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/mocha/node_modules/path-scurry": {
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
"node": ">=16 || 14 >=14.18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -5996,6 +5987,24 @@
"node": ">=8"
}
},
"node_modules/nyc/node_modules/glob": {
"version": "13.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
"integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"minimatch": "^10.2.2",
"minipass": "^7.1.3",
"path-scurry": "^2.0.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/nyc/node_modules/locate-path": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz",
@@ -6038,6 +6047,23 @@
"node": ">=8"
}
},
"node_modules/nyc/node_modules/path-scurry": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
"integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^11.0.0",
"minipass": "^7.1.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/nyc/node_modules/signal-exit": {
"version": "3.0.7",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
@@ -6435,22 +6461,29 @@
"license": "MIT"
},
"node_modules/path-scurry": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
"integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^11.0.0",
"minipass": "^7.1.2"
"lru-cache": "^10.2.0",
"minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
},
"engines": {
"node": "18 || 20 || >=22"
"node": ">=16 || 14 >=14.18"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/path-scurry/node_modules/lru-cache": {
"version": "10.4.3",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
"integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
"dev": true,
"license": "ISC"
},
"node_modules/path-to-regexp": {
"version": "8.4.2",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz",
@@ -6827,6 +6860,41 @@
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/rimraf/node_modules/glob": {
"version": "13.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
"integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"minimatch": "^10.2.2",
"minipass": "^7.1.3",
"path-scurry": "^2.0.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/rimraf/node_modules/path-scurry": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
"integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^11.0.0",
"minipass": "^7.1.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/router": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
@@ -7586,6 +7654,41 @@
"node": "20 || >=22"
}
},
"node_modules/test-exclude/node_modules/glob": {
"version": "13.0.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-13.0.6.tgz",
"integrity": "sha512-Wjlyrolmm8uDpm/ogGyXZXb1Z+Ca2B8NbJwqBVg0axK9GbBeoS7yGV6vjXnYdGm6X53iehEuxxbyiKp8QmN4Vw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"minimatch": "^10.2.2",
"minipass": "^7.1.3",
"path-scurry": "^2.0.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/test-exclude/node_modules/path-scurry": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-2.0.2.tgz",
"integrity": "sha512-3O/iVVsJAPsOnpwWIeD+d6z/7PmqApyQePUtCndjatj/9I5LylHvt5qluFaBT3I5h3r1ejfR056c+FCv+NnNXg==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^11.0.0",
"minipass": "^7.1.2"
},
"engines": {
"node": "18 || 20 || >=22"
},
"funding": {
"url": "https://github.com/sponsors/isaacs"
}
},
"node_modules/tiny-emitter": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.1.0.tgz",
+3 -3
View File
@@ -11,6 +11,9 @@
"workspaces": [
"addons/*"
],
"overrides": {
"serialize-javascript": "^7.0.3"
},
"keywords": [
"cli",
"command-line",
@@ -115,8 +118,5 @@
"webpack-cli": "^7.0.2",
"ws": "^8.20.0",
"xterm-benchmark": "^0.3.2"
},
"overrides": {
"serialize-javascript": "^7.0.5"
}
}
+114 -88
View File
@@ -208,14 +208,14 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.proxy.write('\n\rdef\x1b[2;1H\x1b[2P');
await pollFor(ctx.page, () => getLinesAsArray(2), ['bc', 'f']);
});
test.skip('CSI Pm # P - XTPUSHCOLORS: Push current dynamic- and ANSI-palette colors onto stack, xterm', async () => {
// TODO: Implement
test('CSI Pm # P - XTPUSHCOLORS: Push current dynamic- and ANSI-palette colors onto stack, xterm', async () => {
await assertNoModeChange('\x1b[#P');
});
test.skip('CSI Pm # Q - XTPOPCOLORS: Pop stack to set dynamic- and ANSI-palette colors, xterm', async () => {
// TODO: Implement
test('CSI Pm # Q - XTPOPCOLORS: Pop stack to set dynamic- and ANSI-palette colors, xterm', async () => {
await assertNoModeChange('\x1b[#Q');
});
test.skip('CSI # R - XTREPORTCOLORS: Report the current entry on the palette stack, and the number of palettes stored on the stack, using the same form as XTPOPCOLOR (default = 0), xterm', async () => {
// TODO: Implement
test('CSI # R - XTREPORTCOLORS: Report the current entry on the palette stack, and the number of palettes stored on the stack, using the same form as XTPOPCOLOR (default = 0), xterm', async () => {
await assertNoModeChange('\x1b[#R');
});
test('CSI Ps S - SU: Scroll up Ps lines (default = 1), VT420, ECMA-48', async () => {
await ctx.proxy.write('1\r\n2\r\n3\r\n4\r\n5');
@@ -240,11 +240,11 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.proxy.write('\x1b[2T');
await pollFor(ctx.page, () => getLinesAsArray(5), ['', '', '1', '2', '3']);
});
// Not implemented; the 5-parameter form is currently parsed as SD (scroll down) using the first parameter.
test.skip('CSI Ps ; Ps ; Ps ; Ps ; Ps T - XTHIMOUSE: Initiate highlight mouse tracking (XTHIMOUSE), xterm', async () => {
// TODO: Implement
});
test.skip('CSI > Pm T - XTRMTITLE: Reset title mode features to default value, xterm', async () => {
// TODO: Implement
test('CSI > Pm T - XTRMTITLE: Reset title mode features to default value, xterm', async () => {
await assertNoModeChange('\x1b[>T');
});
test('CSI Ps X - ECH: Erase Ps Character(s) (default = 1)', async () => {
await ctx.proxy.write('abcdef\x1b[1;1H\x1b[X');
@@ -320,8 +320,8 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.proxy.write('\x1b[c');
await pollFor(ctx.page, () => recordedData, ['\x1b[?1;2c']);
});
test.skip('CSI = Ps c - ', async () => {
// TODO: Implement
test('CSI = Ps c - ', async () => {
await assertNoModeChange('\x1b[=c');
});
test('CSI > Ps c - ', async () => {
await ctx.proxy.write('\x1b[>c');
@@ -491,6 +491,7 @@ test.describe('InputHandler Integration Tests', () => {
await pollFor(ctx.page, () => getLinesAsArray(2), ['1234Y', 'X']);
await ctx.proxy.resize(80, 24);
});
// Mode 45 is XTREVWRAP; covered by the test above.
test.skip('Ps = 4 5 - Enable Graphic Print Color Syntax (DECGPCS), VT340', async () => {
});
test('Ps = 4 6 - Start logging (XTLOGGING), xterm', async () => {
@@ -511,6 +512,7 @@ test.describe('InputHandler Integration Tests', () => {
await pollFor(ctx.page, async () => await ctx.proxy.buffer.active.type, 'normal');
await pollFor(ctx.page, () => getLinesAsArray(1), ['main']);
});
// Mode 47 is the alternate screen buffer; covered by the test above.
test.skip('Ps = 4 7 - Enable Graphic Rotated Print Mode (DECGRPM), VT340', async () => {
});
test('Ps = 6 6 - Application keypad mode (DECNKM), VT320', async () => {
@@ -724,11 +726,11 @@ test.describe('InputHandler Integration Tests', () => {
await assertNoModeChange('\x1b[?2006h');
});
});
test.skip('CSI Ps i - MC: Media Copy', async () => {
// TODO: Implement
test('CSI Ps i - MC: Media Copy', async () => {
await assertNoModeChange('\x1b[0i');
});
test.skip('CSI ? Ps i - MC: Media Copy, DEC-specified', async () => {
// TODO: Implement
test('CSI ? Ps i - MC: Media Copy, DEC-specified', async () => {
await assertNoModeChange('\x1b[?0i');
});
test('CSI Pm l - RM: Reset Mode', async () => {
await ctx.proxy.write('\x1b[4h\x1b[20h');
@@ -856,6 +858,7 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.proxy.write('\x1b[?45l');
await pollFor(ctx.page, async () => (await ctx.proxy.modes).reverseWraparoundMode, false);
});
// Mode 45 is XTREVWRAP; covered by the test above.
test.skip('Ps = 4 5 - Disable Graphic Print Color Syntax (DECGPCS), VT340.', async () => {
});
test('Ps = 4 6 - Stop logging (XTLOGGING), xterm. This is normally disabled by a compile-time option.', async () => {
@@ -867,6 +870,7 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.proxy.write('\x1b[?47l');
await pollFor(ctx.page, async () => await ctx.proxy.buffer.active.type, 'normal');
});
// Mode 47 is the alternate screen buffer; covered by the test above.
test.skip('Ps = 4 7 - Disable Graphic Rotated Print Mode (DECGRPM), VT340.', async () => {
});
test('Ps = 6 6 - Numeric keypad mode (DECNKM), VT320.', async () => {
@@ -1398,11 +1402,11 @@ test.describe('InputHandler Integration Tests', () => {
deepStrictEqual(await cell!.getBgColor(), 0x123456);
});
});
test.skip('CSI > Pp [; Pv] m - XTMODKEYS: Set/reset key modifier options, xterm', () => {
// TODO: Implement
test('CSI > Pp [; Pv] m - XTMODKEYS: Set/reset key modifier options, xterm', async () => {
await assertNoModeChange('\x1b[>2;1m');
});
test.skip('CSI ? Pp m - XTQMODKEYS: Query key modifier options, xterm', () => {
// TODO: Implement
test('CSI ? Pp m - XTQMODKEYS: Query key modifier options, xterm', async () => {
await assertNoModeChange('\x1b[?27m');
});
test.describe('CSI Ps n - DSR: Device Status Report', () => {
test('Status Report - CSI 5 n', async () => {
@@ -1430,8 +1434,8 @@ test.describe('InputHandler Integration Tests', () => {
deepStrictEqual(recordedData, ['\x1b[?3;4R']);
});
});
test.skip('CSI > Ps n - Disable key modifier options, xterm', () => {
// TODO: Implement
test('CSI > Ps n - Disable key modifier options, xterm', async () => {
await assertNoModeChange('\x1b[>0n');
});
test.describe('CSI ? Ps n - DECDSR: Device Status Report (DEC-specific)', () => {
test('Color Scheme Query - CSI ? 996 n (dark theme)', async () => {
@@ -1458,8 +1462,8 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.page.evaluate(`window.term.options.vtExtensions = { colorSchemeQuery: true }`);
});
});
test.skip('CSI > Ps p - XTSMPOINTER: Set resource value pointerMode, xterm', () => {
// TODO: Implement
test('CSI > Ps p - XTSMPOINTER: Set resource value pointerMode, xterm', async () => {
await assertNoModeChange('\x1b[>3p');
});
test('CSI ! p - DECSTR: Soft terminal reset, VT220 and up.', async () => {
const rows = await ctx.proxy.rows;
@@ -1471,8 +1475,8 @@ test.describe('InputHandler Integration Tests', () => {
await pollFor(ctx.page, async () => (await ctx.proxy.modes).originMode, false);
await pollFor(ctx.page, () => ctx.page.evaluate(`({ top: window.term._core._bufferService.buffer.scrollTop, bottom: window.term._core._bufferService.buffer.scrollBottom })`), { top: 0, bottom: rows - 1 });
});
test.skip('CSI Pl ; Pc " p - DECSCL: Set conformance level, VT220 and up.', () => {
// TODO: Implement
test('CSI Pl ; Pc " p - DECSCL: Set conformance level, VT220 and up.', async () => {
await assertNoModeChange('\x1b[61;0"p');
});
test('CSI Ps $ p - DECRQM: Request ANSI mode', async () => {
await ctx.proxy.write('\x1b[4h');
@@ -1499,8 +1503,8 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.proxy.write('\x1b[?1$p');
deepStrictEqual(recordedData, ['\x1b[?1;2$y']);
});
test.skip('CSI [Pm] # p - Push video attributes onto stack (XTPUSHSGR), xterm. This is an alias for CSI # { , used to work around language limitations of C#.', async () => {
// TODO: Implement
test('CSI [Pm] # p - Push video attributes onto stack (XTPUSHSGR), xterm. This is an alias for CSI # { , used to work around language limitations of C#.', async () => {
await assertNoModeChange('\x1b[#p');
});
test('CSI > Ps q - Report xterm name and version (XTVERSION).', async () => {
await ctx.proxy.write('\x1b[>q');
@@ -1508,8 +1512,8 @@ test.describe('InputHandler Integration Tests', () => {
ok(recordedData[0].startsWith('\x1bP>|xterm.js('));
ok(recordedData[0].endsWith('\x1b\\'));
});
test.skip('CSI Ps q - Load LEDs (DECLL), VT100.', async () => {
// TODO: Implement
test('CSI Ps q - Load LEDs (DECLL), VT100.', async () => {
await assertNoModeChange('\x1b[0q');
});
test('CSI Ps SP q - Set cursor style (DECSCUSR), VT520.', async () => {
const getCursorMode = async () => ctx.proxy.core.evaluate(([core]) => {
@@ -1540,8 +1544,8 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.proxy.write('\x1b[1;1H\x1b[?2K');
await pollFor(ctx.page, () => getLinesAsArray(1), ['PROT']);
});
test.skip('CSI # q - Pop video attributes from stack (XTPOPSGR), xterm.', async () => {
// TODO: Implement
test('CSI # q - Pop video attributes from stack (XTPOPSGR), xterm.', async () => {
await assertNoModeChange('\x1b[#q');
});
test('CSI Ps ; Ps r - Set Scrolling Region [top;bottom] (default = full size of window) (DECSTBM), VT100.', async () => {
const rows = await ctx.proxy.rows;
@@ -1550,11 +1554,11 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.proxy.write('\x1b[r');
await pollFor(ctx.page, () => ctx.page.evaluate(`({ top: window.term._core._bufferService.buffer.scrollTop, bottom: window.term._core._bufferService.buffer.scrollBottom })`), { top: 0, bottom: rows - 1 });
});
test.skip('CSI ? Pm r - Restore DEC Private Mode Values (XTRESTORE), xterm.', async () => {
// TODO: Implement
test('CSI ? Pm r - Restore DEC Private Mode Values (XTRESTORE), xterm.', async () => {
await assertNoModeChange('\x1b[?1r');
});
test.skip('CSI Pt ; Pl ; Pb ; Pr ; Pm $ r - Change Attributes in Rectangular Area (DECCARA), VT400 and up.', async () => {
// TODO: Implement
test('CSI Pt ; Pl ; Pb ; Pr ; Pm $ r - Change Attributes in Rectangular Area (DECCARA), VT400 and up.', async () => {
await assertNoModeChange('\x1b[1;1;1;1;0$r');
});
test('CSI s - Save cursor, available only when DECLRMM is disabled (SCOSC, also ANSI.SYS).', async () => {
await ctx.proxy.write('\x1b[3;4H');
@@ -1563,23 +1567,23 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.proxy.write('\x1b[u');
await pollFor(ctx.page, () => getCursor(), { col: 3, row: 2 });
});
// Parsed as SCOSC (CSI s) today; keep skipped until DECSLRM is implemented.
test.skip('CSI Pl ; Pr s - Set left and right margins (DECSLRM), VT420 and up.', async () => {
// TODO: Implement
});
test.skip('CSI > Ps s - Set/reset shift-escape options (XTSHIFTESCAPE), xterm.', async () => {
// TODO: Implement
test('CSI > Ps s - Set/reset shift-escape options (XTSHIFTESCAPE), xterm.', async () => {
await assertNoModeChange('\x1b[>0s');
});
test.skip('CSI ? Pm s - Save DEC Private Mode Values (XTSAVE), xterm. Ps values are the same as for DECSET.', async () => {
// TODO: Implement
test('CSI ? Pm s - Save DEC Private Mode Values (XTSAVE), xterm. Ps values are the same as for DECSET.', async () => {
await assertNoModeChange('\x1b[?1s');
});
test.skip('CSI > Pm t - This xterm control sets one or more features of the title modes (XTSMTITLE), xterm.', async () => {
// TODO: Implement
test('CSI > Pm t - This xterm control sets one or more features of the title modes (XTSMTITLE), xterm.', async () => {
await assertNoModeChange('\x1b[>3t');
});
test.skip('CSI Ps SP t - Set warning-bell volume (DECSWBV), VT520.', async () => {
// TODO: Implement
test('CSI Ps SP t - Set warning-bell volume (DECSWBV), VT520.', async () => {
await assertNoModeChange('\x1b[1 t');
});
test.skip('CSI Pt ; Pl ; Pb ; Pr ; Pm $ t - Reverse Attributes in Rectangular Area (DECRARA), VT400 and up.', async () => {
// TODO: Implement
test('CSI Pt ; Pl ; Pb ; Pr ; Pm $ t - Reverse Attributes in Rectangular Area (DECRARA), VT400 and up.', async () => {
await assertNoModeChange('\x1b[1;1;1;1;0$t');
});
test('CSI u - Restore cursor (SCORC, also ANSI.SYS).', async () => {
await ctx.proxy.write('\x1b[4;6H');
@@ -1588,62 +1592,62 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.proxy.write('\x1b[u');
await pollFor(ctx.page, () => getCursor(), { col: 5, row: 3 });
});
test.skip('CSI Ps SP u - Set margin-bell volume (DECSMBV), VT520.', async () => {
// TODO: Implement
test('CSI Ps SP u - Set margin-bell volume (DECSMBV), VT520.', async () => {
await assertNoModeChange('\x1b[1 u');
});
test.skip('CSI Pt ; Pl ; Pb ; Pr ; Pp ; Pt ; Pl ; Pp $ v - Copy Rectangular Area (DECCRA), VT400 and up.', async () => {
// TODO: Implement
test('CSI Pt ; Pl ; Pb ; Pr ; Pp ; Pt ; Pl ; Pp $ v - Copy Rectangular Area (DECCRA), VT400 and up.', async () => {
await assertNoModeChange('\x1b[1;1;1;1;1;1;1;1$v');
});
test.skip('CSI Ps $ w - Request presentation state report (DECRQPSR), VT320 and up.', async () => {
// TODO: Implement
test('CSI Ps $ w - Request presentation state report (DECRQPSR), VT320 and up.', async () => {
await assertNoModeChange('\x1b[1$w');
});
test.skip('CSI Pt ; Pl ; Pb ; Pr \' w - Enable Filter Rectangle (DECEFR), VT420 and up.', async () => {
// TODO: Implement
test('CSI Pt ; Pl ; Pb ; Pr \' w - Enable Filter Rectangle (DECEFR), VT420 and up.', async () => {
await assertNoModeChange('\x1b[1;1;1;1\'w');
});
test.skip('CSI Ps x - Request Terminal Parameters (DECREQTPARM).', async () => {
// TODO: Implement
test('CSI Ps x - Request Terminal Parameters (DECREQTPARM).', async () => {
await assertNoModeChange('\x1b[0x');
});
test.skip('CSI Ps * x - Select Attribute Change Extent (DECSACE), VT420 and up.', async () => {
// TODO: Implement
test('CSI Ps * x - Select Attribute Change Extent (DECSACE), VT420 and up.', async () => {
await assertNoModeChange('\x1b[0*x');
});
test.skip('CSI Pc ; Pt ; Pl ; Pb ; Pr $ x - Fill Rectangular Area (DECFRA), VT420 and up.', async () => {
// TODO: Implement
test('CSI Pc ; Pt ; Pl ; Pb ; Pr $ x - Fill Rectangular Area (DECFRA), VT420 and up.', async () => {
await assertNoModeChange('\x1b[0;0;1;1;1$x');
});
test.skip('CSI Ps # y - Select checksum extension (XTCHECKSUM), xterm.', async () => {
// TODO: Implement
test('CSI Ps # y - Select checksum extension (XTCHECKSUM), xterm.', async () => {
await assertNoModeChange('\x1b[0#y');
});
test.skip('CSI Pi ; Pg ; Pt ; Pl ; Pb ; Pr * y - Request Checksum of Rectangular Area (DECRQCRA), VT420 and up.', async () => {
// TODO: Implement
test('CSI Pi ; Pg ; Pt ; Pl ; Pb ; Pr * y - Request Checksum of Rectangular Area (DECRQCRA), VT420 and up.', async () => {
await assertNoModeChange('\x1b[0;0;1;1;1*y');
});
test.skip('CSI Ps ; Pu \' z - Enable Locator Reporting (DECELR).', async () => {
// TODO: Implement
test('CSI Ps ; Pu \' z - Enable Locator Reporting (DECELR).', async () => {
await assertNoModeChange('\x1b[0\'z');
});
test.skip('CSI Pt ; Pl ; Pb ; Pr $ z - Erase Rectangular Area (DECERA), VT400 and up.', async () => {
// TODO: Implement
test('CSI Pt ; Pl ; Pb ; Pr $ z - Erase Rectangular Area (DECERA), VT400 and up.', async () => {
await assertNoModeChange('\x1b[1;1;1;1$z');
});
test.skip('CSI Pm \' { - Select Locator Events (DECSLE).', async () => {
// TODO: Implement
test('CSI Pm \' { - Select Locator Events (DECSLE).', async () => {
await assertNoModeChange('\x1b[0\'{');
});
test.skip('CSI [Pm] # { Push video attributes onto stack (XTPUSHSGR), xterm.', async () => {
// TODO: Implement
test('CSI [Pm] # { Push video attributes onto stack (XTPUSHSGR), xterm.', async () => {
await assertNoModeChange('\x1b[#{');
});
test.skip('CSI Pt ; Pl ; Pb ; Pr $ { - Selective Erase Rectangular Area (DECSERA), VT400 and up.', async () => {
// TODO: Implement
test('CSI Pt ; Pl ; Pb ; Pr $ { - Selective Erase Rectangular Area (DECSERA), VT400 and up.', async () => {
await assertNoModeChange('\x1b[1;1;1;1${');
});
test.skip('CSI Pt ; Pl ; Pb ; Pr # | - Report selected graphic rendition (XTREPORTSGR), xterm.', async () => {
// TODO: Implement
test('CSI Pt ; Pl ; Pb ; Pr # | - Report selected graphic rendition (XTREPORTSGR), xterm.', async () => {
await assertNoModeChange('\x1b[1;1;1;1#|');
});
test.skip('CSI Ps $ | - Select columns per page (DECSCPP), VT340.', async () => {
// TODO: Implement
test('CSI Ps $ | - Select columns per page (DECSCPP), VT340.', async () => {
await assertNoModeChange('\x1b[80$|');
});
test.skip('CSI Ps \' | - Request Locator Position (DECRQLP).', async () => {
// TODO: Implement
test('CSI Ps \' | - Request Locator Position (DECRQLP).', async () => {
await assertNoModeChange('\x1b[0\'|');
});
test.skip('CSI Ps * | - Select number of lines per screen (DECSNLS), VT420 and up.', async () => {
// TODO: Implement
test('CSI Ps * | - Select number of lines per screen (DECSNLS), VT420 and up.', async () => {
await assertNoModeChange('\x1b[24*|');
});
test.skip('CSI # } - Pop video attributes from stack (XTPOPSGR), xterm.', async () => {
// TODO: Implement
test('CSI # } - Pop video attributes from stack (XTPOPSGR), xterm.', async () => {
await assertNoModeChange('\x1b[#}');
});
test('CSI Ps \' } - Insert Ps Column(s) (default = 1) (DECIC), VT420 and up.', async () => {
await ctx.proxy.resize(5, 5);
@@ -1652,8 +1656,8 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.proxy.write('\x1b[\'}');
await pollFor(ctx.page, () => getLinesAsArray(6), ['12345', '12 34', '12 34', '12 34', '12 34', '12 34']);
});
test.skip('CSI Ps $ } - Select active status display (DECSASD), VT320 and up.', async () => {
// TODO: Implement
test('CSI Ps $ } - Select active status display (DECSASD), VT320 and up.', async () => {
await assertNoModeChange('\x1b[0$}');
});
test('CSI Ps \' ~ - Delete Ps Column(s) (default = 1) (DECDC), VT420 and up.', async () => {
await ctx.proxy.resize(5, 5);
@@ -1662,8 +1666,8 @@ test.describe('InputHandler Integration Tests', () => {
await ctx.proxy.write('\x1b[\'~');
await pollFor(ctx.page, () => getLinesAsArray(6), ['12345', '1245', '1245', '1245', '1245', '1245']);
});
test.skip('CSI Ps $ ~ - Select status line type (DECSSDT), VT320 and up.', async () => {
// TODO: Implement
test('CSI Ps $ ~ - Select status line type (DECSSDT), VT320 and up.', async () => {
await assertNoModeChange('\x1b[0$~');
});
test.describe('CSI Ps ; Ps ; Ps t - Window Options', () => {
test('should be disabled by default', async () => {
@@ -1686,6 +1690,28 @@ test.describe('InputHandler Integration Tests', () => {
const d = await getDimensions();
deepStrictEqual(recordedData, [`\x1b[6;${d.cellHeight};${d.cellWidth}t`]);
});
test('18 - GetWinSizeChars', async () => {
await ctx.proxy.setOption('windowOptions', { getWinSizeChars: true });
await ctx.proxy.write('\x1b[18t');
deepStrictEqual(recordedData, [`\x1b[8;${await ctx.proxy.rows};${await ctx.proxy.cols}t`]);
});
test('22/23 - PushTitle/PopTitle', async () => {
const titles: string[] = [];
const titleDisposable = ctx.proxy.onTitleChange(t => titles.push(t));
await ctx.proxy.setOption('windowOptions', { pushTitle: true, popTitle: true });
await ctx.proxy.write('\x1b]0;1\x07');
await ctx.proxy.write('\x1b[22t');
await ctx.proxy.write('\x1b]0;2\x07');
await ctx.proxy.write('\x1b[22t');
await ctx.proxy.write('\x1b]0;3\x07');
await ctx.proxy.write('\x1b[22t');
await pollFor(ctx.page, () => titles, ['1', '2', '3']);
await ctx.proxy.write('\x1b[23t');
await ctx.proxy.write('\x1b[23t');
await ctx.proxy.write('\x1b[23t');
await pollFor(ctx.page, () => titles, ['1', '2', '3', '3', '2', '1']);
titleDisposable.dispose();
});
});
});