mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge branch 'master' into es2021
This commit is contained in:
@@ -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",
|
||||
|
||||
+88
-40
@@ -90,14 +90,15 @@ jobs:
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build-artifacts
|
||||
- name: Unzip artifacts (Linux, macOS)
|
||||
if: runner.os != 'Windows'
|
||||
run: unzip -o compressed-build.zip
|
||||
- name: Unzip artifacts (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: 7z x compressed-build.zip -aoa -o${{ github.workspace }}
|
||||
- name: Print directory structure
|
||||
run: ls -R
|
||||
- name: Unzip artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}"
|
||||
else
|
||||
unzip -o compressed-build.zip
|
||||
fi
|
||||
ls -R
|
||||
- name: Unit test coverage
|
||||
run: |
|
||||
yarn test-unit-coverage --forbid-only
|
||||
@@ -131,14 +132,15 @@ jobs:
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build-artifacts
|
||||
- name: Unzip artifacts (Linux, macOS)
|
||||
if: runner.os != 'Windows'
|
||||
run: unzip -o compressed-build.zip
|
||||
- name: Unzip artifacts (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: 7z x compressed-build.zip -aoa -o${{ github.workspace }}
|
||||
- name: Print directory structure
|
||||
run: ls -R
|
||||
- name: Unzip artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}"
|
||||
else
|
||||
unzip -o compressed-build.zip
|
||||
fi
|
||||
ls -R
|
||||
- name: Unit tests
|
||||
run: yarn test-unit --forbid-only
|
||||
|
||||
@@ -164,14 +166,15 @@ jobs:
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build-artifacts
|
||||
- name: Unzip artifacts (Linux, macOS)
|
||||
if: runner.os != 'Windows'
|
||||
run: unzip -o compressed-build.zip
|
||||
- name: Unzip artifacts (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: 7z x compressed-build.zip -aoa -o${{ github.workspace }}
|
||||
- name: Print directory structure
|
||||
run: ls -R
|
||||
- name: Unzip artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}"
|
||||
else
|
||||
unzip -o compressed-build.zip
|
||||
fi
|
||||
ls -R
|
||||
- name: Unit tests
|
||||
run: yarn test-unit --forbid-only
|
||||
|
||||
@@ -204,17 +207,61 @@ jobs:
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build-artifacts
|
||||
- name: Unzip artifacts (Linux, macOS)
|
||||
if: runner.os != 'Windows'
|
||||
run: unzip -o compressed-build.zip
|
||||
- name: Unzip artifacts (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: 7z x compressed-build.zip -aoa -o${{ github.workspace }}
|
||||
- name: Print directory structure
|
||||
run: ls -R
|
||||
- name: Unzip artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}"
|
||||
else
|
||||
unzip -o compressed-build.zip
|
||||
fi
|
||||
ls -R
|
||||
- name: Integration tests (${{ matrix.browser }})
|
||||
run: yarn test-api-${{ matrix.browser }} --headless --forbid-only
|
||||
|
||||
test-playwright-parallel:
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
matrix:
|
||||
node-version: [18] # just one as integration tests are about testing in browser
|
||||
runs-on: [ubuntu] # macos is flaky
|
||||
browser: [chromium, firefox, webkit]
|
||||
runs-on: ${{ matrix.runs-on }}-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Use Node.js ${{ matrix.node-version }}.x
|
||||
uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: ${{ matrix.node-version }}.x
|
||||
cache: 'yarn'
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
yarn --frozen-lockfile
|
||||
yarn install-addons
|
||||
- name: Install playwright
|
||||
run: npx playwright install --with-deps ${{ matrix.browser }}
|
||||
- name: Wait for build job
|
||||
uses: NathanFirmo/wait-for-other-job@v1.1.1
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
job: build
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build-artifacts
|
||||
- name: Unzip artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}"
|
||||
else
|
||||
unzip -o compressed-build.zip
|
||||
fi
|
||||
ls -R
|
||||
- name: Build demo
|
||||
run: yarn build-demo
|
||||
- name: Integration tests
|
||||
run: yarn test-playwright-${{ matrix.browser }} --forbid-only
|
||||
|
||||
test-api:
|
||||
needs: build
|
||||
timeout-minutes: 20
|
||||
@@ -240,13 +287,14 @@ jobs:
|
||||
- uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: build-artifacts
|
||||
- name: Unzip artifacts (Linux, macOS)
|
||||
if: runner.os != 'Windows'
|
||||
run: unzip -o compressed-build.zip
|
||||
- name: Unzip artifacts (Windows)
|
||||
if: runner.os == 'Windows'
|
||||
run: 7z x compressed-build.zip -aoa -o${{ github.workspace }}
|
||||
- name: Print directory structure
|
||||
run: ls -R
|
||||
- name: Unzip artifacts
|
||||
shell: bash
|
||||
run: |
|
||||
if [ "$RUNNER_OS" == "Windows" ]; then
|
||||
pwsh -Command "7z x compressed-build.zip -aoa -o${{ github.workspace }}"
|
||||
else
|
||||
unzip -o compressed-build.zip
|
||||
fi
|
||||
ls -R
|
||||
- name: Integration tests (${{ matrix.browser }})
|
||||
run: yarn test-api-${{ matrix.browser }} --headless --forbid-only
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
+11
-4
@@ -13,7 +13,6 @@ 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';
|
||||
@@ -21,6 +20,14 @@ 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, IImageAddonOptions } from '../addons/xterm-addon-image/out/ImageAddon';
|
||||
let ImageAddon: ImageAddonType | undefined; // eslint-disable-line @typescript-eslint/naming-convention
|
||||
if ('WebAssembly' in window) {
|
||||
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';
|
||||
@@ -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
|
||||
@@ -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 :
|
||||
@@ -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 :
|
||||
|
||||
+1
-58
@@ -5,69 +5,12 @@
|
||||
|
||||
// @ts-check
|
||||
|
||||
const path = require('path');
|
||||
const clientConfig = require('./webpack.config');
|
||||
const webpack = require('webpack');
|
||||
const startServer = require('./server.js');
|
||||
|
||||
startServer();
|
||||
|
||||
/**
|
||||
* This webpack config builds and watches the demo project. It works by taking the output from tsc
|
||||
* (via `yarn watch`) which is put into `out/` and then webpacks it into `demo/dist/`. The aliases
|
||||
* are used fix up the absolute paths output by tsc (because of `baseUrl` and `paths` in
|
||||
* `tsconfig.json`.
|
||||
*
|
||||
* For production builds see `webpack.config.js` in the root directory. If that is built the demo
|
||||
* can use that by switching out which `Terminal` is imported in `client.ts`, this is useful for
|
||||
* validating that the packaged version works correctly.
|
||||
*
|
||||
* @type {import('webpack').Configuration}
|
||||
*/
|
||||
const clientConfig = {
|
||||
entry: path.resolve(__dirname, 'client.ts'),
|
||||
devtool: 'inline-source-map',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
use: ["source-map-loader"],
|
||||
enforce: "pre",
|
||||
exclude: /node_modules/
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
modules: [
|
||||
'node_modules',
|
||||
path.resolve(__dirname, '..'),
|
||||
path.resolve(__dirname, '../addons')
|
||||
],
|
||||
extensions: [ '.tsx', '.ts', '.js' ],
|
||||
alias: {
|
||||
common: path.resolve('./out/common'),
|
||||
browser: path.resolve('./out/browser')
|
||||
},
|
||||
fallback: {
|
||||
// The ligature modules contains fallbacks for node environments, we never want to browserify them
|
||||
stream: false,
|
||||
util: false,
|
||||
os: false,
|
||||
path: false,
|
||||
fs: false
|
||||
}
|
||||
},
|
||||
output: {
|
||||
filename: 'client-bundle.js',
|
||||
path: path.resolve(__dirname, 'dist')
|
||||
},
|
||||
mode: 'development',
|
||||
watch: true
|
||||
};
|
||||
const compiler = webpack(clientConfig);
|
||||
|
||||
compiler.watch({
|
||||
|
||||
+1
-1
@@ -7,6 +7,6 @@
|
||||
</head>
|
||||
<body>
|
||||
<div id="terminal-container"></div>
|
||||
<script src="dist/client-bundle.js" defer ></script>
|
||||
<script src="/dist/client-bundle.js" defer></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -0,0 +1,62 @@
|
||||
/**
|
||||
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
// @ts-check
|
||||
|
||||
const path = require('path');
|
||||
|
||||
/**
|
||||
* This webpack config does a production build for xterm.js. It works by taking the output from tsc
|
||||
* (via `yarn watch` or `yarn prebuild`) which are put into `out/` and webpacks them into a
|
||||
* production mode umd library module in `lib/`. The aliases are used fix up the absolute paths
|
||||
* output by tsc (because of `baseUrl` and `paths` in `tsconfig.json`.
|
||||
*
|
||||
* @type {import('webpack').Configuration}
|
||||
*/
|
||||
const config = {
|
||||
entry: path.resolve(__dirname, 'client.ts'),
|
||||
devtool: 'inline-source-map',
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.tsx?$/,
|
||||
use: 'ts-loader',
|
||||
exclude: /node_modules/
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
use: ["source-map-loader"],
|
||||
enforce: "pre",
|
||||
exclude: /node_modules/
|
||||
}
|
||||
]
|
||||
},
|
||||
resolve: {
|
||||
modules: [
|
||||
'node_modules',
|
||||
path.resolve(__dirname, '..'),
|
||||
path.resolve(__dirname, '../addons')
|
||||
],
|
||||
extensions: [ '.tsx', '.ts', '.js' ],
|
||||
alias: {
|
||||
common: path.resolve('./out/common'),
|
||||
browser: path.resolve('./out/browser')
|
||||
},
|
||||
fallback: {
|
||||
// The ligature modules contains fallbacks for node environments, we never want to browserify them
|
||||
stream: false,
|
||||
util: false,
|
||||
os: false,
|
||||
path: false,
|
||||
fs: false
|
||||
}
|
||||
},
|
||||
output: {
|
||||
filename: 'client-bundle.js',
|
||||
path: path.resolve(__dirname, 'dist')
|
||||
},
|
||||
mode: 'development'
|
||||
};
|
||||
module.exports = config;
|
||||
+7
-1
@@ -28,6 +28,7 @@
|
||||
"package-headless": "webpack --config ./webpack.config.headless.js",
|
||||
"postpackage-headless": "node ./bin/package_headless.js",
|
||||
"start": "node demo/start",
|
||||
"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/",
|
||||
@@ -37,6 +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-unit": "node ./bin/test.js",
|
||||
"test-unit-coverage": "node ./bin/test.js --coverage",
|
||||
"test-unit-dev": "cross-env NODE_PATH='./out' mocha",
|
||||
@@ -53,6 +59,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",
|
||||
@@ -80,7 +87,6 @@
|
||||
"mustache": "^4.2.0",
|
||||
"node-pty": "^0.10.1",
|
||||
"nyc": "^15.1.0",
|
||||
"playwright": "^1.22.1",
|
||||
"source-map-loader": "^3.0.0",
|
||||
"source-map-support": "^0.5.20",
|
||||
"ts-loader": "^9.3.1",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,96 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { pollFor, openTerminal, launchBrowser } from './TestUtils';
|
||||
import { Browser, Page } from 'playwright';
|
||||
|
||||
const APP = 'http://127.0.0.1:3001/test';
|
||||
|
||||
let browser: Browser;
|
||||
let page: Page;
|
||||
const width = 800;
|
||||
const height = 600;
|
||||
|
||||
describe('CharWidth Integration Tests', function(): void {
|
||||
before(async function(): Promise<any> {
|
||||
browser = await launchBrowser();
|
||||
page = await (await browser.newContext()).newPage();
|
||||
await page.setViewportSize({ width, height });
|
||||
await page.goto(APP);
|
||||
await openTerminal(page, { rows: 5, cols: 30 });
|
||||
});
|
||||
|
||||
after(() => {
|
||||
browser.close();
|
||||
});
|
||||
|
||||
describe('getStringCellWidth', () => {
|
||||
beforeEach(async () => {
|
||||
await page.evaluate(`window.term.reset()`);
|
||||
});
|
||||
|
||||
it('ASCII chars', async function(): Promise<void> {
|
||||
const input = 'This is just ASCII text.#';
|
||||
await page.evaluate(`window.term.write('${input}')`);
|
||||
await pollFor(page, () => sumWidths(0, 1, '#'), 25);
|
||||
});
|
||||
|
||||
it('combining chars', async function(): Promise<void> {
|
||||
const input = 'e\u0301e\u0301e\u0301e\u0301e\u0301e\u0301e\u0301e\u0301e\u0301#';
|
||||
await page.evaluate(`window.term.write('${input}')`);
|
||||
await pollFor(page, () => sumWidths(0, 1, '#'), 10);
|
||||
});
|
||||
|
||||
it('surrogate chars', async function(): Promise<void> {
|
||||
const input = '𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞𝄞#';
|
||||
await page.evaluate(`window.term.write('${input}')`);
|
||||
await pollFor(page, () => sumWidths(0, 1, '#'), 28);
|
||||
});
|
||||
|
||||
it('surrogate combining chars', async function(): Promise<void> {
|
||||
const input = '𓂀\u0301𓂀\u0301𓂀\u0301𓂀\u0301𓂀\u0301𓂀\u0301𓂀\u0301𓂀\u0301𓂀\u0301𓂀\u0301𓂀\u0301#';
|
||||
await page.evaluate(`window.term.write('${input}')`);
|
||||
await pollFor(page, () => sumWidths(0, 1, '#'), 12);
|
||||
});
|
||||
|
||||
it('fullwidth chars', async function(): Promise<void> {
|
||||
const input = '1234567890#';
|
||||
await page.evaluate(`window.term.write('${input}')`);
|
||||
await pollFor(page, () => sumWidths(0, 1, '#'), 21);
|
||||
});
|
||||
|
||||
it('fullwidth chars offset 1', async function(): Promise<void> {
|
||||
const input = 'a1234567890#';
|
||||
await page.evaluate(`window.term.write('${input}')`);
|
||||
await pollFor(page, () => sumWidths(0, 1, '#'), 22);
|
||||
});
|
||||
|
||||
// TODO: multiline tests once #1685 is resolved
|
||||
});
|
||||
});
|
||||
|
||||
async function sumWidths(start: number, end: number, sentinel: string): Promise<number> {
|
||||
await 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 page.evaluate(`window.result`);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,213 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
|
||||
* @license MIT
|
||||
*/
|
||||
|
||||
import { assert } from 'chai';
|
||||
import { writeSync, openTerminal, launchBrowser } from './TestUtils';
|
||||
import { Browser, Page } from 'playwright';
|
||||
|
||||
const APP = 'http://127.0.0.1:3001/test';
|
||||
|
||||
let browser: Browser;
|
||||
let page: Page;
|
||||
const width = 800;
|
||||
const height = 600;
|
||||
|
||||
describe('Parser Integration Tests', function (): void {
|
||||
before(async function (): Promise<any> {
|
||||
browser = await launchBrowser();
|
||||
page = await (await browser.newContext()).newPage();
|
||||
await page.setViewportSize({ width, height });
|
||||
await page.goto(APP);
|
||||
await openTerminal(page);
|
||||
});
|
||||
|
||||
after(async () => browser.close());
|
||||
|
||||
describe('registerCsiHandler', () => {
|
||||
it('should call custom CSI handler with js array params', async () => {
|
||||
await page.evaluate(`
|
||||
window.term.reset();
|
||||
window._customCsiHandlerParams = [];
|
||||
const _customCsiHandler = window.term.parser.registerCsiHandler({final: 'm'}, (params, collect) => {
|
||||
window._customCsiHandlerParams.push(params);
|
||||
return false;
|
||||
}, '');
|
||||
`);
|
||||
await writeSync(page, '\x1b[38;5;123mparams\x1b[38:2::50:100:150msubparams');
|
||||
assert.deepEqual(await page.evaluate(`window._customCsiHandlerParams`), [
|
||||
[38, 5, 123],
|
||||
[38, [2, -1, 50, 100, 150]]
|
||||
]);
|
||||
});
|
||||
it('async', async () => {
|
||||
await page.evaluate(`
|
||||
window.term.reset();
|
||||
window._customCsiHandlerCallStack = [];
|
||||
const _customCsiHandlerA = window.term.parser.registerCsiHandler({intermediates:'+', final: 'Z'}, params => {
|
||||
window._customCsiHandlerCallStack.push(['A', params]);
|
||||
return false;
|
||||
});
|
||||
const _customCsiHandlerB = window.term.parser.registerCsiHandler({intermediates:'+', final: 'Z'}, async params => {
|
||||
await new Promise(res => setTimeout(res, 50));
|
||||
window._customCsiHandlerCallStack.push(['B', params]);
|
||||
return false;
|
||||
});
|
||||
const _customCsiHandlerC = window.term.parser.registerCsiHandler({intermediates:'+', final: 'Z'}, params => {
|
||||
window._customCsiHandlerCallStack.push(['C', params]);
|
||||
return false;
|
||||
});
|
||||
`);
|
||||
await writeSync(page, '\x1b[1;2+Z');
|
||||
assert.deepEqual(await page.evaluate(`window._customCsiHandlerCallStack`), [
|
||||
['C', [1, 2]],
|
||||
['B', [1, 2]],
|
||||
['A', [1, 2]]
|
||||
]);
|
||||
});
|
||||
});
|
||||
describe('registerDcsHandler', () => {
|
||||
it('should respects return value', async () => {
|
||||
await page.evaluate(`
|
||||
window.term.reset();
|
||||
window._customDcsHandlerCallStack = [];
|
||||
const _customDcsHandlerA = window.term.parser.registerDcsHandler({intermediates:'+', final: 'p'}, (data, params) => {
|
||||
window._customDcsHandlerCallStack.push(['A', params, data]);
|
||||
return false;
|
||||
});
|
||||
const _customDcsHandlerB = window.term.parser.registerDcsHandler({intermediates:'+', final: 'p'}, (data, params) => {
|
||||
window._customDcsHandlerCallStack.push(['B', params, data]);
|
||||
return true;
|
||||
});
|
||||
const _customDcsHandlerC = window.term.parser.registerDcsHandler({intermediates:'+', final: 'p'}, (data, params) => {
|
||||
window._customDcsHandlerCallStack.push(['C', params, data]);
|
||||
return false;
|
||||
});
|
||||
`);
|
||||
await writeSync(page, '\x1bP1;2+psome data\x1b\\\\');
|
||||
assert.deepEqual(await page.evaluate(`window._customDcsHandlerCallStack`), [
|
||||
['C', [1, 2], 'some data'],
|
||||
['B', [1, 2], 'some data']
|
||||
]);
|
||||
});
|
||||
it('async', async () => {
|
||||
await page.evaluate(`
|
||||
window.term.reset();
|
||||
window._customDcsHandlerCallStack = [];
|
||||
const _customDcsHandlerA = window.term.parser.registerDcsHandler({intermediates:'+', final: 'q'}, (data, params) => {
|
||||
window._customDcsHandlerCallStack.push(['A', params, data]);
|
||||
return false;
|
||||
});
|
||||
const _customDcsHandlerB = window.term.parser.registerDcsHandler({intermediates:'+', final: 'q'}, async (data, params) => {
|
||||
await new Promise(res => setTimeout(res, 50));
|
||||
window._customDcsHandlerCallStack.push(['B', params, data]);
|
||||
return false;
|
||||
});
|
||||
const _customDcsHandlerC = window.term.parser.registerDcsHandler({intermediates:'+', final: 'q'}, (data, params) => {
|
||||
window._customDcsHandlerCallStack.push(['C', params, data]);
|
||||
return false;
|
||||
});
|
||||
`);
|
||||
await writeSync(page, '\x1bP1;2+qsome data\x1b\\\\');
|
||||
assert.deepEqual(await page.evaluate(`window._customDcsHandlerCallStack`), [
|
||||
['C', [1, 2], 'some data'],
|
||||
['B', [1, 2], 'some data'],
|
||||
['A', [1, 2], 'some data']
|
||||
]);
|
||||
});
|
||||
});
|
||||
describe('registerEscHandler', () => {
|
||||
it('should respects return value', async () => {
|
||||
await page.evaluate(`
|
||||
window.term.reset();
|
||||
window._customEscHandlerCallStack = [];
|
||||
const _customEscHandlerA = window.term.parser.registerEscHandler({intermediates:'(', final: 'B'}, () => {
|
||||
window._customEscHandlerCallStack.push('A');
|
||||
return false;
|
||||
});
|
||||
const _customEscHandlerB = window.term.parser.registerEscHandler({intermediates:'(', final: 'B'}, () => {
|
||||
window._customEscHandlerCallStack.push('B');
|
||||
return true;
|
||||
});
|
||||
const _customEscHandlerC = window.term.parser.registerEscHandler({intermediates:'(', final: 'B'}, () => {
|
||||
window._customEscHandlerCallStack.push('C');
|
||||
return false;
|
||||
});
|
||||
`);
|
||||
await writeSync(page, '\x1b(B');
|
||||
assert.deepEqual(await page.evaluate(`window._customEscHandlerCallStack`), ['C', 'B']);
|
||||
});
|
||||
it('async', async () => {
|
||||
await page.evaluate(`
|
||||
window.term.reset();
|
||||
window._customEscHandlerCallStack = [];
|
||||
const _customEscHandlerA = window.term.parser.registerEscHandler({intermediates:'(', final: 'Z'}, () => {
|
||||
window._customEscHandlerCallStack.push('A');
|
||||
return false;
|
||||
});
|
||||
const _customEscHandlerB = window.term.parser.registerEscHandler({intermediates:'(', final: 'Z'}, async () => {
|
||||
await new Promise(res => setTimeout(res, 50));
|
||||
window._customEscHandlerCallStack.push('B');
|
||||
return false;
|
||||
});
|
||||
const _customEscHandlerC = window.term.parser.registerEscHandler({intermediates:'(', final: 'Z'}, () => {
|
||||
window._customEscHandlerCallStack.push('C');
|
||||
return false;
|
||||
});
|
||||
`);
|
||||
await writeSync(page, '\x1b(Z');
|
||||
assert.deepEqual(await page.evaluate(`window._customEscHandlerCallStack`), ['C', 'B', 'A']);
|
||||
});
|
||||
});
|
||||
describe('registerOscHandler', () => {
|
||||
it('should respects return value', async () => {
|
||||
await page.evaluate(`
|
||||
window.term.reset();
|
||||
window._customOscHandlerCallStack = [];
|
||||
const _customOscHandlerA = window.term.parser.registerOscHandler(1234, data => {
|
||||
window._customOscHandlerCallStack.push(['A', data]);
|
||||
return false;
|
||||
});
|
||||
const _customOscHandlerB = window.term.parser.registerOscHandler(1234, data => {
|
||||
window._customOscHandlerCallStack.push(['B', data]);
|
||||
return true;
|
||||
});
|
||||
const _customOscHandlerC = window.term.parser.registerOscHandler(1234, data => {
|
||||
window._customOscHandlerCallStack.push(['C', data]);
|
||||
return false;
|
||||
});
|
||||
`);
|
||||
await writeSync(page, '\x1b]1234;some data\x07');
|
||||
assert.deepEqual(await page.evaluate(`window._customOscHandlerCallStack`), [
|
||||
['C', 'some data'],
|
||||
['B', 'some data']
|
||||
]);
|
||||
});
|
||||
it('async', async () => {
|
||||
await page.evaluate(`
|
||||
window.term.reset();
|
||||
window._customOscHandlerCallStack = [];
|
||||
const _customOscHandlerA = window.term.parser.registerOscHandler(666, data => {
|
||||
window._customOscHandlerCallStack.push(['A', data]);
|
||||
return false;
|
||||
});
|
||||
const _customOscHandlerB = window.term.parser.registerOscHandler(666, async data => {
|
||||
await new Promise(res => setTimeout(res, 50));
|
||||
window._customOscHandlerCallStack.push(['B', data]);
|
||||
return false;
|
||||
});
|
||||
const _customOscHandlerC = window.term.parser.registerOscHandler(666, data => {
|
||||
window._customOscHandlerCallStack.push(['C', data]);
|
||||
return false;
|
||||
});
|
||||
`);
|
||||
await writeSync(page, '\x1b]666;some data\x07');
|
||||
assert.deepEqual(await page.evaluate(`window._customOscHandlerCallStack`), [
|
||||
['C', 'some data'],
|
||||
['B', 'some data'],
|
||||
['A', 'some data']
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1 @@
|
||||
This project contains helpers for the legacy playwright tests. Currently addons use this as a dependency, when all addons have moved over to use `@playright/test` this can be removed.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user