diff --git a/.eslintrc.json b/.eslintrc.json index 0626a446..892c297d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -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", diff --git a/addons/xterm-addon-canvas/test/CanvasRenderer.test.ts b/addons/xterm-addon-canvas/test/CanvasRenderer.test.ts new file mode 100644 index 00000000..c87c376f --- /dev/null +++ b/addons/xterm-addon-canvas/test/CanvasRenderer.test.ts @@ -0,0 +1,35 @@ +/** + * 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, + skipSelectionTests: true +} as any; +test.beforeAll(async ({ browser }) => { + ctx = await createTestContext(browser); + await openTerminal(ctx); + ctxWrapper.value = ctx; + await ctx.page.evaluate(` + window.addon = new CanvasAddon(true); + window.term.loadAddon(window.addon); + `); +}); +test.afterAll(async () => await ctx.page.close()); + +test.describe('Canvas 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); +}); diff --git a/addons/xterm-addon-canvas/test/playwright.config.ts b/addons/xterm-addon-canvas/test/playwright.config.ts new file mode 100644 index 00000000..3d1fe4fb --- /dev/null +++ b/addons/xterm-addon-canvas/test/playwright.config.ts @@ -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 start', + port: 3000, + timeout: 120000, + reuseExistingServer: !process.env.CI + } +}; +export default config; diff --git a/addons/xterm-addon-canvas/test/tsconfig.json b/addons/xterm-addon-canvas/test/tsconfig.json new file mode 100644 index 00000000..9523e64b --- /dev/null +++ b/addons/xterm-addon-canvas/test/tsconfig.json @@ -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" + } + ] +} diff --git a/addons/xterm-addon-canvas/tsconfig.json b/addons/xterm-addon-canvas/tsconfig.json index b711f30a..2d820dd1 100644 --- a/addons/xterm-addon-canvas/tsconfig.json +++ b/addons/xterm-addon-canvas/tsconfig.json @@ -2,6 +2,7 @@ "files": [], "include": [], "references": [ - { "path": "./src" } + { "path": "./src" }, + { "path": "./test" } ] } diff --git a/addons/xterm-addon-webgl/test/WebglRenderer.test.ts b/addons/xterm-addon-webgl/test/WebglRenderer.test.ts index 4da9d346..c6789613 100644 --- a/addons/xterm-addon-webgl/test/WebglRenderer.test.ts +++ b/addons/xterm-addon-webgl/test/WebglRenderer.test.ts @@ -5,12 +5,12 @@ 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); diff --git a/bin/test_playwright.js b/bin/test_playwright.js index bc4e7b02..379c0e26 100644 --- a/bin/test_playwright.js +++ b/bin/test_playwright.js @@ -9,7 +9,8 @@ const cp = require('child_process'); const path = require('path'); const configs = [ - { name: 'core', path: 'out-test/playwright/playwright.config.js' }, + // { 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' } ]; diff --git a/demo/client.ts b/demo/client.ts index bde5ca72..7ade385e 100644 --- a/demo/client.ts +++ b/demo/client.ts @@ -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 @@ -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; diff --git a/test/playwright/Renderer.test.ts b/test/playwright/Renderer.test.ts index 17c8b6e1..c5c1e94d 100644 --- a/test/playwright/Renderer.test.ts +++ b/test/playwright/Renderer.test.ts @@ -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; diff --git a/test/playwright/SharedRendererTests.ts b/test/playwright/SharedRendererTests.ts index 2120925f..f8d70cc9 100644 --- a/test/playwright/SharedRendererTests.ts +++ b/test/playwright/SharedRendererTests.ts @@ -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(` @@ -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', @@ -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' @@ -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(`