Skip to content

Commit

Permalink
Add @playwright/test support
Browse files Browse the repository at this point in the history
  • Loading branch information
Tyriar committed Aug 27, 2023
1 parent 2b7b4d6 commit fbebabe
Show file tree
Hide file tree
Showing 24 changed files with 585 additions and 30 deletions.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"src/headless/tsconfig.json",
"test/api/tsconfig.json",
"test/benchmark/tsconfig.json",
"test/playwright/tsconfig.json",
"addons/xterm-addon-attach/src/tsconfig.json",
"addons/xterm-addon-attach/test/tsconfig.json",
"addons/xterm-addon-canvas/src/tsconfig.json",
Expand Down
2 changes: 1 addition & 1 deletion addons/xterm-addon-attach/test/AttachAddon.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import WebSocket = require('ws');
import { openTerminal, pollFor, launchBrowser } from '../../../out-test/api/TestUtils';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';

const APP = 'http://127.0.0.1:3001/test';

Expand Down
2 changes: 1 addition & 1 deletion addons/xterm-addon-fit/test/FitAddon.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { assert } from 'chai';
import { openTerminal, launchBrowser } from '../../../out-test/api/TestUtils';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';

const APP = 'http://127.0.0.1:3001/test';

Expand Down
2 changes: 1 addition & 1 deletion addons/xterm-addon-image/test/ImageAddon.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { assert } from 'chai';
import { openTerminal, launchBrowser, pollFor } from '../../../out-test/api/TestUtils';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';
import { IImageAddonOptions } from '../src/Types';
import { FINALIZER, introducer, sixelEncode } from 'sixel';
import { readFileSync } from 'fs';
Expand Down
2 changes: 1 addition & 1 deletion addons/xterm-addon-search/test/SearchAddon.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { assert } from 'chai';
import { readFile } from 'fs';
import { resolve } from 'path';
import { openTerminal, writeSync, launchBrowser, timeout } from '../../../out-test/api/TestUtils';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';

const APP = 'http://127.0.0.1:3001/test';

Expand Down
2 changes: 1 addition & 1 deletion addons/xterm-addon-serialize/test/SerializeAddon.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { assert } from 'chai';
import { openTerminal, writeSync, launchBrowser } from '../../../out-test/api/TestUtils';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';

const APP = 'http://127.0.0.1:3001/test';

Expand Down
2 changes: 1 addition & 1 deletion addons/xterm-addon-unicode11/test/Unicode11Addon.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { assert } from 'chai';
import { openTerminal, launchBrowser } from '../../../out-test/api/TestUtils';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';

const APP = 'http://127.0.0.1:3001/test';

Expand Down
2 changes: 1 addition & 1 deletion addons/xterm-addon-web-links/test/WebLinksAddon.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { assert } from 'chai';
import { openTerminal, pollFor, writeSync, launchBrowser } from '../../../out-test/api/TestUtils';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';

const APP = 'http://127.0.0.1:3001/test';

Expand Down
2 changes: 1 addition & 1 deletion addons/xterm-addon-webgl/test/WebglRenderer.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { assert } from 'chai';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';
import { ITheme } from 'xterm';
import { getBrowserType, launchBrowser, openTerminal, pollFor, writeSync } from '../../../out-test/api/TestUtils';
import { ITerminalOptions } from '../../../src/common/Types';
Expand Down
17 changes: 12 additions & 5 deletions demo/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,21 @@ import { Terminal } from '../out/browser/public/Terminal';
import { AttachAddon } from '../addons/xterm-addon-attach/out/AttachAddon';
import { CanvasAddon } from '../addons/xterm-addon-canvas/out/CanvasAddon';
import { FitAddon } from '../addons/xterm-addon-fit/out/FitAddon';
import { ImageAddon, IImageAddonOptions } from '../addons/xterm-addon-image/out/ImageAddon';
import { SearchAddon, ISearchOptions } from '../addons/xterm-addon-search/out/SearchAddon';
import { SerializeAddon } from '../addons/xterm-addon-serialize/out/SerializeAddon';
import { WebLinksAddon } from '../addons/xterm-addon-web-links/out/WebLinksAddon';
import { WebglAddon } from '../addons/xterm-addon-webgl/out/WebglAddon';
import { Unicode11Addon } from '../addons/xterm-addon-unicode11/out/Unicode11Addon';
import { LigaturesAddon } from '../addons/xterm-addon-ligatures/out/LigaturesAddon';

