diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b774d4..acabdd0 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -104,6 +104,12 @@ jobs: fcitx5-js.tgz fcitx5-js-dev.tar.bz2 + - name: Test + run: | + npx playwright install + npx playwright install-deps + pnpm run test + - name: Setup tmate session if: ${{ failure() }} uses: mxschmitt/action-tmate@v3 diff --git a/.gitignore b/.gitignore index f6b85a2..0635e85 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,4 @@ node_modules pnpm-lock.yaml preview/index.js preview/index.js.map +test-results diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 999d2d3..ae587bd 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -42,7 +42,7 @@ { "type": "shell", "label": "Preview", - "command": "npx serve -l 9000 -S preview", + "command": "pnpm run preview", "group": { "kind": "build" } @@ -70,6 +70,14 @@ "group": { "kind": "build" } + }, + { + "type": "shell", + "label": "Test", + "command": "pnpm run test", + "group": { + "kind": "build" + } } ] } diff --git a/package.json b/package.json index 535760e..3d2fd53 100644 --- a/package.json +++ b/package.json @@ -9,16 +9,23 @@ "dist" ], "scripts": { - "lint": "eslint page", - "lint:fix": "eslint page --fix", + "lint": "eslint page tests", + "lint:fix": "eslint page tests --fix", "check": "tsc --noEmit", "build": "node scripts/build.mjs", "prepack": "bash scripts/prepack.sh", - "postpack": "bash scripts/postpack.sh" + "postpack": "bash scripts/postpack.sh", + "preview": "serve -l 9000 -S preview", + "test": "playwright test --browser all", + "test:chromium": "playwright test --browser chromium", + "test:firefox": "playwright test --browser firefox", + "test:webkit": "playwright test --browser webkit" }, "license": "AGPL-3.0-or-later", "devDependencies": { "@antfu/eslint-config": "^3.12.1", + "@playwright/test": "^1.50.1", + "@types/node": "^22.13.5", "@types/textarea-caret": "^3.0.3", "@types/uzip": "^0.20201231.2", "error-stack-parser": "^2.1.4", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 0000000..b8ee351 --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,11 @@ +import { defineConfig } from '@playwright/test'; + +export default defineConfig({ + testDir: 'tests', + fullyParallel: true, + webServer: { + command: 'pnpm run preview', + port: 9000, + reuseExistingServer: true + } +}) diff --git a/preview/index.html b/preview/index.html index 134d0c6..5530257 100644 --- a/preview/index.html +++ b/preview/index.html @@ -6,9 +6,9 @@ diff --git a/tests/global.d.ts b/tests/global.d.ts new file mode 100644 index 0000000..ca0629e --- /dev/null +++ b/tests/global.d.ts @@ -0,0 +1,7 @@ +declare global { + interface Window { + fcitxReady: Promise + } +} + +export {} diff --git a/tests/test-generic.spec.ts b/tests/test-generic.spec.ts new file mode 100644 index 0000000..116a94d --- /dev/null +++ b/tests/test-generic.spec.ts @@ -0,0 +1,39 @@ +import { expect, test } from '@playwright/test' +import { init } from './util' + +test('keyboard-us', async ({ page }) => { + const addons: string[] = [] + page.on('console', (msg) => { + const match = msg.text().match(/Loaded addon (\S+)/) + if (match) { + addons.push(match[1]) + } + }) + + await init(page) + expect(addons.sort()).toEqual(['clipboard', 'imselector', 'keyboard', 'quickphrase', 'unicode', 'wasmfrontend', 'webpanel']) + + const textarea = page.locator('textarea') + await textarea.click() + await page.keyboard.press('q') + await expect(textarea).toHaveValue('q') + + const input = page.locator('input') + await input.click() + await page.keyboard.press('w') + await expect(input).toHaveValue('w') +}) + +test('keyboard-th', async ({ page }) => { + await init(page) + + await page.evaluate(async () => { + window.fcitx.setInputMethods(['keyboard-th']) + }) + const textarea = page.locator('textarea') + await textarea.click() + for (const key of 'l;ylfu') { + await page.keyboard.press(key) + } + await expect(textarea).toHaveValue('สวัสดี') +}) diff --git a/tests/util.ts b/tests/util.ts new file mode 100644 index 0000000..2f912fd --- /dev/null +++ b/tests/util.ts @@ -0,0 +1,10 @@ +import type { + Page, +} from '@playwright/test' + +export async function init(page: Page) { + await page.goto('http://localhost:9000') + return page.evaluate(() => { + return window.fcitxReady + }) +} diff --git a/tsconfig.json b/tsconfig.json index aa99bbd..733fb6e 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,5 +9,5 @@ "esModuleInterop": true, "isolatedModules": true }, - "include": ["page/*.ts"] + "include": ["page/*.ts", "tests/*.ts"] }