Merge branch 'master' into clusters

This commit is contained in:
Per Bothner
2023-09-10 17:20:40 -07:00
committed by GitHub
49 changed files with 1629 additions and 1242 deletions
+2 -1
View File
@@ -1,7 +1,7 @@
{
"env": {
"browser": true,
"es6": true,
"es2021": true,
"node": true
},
"parser": "@typescript-eslint/parser",
@@ -17,6 +17,7 @@
"addons/xterm-addon-attach/src/tsconfig.json",
"addons/xterm-addon-attach/test/tsconfig.json",
"addons/xterm-addon-canvas/src/tsconfig.json",
"addons/xterm-addon-canvas/test/tsconfig.json",
"addons/xterm-addon-fit/src/tsconfig.json",
"addons/xterm-addon-fit/test/tsconfig.json",
"addons/xterm-addon-image/src/tsconfig.json",
+1 -1
View File
@@ -1,7 +1,7 @@
{
"env": {
"browser": true,
"es6": true,
"es2021": true,
"node": true
},
"parser": "@typescript-eslint/parser",
+6 -2
View File
@@ -259,8 +259,12 @@ jobs:
ls -R
- name: Build demo
run: yarn build-demo
- name: Integration tests
run: yarn test-playwright-${{ matrix.browser }} --forbid-only
- name: Integration tests (core) # Tests use 50% workers to reduce flakiness
run: yarn test-playwright-${{ matrix.browser }} --workers=50% --forbid-only --suite=core
- name: Integration tests (xterm-addon-canvas)
run: yarn test-playwright-${{ matrix.browser }} --workers=50% --forbid-only --suite=xterm-addon-canvas
- name: Integration tests (xterm-addon-webgl)
run: yarn test-playwright-${{ matrix.browser }} --workers=50% --forbid-only --suite=xterm-addon-webgl
test-api:
needs: build
+11 -6
View File
@@ -43,7 +43,14 @@
{
"type": "chrome",
"request": "launch",
"name": "Demo Client",
"name": "Demo Client (Chrome)",
"url": "http://127.0.0.1:3000",
"webRoot": "${workspaceFolder}/"
},
{
"type": "msedge",
"request": "launch",
"name": "Demo Client (Edge)",
"url": "http://127.0.0.1:3000",
"webRoot": "${workspaceFolder}/"
},
@@ -52,11 +59,9 @@
"request": "launch",
"name": "Demo Server",
"runtimeExecutable": "npm",
"runtimeArgs": [
"run",
"start-debug"
],
"port": 9229,
"runtimeArgs": ["start"],
"stopOnEntry": true,
"runtimeVersion": "16",
"serverReadyAction": {
"action": "openExternally",
"pattern": "App listening to (http://.*?:[0-9]+)"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"dom",
"es2015"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"es2015"
],
+2 -1
View File
@@ -19,7 +19,8 @@
"build": "../../node_modules/.bin/tsc -p .",
"prepackage": "npm run build",
"package": "../../node_modules/.bin/webpack",
"prepublishOnly": "npm run package"
"prepublishOnly": "npm run package",
"start-server-only": "node ../../demo/start-server-only"
},
"peerDependencies": {
"xterm": "^5.0.0"
+2 -2
View File
@@ -1,10 +1,10 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"dom",
"es6"
"es2021"
],
"rootDir": ".",
"outDir": "../out",
@@ -0,0 +1,31 @@
/**
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
* @license MIT
*/
import test from '@playwright/test';
import { ISharedRendererTestContext, injectSharedRendererTests } from '../../../out-test/playwright/SharedRendererTests';
import { ITestContext, createTestContext, openTerminal } from '../../../out-test/playwright/TestUtils';
let ctx: ITestContext;
const ctxWrapper: ISharedRendererTestContext = {
value: undefined,
skipCanvasExceptions: true
} as any;
test.beforeAll(async ({ browser }) => {
ctx = await createTestContext(browser);
await openTerminal(ctx);
ctxWrapper.value = ctx;
await ctx.page.evaluate(`
window.addon = new window.CanvasAddon(true);
window.term.loadAddon(window.addon);
`);
});
test.afterAll(async () => await ctx.page.close());
test.describe('Canvas Renderer Integration Tests', () => {
// HACK: The tests fail for an unknown reason
test.skip(({ browserName }) => browserName === 'webkit');
injectSharedRendererTests(ctxWrapper);
});
@@ -0,0 +1,35 @@
import { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
testDir: '.',
timeout: 10000,
projects: [
{
name: 'Chrome Stable',
use: {
browserName: 'chromium',
channel: 'chrome'
}
},
{
name: 'Firefox Stable',
use: {
browserName: 'firefox'
}
},
{
name: 'WebKit',
use: {
browserName: 'webkit'
}
}
],
reporter: 'list',
webServer: {
command: 'npm run start-server-only',
port: 3000,
timeout: 120000,
reuseExistingServer: !process.env.CI
}
};
export default config;
@@ -0,0 +1,41 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"lib": [
"es6",
],
"rootDir": ".",
"outDir": "../out-test",
"sourceMap": true,
"removeComments": true,
"baseUrl": ".",
"paths": {
"common/*": [
"../../../src/common/*"
],
"browser/*": [
"../../../src/browser/*"
]
},
"strict": true,
"types": [
"../../../node_modules/@types/node",
"../../../node_modules/@lunapaint/png-codec",
"../../../out-test/playwright/TestUtils",
"../../../out-test/playwright/SharedRendererTests"
]
},
"include": [
"./**/*",
"../../../typings/xterm.d.ts"
],
"references": [
{
"path": "../../../src/common"
},
{
"path": "../../../src/browser"
}
]
}
+2 -1
View File
@@ -2,6 +2,7 @@
"files": [],
"include": [],
"references": [
{ "path": "./src" }
{ "path": "./src" },
{ "path": "./test" }
]
}
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"dom",
"es2015"
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"es2015"
],
+2 -2
View File
@@ -1,10 +1,10 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"dom",
"es6",
"es2021",
],
"rootDir": ".",
"outDir": "../out",
+2 -2
View File
@@ -1,9 +1,9 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"es6",
"es2021",
],
"rootDir": ".",
"outDir": "../out-test",
@@ -1,11 +1,14 @@
{
"compilerOptions": {
"lib": ["dom", "es6"],
"lib": [
"dom",
"es2021"
],
"outDir": "../out-benchmark",
"types": ["../../../node_modules/@types/node"],
"moduleResolution": "node",
"strict": false,
"target": "es2015",
"target": "es2021",
"module": "commonjs",
"baseUrl": ".",
"paths": {
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"dom",
"es2015"
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"es2015"
],
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"dom",
"es2015"
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"dom",
"es2015"
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"dom",
"es2015"
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"es2015"
],
+2 -1
View File
@@ -19,7 +19,8 @@
"build": "../../node_modules/.bin/tsc -p .",
"prepackage": "npm run build",
"package": "../../node_modules/.bin/webpack",
"prepublishOnly": "npm run package"
"prepublishOnly": "npm run package",
"start-server-only": "node ../../demo/start-server-only"
},
"peerDependencies": {
"xterm": "^5.0.0"
+2 -2
View File
@@ -1,10 +1,10 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"dom",
"es6"
"es2021"
],
"rootDir": ".",
"outDir": "../out",
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,32 @@
/**
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
* @license MIT
*/
import test from '@playwright/test';
import { ISharedRendererTestContext, injectSharedRendererTests } from '../../../out-test/playwright/SharedRendererTests';
import { ITestContext, createTestContext, openTerminal } from '../../../out-test/playwright/TestUtils';
import { platform } from 'os';
let ctx: ITestContext;
const ctxWrapper: ISharedRendererTestContext = { value: undefined } as any;
test.beforeAll(async ({ browser }) => {
ctx = await createTestContext(browser);
await openTerminal(ctx);
ctxWrapper.value = ctx;
await ctx.page.evaluate(`
window.addon = new window.WebglAddon(true);
window.term.loadAddon(window.addon);
`);
});
test.afterAll(async () => await ctx.page.close());
test.describe('WebGL Renderer Integration Tests', async () => {
// HACK: webgl2 is often not supported in headless firefox on Linux
// https://github.com/microsoft/playwright/issues/11566
if (platform() === 'linux') {
test.skip(({ browserName }) => browserName === 'firefox');
}
injectSharedRendererTests(ctxWrapper);
});
@@ -0,0 +1,35 @@
import { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
testDir: '.',
timeout: 10000,
projects: [
{
name: 'Chrome Stable',
use: {
browserName: 'chromium',
channel: 'chrome'
}
},
{
name: 'Firefox Stable',
use: {
browserName: 'firefox'
}
},
{
name: 'WebKit',
use: {
browserName: 'webkit'
}
}
],
reporter: 'list',
webServer: {
command: 'npm run start-server-only',
port: 3000,
timeout: 120000,
reuseExistingServer: !process.env.CI
}
};
export default config;
+5 -4
View File
@@ -1,9 +1,9 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"lib": [
"es6",
"es2021",
],
"rootDir": ".",
"outDir": "../out-test",
@@ -20,9 +20,10 @@
},
"strict": true,
"types": [
"../../../node_modules/@types/mocha",
"../../../node_modules/@types/node",
"../../../out-test/api/TestUtils"
"../../../node_modules/@lunapaint/png-codec",
"../../../out-test/playwright/TestUtils",
"../../../out-test/playwright/SharedRendererTests"
]
},
"include": [
+51
View File
@@ -0,0 +1,51 @@
/**
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
* @license MIT
*/
// @ts-check
const cp = require('child_process');
const path = require('path');
let argv = process.argv.slice(2);
let suiteFilter = undefined;
while (argv.some(e => e.startsWith('--suite='))) {
const i = argv.findIndex(e => e.startsWith('--suite='));
const match = argv[i].match(/--suite=(?<suitename>.+)/)
suiteFilter = match?.groups?.suitename ?? undefined;
argv.splice(i, 1);
}
let configs = [
{ name: 'core', path: 'out-test/playwright/playwright.config.js' },
{ name: 'xterm-addon-canvas', path: 'addons/xterm-addon-canvas/out-test/playwright.config.js' },
{ name: 'xterm-addon-webgl', path: 'addons/xterm-addon-webgl/out-test/playwright.config.js' }
];
if (suiteFilter) {
configs = configs.filter(e => e.name === suiteFilter);
}
function npmBinScript(script) {
return path.resolve(__dirname, `../node_modules/.bin/` + (process.platform === 'win32' ?
`${script}.cmd` : script));
}
async function run() {
for (const config of configs) {
const command = npmBinScript('playwright');
const args = ['test', '-c', config.path, ...argv];
console.log(`Running suite \x1b[1;34m${config.name}...\x1b[0m`);
console.log(`\n\x1b[32m${command}\x1b[0m`, args);
const run = cp.spawnSync(command, args, {
cwd: path.resolve(__dirname, '..'),
stdio: 'inherit'
}
);
if (run.status) {
process.exit(run.status);
}
}
}
run();
+3
View File
@@ -50,6 +50,7 @@ export interface IWindowWithTerminal extends Window {
term: TerminalType;
Terminal?: typeof TerminalType; // eslint-disable-line @typescript-eslint/naming-convention
AttachAddon?: typeof AttachAddon; // eslint-disable-line @typescript-eslint/naming-convention
CanvasAddon?: typeof CanvasAddon; // eslint-disable-line @typescript-eslint/naming-convention
FitAddon?: typeof FitAddon; // eslint-disable-line @typescript-eslint/naming-convention
ImageAddon?: typeof ImageAddonType; // eslint-disable-line @typescript-eslint/naming-convention
SearchAddon?: typeof SearchAddon; // eslint-disable-line @typescript-eslint/naming-convention
@@ -130,6 +131,7 @@ const xtermjsTheme = {
foreground: '#F8F8F8',
background: '#2D2E2C',
selectionBackground: '#5DA5D533',
selectionInactiveBackground: '#555555AA',
black: '#1E1E1D',
brightBlack: '#262625',
red: '#CE5C5C',
@@ -225,6 +227,7 @@ const createNewWindowButtonHandler: () => void = () => {
if (document.location.pathname === '/test') {
window.Terminal = Terminal;
window.AttachAddon = AttachAddon;
window.CanvasAddon = CanvasAddon;
window.FitAddon = FitAddon;
window.ImageAddon = ImageAddon;
window.SearchAddon = SearchAddon;
+10
View File
@@ -0,0 +1,10 @@
/**
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
* @license MIT
*/
// @ts-check
const startServer = require('./server.js');
startServer();
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"rootDir": ".",
"sourceMap": true,
"baseUrl": ".",
+7 -6
View File
@@ -28,8 +28,8 @@
"package-headless": "webpack --config ./webpack.config.headless.js",
"postpackage-headless": "node ./bin/package_headless.js",
"start": "node demo/start",
"start-server-only": "node demo/start-server-only",
"build-demo": "webpack --config ./demo/webpack.config.js",
"start-debug": "node --inspect-brk demo/start",
"lint": "eslint -c .eslintrc.json --max-warnings 0 --ext .ts src/ addons/",
"lint-api": "eslint --no-eslintrc -c .eslintrc.json.typings --max-warnings 0 --no-ignore --ext .d.ts typings/",
"test": "npm run test-unit",
@@ -38,11 +38,11 @@
"test-api-chromium": "node ./bin/test_api.js --browser=chromium --timeout=20000",
"test-api-firefox": "node ./bin/test_api.js --browser=firefox --timeout=20000",
"test-api-webkit": "node ./bin/test_api.js --browser=webkit --timeout=20000",
"test-playwright": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4",
"test-playwright-chromium": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4 --project='Chrome Stable'",
"test-playwright-firefox": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4 --project='Firefox Stable'",
"test-playwright-webkit": "playwright test -c ./out-test/playwright/playwright.config.js --workers 4 --project='WebKit'",
"test-playwright-debug": "playwright test -c ./out-test/playwright/playwright.config.js --headed --workers 1 --timeout 30000",
"test-playwright": "node ./bin/test_playwright.js --workers=75%",
"test-playwright-chromium": "node ./bin/test_playwright.js --workers=75% \"--project=Chrome Stable\"",
"test-playwright-firefox": "node ./bin/test_playwright.js --workers=75% \"--project=Firefox Stable\"",
"test-playwright-webkit": "node ./bin/test_playwright.js --workers=75% \"--project=WebKit\"",
"test-playwright-debug": "node ./bin/test_playwright.js --workers=1 --headed --timeout=30000",
"test-unit": "node ./bin/test.js",
"test-unit-coverage": "node ./bin/test.js --coverage",
"test-unit-dev": "cross-env NODE_PATH='./out' mocha",
@@ -59,6 +59,7 @@
"vtfeatures": "node bin/extract_vtfeatures.js src/**/*.ts src/*.ts"
},
"devDependencies": {
"@lunapaint/png-codec": "^0.2.0",
"@playwright/test": "^1.37.1",
"@types/chai": "^4.2.22",
"@types/debug": "^4.1.7",
-2
View File
@@ -729,10 +729,8 @@ export class Terminal extends CoreTerminal implements ITerminal {
if (!(events & CoreMouseEventType.UP)) {
this._document!.removeEventListener('mouseup', requestedEvents.mouseup!);
el.removeEventListener('mouseup', requestedEvents.mouseup!);
requestedEvents.mouseup = null;
} else if (!requestedEvents.mouseup) {
el.addEventListener('mouseup', eventListeners.mouseup);
requestedEvents.mouseup = eventListeners.mouseup;
}
+3 -3
View File
@@ -119,10 +119,10 @@ export class Viewport extends Disposable implements IViewport {
private _innerRefresh(): void {
if (this._charSizeService.height > 0) {
this._currentRowHeight = this._renderService.dimensions.device.cell.height / this._coreBrowserService.dpr;
this._currentDeviceCellHeight = this._renderService.dimensions.device.cell.height;
this._currentRowHeight = this._renderDimensions.device.cell.height / this._coreBrowserService.dpr;
this._currentDeviceCellHeight = this._renderDimensions.device.cell.height;
this._lastRecordedViewportHeight = this._viewportElement.offsetHeight;
const newBufferHeight = Math.round(this._currentRowHeight * this._lastRecordedBufferLength) + (this._lastRecordedViewportHeight - this._renderService.dimensions.css.canvas.height);
const newBufferHeight = Math.round(this._currentRowHeight * this._lastRecordedBufferLength) + (this._lastRecordedViewportHeight - this._renderDimensions.css.canvas.height);
if (this._lastRecordedBufferHeight !== newBufferHeight) {
this._lastRecordedBufferHeight = newBufferHeight;
this._scrollArea.style.height = this._lastRecordedBufferHeight + 'px';
+3 -2
View File
@@ -205,8 +205,8 @@ export class DomRenderer extends Disposable implements IRenderer {
` animation: blink_block` + `_` + this._terminalClass + ` 1s step-end infinite;` +
`}` +
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_BLOCK_CLASS} {` +
` background-color: ${colors.cursor.css};` +
` color: ${colors.cursorAccent.css};` +
` background-color: ${colors.cursor.css} !important;` +
` color: ${colors.cursorAccent.css} !important;` +
`}` +
`${this._terminalSelector} .${ROW_CONTAINER_CLASS} .${RowCss.CURSOR_CLASS}.${RowCss.CURSOR_STYLE_OUTLINE_CLASS} {` +
` outline: 1px solid ${colors.cursor.css};` +
@@ -299,6 +299,7 @@ export class DomRenderer extends Disposable implements IRenderer {
public handleBlur(): void {
this._rowContainer.classList.remove(FOCUS_CLASS);
this.renderRows(0, this._bufferService.rows - 1);
}
public handleFocus(): void {
@@ -180,7 +180,11 @@ export class DomRendererRowFactory {
&& !isDecorated
) {
// no span alterations, thus only account chars skipping all code below
text += chars;
if (cell.isInvisible()) {
text += WHITESPACE_CELL_CHAR;
} else {
text += chars;
}
cellAmount++;
continue;
} else {
@@ -415,7 +419,7 @@ export class DomRendererRowFactory {
break;
case Attributes.CM_DEFAULT:
default:
if (!this._applyMinimumContrast(charElement, resolvedBg, colors.foreground, cell, bgOverride, undefined)) {
if (!this._applyMinimumContrast(charElement, resolvedBg, colors.foreground, cell, bgOverride, fgOverride)) {
if (isInverse) {
classes.push(`xterm-fg-${INVERTED_DEFAULT_COLOR}`);
}
+1 -1
View File
@@ -309,7 +309,7 @@ export class TextureAtlas implements ITextureAtlas {
}
private _getForegroundColor(bg: number, bgColorMode: number, bgColor: number, fg: number, fgColorMode: number, fgColor: number, inverse: boolean, dim: boolean, bold: boolean, excludeFromContrastRatioDemands: boolean): IColor {
const minimumContrastColor = this._getMinimumContrastColor(bg, bgColorMode, bgColor, fg, fgColorMode, fgColor, false, bold, dim, excludeFromContrastRatioDemands);
const minimumContrastColor = this._getMinimumContrastColor(bg, bgColorMode, bgColor, fg, fgColorMode, fgColor, inverse, bold, dim, excludeFromContrastRatioDemands);
if (minimumContrastColor) {
return minimumContrastColor;
}
+7 -4
View File
@@ -203,11 +203,14 @@ export class RenderService extends Disposable implements IRenderService {
public setRenderer(renderer: IRenderer): void {
this._renderer.value = renderer;
this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, true));
// If the value was not set, the terminal is being disposed so ignore it
if (this._renderer.value) {
this._renderer.value.onRequestRedraw(e => this.refreshRows(e.start, e.end, true));
// Force a refresh
this._needsSelectionRefresh = true;
this._fullRefresh();
// Force a refresh
this._needsSelectionRefresh = true;
this._fullRefresh();
}
}
public addRefreshCallback(callback: FrameRequestCallback): number {
+1 -2
View File
@@ -3,8 +3,7 @@
"compilerOptions": {
"lib": [
"dom",
"es2015",
"es2016.Array.Include"
"es2021"
],
"outDir": "../../out",
"types": [
+1 -1
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2015",
"target": "es2021",
"rootDir": ".",
"sourceMap": true,
+1 -1
View File
@@ -2,7 +2,7 @@
"compilerOptions": {
"lib": [
"dom",
"es6"
"es2021"
],
"rootDir": ".",
"outDir": "../../out-test/api",
+2 -2
View File
@@ -2,7 +2,7 @@
"compilerOptions": {
"lib": [
"dom",
"es6",
"es2021",
],
"outDir": "../../out-test/benchmark",
"types": [
@@ -10,7 +10,7 @@
],
"moduleResolution": "node",
"strict": false,
"target": "es2015",
"target": "es2021",
"module": "commonjs",
"baseUrl": ".",
"paths": {
+22
View File
@@ -0,0 +1,22 @@
/**
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
* @license MIT
*/
import { test } from '@playwright/test';
import { ITestContext, createTestContext, openTerminal } from './TestUtils';
import { ISharedRendererTestContext, injectSharedRendererTests } from './SharedRendererTests';
let ctx: ITestContext;
const ctxWrapper: ISharedRendererTestContext = { value: undefined } as any;
test.beforeAll(async ({ browser }) => {
ctx = await createTestContext(browser);
ctxWrapper.value = ctx;
await openTerminal(ctx);
});
test.afterAll(async () => await ctx.page.close());
test.describe('DOM Renderer Integration Tests', () => {
injectSharedRendererTests(ctxWrapper);
});
File diff suppressed because it is too large Load Diff
+63 -14
View File
@@ -12,8 +12,6 @@ import * as playwright from '@playwright/test';
import { PageFunction } from 'playwright-core/types/structs';
import { IBuffer, IBufferCell, IBufferLine, IBufferNamespace, IBufferRange, IDecoration, IDecorationOptions, IModes, ITerminalInitOnlyOptions, ITerminalOptions, Terminal } from 'xterm';
import { EventEmitter } from '../../out/common/EventEmitter';
// TODO: We could avoid needing this
import deepEqual = require('deep-equal');
export interface ITestContext {
browser: Browser;
@@ -365,7 +363,7 @@ export async function openTerminal(ctx: ITestContext, options: ITerminalOptions
// assertion catches this case early.
strictEqual(await ctx.page.evaluate(`document.querySelector('#terminal-container').children.length`), 0, 'there must be no terminals on the page');
await ctx.page.evaluate(`
window.term = new Terminal(${JSON.stringify({ allowProposedApi: true, ...options })});
window.term = new window.Terminal(${JSON.stringify({ allowProposedApi: true, ...options })});
window.term.open(document.querySelector('#terminal-container'));
`);
// See https://github.com/xtermjs/xterm.js/pull/4519#discussion_r1285234453
@@ -382,37 +380,88 @@ export async function openTerminal(ctx: ITestContext, options: ITerminalOptions
}
export type MaybeAsync<T> = Promise<T> | T;
export async function pollFor<T>(page: playwright.Page, evalOrFn: string | (() => Promise<T>), val: T, preFn?: () => Promise<void>, maxDuration?: number, stack?: string): Promise<void> {
stack ??= new Error().stack;
interface IPollForOptions<T> {
equalityFn?: (a: T, b: T) => boolean;
maxDuration?: number;
stack?: string;
}
export async function pollFor<T>(page: playwright.Page, evalOrFn: string | (() => MaybeAsync<T>), val: T, preFn?: () => Promise<void>, options?: IPollForOptions<T>): Promise<void> {
if (!options) {
options = {};
}
options.stack ??= new Error().stack;
if (preFn) {
await preFn();
}
const result = typeof evalOrFn === 'string' ? await page.evaluate(evalOrFn) : await evalOrFn();
if (process.env.DEBUG) {
console.log('pollFor result: ', JSON.stringify(result));
console.log('pollFor\n actual: ', JSON.stringify(result), ' expected: ', JSON.stringify(val));
}
if (!deepEqual(result, val)) {
if (maxDuration === undefined) {
maxDuration = 2000;
let equalityCheck: boolean;
if (options.equalityFn) {
equalityCheck = options.equalityFn(result as T, val);
} else {
equalityCheck = true;
try {
deepStrictEqual(result, val);
} catch (e) {
equalityCheck = false;
}
if (maxDuration <= 0) {
}
if (!equalityCheck) {
if (options.maxDuration === undefined) {
options.maxDuration = 2000;
}
if (options.maxDuration <= 0) {
deepStrictEqual(result, val, ([
`pollFor max duration exceeded.`,
(`Last comparison: ` +
`${typeof result === 'object' ? JSON.stringify(result) : result} !== ` +
`${typeof val === 'object' ? JSON.stringify(val) : val}`),
`Stack: ${stack}`
`${typeof result === 'object' ? JSON.stringify(result) : result} (actual) !== ` +
`${typeof val === 'object' ? JSON.stringify(val) : val} (expected)`),
`Stack: ${options.stack}`
].join('\n')));
}
return new Promise<void>(r => {
setTimeout(() => r(pollFor(page, evalOrFn, val, preFn, maxDuration! - 10, stack)), 10);
setTimeout(() => r(pollFor(page, evalOrFn, val, preFn, {
...options,
maxDuration: options!.maxDuration! - 10,
stack: options!.stack
})), 10);
});
}
}
export async function pollForApproximate<T>(page: playwright.Page, marginOfError: number, evalOrFn: string | (() => MaybeAsync<T>), val: T, preFn?: () => Promise<void>, maxDuration?: number, stack?: string): Promise<void> {
await pollFor(page, evalOrFn, val, preFn, {
maxDuration,
stack,
equalityFn: (a, b) => {
if (a === b) {
return true;
}
if (Array.isArray(a) && Array.isArray(b) && a.length === b.length) {
let success = true;
for (let i = 0 ; i < a.length; i++) {
if (Math.abs(a[i] - b[i]) > marginOfError) {
success = false;
break;
}
}
if (success) {
return true;
}
}
return false;
}
});
}
export async function writeSync(page: playwright.Page, data: string): Promise<void> {
await page.evaluate(`
window.ready = false;
+2 -1
View File
@@ -7,7 +7,8 @@
"rootDir": ".",
"outDir": "../../out-test/playwright",
"types": [
"../../node_modules/@types/node"
"../../node_modules/@types/node",
"../../node_modules/@lunapaint/png-codec"
],
"sourceMap": true,
"removeComments": true,
+12
View File
@@ -326,6 +326,13 @@
"@jridgewell/resolve-uri" "3.1.0"
"@jridgewell/sourcemap-codec" "1.4.14"
"@lunapaint/png-codec@^0.2.0":
version "0.2.0"
resolved "https://registry.yarnpkg.com/@lunapaint/png-codec/-/png-codec-0.2.0.tgz#b9fe0a0728889af280c31239b061eb3f8c848816"
integrity sha512-S2Fk8+I27j8ZL585PlEK9hhljZcp6j+JWB5ZHAeePdufJMYHxXD2zlatLRaiy5riXRFqkCi/gong7yP9kSsEZg==
dependencies:
pako "^2.0.4"
"@nodelib/fs.scandir@2.1.5":
version "2.1.5"
resolved "https://registry.yarnpkg.com/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz#7619c2eb21b25483f6d167548b4cfd5a7488c3d5"
@@ -3002,6 +3009,11 @@ package-hash@^4.0.0:
lodash.flattendeep "^4.4.0"
release-zalgo "^1.0.0"
pako@^2.0.4:
version "2.1.0"
resolved "https://registry.yarnpkg.com/pako/-/pako-2.1.0.tgz#266cc37f98c7d883545d11335c00fbd4062c9a86"
integrity sha512-w+eufiZ1WuJYgPXbV/PO3NCMEc3xqylkKHzp8bxp1uW4qaSNQUkwmLLEc3kKsfz8lpV1F8Ht3U1Cm+9Srog2ug==
parent-module@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"