mirror of
https://github.com/keymanapp/keyman.git
synced 2026-08-05 00:15:32 +00:00
test(web): add e2e tests for KMX keyboard with web-core
Also add similar tests for a JS keyboard. Test-bot: skip
This commit is contained in:
parent
7467584364
commit
12d56453a4
9 changed files with 257 additions and 35 deletions
17
package-lock.json
generated
17
package-lock.json
generated
|
|
@ -2404,6 +2404,22 @@
|
|||
"node": ">=14"
|
||||
}
|
||||
},
|
||||
"node_modules/@playwright/test": {
|
||||
"version": "1.46.1",
|
||||
"resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.46.1.tgz",
|
||||
"integrity": "sha512-Fq6SwLujA/DOIvNC2EL/SojJnkKf/rAwJ//APpJJHRyMi1PdKrY3Az+4XNQ51N4RTbItbIByQ0jgd1tayq1aeA==",
|
||||
"dev": true,
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright": "1.46.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/@puppeteer/browsers": {
|
||||
"version": "2.3.0",
|
||||
"resolved": "https://registry.npmjs.org/@puppeteer/browsers/-/browsers-2.3.0.tgz",
|
||||
|
|
@ -14161,6 +14177,7 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@keymanapp/resources-gosh": "*",
|
||||
"@playwright/test": "^1.46.1",
|
||||
"@sentry/cli": "^2.31.0",
|
||||
"@zip.js/zip.js": "^2.7.32",
|
||||
"c8": "^7.12.0",
|
||||
|
|
|
|||
6
web/.gitignore
vendored
6
web/.gitignore
vendored
|
|
@ -11,4 +11,8 @@ node_modules/
|
|||
source/environment.inc.ts
|
||||
**/.idea/**/*.xml
|
||||
**/*.iml
|
||||
**/*.kpj.user
|
||||
**/*.kpj.user
|
||||
|
||||
# Playwright
|
||||
playwright-report/
|
||||
test-results/
|
||||
|
|
|
|||
27
web/build.sh
27
web/build.sh
|
|
@ -40,6 +40,7 @@ builder_describe "Builds engine modules for Keyman Engine for Web (KMW)." \
|
|||
\
|
||||
"--test-dom-only For test, run only DOM-oriented unit tests (reduced footprint, nothing browser-specific)" \
|
||||
"--test-integrated-only For test, run only KMW's integration test suite" \
|
||||
"--test-e2e-only For test, run only KMW's end-to-end test suite" \
|
||||
"--test-inspect For test, run browser-based unit tests in an inspectable mode"
|
||||
|
||||
builder_parse "$@"
|
||||
|
|
@ -168,6 +169,24 @@ builder_run_action build:_all build_tests_action
|
|||
# Run tests
|
||||
builder_run_child_actions test
|
||||
|
||||
function is_test_included() {
|
||||
local test_opt=$1
|
||||
local run_dom_tests=true run_integrated_tests=true run_e2e_tests=true
|
||||
local var_name="run_${test_opt}_tests"
|
||||
|
||||
if builder_has_option --test-integrated-only || builder_has_option --test-e2e-only; then
|
||||
run_dom_tests=false
|
||||
fi
|
||||
if builder_has_option --test-dom-only || builder_has_option --test-e2e-only; then
|
||||
run_integrated_tests=false
|
||||
fi
|
||||
if builder_has_option --test-dom-only || builder_has_option --test-integrated-only; then
|
||||
run_e2e_tests=false
|
||||
fi
|
||||
|
||||
${!var_name}
|
||||
}
|
||||
|
||||
function do_browser_tests() {
|
||||
# Browser-based tests: common configs & kill-switches
|
||||
|
||||
|
|
@ -175,6 +194,7 @@ function do_browser_tests() {
|
|||
local WTR_CONFIG=
|
||||
if builder_is_ci_build; then
|
||||
WTR_CONFIG=.CI
|
||||
export KEYMAN_IS_CI_BUILD=1
|
||||
fi
|
||||
|
||||
# Prepare the flags for the karma command.
|
||||
|
|
@ -184,12 +204,15 @@ function do_browser_tests() {
|
|||
fi
|
||||
|
||||
pushd "${KEYMAN_ROOT}"
|
||||
if builder_has_option --test-dom-only || ! builder_has_option --test-integrated-only; then
|
||||
if is_test_included dom; then
|
||||
web-test-runner --config "web/src/test/auto/dom/web-test-runner${WTR_CONFIG}.config.mjs" ${WTR_INSPECT}
|
||||
fi
|
||||
if builder_has_option --test-integrated-only || ! builder_has_option --test-dom-only; then
|
||||
if is_test_included integrated; then
|
||||
web-test-runner --config "web/src/test/auto/integrated/web-test-runner${WTR_CONFIG}.config.mjs" ${WTR_INSPECT}
|
||||
fi
|
||||
if is_test_included e2e; then
|
||||
npx playwright test --config "web/src/test/auto/e2e/playwright.config.ts"
|
||||
fi
|
||||
popd
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,7 @@
|
|||
"homepage": "https://github.com/keymanapp/keyman#readme",
|
||||
"devDependencies": {
|
||||
"@keymanapp/resources-gosh": "*",
|
||||
"@playwright/test": "^1.46.1",
|
||||
"@sentry/cli": "^2.31.0",
|
||||
"@zip.js/zip.js": "^2.7.32",
|
||||
"c8": "^7.12.0",
|
||||
|
|
@ -116,9 +117,9 @@
|
|||
"test": "gosh ./test.sh"
|
||||
},
|
||||
"dependencies": {
|
||||
"@keymanapp/common-types": "*",
|
||||
"@keymanapp/keyman-version": "*",
|
||||
"@keymanapp/lexical-model-layer": "*",
|
||||
"@keymanapp/common-types": "*",
|
||||
"@keymanapp/recorder-core": "*",
|
||||
"core-js": "^3.34.0",
|
||||
"eventemitter3": "^5.0.0",
|
||||
|
|
|
|||
18
web/src/test/auto/e2e/README.md
Normal file
18
web/src/test/auto/e2e/README.md
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
# Keyman Engine for Web e2e tests
|
||||
|
||||
These tests are run as part of the regular build, but can be run separately
|
||||
with:
|
||||
|
||||
```bash
|
||||
web/test.sh test:e2e
|
||||
```
|
||||
|
||||
The Playwright Test for VSCode extension (ms-playwright.playwright) allows to run
|
||||
the tests in VSCode.
|
||||
|
||||
It's also possible to run them with a UI that shows screenshots
|
||||
captured while running the tests:
|
||||
|
||||
```bash
|
||||
npx playwright test --config "web/src/test/auto/e2e/playwright.config.ts" --ui
|
||||
```
|
||||
66
web/src/test/auto/e2e/keyboard.tests.ts
Normal file
66
web/src/test/auto/e2e/keyboard.tests.ts
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
/*
|
||||
* Keyman is copyright (C) SIL Global. MIT License.
|
||||
*/
|
||||
import { test, expect, Page, Locator } from '@playwright/test';
|
||||
|
||||
test.describe('KMX keyboards', function () {
|
||||
let textarea: Locator;
|
||||
const beforeEach = async (page: Page) => {
|
||||
await page.goto('http://localhost:3000/src/test/manual/web/kmxkeyboard.html?keyboard=kmx');
|
||||
await page.evaluate(async () => { await window.KmwLoaded; });
|
||||
textarea = page.locator('#inputarea');
|
||||
await textarea.click();
|
||||
// we don't have a OSK yet, so don't wait for it to appear
|
||||
}
|
||||
|
||||
test('can type on a (simulated) hardware keyboard', async ({ page }) => {
|
||||
await beforeEach(page);
|
||||
await page.keyboard.press('x');
|
||||
await page.keyboard.press('j');
|
||||
await page.keyboard.press('m');
|
||||
await page.keyboard.press('Shift+e');
|
||||
await page.keyboard.press('r');
|
||||
await expect(textarea).toHaveValue('ខ្មែរ', { timeout: 500 });
|
||||
});
|
||||
|
||||
test('can type on a (simulated) hardware keyboard with reordering', async ({ page }) => {
|
||||
await beforeEach(page);
|
||||
await page.keyboard.press('x');
|
||||
await page.keyboard.press('Shift+e');
|
||||
await page.keyboard.press('j');
|
||||
await page.keyboard.press('m');
|
||||
await page.keyboard.press('r');
|
||||
await expect(textarea).toHaveValue('ខ្មែរ', { timeout: 500 });
|
||||
});
|
||||
});
|
||||
|
||||
test.describe('JS keyboards', function () {
|
||||
let textarea: Locator;
|
||||
const beforeEach = async (page: Page) => {
|
||||
await page.goto('http://localhost:3000/src/test/manual/web/kmxkeyboard.html?keyboard=js');
|
||||
await page.evaluate(async () => { await window.KmwLoaded; });
|
||||
textarea = page.locator('#inputarea');
|
||||
await textarea.click();
|
||||
await page.evaluate(async () => { await window.OskShown; });
|
||||
};
|
||||
|
||||
test('can type on a (simulated) hardware keyboard', async ({ page }) => {
|
||||
await beforeEach(page);
|
||||
await page.keyboard.press('x');
|
||||
await page.keyboard.press('j');
|
||||
await page.keyboard.press('m');
|
||||
await page.keyboard.press('Shift+e');
|
||||
await page.keyboard.press('r');
|
||||
await expect(textarea).toHaveValue('ខ្មែរ', { timeout: 500 });
|
||||
});
|
||||
|
||||
test('can type on a (simulated) hardware keyboard with reordering', async ({ page }) => {
|
||||
await beforeEach(page);
|
||||
await page.keyboard.press('x');
|
||||
await page.keyboard.press('Shift+e');
|
||||
await page.keyboard.press('j');
|
||||
await page.keyboard.press('m');
|
||||
await page.keyboard.press('r');
|
||||
await expect(textarea).toHaveValue('ខ្មែរ', { timeout: 500 });
|
||||
});
|
||||
});
|
||||
84
web/src/test/auto/e2e/playwright.config.ts
Normal file
84
web/src/test/auto/e2e/playwright.config.ts
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import { dirname, resolve } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { defineConfig, devices } from '@playwright/test';
|
||||
|
||||
const dir = dirname(fileURLToPath(import.meta.url));
|
||||
const KEYMAN_ROOT = resolve(dir, '../../../../../');
|
||||
|
||||
/**
|
||||
* See https://playwright.dev/docs/test-configuration.
|
||||
*/
|
||||
export default defineConfig({
|
||||
rootDir: KEYMAN_ROOT,
|
||||
testDir: '.',
|
||||
testMatch: '*.tests.ts',
|
||||
/* Run tests in files in parallel */
|
||||
fullyParallel: true,
|
||||
/* Fail the build on CI if you accidentally left test.only in the source code. */
|
||||
forbidOnly: !!process.env.KEYMAN_IS_CI_BUILD,
|
||||
/* Retry on CI only */
|
||||
retries: process.env.KEYMAN_IS_CI_BUILD ? 2 : 0,
|
||||
/* Opt out of parallel tests on CI. */
|
||||
workers: process.env.KEYMAN_IS_CI_BUILD ? 1 : undefined,
|
||||
/* Reporter to use. See https://playwright.dev/docs/test-reporters */
|
||||
// reporter: process.env.KEYMAN_IS_CI_BUILD ? [
|
||||
// [KEYMAN_ROOT + '/common/test/resources/playwright-TC-reporter.ts', { parentFlow: 'web_tests' }]
|
||||
// ] : [
|
||||
reporter: [
|
||||
['list'],
|
||||
['html', { open: 'never' }],
|
||||
],
|
||||
/* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
|
||||
use: {
|
||||
/* Base URL to use in actions like `await page.goto('')`. */
|
||||
// baseURL: 'http://localhost:3000',
|
||||
|
||||
/* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
|
||||
trace: 'on-first-retry',
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
},
|
||||
|
||||
// {
|
||||
// name: 'firefox',
|
||||
// use: { ...devices['Desktop Firefox'] },
|
||||
// },
|
||||
|
||||
// {
|
||||
// name: 'webkit',
|
||||
// use: { ...devices['Desktop Safari'] },
|
||||
// },
|
||||
|
||||
/* Test against mobile viewports. */
|
||||
// {
|
||||
// name: 'Mobile Chrome',
|
||||
// use: { ...devices['Pixel 5'] },
|
||||
// },
|
||||
// {
|
||||
// name: 'Mobile Safari',
|
||||
// use: { ...devices['iPhone 12'] },
|
||||
// },
|
||||
|
||||
/* Test against branded browsers. */
|
||||
// {
|
||||
// name: 'Microsoft Edge',
|
||||
// use: { ...devices['Desktop Edge'], channel: 'msedge' },
|
||||
// },
|
||||
// {
|
||||
// name: 'Google Chrome',
|
||||
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
|
||||
// },
|
||||
],
|
||||
|
||||
/* Run your local dev server before starting the tests */
|
||||
webServer: {
|
||||
command: `${KEYMAN_ROOT}/web/build.sh start`,
|
||||
url: 'http://localhost:3000',
|
||||
reuseExistingServer: !process.env.KEYMAN_IS_CI_BUILD,
|
||||
},
|
||||
});
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
<!-- Enable IE9 Standards mode -->
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
|
||||
<title>KeymanWeb Sample Page - Unminified Source</title>
|
||||
<title>KeymanWeb Khmer KMX/JS test page</title>
|
||||
|
||||
<!-- Your page CSS -->
|
||||
<style type='text/css'>
|
||||
|
|
@ -36,19 +36,35 @@
|
|||
|
||||
<!-- Initialization: set paths to keyboards, resources and fonts as required -->
|
||||
<script>
|
||||
window.addEventListener('load', function () {
|
||||
keyman.init().then(function () {
|
||||
keyman.addKeyboards({
|
||||
const searchParams = new URLSearchParams(window.location.search);
|
||||
const kmx = {
|
||||
id: 'khmer_angkor',
|
||||
name: 'Khmer Angkor',
|
||||
languages: {
|
||||
id: 'km',
|
||||
name: 'Khmer'
|
||||
},
|
||||
filename: '/build/test-resources/keyboards/khmer_angkor.kmx'
|
||||
languages: { id: 'km', name: 'Khmer' }, filename: '/build/test-resources/keyboards/khmer_angkor.kmx' };
|
||||
let keyboard;
|
||||
switch (searchParams.get('keyboard')) {
|
||||
case 'js':
|
||||
keyboard = { id: 'khmer_angkor', name: 'Khmer Angkor', languages: { id: 'km' } };
|
||||
break;
|
||||
case 'kmx':
|
||||
default:
|
||||
keyboard = kmx;
|
||||
break;
|
||||
};
|
||||
// allow to wait on KMW being fully initialized
|
||||
window.KmwLoaded = new Promise((resolve) => {
|
||||
window.addEventListener('load', async function () {
|
||||
await keyman.init();
|
||||
await keyman.addKeyboards(keyboard);
|
||||
// allow to wait on OSK being visible
|
||||
window.OskShown = new Promise((resolve) => {
|
||||
keyman.osk.addEventListener('show', async function () {
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
resolve(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
<!-- Add keyboard management script for local selection of keyboards to use -->
|
||||
|
|
@ -58,7 +74,7 @@
|
|||
|
||||
<!-- Sample page HTML -->
|
||||
<body>
|
||||
<h2>KeymanWeb Sample Page - KMX Keyboards</h2>
|
||||
<h2>KeymanWeb Sample Page - Khmer Angkor KMX and JS Keyboards</h2>
|
||||
|
||||
<div>
|
||||
<!--
|
||||
|
|
@ -68,24 +84,13 @@
|
|||
-->
|
||||
<div id='KeymanWebControl'></div>
|
||||
|
||||
<h3>Type in your language in this text area:</h3>
|
||||
<textarea id='ta1' class='test' placeholder='Type here'></textarea>
|
||||
|
||||
<h3>or in this input field:</h3>
|
||||
<input class='test' value='' placeholder='or here'/>
|
||||
|
||||
<!-- The following elements show how the language menu can be dynamically extended at any time -->
|
||||
<h3>Add a keyboard by keyboard name:</h3>
|
||||
<input type='input' id='kbd_id1' class='kmw-disabled' onkeypress="clickOnEnter(event,1);"/>
|
||||
<input type='button' id='btn1' onclick='addKeyboard(1);' value='Add' />
|
||||
|
||||
<h3>Add a keyboard by BCP-47 language code:</h3>
|
||||
<input type='input' id='kbd_id2' class='kmw-disabled' onkeypress="clickOnEnter(event,2);"/>
|
||||
<input type='button' id='btn2' onclick='addKeyboard(2);' value='Add' />
|
||||
|
||||
<h3>Add a keyboard by language name(s):</h3>
|
||||
<input type='input' id='kbd_id3' class='kmw-disabled' onkeypress="clickOnEnter(event,3);"/>
|
||||
<input type='button' id='btn3' onclick='addKeyboard(3);' value='Add' />
|
||||
<p>This page allows to use either the .kmx or the .js version of the Khmer Angkor keyboard.
|
||||
Which one can be selected by the <code>keyboard</code> query parameter:
|
||||
append <code>?keyboard=kmx</code> or <code>?keyboard=js</code> to the URL..
|
||||
The default is to use the .kmx version.
|
||||
</p>
|
||||
<h3>Type Khmer in this text area:</h3>
|
||||
<textarea id='inputarea' class='test' placeholder='Type here'></textarea>
|
||||
|
||||
<h3><a href="./">Return to testing home page</a></h3>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ builder_describe "Runs the Keyman Engine for Web unit-testing suites" \
|
|||
"test+" \
|
||||
":dom Runs DOM-oriented unit tests (reduced footprint, nothing browser-specific)" \
|
||||
":integrated Runs KMW's integration test suite" \
|
||||
":e2e Runs KMW's end-to-end test suite" \
|
||||
"--inspect Runs browser-based unit tests in an inspectable mode"
|
||||
|
||||
builder_parse "$@"
|
||||
|
|
@ -30,6 +31,7 @@ builder_parse "$@"
|
|||
WTR_CONFIG=
|
||||
if builder_is_ci_build; then
|
||||
WTR_CONFIG=.CI
|
||||
export KEYMAN_IS_CI_BUILD=1
|
||||
fi
|
||||
|
||||
# Prepare the flags for the karma command.
|
||||
|
|
@ -42,6 +44,8 @@ fi
|
|||
|
||||
cd "${KEYMAN_ROOT}"
|
||||
|
||||
builder_run_action test:dom web-test-runner --config "web/src/test/auto/dom/web-test-runner${WTR_CONFIG}.config.mjs" ${WTR_INSPECT}
|
||||
builder_run_action test:dom web-test-runner --config "web/src/test/auto/dom/web-test-runner${WTR_CONFIG}.config.mjs" ${WTR_INSPECT}
|
||||
|
||||
builder_run_action test:integrated web-test-runner --config "web/src/test/auto/integrated/web-test-runner${WTR_CONFIG}.config.mjs" ${WTR_INSPECT}
|
||||
builder_run_action test:integrated web-test-runner --config "web/src/test/auto/integrated/web-test-runner${WTR_CONFIG}.config.mjs" ${WTR_INSPECT}
|
||||
|
||||
builder_run_action test:e2e npx playwright test --config "web/src/test/auto/e2e/playwright.config.ts"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue