Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
8 changes: 6 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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)
run: yarn test-playwright-${{ matrix.browser }} --forbid-only --workers 4 --suite=core
- name: Integration tests (xterm-addon-canvas)
run: yarn test-playwright-${{ matrix.browser }} --forbid-only --workers 4 --suite=xterm-addon-canvas
- name: Integration tests (xterm-addon-webgl)
run: yarn test-playwright-${{ matrix.browser }} --forbid-only --workers 4 --suite=xterm-addon-webgl

test-api:
needs: build
Expand Down
3 changes: 2 additions & 1 deletion addons/xterm-addon-canvas/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
31 changes: 31 additions & 0 deletions addons/xterm-addon-canvas/test/CanvasRenderer.test.ts
Original file line number Diff line number Diff line change
@@ -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);
});
35 changes: 35 additions & 0 deletions addons/xterm-addon-canvas/test/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -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;
41 changes: 41 additions & 0 deletions addons/xterm-addon-canvas/test/tsconfig.json
Original file line number Diff line number Diff line change
@@ -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"
}
]
}
3 changes: 2 additions & 1 deletion addons/xterm-addon-canvas/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
"files": [],
"include": [],
"references": [
{ "path": "./src" }
{ "path": "./src" },
{ "path": "./test" }
]
}
2 changes: 1 addition & 1 deletion addons/xterm-addon-webgl/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"prepackage": "npm run build",
"package": "../../node_modules/.bin/webpack",
"prepublishOnly": "npm run package",
"start": "node ../../demo/start"
"start-server-only": "node ../../demo/start-server-only"
},
"peerDependencies": {
"xterm": "^5.0.0"
Expand Down
18 changes: 3 additions & 15 deletions addons/xterm-addon-webgl/test/WebglRenderer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,18 @@
*/

import test from '@playwright/test';
import { strictEqual } from 'assert';
import { injectSharedRendererTests } from '../../../out-test/playwright/SharedRendererTests';
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: { value: ITestContext } = { value: undefined } as any;
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 WebglAddon(true);
window.addon = new window.WebglAddon(true);
window.term.loadAddon(window.addon);
`);
});
Expand All @@ -29,16 +28,5 @@ test.describe('WebGL Renderer Integration Tests', async () => {
test.skip(({ browserName }) => browserName === 'firefox');
}

test('dispose removes renderer canvases', async function(): Promise<void> {
strictEqual(await ctx.page.evaluate(`document.querySelectorAll('.xterm canvas').length`), 2);
await ctx.page.evaluate(`addon.dispose()`);
strictEqual(await ctx.page.evaluate(`document.querySelectorAll('.xterm canvas').length`), 0);
// Re-create webgl addon to avoid side effects impacting other tests
await ctx.page.evaluate(`
window.addon = new WebglAddon(true);
window.term.loadAddon(window.addon);
`);
});

injectSharedRendererTests(ctxWrapper);
});
2 changes: 1 addition & 1 deletion addons/xterm-addon-webgl/test/playwright.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ const config: PlaywrightTestConfig = {
],
reporter: 'list',
webServer: {
command: 'npm start',
command: 'npm run start-server-only',
port: 3000,
timeout: 120000,
reuseExistingServer: !process.env.CI
Expand Down
41 changes: 29 additions & 12 deletions bin/test_playwright.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,27 +8,44 @@
const cp = require('child_process');
const path = require('path');

const configs = [
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));
}

for (const config of configs) {
const command = npmBinScript('playwright');
const args = ['test', '-c', config.path, ...process.argv.slice(2)];
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'
async function run() {
for (const config of configs) {
const command = npmBinScript('playwright');
const args = ['test', '-c', config.path, ...argv.slice(2)];
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);
}
);
if (run.status) {
process.exit(run.status);
}
}
run();
2 changes: 2 additions & 0 deletions demo/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,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
Expand Down Expand Up @@ -218,6 +219,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;
Expand Down
10 changes: 10 additions & 0 deletions demo/start-server-only.js
Original file line number Diff line number Diff line change
@@ -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 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"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/",
Expand Down
4 changes: 2 additions & 2 deletions test/playwright/Renderer.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@

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

let ctx: ITestContext;
const ctxWrapper: { value: ITestContext } = { value: undefined } as any;
const ctxWrapper: ISharedRendererTestContext = { value: undefined } as any;
test.beforeAll(async ({ browser }) => {
ctx = await createTestContext(browser);
ctxWrapper.value = ctx;
Expand Down
13 changes: 9 additions & 4 deletions test/playwright/SharedRendererTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import { LocatorScreenshotOptions, test } from '@playwright/test';
import { ITheme } from 'xterm';
import { ITestContext, MaybeAsync, pollFor } from './TestUtils';

export function injectSharedRendererTests(ctx: { value: ITestContext }): void {
export interface ISharedRendererTestContext {
value: ITestContext;
skipCanvasExceptions?: boolean;
}

export function injectSharedRendererTests(ctx: ISharedRendererTestContext): void {
test.beforeEach(async () => {
await ctx.value.proxy.reset();
ctx.value.page.evaluate(`
Expand Down Expand Up @@ -934,7 +939,7 @@ export function injectSharedRendererTests(ctx: { value: ITestContext }): void {
});
});

test.describe('selectionBackground', async () => {
(ctx.skipCanvasExceptions ? test.describe.skip : test.describe)('selectionBackground', async () => {
test('should resolve the inverse foreground color based on the original background color, not the selection', async () => {
const theme: ITheme = {
foreground: '#FF0000',
Expand Down Expand Up @@ -970,7 +975,7 @@ export function injectSharedRendererTests(ctx: { value: ITestContext }): void {
});
});

test.describe('selectionForeground', () => {
(ctx.skipCanvasExceptions ? test.describe.skip : test.describe)('selectionForeground', () => {
test('transparent background inverse', async () => {
const theme: ITheme = {
selectionForeground: '#ff0000'
Expand Down Expand Up @@ -1050,7 +1055,7 @@ export function injectSharedRendererTests(ctx: { value: ITestContext }): void {
await ctx.value.proxy.write( data);
await pollFor(ctx.value.page, () => getCellColor(ctx.value, 1, 1), [0, 0, 255, 255]);
});
test('backgroundColor should ignore inverse (only bg on decoration)', async () => {
(ctx.skipCanvasExceptions ? test.skip : test)('backgroundColor should ignore inverse (only bg on decoration)', async () => {
const data = `\x1b[7m█ \x1b[0m`;
await ctx.value.proxy.write( data);
await ctx.value.page.evaluate(`
Expand Down
2 changes: 1 addition & 1 deletion test/playwright/TestUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -363,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'));
`);
await ctx.page.waitForSelector('.xterm-rows');
Expand Down