test: the browser runs take their engine from BROWSER, and CI runs all three
openApp() launches chromium, firefox or webkit from playwright-core; the smoke and DOM runs pass in each. CI runs both per engine, WebKit on macOS for Safari's text shaping. build.target is set explicitly to the browsers the bundle promises. CLAUDE.md is back under its 120-line budget.
This commit is contained in:
1 parent
abb4870544
commit
6b6b621a5a
5 files changed
+44
-19
No files matched your search
@@ -44,11 +44,20 @@ jobs:
|
||||
- run: npm ci
|
||||
- run: npm run test:lo
|
||||
|
||||
# Production build booted in headless Chromium — catches bundling and boot
|
||||
# regressions the jsdom suite cannot see.
|
||||
smoke:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 20
|
||||
# Production build booted in the three engines behind the supported browsers
|
||||
# (vite build.target). WebKit runs on macOS: its text shaping there is Safari's.
|
||||
browser:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- { browser: chromium, os: ubuntu-latest }
|
||||
- { browser: firefox, os: ubuntu-latest }
|
||||
- { browser: webkit, os: macos-latest }
|
||||
runs-on: ${{ matrix.os }}
|
||||
timeout-minutes: 30
|
||||
env:
|
||||
BROWSER: ${{ matrix.browser }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-node@v4
|
||||
@@ -56,6 +65,7 @@ jobs:
|
||||
node-version: 20
|
||||
cache: npm
|
||||
- run: npm ci
|
||||
- run: npx playwright-core install chromium
|
||||
- run: npx playwright-core install --with-deps ${{ matrix.browser }}
|
||||
- run: npm run build
|
||||
- run: npm run test:smoke
|
||||
- run: npm run test:dom
|
||||
@@ -16,8 +16,8 @@ npm run check # svelte-check type-check (svelte + ts)
|
||||
npm test # Vitest suite once (tests/**/*.test.ts)
|
||||
npm run test:watch # Vitest in watch mode
|
||||
npm run test:lo # LibreOffice legs: round trip + ODT/DOCX render consistency (needs `soffice`)
|
||||
npm run test:smoke # boots the dist/ build in headless Chromium (tests/smoke/run.mjs)
|
||||
npm run test:dom # pagination + editing in the real browser (tests/dom/run.mjs)
|
||||
npm run test:smoke # boots the dist/ build headless (tests/smoke/run.mjs); BROWSER=firefox|webkit
|
||||
npm run test:dom # pagination + editing in the real browser (tests/dom/run.mjs); same BROWSER
|
||||
npm run test:coverage # vitest + v8 coverage over src/ → coverage/index.html
|
||||
npm run test:parity # render parity vs LibreOffice (tests/render-parity/README.md)
|
||||
node scripts/make-thesaurus.mjs # re-vendor public/thesaurus/ from LibreOffice's MyThes data
|
||||
@@ -64,10 +64,9 @@ silently lands in every imported document as direct formatting. The defaults fol
|
||||
`components/Editor.svelte` and `styles/editor.css` (`PAGE_HEIGHT` 1123px, `PAGE_GAP` 20px, the
|
||||
`--user-page-*`/`--user-margin-*` custom properties) — details in `docs/architecture/pagination.md`.
|
||||
|
||||
**Headless browser testing** — this container is linux **arm64**. Never `puppeteer` /
|
||||
`@puppeteer/browsers`: they fetch an x86-64 Chrome that cannot run here. Use `playwright-core` +
|
||||
its Chromium; full recipe in `docs/headless-testing.md`. Driving the live app is the only way to
|
||||
verify rendering, layout or NodeView behaviour — there is no DOM test suite for it.
|
||||
**Headless browser testing** — `playwright-core` with its own engines, never `puppeteer` (it
|
||||
fetches an x86-64 Chrome that cannot run on arm64). Recipe and the three-engine CI matrix in
|
||||
`docs/headless-testing.md`; driving the live app is the only way to verify rendering or NodeViews.
|
||||
|
||||
**Naming** — components `PascalCase.svelte`, every `.ts` module `camelCase`; extension files are
|
||||
named by feature (`image.ts`, `indent.ts`), not `XyzExtension.ts`.
|
||||
|
||||
@@ -12,10 +12,17 @@ For PDF-export repros specifically: replicate `pdf.ts`'s clone + `html2canvas(..
|
||||
## The two committed browser runs
|
||||
|
||||
`npm run test:smoke` and `npm run test:dom` are these probes made permanent: both boot
|
||||
`dist/` in headless Chromium through `tests/browser.mjs` (preview server, checklist,
|
||||
`pageerror` collector) and fail on any uncaught page error. The DOM run keeps the
|
||||
pagination invariants of pass 4 below — one page count through a settle, a reload, a
|
||||
zoom, a page break and its undo — which is the only test `src/lib/components/**` has.
|
||||
`dist/` headless through `tests/browser.mjs` (preview server, checklist, `pageerror`
|
||||
collector) and fail on any uncaught page error. The DOM run keeps the pagination
|
||||
invariants of pass 4 below — one page count through a settle, a reload, a zoom, a page
|
||||
break and its undo — which is the only test `src/lib/components/**` has.
|
||||
|
||||
`BROWSER=chromium|firefox|webkit` picks the engine (Chromium by default; the others via
|
||||
`npx playwright-core install firefox webkit`). CI runs both on all three, one per matrix
|
||||
leg, WebKit on macOS because only there its text shaping is Safari's. The engines are
|
||||
the ones behind `build.target` in `vite.config.ts`; a browser older than that target
|
||||
fails to parse the bundle and no run reaches it. Playwright's WebKit is the engine, not
|
||||
Safari: storage eviction, the install prompt and iOS input are outside the matrix.
|
||||
|
||||
## Hunting for bugs the suite cannot see
|
||||
|
||||
|
||||
+9
-3
@@ -4,7 +4,7 @@ import { spawn, execSync } from 'node:child_process';
|
||||
import { existsSync } from 'node:fs';
|
||||
import { join, resolve, dirname } from 'node:path';
|
||||
import { fileURLToPath } from 'node:url';
|
||||
import { chromium } from 'playwright-core';
|
||||
import * as playwright from 'playwright-core';
|
||||
|
||||
export const ROOT = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
||||
export const MOD = process.platform === 'darwin' ? 'Meta' : 'Control';
|
||||
@@ -34,9 +34,15 @@ export async function previewServer(port) {
|
||||
throw new Error('preview server did not start');
|
||||
}
|
||||
|
||||
// Fixed locale, so the UI labels a test clicks are deterministic across machines.
|
||||
// BROWSER=chromium|firefox|webkit picks the engine (Chromium by default). Fixed locale,
|
||||
// so the UI labels a test clicks are deterministic across machines.
|
||||
export async function openApp(port) {
|
||||
const browser = await chromium.launch({ executablePath: chromium.executablePath(), args: ['--no-sandbox'] });
|
||||
const name = process.env.BROWSER ?? 'chromium';
|
||||
const engine = playwright[name];
|
||||
if (!engine) throw new Error(`unknown BROWSER "${name}": chromium, firefox or webkit`);
|
||||
const args = name === 'chromium' ? ['--no-sandbox'] : [];
|
||||
const browser = await engine.launch({ executablePath: engine.executablePath(), args });
|
||||
console.log(`engine: ${name} ${browser.version()}`);
|
||||
const page = await browser.newPage({ viewport: { width: 1400, height: 1000 }, locale: 'en-US' });
|
||||
const pageErrors = [];
|
||||
page.on('pageerror', (err) => pageErrors.push(String(err)));
|
||||
|
||||
@@ -21,6 +21,9 @@ export default defineConfig({
|
||||
// subpath (GitHub Pages project site). sw.js and the manifest are relative too.
|
||||
base: './',
|
||||
plugins: [svelte()],
|
||||
// The browsers the bundle promises to parse in; the CI browser matrix runs the
|
||||
// engines behind them (docs/headless-testing.md).
|
||||
build: { target: 'baseline-widely-available' },
|
||||
define: {
|
||||
__APP_VERSION__: JSON.stringify(commit ? `${pkg.version} (${commit})` : pkg.version),
|
||||
},
|
||||
|
||||
Reference in new issue
Block a user