Merge branch 'master' of https://github.com/xtermjs/xterm.js into playwright

This commit is contained in:
Jon Bockhorst
2020-02-12 23:53:53 -06:00
22 changed files with 478 additions and 692 deletions
@@ -4,9 +4,8 @@
*/
import * as playwright from 'playwright';
import { assert } from 'chai';
import { ITerminalOptions } from 'xterm';
import WebSocket = require('ws');
import { openTerminal, pollFor } from '../../../out-test/api/TestUtils';
const APP = 'http://127.0.0.1:3000/test';
@@ -37,7 +36,7 @@ describe('AttachAddon', () => {
it('string', async function(): Promise<any> {
this.timeout(20000);
await openTerminal({ rendererType: 'dom' });
await openTerminal(page, { rendererType: 'dom' });
const port = 8080;
const server = new WebSocket.Server({ port });
server.on('connection', socket => socket.send('foo'));
@@ -48,7 +47,7 @@ describe('AttachAddon', () => {
it('utf8', async function(): Promise<any> {
this.timeout(20000);
await openTerminal({ rendererType: 'dom' });
await openTerminal(page, { rendererType: 'dom' });
const port = 8080;
const server = new WebSocket.Server({ port });
const data = new Uint8Array([102, 111, 111]);
@@ -58,37 +57,3 @@ describe('AttachAddon', () => {
server.close();
});
});
async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`);
await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);
if (options.rendererType === 'dom') {
await page.waitForSelector('.xterm-rows');
} else {
await page.waitForSelector('.xterm-text-layer');
}
}
async function pollFor(page: playwright.Page, fn: string, val: any): Promise<void> {
const result = await page.evaluate(fn);
if (result !== val) {
return new Promise<void>(r => {
setTimeout(() => r(pollFor(page, fn, val)), 10);
});
}
}
function getBrowserType(): playwright.BrowserType {
// Default to chromium
let browserType: playwright.BrowserType = playwright['chromium'];
const index = process.argv.indexOf('--browser');
if (index !== -1 && process.argv.length > index + 2 && typeof process.argv[index + 1] === 'string') {
const string = process.argv[index + 1];
if (string === 'firefox' || string === 'webkit') {
browserType = playwright[string];
}
}
return browserType;
}
+5 -1
View File
@@ -10,7 +10,11 @@
"outDir": "../out",
"sourceMap": true,
"removeComments": true,
"strict": true
"strict": true,
"types": [
"../../../node_modules/@types/mocha",
"../../../out-test/api/TestUtils"
]
},
"include": [
"./**/*",
+2 -27
View File
@@ -5,7 +5,7 @@
import * as playwright from 'playwright';
import { assert } from 'chai';
import { ITerminalOptions } from 'xterm';
import { openTerminal } from '../../../out-test/api/TestUtils';
const APP = 'http://127.0.0.1:3000/test';
@@ -24,7 +24,7 @@ describe('FitAddon', () => {
page = (await browser.defaultContext().pages())[0];
await page.setViewport({ width, height });
await page.goto(APP);
await openTerminal();
await openTerminal(page);
});
after(async () => {
@@ -106,28 +106,3 @@ async function loadFit(width: number = 800, height: number = 450): Promise<void>
async function unloadFit(): Promise<void> {
await page.evaluate(`window.fit.dispose();`);
}
async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`);
await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);
if (options.rendererType === 'dom') {
await page.waitForSelector('.xterm-rows');
} else {
await page.waitForSelector('.xterm-text-layer');
}
}
function getBrowserType(): playwright.BrowserType {
// Default to chromium
let browserType: playwright.BrowserType = playwright['chromium'];
const index = process.argv.indexOf('--browser');
if (index !== -1 && process.argv.length > index + 2 && typeof process.argv[index + 1] === 'string') {
const string = process.argv[index + 1];
if (string === 'firefox' || string === 'webkit') {
browserType = playwright[string];
}
}
return browserType;
}
+5 -1
View File
@@ -10,7 +10,11 @@
"outDir": "../out",
"sourceMap": true,
"removeComments": true,
"strict": true
"strict": true,
"types": [
"../../../node_modules/@types/mocha",
"../../../out-test/api/TestUtils"
]
},
"include": [
"./**/*",
@@ -5,9 +5,9 @@
import * as playwright from 'playwright';
import { assert } from 'chai';
import { ITerminalOptions } from 'xterm';
import { readFile } from 'fs';
import { resolve } from 'path';
import { openTerminal, writeSync } from '../../../out-test/api/TestUtils';
const APP = 'http://127.0.0.1:3000/test';
@@ -27,7 +27,7 @@ describe('Search Tests', function(): void {
page = (await browser.defaultContext().pages())[0];
await page.setViewport({ width, height });
await page.goto(APP);
await openTerminal();
await openTerminal(page);
await page.evaluate(`window.search = new SearchAddon();`);
await page.evaluate(`window.term.loadAddon(window.search);`);
});
@@ -41,7 +41,7 @@ describe('Search Tests', function(): void {
});
it('Simple Search', async () => {
await writeSync('dafhdjfldshafhldsahfkjhldhjkftestlhfdsakjfhdjhlfdsjkafhjdlk');
await writeSync(page, 'dafhdjfldshafhldsahfkjhldhjkftestlhfdsakjfhdjhlfdsjkafhjdlk');
assert.deepEqual(await page.evaluate(`window.search.findNext('test')`), true);
assert.deepEqual(await page.evaluate(`window.term.getSelection()`), 'test');
});
@@ -54,13 +54,13 @@ describe('Search Tests', function(): void {
}
dataString += makeData(50);
}
await writeSync(dataString);
await writeSync(page, dataString);
assert.deepEqual(await page.evaluate(`window.search.findNext('$^1_3{}test$#')`), true);
assert.deepEqual(await page.evaluate(`window.term.getSelection()`), '$^1_3{}test$#');
});
it('Incremental Find Previous', async () => {
await page.evaluate(`window.term.writeln('package.jsonc\\n')`);
await writeSync('package.json pack package.lock');
await writeSync(page, 'package.json pack package.lock');
await page.evaluate(`window.search.findPrevious('pack', {incremental: true})`);
let line: string = await page.evaluate(`window.term.buffer.getLine(window.term.getSelectionPosition().startRow).translateToString()`);
let selectionPosition: { startColumn: number, startRow: number, endColumn: number, endRow: number } = await page.evaluate(`window.term.getSelectionPosition()`);
@@ -77,7 +77,7 @@ describe('Search Tests', function(): void {
});
it('Incremental Find Next', async () => {
await page.evaluate(`window.term.writeln('package.lock pack package.json package.ups\\n')`);
await writeSync('package.jsonc');
await writeSync(page, 'package.jsonc');
await page.evaluate(`window.search.findNext('pack', {incremental: true})`);
let line: string = await page.evaluate(`window.term.buffer.getLine(window.term.getSelectionPosition().startRow).translateToString()`);
let selectionPosition: { startColumn: number, startRow: number, endColumn: number, endRow: number } = await page.evaluate(`window.term.getSelectionPosition()`);
@@ -93,7 +93,7 @@ describe('Search Tests', function(): void {
assert.deepEqual(line.substring(selectionPosition.startColumn, selectionPosition.endColumn), 'package.jsonc');
});
it('Simple Regex', async () => {
await writeSync('abc123defABCD');
await writeSync(page, 'abc123defABCD');
await page.evaluate(`window.search.findNext('[a-z]+', {regex: true})`);
assert.deepEqual(await page.evaluate(`window.term.getSelection()`), 'abc');
await page.evaluate(`window.search.findNext('[A-Z]+', {regex: true, caseSensitive: true})`);
@@ -101,7 +101,7 @@ describe('Search Tests', function(): void {
});
it('Search for single result twice should not unselect it', async () => {
await writeSync('abc def');
await writeSync(page, 'abc def');
assert.deepEqual(await page.evaluate(`window.search.findNext('abc')`), true);
assert.deepEqual(await page.evaluate(`window.term.getSelection()`), 'abc');
assert.deepEqual(await page.evaluate(`window.search.findNext('abc')`), true);
@@ -118,7 +118,7 @@ describe('Search Tests', function(): void {
.replace(/'/g, '\\\'');
});
it('should find all occurrences using findNext', async () => {
await writeSync(fixture);
await writeSync(page, fixture);
assert.deepEqual(await page.evaluate(`window.search.findNext('opencv')`), true);
let selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 24, startRow: 53, endColumn: 30, endRow: 53 });
@@ -152,7 +152,7 @@ describe('Search Tests', function(): void {
assert.deepEqual(selectionPosition, { startColumn: 24, startRow: 53, endColumn: 30, endRow: 53 });
});
it('should find all occurrences using findPrevious', async () => {
await writeSync(fixture);
await writeSync(page, fixture);
assert.deepEqual(await page.evaluate(`window.search.findPrevious('opencv')`), true);
let selectionPosition = await page.evaluate(`window.term.getSelectionPosition()`);
assert.deepEqual(selectionPosition, { startColumn: 11, startRow: 136, endColumn: 17, endRow: 136 });
@@ -189,20 +189,6 @@ describe('Search Tests', function(): void {
});
});
async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`);
await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);
if (options.rendererType === 'dom') {
await page.waitForSelector('.xterm-rows');
} else {
await page.waitForSelector('.xterm-text-layer');
}
}
async function writeSync(data: string): Promise<void> {
return page.evaluate(`new Promise(resolve => window.term.write('${data}', resolve))`);
}
function makeData(length: number): string {
let result = '';
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
+5 -1
View File
@@ -10,7 +10,11 @@
"outDir": "../out",
"sourceMap": true,
"removeComments": true,
"strict": true
"strict": true,
"types": [
"../../../node_modules/@types/mocha",
"../../../out-test/api/TestUtils"
]
},
"include": [
"./**/*",
@@ -5,7 +5,7 @@
import * as playwright from 'playwright';
import { assert } from 'chai';
import { ITerminalOptions } from 'xterm';
import { openTerminal, writeSync } from '../../../out-test/api/TestUtils';
const APP = 'http://127.0.0.1:3000/test';
@@ -23,7 +23,7 @@ describe('SerializeAddon', () => {
page = (await browser.defaultContext().pages())[0];
await page.setViewport({ width, height });
await page.goto(APP);
await openTerminal({ rows: 10, cols: 10, rendererType: 'dom' });
await openTerminal(page, { rows: 10, cols: 10, rendererType: 'dom' });
await page.evaluate(`
window.serializeAddon = new SerializeAddon();
window.term.loadAddon(window.serializeAddon);
@@ -272,16 +272,6 @@ describe('SerializeAddon', () => {
});
});
async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`);
await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);
if (options.rendererType === 'dom') {
await page.waitForSelector('.xterm-rows');
} else {
await page.waitForSelector('.xterm-text-layer');
}
}
function newArray<T>(initial: T | ((index: number) => T), count: number): T[] {
const array: T[] = new Array<T>(count);
for (let i = 0; i < array.length; i++) {
@@ -348,38 +338,3 @@ const DIM = '2';
const NO_ITALIC = '23';
const NO_DIM = '22';
async function writeSync(page: playwright.Page, data: string): Promise<void> {
await page.evaluate(`
window.ready = false;
window.term.write('${data}', () => window.ready = true);
`);
await pollFor(page, 'window.ready', true);
}
async function pollFor(page: playwright.Page, fn: string, val: any, preFn?: () => Promise<void>): Promise<void> {
if (preFn) {
await preFn();
}
const result = await page.evaluate(fn);
if (result !== val) {
return new Promise<void>(r => {
setTimeout(() => r(pollFor(page, fn, val, preFn)), 10);
});
}
}
function getBrowserType(): playwright.BrowserType {
// Default to chromium
let browserType: playwright.BrowserType = playwright['chromium'];
const index = process.argv.indexOf('--browser');
if (index !== -1 && process.argv.length > index + 2 && typeof process.argv[index + 1] === 'string') {
const string = process.argv[index + 1];
if (string === 'firefox' || string === 'webkit') {
browserType = playwright[string];
}
}
return browserType;
}
+11 -3
View File
@@ -12,15 +12,23 @@
"removeComments": true,
"baseUrl": ".",
"paths": {
"common/*": [ "../../../src/common/*" ]
"common/*": [
"../../../src/common/*"
]
},
"strict": true
"strict": true,
"types": [
"../../../node_modules/@types/mocha",
"../../../out-test/api/TestUtils"
]
},
"include": [
"./**/*",
"../../../typings/xterm.d.ts"
],
"references": [
{ "path": "../../../src/common" }
{
"path": "../../../src/common"
}
]
}
@@ -4,8 +4,8 @@
*/
import * as playwright from 'playwright';
import { ITerminalOptions } from 'xterm';
import { assert } from 'chai';
import { openTerminal } from '../../../out-test/api/TestUtils';
const APP = 'http://127.0.0.1:3000/test';
@@ -32,7 +32,7 @@ describe('Unicode11Addon', () => {
beforeEach(async function(): Promise<any> {
this.timeout(20000);
await page.goto(APP);
await openTerminal();
await openTerminal(page);
});
it('wcwidth V11 emoji test', async () => {
@@ -49,28 +49,3 @@ describe('Unicode11Addon', () => {
assert.deepEqual(await page.evaluate(`window.term._core.unicodeService.getStringCellWidth('🤣🤣🤣🤣🤣🤣🤣🤣🤣🤣')`), 20);
});
});
async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`);
await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);
if (options.rendererType === 'dom') {
await page.waitForSelector('.xterm-rows');
} else {
await page.waitForSelector('.xterm-text-layer');
}
}
function getBrowserType(): playwright.BrowserType {
// Default to chromium
let browserType: playwright.BrowserType = playwright['chromium'];
const index = process.argv.indexOf('--browser');
if (index !== -1 && process.argv.length > index + 2 && typeof process.argv[index + 1] === 'string') {
const string = process.argv[index + 1];
if (string === 'firefox' || string === 'webkit') {
browserType = playwright[string];
}
}
return browserType;
}
+10 -2
View File
@@ -13,14 +13,22 @@
"strict": true,
"baseUrl": ".",
"paths": {
"common/*": [ "../../../src/common/*" ]
"common/*": [
"../../../src/common/*"
]
},
"types": [
"../../../node_modules/@types/mocha",
"../../../out-test/api/TestUtils"
]
},
"include": [
"./**/*",
"../../../typings/xterm.d.ts"
],
"references": [
{ "path": "../../../src/common" }
{
"path": "../../../src/common"
}
]
}
@@ -5,7 +5,7 @@
import * as playwright from 'playwright';
import { assert } from 'chai';
import { ITerminalOptions } from 'xterm';
import { openTerminal, pollFor, writeSync } from '../../../out-test/api/TestUtils';
const APP = 'http://127.0.0.1:3000/test';
@@ -51,7 +51,7 @@ describe('WebLinksAddon', () => {
});
async function testHostName(hostname: string): Promise<void> {
await openTerminal({ rendererType: 'dom', cols: 40 });
await openTerminal(page, { rendererType: 'dom', cols: 40 });
await page.evaluate(`window.term.loadAddon(new window.WebLinksAddon())`);
const data = ` http://${hostname} \\r\\n` +
` http://${hostname}/a~b#c~d?e~f \\r\\n` +
@@ -70,16 +70,6 @@ async function testHostName(hostname: string): Promise<void> {
await pollForLinkAtCell(1, 7, `http://${hostname}/subpath/+/id`);
}
async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`);
await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);
if (options.rendererType === 'dom') {
await page.waitForSelector('.xterm-rows');
} else {
await page.waitForSelector('.xterm-text-layer');
}
}
async function pollForLinkAtCell(col: number, row: number, value: string): Promise<void> {
const rowSelector = `.xterm-rows > :nth-child(${row})`;
// Ensure the hover element exists before trying to hover it
@@ -87,38 +77,3 @@ async function pollForLinkAtCell(col: number, row: number, value: string): Promi
await pollFor(page, `document.querySelectorAll('${rowSelector} > span[style]').length >= ${value.length}`, true, async () => page.hover(`${rowSelector} > :nth-child(${col})`));
assert.equal(await page.evaluate(`Array.prototype.reduce.call(document.querySelectorAll('${rowSelector} > span[style]'), (a, b) => a + b.textContent, '');`), value);
}
async function pollFor(page: playwright.Page, fn: string, val: any, preFn?: () => Promise<void>): Promise<void> {
if (preFn) {
await preFn();
}
const result = await page.evaluate(fn);
if (result !== val) {
return new Promise<void>(r => {
setTimeout(() => r(pollFor(page, fn, val, preFn)), 10);
});
}
}
async function writeSync(page: playwright.Page, data: string): Promise<void> {
await page.evaluate(`
window.ready = false;
window.term.write('${data}', () => window.ready = true);
`);
await pollFor(page, 'window.ready', true);
}
function getBrowserType(): playwright.BrowserType {
// Default to chromium
let browserType: playwright.BrowserType = playwright['chromium'];
const index = process.argv.indexOf('--browser');
if (index !== -1 && process.argv.length > index + 2 && typeof process.argv[index + 1] === 'string') {
const string = process.argv[index + 1];
if (string === 'firefox' || string === 'webkit') {
browserType = playwright[string];
}
}
return browserType;
}
@@ -10,7 +10,11 @@
"outDir": "../out",
"sourceMap": true,
"removeComments": true,
"strict": true
"strict": true,
"types": [
"../../../node_modules/@types/mocha",
"../../../out-test/api/TestUtils"
]
},
"include": [
"./**/*",
@@ -7,7 +7,7 @@ import * as playwright from 'playwright';
import { ITerminalOptions } from '../../../src/Types';
import { ITheme } from 'xterm';
import { assert } from 'chai';
import deepEqual = require('deep-equal');
import { openTerminal, pollFor, writeSync } from '../../../out-test/api/TestUtils';
const APP = 'http://127.0.0.1:3000/test';
@@ -16,7 +16,7 @@ let page: playwright.Page;
const width = 800;
const height = 600;
describe('WebGL Renderer Integration Tests', function (): void {
describe('WebGL Renderer Integration Tests', function(): void {
it('dispose removes renderer canvases', async () => {
await setupBrowser();
assert.equal(await page.evaluate(`document.querySelectorAll('.xterm canvas').length`), 3);
@@ -42,7 +42,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
white: '#161718'
};
await page.evaluate(`window.term.setOption('theme', ${JSON.stringify(theme)});`);
await writeSync(`\\x1b[30m█\\x1b[31m█\\x1b[32m█\\x1b[33m█\\x1b[34m█\\x1b[35m█\\x1b[36m█\\x1b[37m█`);
await writeSync(page, `\\x1b[30m█\\x1b[31m█\\x1b[32m█\\x1b[33m█\\x1b[34m█\\x1b[35m█\\x1b[36m█\\x1b[37m█`);
await pollFor(page, () => getCellColor(1, 1), [1, 2, 3, 255]);
await pollFor(page, () => getCellColor(2, 1), [4, 5, 6, 255]);
await pollFor(page, () => getCellColor(3, 1), [7, 8, 9, 255]);
@@ -68,7 +68,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
window.term.setOption('theme', ${JSON.stringify(theme)});
window.term.setOption('drawBoldTextInBrightColors', true);
`);
await writeSync(`\\x1b[1;30m█\\x1b[1;31m█\\x1b[1;32m█\\x1b[1;33m█\\x1b[1;34m█\\x1b[1;35m█\\x1b[1;36m█\\x1b[1;37m█`);
await writeSync(page, `\\x1b[1;30m█\\x1b[1;31m█\\x1b[1;32m█\\x1b[1;33m█\\x1b[1;34m█\\x1b[1;35m█\\x1b[1;36m█\\x1b[1;37m█`);
await pollFor(page, () => getCellColor(1, 1), [1, 2, 3, 255]);
await pollFor(page, () => getCellColor(2, 1), [4, 5, 6, 255]);
await pollFor(page, () => getCellColor(3, 1), [7, 8, 9, 255]);
@@ -91,7 +91,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
white: '#161718'
};
await page.evaluate(`window.term.setOption('theme', ${JSON.stringify(theme)});`);
await writeSync(`\\x1b[40m \\x1b[41m \\x1b[42m \\x1b[43m \\x1b[44m \\x1b[45m \\x1b[46m \\x1b[47m `);
await writeSync(page, `\\x1b[40m \\x1b[41m \\x1b[42m \\x1b[43m \\x1b[44m \\x1b[45m \\x1b[46m \\x1b[47m `);
await pollFor(page, () => getCellColor(1, 1), [1, 2, 3, 255]);
await pollFor(page, () => getCellColor(2, 1), [4, 5, 6, 255]);
await pollFor(page, () => getCellColor(3, 1), [7, 8, 9, 255]);
@@ -114,7 +114,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
white: '#161718'
};
await page.evaluate(`window.term.setOption('theme', ${JSON.stringify(theme)});`);
await writeSync(`\\x1b[7;30m \\x1b[7;31m \\x1b[7;32m \\x1b[7;33m \\x1b[7;34m \\x1b[7;35m \\x1b[7;36m \\x1b[7;37m `);
await writeSync(page, `\\x1b[7;30m \\x1b[7;31m \\x1b[7;32m \\x1b[7;33m \\x1b[7;34m \\x1b[7;35m \\x1b[7;36m \\x1b[7;37m `);
await pollFor(page, () => getCellColor(1, 1), [1, 2, 3, 255]);
await pollFor(page, () => getCellColor(2, 1), [4, 5, 6, 255]);
await pollFor(page, () => getCellColor(3, 1), [7, 8, 9, 255]);
@@ -137,7 +137,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
white: '#161718'
};
await page.evaluate(`window.term.setOption('theme', ${JSON.stringify(theme)});`);
await writeSync(`\\x1b[7;40m█\\x1b[7;41m█\\x1b[7;42m█\\x1b[7;43m█\\x1b[7;44m█\\x1b[7;45m█\\x1b[7;46m█\\x1b[7;47m█`);
await writeSync(page, `\\x1b[7;40m█\\x1b[7;41m█\\x1b[7;42m█\\x1b[7;43m█\\x1b[7;44m█\\x1b[7;45m█\\x1b[7;46m█\\x1b[7;47m█`);
await pollFor(page, () => getCellColor(1, 1), [1, 2, 3, 255]);
await pollFor(page, () => getCellColor(2, 1), [4, 5, 6, 255]);
await pollFor(page, () => getCellColor(3, 1), [7, 8, 9, 255]);
@@ -160,7 +160,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
white: '#161718'
};
await page.evaluate(`window.term.setOption('theme', ${JSON.stringify(theme)});`);
await writeSync(`\\x1b[8;30m \\x1b[8;31m \\x1b[8;32m \\x1b[8;33m \\x1b[8;34m \\x1b[8;35m \\x1b[8;36m \\x1b[8;37m `);
await writeSync(page, `\\x1b[8;30m \\x1b[8;31m \\x1b[8;32m \\x1b[8;33m \\x1b[8;34m \\x1b[8;35m \\x1b[8;36m \\x1b[8;37m `);
await pollFor(page, () => getCellColor(1, 1), [0, 0, 0, 255]);
await pollFor(page, () => getCellColor(2, 1), [0, 0, 0, 255]);
await pollFor(page, () => getCellColor(3, 1), [0, 0, 0, 255]);
@@ -183,7 +183,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
white: '#161718'
};
await page.evaluate(`window.term.setOption('theme', ${JSON.stringify(theme)});`);
await writeSync(`\\x1b[8;40m█\\x1b[8;41m█\\x1b[8;42m█\\x1b[8;43m█\\x1b[8;44m█\\x1b[8;45m█\\x1b[8;46m█\\x1b[8;47m█`);
await writeSync(page, `\\x1b[8;40m█\\x1b[8;41m█\\x1b[8;42m█\\x1b[8;43m█\\x1b[8;44m█\\x1b[8;45m█\\x1b[8;46m█\\x1b[8;47m█`);
await pollFor(page, () => getCellColor(1, 1), [1, 2, 3, 255]);
await pollFor(page, () => getCellColor(2, 1), [4, 5, 6, 255]);
await pollFor(page, () => getCellColor(3, 1), [7, 8, 9, 255]);
@@ -206,7 +206,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
brightWhite: '#161718'
};
await page.evaluate(`window.term.setOption('theme', ${JSON.stringify(theme)});`);
await writeSync(`\\x1b[90m█\\x1b[91m█\\x1b[92m█\\x1b[93m█\\x1b[94m█\\x1b[95m█\\x1b[96m█\\x1b[97m█`);
await writeSync(page, `\\x1b[90m█\\x1b[91m█\\x1b[92m█\\x1b[93m█\\x1b[94m█\\x1b[95m█\\x1b[96m█\\x1b[97m█`);
await pollFor(page, () => getCellColor(1, 1), [1, 2, 3, 255]);
await pollFor(page, () => getCellColor(2, 1), [4, 5, 6, 255]);
await pollFor(page, () => getCellColor(3, 1), [7, 8, 9, 255]);
@@ -229,7 +229,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
brightWhite: '#161718'
};
await page.evaluate(`window.term.setOption('theme', ${JSON.stringify(theme)});`);
await writeSync(`\\x1b[100m \\x1b[101m \\x1b[102m \\x1b[103m \\x1b[104m \\x1b[105m \\x1b[106m \\x1b[107m `);
await writeSync(page, `\\x1b[100m \\x1b[101m \\x1b[102m \\x1b[103m \\x1b[104m \\x1b[105m \\x1b[106m \\x1b[107m `);
await pollFor(page, () => getCellColor(1, 1), [1, 2, 3, 255]);
await pollFor(page, () => getCellColor(2, 1), [4, 5, 6, 255]);
await pollFor(page, () => getCellColor(3, 1), [7, 8, 9, 255]);
@@ -248,7 +248,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 240 / 16; y++) {
for (let x = 0; x < 16; x++) {
const cssColor = COLORS_16_TO_255[y * 16 + x];
@@ -268,7 +268,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 240 / 16; y++) {
for (let x = 0; x < 16; x++) {
const cssColor = COLORS_16_TO_255[y * 16 + x];
@@ -288,7 +288,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 240 / 16; y++) {
for (let x = 0; x < 16; x++) {
const cssColor = COLORS_16_TO_255[y * 16 + x];
@@ -308,7 +308,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 240 / 16; y++) {
for (let x = 0; x < 16; x++) {
const cssColor = COLORS_16_TO_255[y * 16 + x];
@@ -328,7 +328,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 240 / 16; y++) {
for (let x = 0; x < 16; x++) {
const cssColor = COLORS_16_TO_255[y * 16 + x];
@@ -348,7 +348,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 240 / 16; y++) {
for (let x = 0; x < 16; x++) {
const cssColor = COLORS_16_TO_255[y * 16 + x];
@@ -369,7 +369,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -387,7 +387,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -405,7 +405,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -423,7 +423,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -441,7 +441,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -459,7 +459,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -477,7 +477,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -495,7 +495,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -504,7 +504,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
});
it('foreground true color red inverse', async function (): Promise<void> {
it('foreground true color red inverse', async function(): Promise<void> {
let data = '';
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
@@ -513,7 +513,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -522,7 +522,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
});
it('background true color red inverse', async function (): Promise<void> {
it('background true color red inverse', async function(): Promise<void> {
let data = '';
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
@@ -531,7 +531,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -549,7 +549,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -567,7 +567,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -585,7 +585,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -603,7 +603,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -621,7 +621,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -639,7 +639,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -657,7 +657,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -675,7 +675,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
}
data += '\\r\\n';
}
await writeSync(data);
await writeSync(page, data);
for (let y = 0; y < 16; y++) {
for (let x = 0; x < 16; x++) {
const i = y * 16 + x;
@@ -713,7 +713,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
window.term.setOption('theme', ${JSON.stringify(theme)});
window.term.setOption('minimumContrastRatio', 1);
`);
await writeSync(
await writeSync(page,
`\\x1b[30m█\\x1b[31m█\\x1b[32m█\\x1b[33m█\\x1b[34m█\\x1b[35m█\\x1b[36m█\\x1b[37m█\\r\\n` +
`\\x1b[90m█\\x1b[91m█\\x1b[92m█\\x1b[93m█\\x1b[94m█\\x1b[95m█\\x1b[96m█\\x1b[97m█`
);
@@ -781,7 +781,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
window.term.setOption('theme', ${JSON.stringify(theme)});
window.term.setOption('minimumContrastRatio', 1);
`);
await writeSync(
await writeSync(page,
`\\x1b[30m█\\x1b[31m█\\x1b[32m█\\x1b[33m█\\x1b[34m█\\x1b[35m█\\x1b[36m█\\x1b[37m█\\r\\n` +
`\\x1b[90m█\\x1b[91m█\\x1b[92m█\\x1b[93m█\\x1b[94m█\\x1b[95m█\\x1b[96m█\\x1b[97m█`
);
@@ -837,7 +837,7 @@ describe('WebGL Renderer Integration Tests', function (): void {
selection: '#0000FF'
};
await page.evaluate(`window.term.setOption('theme', ${JSON.stringify(theme)});`);
await writeSync(`\\x1b[7m█\\x1b[0m`);
await writeSync(page, `\\x1b[7m█\\x1b[0m`);
await pollFor(page, () => getCellColor(1, 1), [0, 255, 0, 255]);
await pollFor(page, () => getCellColor(2, 1), [255, 0, 0, 255]);
await pollFor(page, () => getCellColor(3, 1), [0, 255, 0, 255]);
@@ -859,27 +859,13 @@ describe('WebGL Renderer Integration Tests', function (): void {
};
await page.evaluate(`window.term.setOption('theme', ${JSON.stringify(theme)});`);
const data = `\\x1b[7m█\x1b[0m`;
await writeSync(data);
await writeSync(page, data);
// Inverse background should be opaque
await pollFor(page, () => getCellColor(1, 1), [255, 0, 0, 255]);
});
});
});
async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`);
await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);
if (options.rendererType === 'dom') {
await page.waitForSelector('.xterm-rows');
} else {
await page.waitForSelector('.xterm-text-layer');
}
}
async function writeSync(data: string): Promise<void> {
return page.evaluate(`new Promise(resolve => window.term.write('${data}', resolve))`);
}
async function getCellColor(col: number, row: number): Promise<number[]> {
await page.evaluate(`
window.gl = window.term._core._renderService._renderer._gl;
@@ -902,25 +888,13 @@ async function setupBrowser(options: ITerminalOptions = { rendererType: 'dom' })
page = (await browser.defaultContext().pages())[0];
await page.setViewport({ width, height });
await page.goto(APP);
await openTerminal(options);
await openTerminal(page, options);
await page.evaluate(`
window.addon = new WebglAddon(true);
window.term.loadAddon(window.addon);
`);
}
export async function pollFor<T>(page: playwright.Page, evalOrFn: string | (() => Promise<T>), val: T, preFn?: () => Promise<void>): Promise<void> {
if (preFn) {
await preFn();
}
const result = typeof evalOrFn === 'string' ? await page.evaluate(evalOrFn) : await evalOrFn();
if (!deepEqual(result, val)) {
return new Promise<void>(r => {
setTimeout(() => r(pollFor(page, evalOrFn, val, preFn)), 1);
});
}
}
const COLORS_16_TO_255 = [
'#000000', '#00005f', '#000087', '#0000af', '#0000d7', '#0000ff', '#005f00', '#005f5f', '#005f87', '#005faf', '#005fd7', '#005fff', '#008700', '#00875f', '#008787', '#0087af',
'#0087d7', '#0087ff', '#00af00', '#00af5f', '#00af87', '#00afaf', '#00afd7', '#00afff', '#00d700', '#00d75f', '#00d787', '#00d7af', '#00d7d7', '#00d7ff', '#00ff00', '#00ff5f',
+17 -5
View File
@@ -12,17 +12,29 @@
"removeComments": true,
"baseUrl": ".",
"paths": {
"common/*": [ "../../../src/common/*" ],
"browser/*": [ "../../../src/browser/*" ]
"common/*": [
"../../../src/common/*"
],
"browser/*": [
"../../../src/browser/*"
]
},
"strict": true
"strict": true,
"types": [
"../../../node_modules/@types/mocha",
"../../../out-test/api/TestUtils"
]
},
"include": [
"./**/*",
"../../../typings/xterm.d.ts"
],
"references": [
{ "path": "../../../src/common" },
{ "path": "../../../src/browser" }
{
"path": "../../../src/common"
},
{
"path": "../../../src/browser"
}
]
}
-1
View File
@@ -160,7 +160,6 @@ export class DomRenderer extends Disposable implements IRenderer {
let styles =
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} {` +
` color: ${this._colors.foreground.css};` +
` background-color: ${this._colors.background.css};` +
` font-family: ${this._optionsService.options.fontFamily};` +
` font-size: ${this._optionsService.options.fontSize}px;` +
`}`;
+2 -13
View File
@@ -3,8 +3,7 @@
* @license MIT
*/
import { ITerminalOptions } from 'xterm';
import { pollFor, getBrowserType } from './TestUtils';
import { pollFor, getBrowserType, openTerminal } from './TestUtils';
import { Browser, Page } from 'playwright';
const APP = 'http://127.0.0.1:3000/test';
@@ -23,7 +22,7 @@ describe('CharWidth Integration Tests', function(): void {
page = (await browser.defaultContext().pages())[0];
await page.setViewport({ width, height });
await page.goto(APP);
await openTerminal({ rows: 5, cols: 30 });
await openTerminal(page, { rows: 5, cols: 30 });
});
after(() => {
@@ -75,16 +74,6 @@ describe('CharWidth Integration Tests', function(): void {
});
});
async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`);
await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);
if (options.rendererType === 'dom') {
await page.waitForSelector('.xterm-rows');
} else {
await page.waitForSelector('.xterm-text-layer');
}
}
async function sumWidths(start: number, end: number, sentinel: string): Promise<number> {
await page.evaluate(`
(function() {
+73 -83
View File
@@ -5,7 +5,7 @@
import { assert } from 'chai';
import { ITerminalOptions } from 'xterm';
import { pollFor, getBrowserType } from './TestUtils';
import { pollFor, openTerminal, getBrowserType } from './TestUtils';
import { Page, Browser } from 'playwright';
import { IRenderDimensions } from 'browser/renderer/Types';
@@ -25,7 +25,7 @@ describe('InputHandler Integration Tests', function(): void {
page = (await browser.defaultContext().pages())[0];
await page.setViewport({ width, height });
await page.goto(APP);
await openTerminal();
await openTerminal(page);
});
after(() => {
@@ -263,10 +263,10 @@ describe('InputHandler Integration Tests', function(): void {
describe('CSI ? Pm h', () => {
it('Pm = 1003, Set Use All Motion (any event) Mouse Tracking', async () => {
const coords: { left: number, top: number, bottom: number, right: number } = await page.evaluate(`
(function() {
const rect = window.term.element.getBoundingClientRect();
return {left: rect.left, top: rect.top, bottom: rect.bottom, right: rect.right};
})();
(function() {
const rect = window.term.element.getBoundingClientRect();
return { left: rect.left, top: rect.top, bottom: rect.bottom, right: rect.right };
})();
`);
// Click and drag and ensure there is a selection
await page.mouse.click((coords.left + coords.right) / 2, (coords.top + coords.bottom) / 2);
@@ -300,88 +300,88 @@ describe('InputHandler Integration Tests', function(): void {
it('REP: Repeat preceding character, ECMA48 - CSI Ps b', async function(): Promise<any> {
// default to 1
await page.evaluate(`
window.term.resize(10, 10);
window.term.write('#\x1b[b');
window.term.writeln('');
window.term.write('#\x1b[0b');
window.term.writeln('');
window.term.write('#\x1b[1b');
window.term.writeln('');
window.term.write('#\x1b[5b');
`);
window.term.resize(10, 10);
window.term.write('#\x1b[b');
window.term.writeln('');
window.term.write('#\x1b[0b');
window.term.writeln('');
window.term.write('#\x1b[1b');
window.term.writeln('');
window.term.write('#\x1b[5b');
`);
await pollFor(page, () => getLinesAsArray(4), ['##', '##', '##', '######']);
await pollFor(page, () => getCursor(), { col: 6, row: 3 });
// should not repeat on fullwidth chars
await page.evaluate(`
window.term.reset();
window.term.write('¥\x1b[10b');
`);
window.term.reset();
window.term.write('¥\x1b[10b');
`);
await pollFor(page, () => getLinesAsArray(1), ['¥']);
// should repeat only base char of combining
await page.evaluate(`
window.term.reset();
window.term.write('e\u0301\x1b[5b');
`);
window.term.reset();
window.term.write('e\u0301\x1b[5b');
`);
await pollFor(page, () => getLinesAsArray(1), ['e\u0301eeeee']);
// should wrap correctly
await page.evaluate(`
window.term.reset();
window.term.write('#\x1b[15b');
`);
window.term.reset();
window.term.write('#\x1b[15b');
`);
await pollFor(page, () => getLinesAsArray(2), ['##########', '######']);
await page.evaluate(`
window.term.reset();
window.term.write('\x1b[?7l'); // disable wrap around
window.term.write('#\x1b[15b');
`);
window.term.reset();
window.term.write('\x1b[?7l'); // disable wrap around
window.term.write('#\x1b[15b');
`);
await pollFor(page, () => getLinesAsArray(2), ['##########', '']);
// any successful sequence should reset REP
await page.evaluate(`
window.term.reset();
window.term.write('\x1b[?7h'); // re-enable wrap around
window.term.write('#\\n\x1b[3b');
window.term.write('#\\r\x1b[3b');
window.term.writeln('');
window.term.write('abcdefg\x1b[3D\x1b[10b#\x1b[3b');
`);
window.term.reset();
window.term.write('\x1b[?7h'); // re-enable wrap around
window.term.write('#\\n\x1b[3b');
window.term.write('#\\r\x1b[3b');
window.term.writeln('');
window.term.write('abcdefg\x1b[3D\x1b[10b#\x1b[3b');
`);
await pollFor(page, () => getLinesAsArray(3), ['#', ' #', 'abcd####']);
});
describe('Window Options - CSI Ps ; Ps ; Ps t', () => {
it('should be disabled by default', async function(): Promise<any> {
await page.evaluate(`(() => {
window._stack = [];
const _h = window.term.onData(data => window._stack.push(data));
window.term.write('\x1b[14t');
window.term.write('\x1b[16t');
window.term.write('\x1b[18t');
window.term.write('\x1b[20t');
window.term.write('\x1b[21t');
return new Promise((r) => window.term.write('', () => { _h.dispose(); r(); }));
})()`);
window._stack = [];
const _h = window.term.onData(data => window._stack.push(data));
window.term.write('\x1b[14t');
window.term.write('\x1b[16t');
window.term.write('\x1b[18t');
window.term.write('\x1b[20t');
window.term.write('\x1b[21t');
return new Promise((r) => window.term.write('', () => { _h.dispose(); r(); }));
})()`);
await pollFor(page, async () => await page.evaluate(`(() => _stack)()`), []);
});
it('14 - GetWinSizePixels', async function(): Promise<any> {
await page.evaluate(`window.term.setOption('windowOptions', {getWinSizePixels: true});`);
await page.evaluate(`window.term.setOption('windowOptions', { getWinSizePixels: true }); `);
await page.evaluate(`(() => {
window._stack = [];
const _h = window.term.onData(data => window._stack.push(data));
window.term.write('\x1b[14t');
return new Promise((r) => window.term.write('', () => { _h.dispose(); r(); }));
})()`);
window._stack = [];
const _h = window.term.onData(data => window._stack.push(data));
window.term.write('\x1b[14t');
return new Promise((r) => window.term.write('', () => { _h.dispose(); r(); }));
})()`);
const d = await getDimensions();
await pollFor(page, async () => await page.evaluate(`(() => _stack)()`), [`\x1b[4;${d.height};${d.width}t`]);
await pollFor(page, async () => await page.evaluate(`(() => _stack)()`), [`\x1b[4; ${d.height}; ${d.width} t`]);
});
it('16 - GetCellSizePixels', async function(): Promise<any> {
await page.evaluate(`window.term.setOption('windowOptions', {getCellSizePixels: true});`);
await page.evaluate(`window.term.setOption('windowOptions', { getCellSizePixels: true }); `);
await page.evaluate(`(() => {
window._stack = [];
const _h = window.term.onData(data => window._stack.push(data));
window.term.write('\x1b[16t');
return new Promise((r) => window.term.write('', () => { _h.dispose(); r(); }));
})()`);
window._stack = [];
const _h = window.term.onData(data => window._stack.push(data));
window.term.write('\x1b[16t');
return new Promise((r) => window.term.write('', () => { _h.dispose(); r(); }));
})()`);
const d = await getDimensions();
await pollFor(page, async () => await page.evaluate(`(() => _stack)()`), [`\x1b[6;${d.cellHeight};${d.cellWidth}t`]);
await pollFor(page, async () => await page.evaluate(`(() => _stack)()`), [`\x1b[6; ${d.cellHeight}; ${d.cellWidth} t`]);
});
});
});
@@ -393,31 +393,21 @@ describe('InputHandler Integration Tests', function(): void {
window.term.resize(10, 2);
window.term.write('1\\n\\r2\\n\\r3\\n\\r4\\n\\r5');
window.term.write('\\x1b7\\x1b[?47h');
`);
`);
await page.evaluate(`
window.term.resize(10, 4);
window.term.write('\\x1b[?47l\\x1b8');
`);
`);
await pollFor(page, () => getCursor(), { col: 1, row: 3 });
});
});
});
});
async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`);
await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);
if (options.rendererType === 'dom') {
await page.waitForSelector('.xterm-rows');
} else {
await page.waitForSelector('.xterm-text-layer');
}
}
async function getLinesAsArray(count: number, start: number = 0): Promise<string[]> {
let text = '';
for (let i = start; i < start + count; i++) {
text += `window.term.buffer.getLine(${i}).translateToString(true),`;
text += `window.term.buffer.getLine(${i}).translateToString(true), `;
}
return await page.evaluate(`[${text}]`);
}
@@ -425,22 +415,22 @@ async function getLinesAsArray(count: number, start: number = 0): Promise<string
async function simulatePaste(text: string): Promise<string> {
const id = Math.floor(Math.random() * 1000000);
await page.evaluate(`
(function () {
window.term.onData(e => window.result_${id} = e);
const clipboardData = new DataTransfer();
clipboardData.setData('text/plain', '${text}');
window.term.textarea.dispatchEvent(new ClipboardEvent('paste', { clipboardData }));
})();
`);
return await page.evaluate(`window.result_${id}`);
(function() {
window.term.onData(e => window.result_${ id} = e);
const clipboardData = new DataTransfer();
clipboardData.setData('text/plain', '${text}');
window.term.textarea.dispatchEvent(new ClipboardEvent('paste', { clipboardData }));
})();
`);
return await page.evaluate(`window.result_${id} `);
}
async function getCursor(): Promise<{ col: number, row: number }> {
return page.evaluate(`
(function() {
return {col: term.buffer.cursorX, row: term.buffer.cursorY};
})();
`);
(function() {
return { col: term.buffer.cursorX, row: term.buffer.cursorY };
})();
`);
}
async function getDimensions(): Promise<any> {
File diff suppressed because it is too large Load Diff
+4 -15
View File
@@ -4,8 +4,7 @@
*/
import { assert } from 'chai';
import { ITerminalOptions } from 'xterm';
import { writeSync, getBrowserType } from './TestUtils';
import { writeSync, openTerminal, getBrowserType } from './TestUtils';
import { Browser, Page } from 'playwright';
const APP = 'http://127.0.0.1:3000/test';
@@ -15,8 +14,8 @@ let page: Page;
const width = 800;
const height = 600;
describe('Parser Integration Tests', function (): void {
before(async function (): Promise<any> {
describe('Parser Integration Tests', function(): void {
before(async function(): Promise<any> {
browser = await getBrowserType().launch({
headless: process.argv.indexOf('--headless') !== -1,
args: [`--window-size=${width},${height}`, `--no-sandbox`]
@@ -24,7 +23,7 @@ describe('Parser Integration Tests', function (): void {
page = (await browser.defaultContext().pages())[0];
await page.setViewport({ width, height });
await page.goto(APP);
await openTerminal();
await openTerminal(page);
});
after(async () => browser.close());
@@ -110,13 +109,3 @@ describe('Parser Integration Tests', function (): void {
});
});
});
async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`);
await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);
if (options.rendererType === 'dom') {
await page.waitForSelector('.xterm-rows');
} else {
await page.waitForSelector('.xterm-text-layer');
}
}
+44 -55
View File
@@ -4,8 +4,7 @@
*/
import { assert } from 'chai';
import { ITerminalOptions } from 'xterm';
import { pollFor, timeout, writeSync, getBrowserType } from './TestUtils';
import { pollFor, timeout, writeSync, openTerminal, getBrowserType } from './TestUtils';
import { Browser, Page } from 'playwright';
const APP = 'http://127.0.0.1:3000/test';
@@ -15,7 +14,7 @@ let page: Page;
const width = 800;
const height = 600;
describe('API Integration Tests', function (): void {
describe('API Integration Tests', function(): void {
before(async () => {
browser = await getBrowserType().launch({
headless: process.argv.indexOf('--headless') !== -1,
@@ -29,13 +28,13 @@ describe('API Integration Tests', function (): void {
beforeEach(async () => page.goto(APP));
it('Default options', async () => {
await openTerminal();
await openTerminal(page);
assert.equal(await page.evaluate(`window.term.cols`), 80);
assert.equal(await page.evaluate(`window.term.rows`), 24);
});
it('write', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.term.write('foo');
window.term.write('bar');
@@ -45,7 +44,7 @@ describe('API Integration Tests', function (): void {
});
it('write with callback', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.term.write('foo', () => { window.__x = 'a'; });
window.term.write('bar', () => { window.__x += 'b'; });
@@ -56,7 +55,7 @@ describe('API Integration Tests', function (): void {
});
it('write - bytes (UTF8)', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
// foo
window.term.write(new Uint8Array([102, 111, 111]));
@@ -69,7 +68,7 @@ describe('API Integration Tests', function (): void {
});
it('write - bytes (UTF8) with callback', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
// foo
window.term.write(new Uint8Array([102, 111, 111]), () => { window.__x = 'A'; });
@@ -83,7 +82,7 @@ describe('API Integration Tests', function (): void {
});
it('writeln', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.term.writeln('foo');
window.term.writeln('bar');
@@ -95,7 +94,7 @@ describe('API Integration Tests', function (): void {
});
it('writeln with callback', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.term.writeln('foo', () => { window.__x = '1'; });
window.term.writeln('bar', () => { window.__x += '2'; });
@@ -108,7 +107,7 @@ describe('API Integration Tests', function (): void {
});
it('writeln - bytes (UTF8)', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.term.writeln(new Uint8Array([102, 111, 111]));
window.term.writeln(new Uint8Array([98, 97, 114]));
@@ -120,7 +119,7 @@ describe('API Integration Tests', function (): void {
});
it('paste', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.calls = [];
window.term.onData(e => calls.push(e));
@@ -134,7 +133,7 @@ describe('API Integration Tests', function (): void {
});
it('clear', async () => {
await openTerminal({ rows: 5 });
await openTerminal(page, { rows: 5 });
await page.evaluate(`
window.term.write('test0');
window.parsed = 0;
@@ -152,7 +151,7 @@ describe('API Integration Tests', function (): void {
});
it('getOption, setOption', async () => {
await openTerminal();
await openTerminal(page);
assert.equal(await page.evaluate(`window.term.getOption('rendererType')`), 'canvas');
await page.evaluate(`window.term.setOption('rendererType', 'dom')`);
assert.equal(await page.evaluate(`window.term.getOption('rendererType')`), 'dom');
@@ -160,7 +159,7 @@ describe('API Integration Tests', function (): void {
describe('renderer', () => {
it('foreground', async () => {
await openTerminal({ rendererType: 'dom' });
await openTerminal(page, { rendererType: 'dom' });
await writeSync(page, '\\x1b[30m0\\x1b[31m1\\x1b[32m2\\x1b[33m3\\x1b[34m4\\x1b[35m5\\x1b[36m6\\x1b[37m7');
await pollFor(page, `document.querySelectorAll('.xterm-rows > :nth-child(1) > *').length`, 9);
assert.deepEqual(await page.evaluate(`
@@ -185,7 +184,7 @@ describe('API Integration Tests', function (): void {
});
it('background', async () => {
await openTerminal({ rendererType: 'dom' });
await openTerminal(page, { rendererType: 'dom' });
await writeSync(page, '\\x1b[40m0\\x1b[41m1\\x1b[42m2\\x1b[43m3\\x1b[44m4\\x1b[45m5\\x1b[46m6\\x1b[47m7');
await pollFor(page, `document.querySelectorAll('.xterm-rows > :nth-child(1) > *').length`, 9);
assert.deepEqual(await page.evaluate(`
@@ -211,7 +210,7 @@ describe('API Integration Tests', function (): void {
});
it('selection', async () => {
await openTerminal({ rows: 5, cols: 5 });
await openTerminal(page, { rows: 5, cols: 5 });
await page.evaluate(`window.term.write('\\n\\nfoo\\n\\n\\rbar\\n\\n\\rbaz')`);
assert.equal(await page.evaluate(`window.term.hasSelection()`), false);
assert.equal(await page.evaluate(`window.term.getSelection()`), '');
@@ -231,7 +230,7 @@ describe('API Integration Tests', function (): void {
});
it('focus, blur', async () => {
await openTerminal();
await openTerminal(page);
assert.equal(await page.evaluate(`document.activeElement.className`), '');
await page.evaluate(`window.term.focus()`);
assert.equal(await page.evaluate(`document.activeElement.className`), 'xterm-helper-textarea');
@@ -241,7 +240,7 @@ describe('API Integration Tests', function (): void {
describe('loadAddon', () => {
it('constructor', async () => {
await openTerminal({ cols: 5 });
await openTerminal(page, { cols: 5 });
await page.evaluate(`
window.cols = 0;
window.term.loadAddon({
@@ -253,7 +252,7 @@ describe('API Integration Tests', function (): void {
});
it('dispose (addon)', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.disposeCalled = false
window.addon = {
@@ -268,7 +267,7 @@ describe('API Integration Tests', function (): void {
});
it('dispose (terminal)', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.disposeCalled = false
window.term.loadAddon({
@@ -284,7 +283,7 @@ describe('API Integration Tests', function (): void {
describe('Events', () => {
it('onCursorMove', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.callCount = 0;
window.term.onCursorMove(e => window.callCount++);
@@ -296,7 +295,7 @@ describe('API Integration Tests', function (): void {
});
it('onData', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.calls = [];
window.term.onData(e => calls.push(e));
@@ -306,7 +305,7 @@ describe('API Integration Tests', function (): void {
});
it('onKey', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.calls = [];
window.term.onKey(e => calls.push(e.key));
@@ -316,7 +315,7 @@ describe('API Integration Tests', function (): void {
});
it('onLineFeed', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.callCount = 0;
window.term.onLineFeed(() => callCount++);
@@ -328,7 +327,7 @@ describe('API Integration Tests', function (): void {
});
it('onScroll', async () => {
await openTerminal({ rows: 5 });
await openTerminal(page, { rows: 5 });
await page.evaluate(`
window.calls = [];
window.term.onScroll(e => window.calls.push(e));
@@ -344,7 +343,7 @@ describe('API Integration Tests', function (): void {
});
it('onSelectionChange', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.callCount = 0;
window.term.onSelectionChange(() => window.callCount++);
@@ -356,9 +355,9 @@ describe('API Integration Tests', function (): void {
await pollFor(page, `window.callCount`, 2);
});
it('onRender', async function (): Promise<void> {
it('onRender', async function(): Promise<void> {
this.retries(3);
await openTerminal();
await openTerminal(page);
await timeout(20); // Ensure all init events are fired
await page.evaluate(`
window.calls = [];
@@ -372,7 +371,7 @@ describe('API Integration Tests', function (): void {
});
it('onResize', async () => {
await openTerminal();
await openTerminal(page);
await timeout(20); // Ensure all init events are fired
await page.evaluate(`
window.calls = [];
@@ -386,7 +385,7 @@ describe('API Integration Tests', function (): void {
});
it('onTitleChange', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`
window.calls = [];
window.term.onTitleChange(e => window.calls.push(e));
@@ -399,7 +398,7 @@ describe('API Integration Tests', function (): void {
describe('buffer', () => {
it('cursorX, cursorY', async () => {
await openTerminal({ rows: 5, cols: 5 });
await openTerminal(page, { rows: 5, cols: 5 });
assert.equal(await page.evaluate(`window.term.buffer.cursorX`), 0);
assert.equal(await page.evaluate(`window.term.buffer.cursorY`), 0);
await writeSync(page, 'foo');
@@ -420,7 +419,7 @@ describe('API Integration Tests', function (): void {
});
it('viewportY', async () => {
await openTerminal({ rows: 5 });
await openTerminal(page, { rows: 5 });
assert.equal(await page.evaluate(`window.term.buffer.viewportY`), 0);
await writeSync(page, '\\n\\n\\n\\n');
assert.equal(await page.evaluate(`window.term.buffer.viewportY`), 0);
@@ -435,7 +434,7 @@ describe('API Integration Tests', function (): void {
});
it('baseY', async () => {
await openTerminal({ rows: 5 });
await openTerminal(page, { rows: 5 });
assert.equal(await page.evaluate(`window.term.buffer.baseY`), 0);
await writeSync(page, '\\n\\n\\n\\n');
assert.equal(await page.evaluate(`window.term.buffer.baseY`), 0);
@@ -450,7 +449,7 @@ describe('API Integration Tests', function (): void {
});
it('length', async () => {
await openTerminal({ rows: 5 });
await openTerminal(page, { rows: 5 });
assert.equal(await page.evaluate(`window.term.buffer.length`), 5);
await writeSync(page, '\\n\\n\\n\\n');
assert.equal(await page.evaluate(`window.term.buffer.length`), 5);
@@ -462,13 +461,13 @@ describe('API Integration Tests', function (): void {
describe('getLine', () => {
it('invalid index', async () => {
await openTerminal({ rows: 5 });
await openTerminal(page, { rows: 5 });
assert.equal(await page.evaluate(`window.term.buffer.getLine(-1)`), undefined);
assert.equal(await page.evaluate(`window.term.buffer.getLine(5)`), undefined);
});
it('isWrapped', async () => {
await openTerminal({ cols: 5 });
await openTerminal(page, { cols: 5 });
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).isWrapped`), false);
assert.equal(await page.evaluate(`window.term.buffer.getLine(1).isWrapped`), false);
await writeSync(page, 'abcde');
@@ -480,7 +479,7 @@ describe('API Integration Tests', function (): void {
});
it('translateToString', async () => {
await openTerminal({ cols: 5 });
await openTerminal(page, { cols: 5 });
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString()`), ' ');
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).translateToString(true)`), '');
await writeSync(page, 'foo');
@@ -495,7 +494,7 @@ describe('API Integration Tests', function (): void {
});
it('getCell', async () => {
await openTerminal({ cols: 5 });
await openTerminal(page, { cols: 5 });
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(-1)`), undefined);
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(5)`), undefined);
assert.equal(await page.evaluate(`window.term.buffer.getLine(0).getCell(0).getChars()`), '');
@@ -520,14 +519,14 @@ describe('API Integration Tests', function (): void {
});
it('dispose (opened)', async () => {
await openTerminal();
await openTerminal(page);
await page.evaluate(`window.term.dispose()`);
assert.equal(await page.evaluate(`window.term._core._isDisposed`), true);
});
describe('registerLinkProvider', () => {
it('should fire provideLink when hovering cells', async () => {
await openTerminal({ rendererType: 'dom' });
await openTerminal(page, { rendererType: 'dom' });
await page.evaluate(`
window.calls = [];
window.disposable = window.term.registerLinkProvider({
@@ -546,7 +545,7 @@ describe('API Integration Tests', function (): void {
});
it('should fire hover and leave events on the link', async () => {
await openTerminal({ rendererType: 'dom' });
await openTerminal(page, { rendererType: 'dom' });
await writeSync(page, 'foo bar baz');
// Wait for renderer to catch up as links are cleared on render
await pollFor(page, `document.querySelector('.xterm-rows').textContent`, 'foo bar baz ');
@@ -581,7 +580,7 @@ describe('API Integration Tests', function (): void {
});
it('should work fine when hover and leave callbacks are not provided', async () => {
await openTerminal({ rendererType: 'dom' });
await openTerminal(page, { rendererType: 'dom' });
await writeSync(page, 'foo bar baz');
// Wait for renderer to catch up as links are cleared on render
await pollFor(page, `document.querySelector('.xterm-rows').textContent`, 'foo bar baz ');
@@ -614,7 +613,7 @@ describe('API Integration Tests', function (): void {
});
it('should fire activate events when clicking the link', async () => {
await openTerminal({ rendererType: 'dom' });
await openTerminal(page, { rendererType: 'dom' });
await writeSync(page, 'a b c');
// Wait for renderer to catch up as links are cleared on render
@@ -662,16 +661,6 @@ describe('API Integration Tests', function (): void {
});
});
async function openTerminal(options: ITerminalOptions = {}): Promise<void> {
await page.evaluate(`window.term = new Terminal(${JSON.stringify(options)})`);
await page.evaluate(`window.term.open(document.querySelector('#terminal-container'))`);
if (options.rendererType === 'dom') {
await page.waitForSelector('.xterm-rows');
} else {
await page.waitForSelector('.xterm-text-layer');
}
}
interface IDimensions {
top: number;
left: number;
@@ -713,7 +702,7 @@ async function getCellCoordinates(dimensions: IDimensions, col: number, row: num
};
}
async function moveMouseCell(page: Page, dimensions: IDimensions, col: number, row: number) {
async function moveMouseCell(page: Page, dimensions: IDimensions, col: number, row: number): Promise<void> {
const coords = await getCellCoordinates(dimensions, col, row);
await page.mouse.move(coords.x, coords.y);
}

Some files were not shown because too many files have changed in this diff Show More