Skip to content

Commit bc562bd

Browse files
test(e2e): make hub-client e2e suite pass on CI
Once the workflow could actually run the tests (see prior commit), several real bugs and config gaps surfaced that had been hidden while the workflow sat in the queue. None of these would have shown up locally because the e2e suite had never been wired into anyone's regular workflow. - TS2345 in client.test.ts: installMockRepo used `ReturnType<typeof createMockHandle>` without supplying T, so the parameter defaulted to unknown. Forwarding T through makes the helper generic and the test compiles again. - Node-side IndexedDB shim: projectFactory.ts runs in the Playwright test process (Node, not browser) but createSyncClient instantiates an IndexedDBStorageAdapter unconditionally. Without a shim every e2e test that called createProjectOnServer threw "indexedDB is not defined" before doing anything else. Import fake-indexeddb/auto, matching how sync-test-harness already handles vitest. - Vite proxy target: hub-client's vite.config.ts proxies /auth/* and the websocket to VITE_HUB_SERVER (default http://localhost:3000), but globalSetup starts the e2e hub on port 3030 — so vite returned HTTP 500 from /auth/me on every test, blocking the in-browser hub-client from rendering the preview iframe. Pass VITE_HUB_SERVER=http://localhost:3030 to the webServer env. - Functional config picks up visual specs: testDir './e2e' with no testIgnore was finding setup-screens.visual.spec.ts and running it through the functional config, which has no missing-baseline retry. Skip *.visual.spec.ts so those run only via playwright.visual.config.ts. - CI workers: drop from 4 to 2. The 4-workers value was sized for the original ubuntu-latest-8x; under ubuntu-latest (2 cores) random tests stalled in the WASM render pipeline and missed the 45s preview-iframe deadline non-deterministically. Reproduced locally with 4 workers (a different test failed each run); 2 workers cleared all flakes. - Hub-client WASM gap (bd-izfv): the project-render path (RenderToHtmlRenderer) drops the user_grammars provider on the floor, so the smoke-all fixture highlighting/03-user-grammar/03-user-grammar-toml.qmd renders a bare <code> block instead of highlighted TOML. Add a SKIP_WASM_UNSUPPORTED map in smokeAllDiscovery.ts pointing at bd-izfv (which has a complete TDD plan on branch beads/bd-izfv-thread-user-grammars).
1 parent af0eec9 commit bc562bd

5 files changed

Lines changed: 42 additions & 7 deletions

File tree

hub-client/e2e/helpers/projectFactory.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
* - `seedProjectInBrowser()` runs in the browser via page.evaluate()
66
*/
77

8+
// createSyncClient instantiates IndexedDBStorageAdapter unconditionally;
9+
// shim indexedDB in Node so the helper can run outside the browser.
10+
import 'fake-indexeddb/auto';
11+
812
import { readFileSync } from 'node:fs';
913
import {
1014
createSyncClient,

hub-client/e2e/helpers/smokeAllDiscovery.ts

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,16 @@ const SKIP_PRINTS_MESSAGE: Set<string> = new Set([
2020
'quarto-test/expected-error.qmd',
2121
]);
2222

23+
// Tests that fail in the hub-client preview because of a known gap in
24+
// the WASM render pipeline. The native CLI runner handles these. Skip
25+
// in the browser until the gap is closed.
26+
const SKIP_WASM_UNSUPPORTED: Map<string, string> = new Map([
27+
[
28+
'highlighting/03-user-grammar/03-user-grammar-toml.qmd',
29+
'bd-izfv: RenderToHtmlRenderer drops user_grammars on the project-render path',
30+
],
31+
]);
32+
2333
// ---------------------------------------------------------------------------
2434
// Types
2535
// ---------------------------------------------------------------------------
@@ -231,7 +241,15 @@ function parseFormatSpec(
231241
// Skip logic
232242
// ---------------------------------------------------------------------------
233243

234-
export function shouldSkip(runConfig: RunConfig | null): string | null {
244+
export function shouldSkip(
245+
runConfig: RunConfig | null,
246+
relPath?: string,
247+
): string | null {
248+
if (relPath) {
249+
const wasmReason = SKIP_WASM_UNSUPPORTED.get(relPath);
250+
if (wasmReason) return `WASM unsupported: ${wasmReason}`;
251+
}
252+
235253
if (!runConfig) return null;
236254

237255
if (runConfig.skip) {

hub-client/e2e/smoke-all.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ test.describe('smoke-all E2E tests', () => {
3939
test.setTimeout(60000);
4040

4141
for (const fixture of allTests) {
42-
const skipReason = shouldSkip(fixture.runConfig);
42+
const skipReason = shouldSkip(fixture.runConfig, fixture.relPath);
4343

4444
for (const spec of fixture.formatSpecs) {
4545
const testName = `${fixture.relPath} [${spec.format}]`;

hub-client/playwright.config.ts

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,14 +11,21 @@ import { defineConfig, devices } from '@playwright/test';
1111
*/
1212
export default defineConfig({
1313
testDir: './e2e',
14+
// Visual-regression specs run via playwright.visual.config.ts (which has
15+
// the --update-snapshots-on-missing retry flow); exclude them from the
16+
// functional run so a missing baseline isn't a hard failure here.
17+
testIgnore: '**/*.visual.spec.ts',
1418
// Parallel tests are OK - they use different documents, single sync server handles concurrency
1519
fullyParallel: true,
1620
// Fail on `test.only` in CI
1721
forbidOnly: !!process.env.CI,
1822
// Retries for flaky tests in CI
1923
retries: process.env.CI ? 2 : 0,
20-
// Parallel workers
21-
workers: process.env.CI ? 4 : undefined,
24+
// Parallel workers. Match the runner's CPU count: ubuntu-latest has
25+
// 2 cores. Running more workers than cores causes the WASM render
26+
// pipeline to stall under contention and individual tests miss the
27+
// preview-render deadline non-deterministically.
28+
workers: process.env.CI ? 2 : undefined,
2229
// HTML reporter
2330
reporter: 'html',
2431

@@ -61,5 +68,11 @@ export default defineConfig({
6168
reuseExistingServer: !process.env.CI,
6269
// Timeout for server to start
6370
timeout: 120000,
71+
// Vite proxies /auth/* and the websocket to VITE_HUB_SERVER
72+
// (default http://localhost:3000). globalSetup starts the e2e hub
73+
// on port 3030, so point Vite at that port.
74+
env: {
75+
VITE_HUB_SERVER: 'http://localhost:3030',
76+
},
6477
},
6578
});

ts-packages/quarto-sync-client/src/client.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,9 +105,9 @@ function noopCallbacks(): SyncClientCallbacks {
105105
* - `create()` returns `createHandle`
106106
* - networkSubsystem never emits 'peer', so `waitForPeer` always times out
107107
*/
108-
function installMockRepo(
109-
connectHandle: ReturnType<typeof createMockHandle>['handle'],
110-
createHandle: ReturnType<typeof createMockHandle>['handle'],
108+
function installMockRepo<T>(
109+
connectHandle: ReturnType<typeof createMockHandle<T>>['handle'],
110+
createHandle: ReturnType<typeof createMockHandle<T>>['handle'],
111111
) {
112112
const mockNetworkSubsystem = {
113113
on: vi.fn(),

0 commit comments

Comments
 (0)