From 4295dfaf20b448aaa9cfef7083ae10d92a18a616 Mon Sep 17 00:00:00 2001 From: Daniel Imms <2193314+Tyriar@users.noreply.github.com> Date: Tue, 2 Jul 2024 14:49:36 -0700 Subject: [PATCH] Migrate clipboard api tests to playwright (only chromium) --- .../test/ClipboardAddon.api.ts | 88 ------------------- .../test/ClipboardAddon.test.ts | 78 ++++++++++++++++ .../addon-clipboard/test/playwright.config.ts | 35 ++++++++ addons/addon-clipboard/test/tsconfig.json | 22 ++++- bin/test_playwright.js | 11 +-- 5 files changed, 138 insertions(+), 96 deletions(-) delete mode 100644 addons/addon-clipboard/test/ClipboardAddon.api.ts create mode 100644 addons/addon-clipboard/test/ClipboardAddon.test.ts create mode 100644 addons/addon-clipboard/test/playwright.config.ts diff --git a/addons/addon-clipboard/test/ClipboardAddon.api.ts b/addons/addon-clipboard/test/ClipboardAddon.api.ts deleted file mode 100644 index 4ef768e8..00000000 --- a/addons/addon-clipboard/test/ClipboardAddon.api.ts +++ /dev/null @@ -1,88 +0,0 @@ -/** - * Copyright (c) 2023 The xterm.js authors. All rights reserved. - * @license MIT - */ - -import { assert } from 'chai'; -import { openTerminal, launchBrowser, writeSync, getBrowserType } from '../../../out-test/api/TestUtils'; -import { Browser, BrowserContext, Page } from '@playwright/test'; -import { beforeEach } from 'mocha'; - -const APP = 'http://127.0.0.1:3001/test'; - -let browser: Browser; -let context: BrowserContext; -let page: Page; -const width = 800; -const height = 600; - -describe('ClipboardAddon', () => { - before(async function (): Promise { - browser = await launchBrowser({ - // Enable clipboard access in firefox, mainly for readText - firefoxUserPrefs: { - // eslint-disable-next-line @typescript-eslint/naming-convention - 'dom.events.testing.asyncClipboard': true, - // eslint-disable-next-line @typescript-eslint/naming-convention - 'dom.events.asyncClipboard.readText': true - } - }); - context = await browser.newContext(); - if (getBrowserType().name() !== 'webkit') { - // Enable clipboard access in chromium without user gesture - context.grantPermissions(['clipboard-read', 'clipboard-write']); - } - page = await context.newPage(); - await page.setViewportSize({ width, height }); - await page.goto(APP); - await openTerminal(page); - await page.evaluate(` - window.clipboardAddon = new ClipboardAddon(); - window.term.loadAddon(window.clipboardAddon); - `); - }); - - after(() => { - browser.close(); - }); - - beforeEach(async () => { - await page.evaluate(`window.term.reset()`); - }); - - const testDataEncoded = 'aGVsbG8gd29ybGQ='; - const testDataDecoded = 'hello world'; - - describe('write data', async function (): Promise { - it('simple string', async () => { - await writeSync(page, `\x1b]52;c;${testDataEncoded}\x07`); - assert.deepEqual(await page.evaluate(() => window.navigator.clipboard.readText()), testDataDecoded); - }); - it('invalid base64 string', async () => { - await writeSync(page, `\x1b]52;c;${testDataEncoded}invalid\x07`); - assert.deepEqual(await page.evaluate(() => window.navigator.clipboard.readText()), ''); - }); - it('empty string', async () => { - await writeSync(page, `\x1b]52;c;${testDataEncoded}\x07`); - await writeSync(page, `\x1b]52;c;\x07`); - assert.deepEqual(await page.evaluate(() => window.navigator.clipboard.readText()), ''); - }); - }); - - describe('read data', async function (): Promise { - it('simple string', async () => { - await page.evaluate(` - window.data = []; - window.term.onData(e => data.push(e)); - `); - await page.evaluate(() => window.navigator.clipboard.writeText('hello world')); - await writeSync(page, `\x1b]52;c;?\x07`); - assert.deepEqual(await page.evaluate('window.data'), [`\x1b]52;c;${testDataEncoded}\x07`]); - }); - it('clear clipboard', async () => { - await writeSync(page, `\x1b]52;c;!\x07`); - await writeSync(page, `\x1b]52;c;?\x07`); - assert.deepEqual(await page.evaluate(() => window.navigator.clipboard.readText()), ''); - }); - }); -}); diff --git a/addons/addon-clipboard/test/ClipboardAddon.test.ts b/addons/addon-clipboard/test/ClipboardAddon.test.ts new file mode 100644 index 00000000..6234a3cd --- /dev/null +++ b/addons/addon-clipboard/test/ClipboardAddon.test.ts @@ -0,0 +1,78 @@ +/** + * Copyright (c) 2023 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import test from '@playwright/test'; +import { deepEqual, ok, strictEqual } from 'assert'; +import { ITestContext, createTestContext, launchBrowser, openTerminal, timeout } from '../../../out-test/playwright/TestUtils'; + +let ctx: ITestContext; +test.beforeAll(async ({ browser }, testInfo) => { + ctx = await createTestContext(browser); + await openTerminal(ctx); +}); +test.afterAll(async () => { + await ctx.page.close(); +}); + +test.describe('ClipboardAddon', () => { + + test.beforeEach(async ({}, testInfo) => { + // DEBT: This test doesn't work since the migration to @playwright/test + if (ctx.browser.browserType().name() !== 'chromium') { + testInfo.skip(); + return; + } + if (ctx.browser.browserType().name() === 'chromium') { + // Enable clipboard access in chromium without user gesture + await ctx.page.context().grantPermissions(['clipboard-read', 'clipboard-write']); + } + await ctx.page.evaluate(` + window.term.reset() + window.clipboard?.dispose(); + window.clipboard = new ClipboardAddon(); + window.term.loadAddon(window.clipboard); + `); + }); + + test.beforeEach(async () => { + await ctx.proxy.reset(); + }); + + const testDataEncoded = 'aGVsbG8gd29ybGQ='; + const testDataDecoded = 'hello world'; + + test.describe('write data', async function (): Promise { + test('simple string', async () => { + await ctx.proxy.write(`\x1b]52;c;${testDataEncoded}\x07`); + deepEqual(await ctx.page.evaluate(() => window.navigator.clipboard.readText()), testDataDecoded); + }); + test('invalid base64 string', async () => { + await ctx.proxy.write(`\x1b]52;c;${testDataEncoded}invalid\x07`); + deepEqual(await ctx.page.evaluate(() => window.navigator.clipboard.readText()), ''); + }); + test('empty string', async () => { + await ctx.proxy.write(`\x1b]52;c;${testDataEncoded}\x07`); + await ctx.proxy.write(`\x1b]52;c;\x07`); + deepEqual(await ctx.page.evaluate(() => window.navigator.clipboard.readText()), ''); + }); + }); + + test.describe('read data', async function (): Promise { + test('simple string', async () => { + await ctx.page.evaluate(` + window.data = []; + window.term.onData(e => data.push(e)); + `); + await ctx.page.evaluate(() => window.navigator.clipboard.writeText('hello world')); + await ctx.proxy.write(`\x1b]52;c;?\x07`); + deepEqual(await ctx.page.evaluate('window.data'), [`\x1b]52;c;${testDataEncoded}\x07`]); + }); + test('clear clipboard', async () => { + await ctx.proxy.write(`\x1b]52;c;!\x07`); + await ctx.proxy.write(`\x1b]52;c;?\x07`); + deepEqual(await ctx.page.evaluate(() => window.navigator.clipboard.readText()), ''); + }); + }); +}); diff --git a/addons/addon-clipboard/test/playwright.config.ts b/addons/addon-clipboard/test/playwright.config.ts new file mode 100644 index 00000000..79cf9f02 --- /dev/null +++ b/addons/addon-clipboard/test/playwright.config.ts @@ -0,0 +1,35 @@ +import { PlaywrightTestConfig } from '@playwright/test'; + +const config: PlaywrightTestConfig = { + testDir: '.', + timeout: 10000, + projects: [ + { + name: 'ChromeStable', + use: { + browserName: 'chromium', + channel: 'chrome' + } + }, + { + name: 'FirefoxStable', + 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; diff --git a/addons/addon-clipboard/test/tsconfig.json b/addons/addon-clipboard/test/tsconfig.json index 67ad42b7..cb6fed28 100644 --- a/addons/addon-clipboard/test/tsconfig.json +++ b/addons/addon-clipboard/test/tsconfig.json @@ -3,21 +3,37 @@ "module": "commonjs", "target": "es2021", "lib": [ - "es2015" + "es2021", ], "rootDir": ".", "outDir": "../out-test", "sourceMap": true, "removeComments": true, + "baseUrl": ".", + "paths": { + "common/*": [ + "../../../src/common/*" + ], + "browser/*": [ + "../../../src/browser/*" + ] + }, "strict": true, "types": [ - "../../../node_modules/@types/mocha", "../../../node_modules/@types/node", - "../../../out-test/api/TestUtils" + "../../../out-test/playwright/TestUtils" ] }, "include": [ "./**/*", "../../../typings/xterm.d.ts" + ], + "references": [ + { + "path": "../../../src/common" + }, + { + "path": "../../../src/browser" + } ] } diff --git a/bin/test_playwright.js b/bin/test_playwright.js index 30d21e95..4063f5f5 100644 --- a/bin/test_playwright.js +++ b/bin/test_playwright.js @@ -18,11 +18,12 @@ while (argv.some(e => e.startsWith('--suite='))) { } let configs = [ - { name: 'core', path: 'out-test/playwright/playwright.config.js' }, - { name: 'addon-canvas', path: 'addons/addon-canvas/out-test/playwright.config.js' }, - { name: 'addon-fit', path: 'addons/addon-fit/out-test/playwright.config.js' }, - { name: 'addon-search', path: 'addons/addon-search/out-test/playwright.config.js' }, - { name: 'addon-webgl', path: 'addons/addon-webgl/out-test/playwright.config.js' } + { name: 'core', path: 'out-test/playwright/playwright.config.js' }, + { name: 'addon-canvas', path: 'addons/addon-canvas/out-test/playwright.config.js' }, + { name: 'addon-clipboard', path: 'addons/addon-clipboard/out-test/playwright.config.js' }, + { name: 'addon-fit', path: 'addons/addon-fit/out-test/playwright.config.js' }, + { name: 'addon-search', path: 'addons/addon-search/out-test/playwright.config.js' }, + { name: 'addon-webgl', path: 'addons/addon-webgl/out-test/playwright.config.js' } ]; if (suiteFilter) {