// Playwright/WebKit on Windows does not support WebAssembly https://stackoverflow.com/q/62311688/1156119
import type { ImageAddonType, IImageAddonOptionsType } from '../addons/xterm-addon-image/out/ImageAddon';
let ImageAddon: ImageAddonType | undefined; // eslint-disable-line @typescript-eslint/naming-convention
if (!navigator.userAgent.includes('AppleWebKit')) {
const imageAddon = require('../addons/xterm-addon-image/out/ImageAddon');
ImageAddon = imageAddon.ImageAddon;
}

// Use webpacked version (yarn package)
// import { Terminal } from '../lib/xterm';
// import { AttachAddon } from 'xterm-addon-attach';
Expand All @@ -42,7 +49,7 @@ export interface IWindowWithTerminal extends Window {
Terminal?: typeof TerminalType; // eslint-disable-line @typescript-eslint/naming-convention
AttachAddon?: typeof AttachAddon; // eslint-disable-line @typescript-eslint/naming-convention
FitAddon?: typeof FitAddon; // eslint-disable-line @typescript-eslint/naming-convention
ImageAddon?: typeof ImageAddon; // 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
SerializeAddon?: typeof SerializeAddon; // eslint-disable-line @typescript-eslint/naming-convention
WebLinksAddon?: typeof WebLinksAddon; // eslint-disable-line @typescript-eslint/naming-convention
Expand All @@ -68,7 +75,7 @@ interface IDemoAddon<T extends AddonType> {
T extends 'attach' ? typeof AttachAddon :
T extends 'canvas' ? typeof CanvasAddon :
T extends 'fit' ? typeof FitAddon :
T extends 'image' ? typeof ImageAddon :
T extends 'image' ? typeof ImageAddonType :
T extends 'search' ? typeof SearchAddon :
T extends 'serialize' ? typeof SerializeAddon :
T extends 'webLinks' ? typeof WebLinksAddon :
Expand All @@ -80,7 +87,7 @@ interface IDemoAddon<T extends AddonType> {
T extends 'attach' ? AttachAddon :
T extends 'canvas' ? CanvasAddon :
T extends 'fit' ? FitAddon :
T extends 'image' ? ImageAddon :
T extends 'image' ? ImageAddonType :
T extends 'search' ? SearchAddon :
T extends 'serialize' ? SerializeAddon :
T extends 'webLinks' ? WebLinksAddon :
Expand Down Expand Up @@ -1256,7 +1263,7 @@ Test BG-colored Erase (BCE):


function initImageAddonExposed(): void {
const DEFAULT_OPTIONS: IImageAddonOptions = (addons.image.instance as any)._defaultOpts;
const DEFAULT_OPTIONS: IImageAddonOptionsType = (addons.image.instance as any)._defaultOpts;
const limitStorageElement = document.querySelector<HTMLInputElement>('#image-storagelimit');
limitStorageElement.valueAsNumber = addons.image.instance.storageLimit;
addDomListener(limitStorageElement, 'change', () => {
Expand Down
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
"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-debug": "playwright test -c ./out-test/playwright/playwright.config.js --headed --workers 1 --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",
Expand All @@ -53,6 +55,7 @@
"vtfeatures": "node bin/extract_vtfeatures.js src/**/*.ts src/*.ts"
},
"devDependencies": {
"@playwright/test": "^1.37.1",
"@types/chai": "^4.2.22",
"@types/debug": "^4.1.7",
"@types/deep-equal": "^1.0.1",
Expand Down Expand Up @@ -80,7 +83,6 @@
"mustache": "^4.2.0",
"node-pty": "^0.10.1",
"nyc": "^15.1.0",
"playwright": "^1.37.1",
"source-map-loader": "^3.0.0",
"source-map-support": "^0.5.20",
"ts-loader": "^9.3.1",
Expand Down
6 changes: 5 additions & 1 deletion src/common/EventEmitter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,10 +57,14 @@ export class EventEmitter<T, U = void> implements IEventEmitter<T, U> {
}

public dispose(): void {
this.clearListeners();
this._disposed = true;
}

public clearListeners(): void {
if (this._listeners) {
this._listeners.length = 0;
}
this._disposed = true;
}
}

Expand Down
2 changes: 1 addition & 1 deletion test/api/CharWidth.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { pollFor, openTerminal, launchBrowser } from './TestUtils';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';

const APP = 'http://127.0.0.1:3001/test';

Expand Down
2 changes: 1 addition & 1 deletion test/api/InputHandler.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { assert } from 'chai';
import { pollFor, openTerminal, getBrowserType, launchBrowser, writeSync } from './TestUtils';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';
import { IRenderDimensions } from 'browser/renderer/shared/Types';

const APP = 'http://127.0.0.1:3001/test';
Expand Down
2 changes: 1 addition & 1 deletion test/api/MouseTracking.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
*/

import { pollFor, writeSync, openTerminal, getBrowserType, launchBrowser } from './TestUtils';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';

const APP = 'http://127.0.0.1:3001/test';

Expand Down
2 changes: 1 addition & 1 deletion test/api/Parser.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { assert } from 'chai';
import { writeSync, openTerminal, launchBrowser } from './TestUtils';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';

const APP = 'http://127.0.0.1:3001/test';

Expand Down
2 changes: 1 addition & 1 deletion test/api/Terminal.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

import { assert } from 'chai';
import { pollFor, timeout, writeSync, openTerminal, launchBrowser } from './TestUtils';
import { Browser, Page } from 'playwright';
import { Browser, Page } from '@playwright/test';
import { fail } from 'assert';
import { IRenderDimensions } from 'browser/renderer/shared/Types';

Expand Down
4 changes: 2 additions & 2 deletions test/api/TestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
* @license MIT
*/

import * as playwright from 'playwright';
import * as playwright from '@playwright/test';
import deepEqual = require('deep-equal');
import { ITerminalInitOnlyOptions, ITerminalOptions } from 'xterm';
import { deepStrictEqual, fail } from 'assert';
import { deepStrictEqual } from 'assert';

export async function pollFor<T>(page: playwright.Page, evalOrFn: string | (() => Promise<T>), val: T, preFn?: () => Promise<void>, maxDuration?: number): Promise<void> {
if (preFn) {
Expand Down
76 changes: 76 additions & 0 deletions test/playwright/CharWidth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/**
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
* @license MIT
*/

import { test } from '@playwright/test';
import { createTestContext, ITestContext, openTerminal, pollFor } from './TestUtils';

let ctx: ITestContext;
test.beforeAll(async ({ browser }) => {
ctx = await createTestContext(browser);
await openTerminal(ctx);
});
test.afterAll(async () => await ctx.page.close());

test.beforeEach(async () => await ctx.proxy.reset());

test.describe('CharWidth Integration Tests', function(): void {
test.describe('getStringCellWidth', () => {
test('ASCII chars', async () => {
await ctx.proxy.write('This is just ASCII text.#');
await pollFor(ctx.page, () => sumWidths(0, 1, '#'), 25);
});

test('combining chars', async () => {
await ctx.proxy.write('e\u0301e\u0301e\u0301e\u0301e\u0301e\u0301e\u0301e\u0301e\u0301#');
await pollFor(ctx.page, () => sumWidths(0, 1, '#'), 10);
});

test('surrogate chars', async () => {
await ctx.proxy.write('π„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„žπ„ž#');
await pollFor(ctx.page, () => sumWidths(0, 1, '#'), 28);
});

test('surrogate combining chars', async () => {
await ctx.proxy.write('π“‚€\u0301π“‚€\u0301π“‚€\u0301π“‚€\u0301π“‚€\u0301π“‚€\u0301π“‚€\u0301π“‚€\u0301π“‚€\u0301π“‚€\u0301π“‚€\u0301#');
await pollFor(ctx.page, () => sumWidths(0, 1, '#'), 12);
});

test('fullwidth chars', async () => {
await ctx.proxy.write('οΌ‘οΌ’οΌ“οΌ”οΌ•οΌ–οΌ—οΌ˜οΌ™οΌ#');
await pollFor(ctx.page, () => sumWidths(0, 1, '#'), 21);
});

test('fullwidth chars offset 1', async () => {
await ctx.proxy.write('aοΌ‘οΌ’οΌ“οΌ”οΌ•οΌ–οΌ—οΌ˜οΌ™οΌ#');
await pollFor(ctx.page, () => sumWidths(0, 1, '#'), 22);
});

// TODO: multiline tests once #1685 is resolved
});
});

async function sumWidths(start: number, end: number, sentinel: string): Promise<number> {
await ctx.page.evaluate(`
(function() {
window.result = 0;
const buffer = window.term.buffer.active;
for (let i = ${start}; i < ${end}; i++) {
const line = buffer.getLine(i);
let j = 0;
while (true) {
const cell = line.getCell(j++);
if (!cell) {
break;
}
window.result += cell.getWidth();
if (cell.getChars() === '${sentinel}') {
return;
}
}
}
})();
`);
return await ctx.page.evaluate(`window.result`);
}
Loading

0 comments on commit fbebabe

Please sign in to comment.