diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a79f427823a..fc88abe924f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -86,7 +86,21 @@ jobs: frontend: if: ${{ inputs.run_frontend }} runs-on: ${{ matrix.os }} + # Only the "Install dependency" step below is bounded, so a spec that + # truly hangs would otherwise run to GitHub's implicit 6h cap — billed at + # 10x on the macOS leg. Sized off observed green legs, which run 8.6-10.7 + # minutes end to end (install itself lands under 90s on all three OSes): + # 30 is ~3x the slowest, leaving ~19 minutes of slack for a cold yarn + # cache without masking a hang. + timeout-minutes: 30 strategy: + # An OS-specific failure should not cancel the other two legs: with the + # default fail-fast the surviving jobs report "The operation was + # canceled" and the run no longer says whether the failure reproduces + # off that OS — exactly the evidence needed to tell a runner flake from + # a real break. `platform`, `platform-integration`, `agent-service` and + # `infra` opt out for the same reason. + fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] include: diff --git a/frontend/TESTING.md b/frontend/TESTING.md index 7372fc4b29d..e27b86d09e3 100644 --- a/frontend/TESTING.md +++ b/frontend/TESTING.md @@ -47,6 +47,7 @@ For repo-wide testing philosophy (TDD, characterization tests, "every test must | Coverage | `@vitest/coverage-v8` | | Test setup | `src/test-zone-setup.ts` wraps `it`/`test` in an Angular ProxyZone (Vitest does not provide one and Angular's `fakeAsync` requires it) | | Globals | `globals: true` in `vitest.config.ts`, so `describe / it / expect / vi / beforeEach` come from the runtime — no per-file imports | +| Timeouts | 30s per test in both configs — a raise from Vitest's 5s jsdom default, and from the 15s it resolves under `browser.enabled`. Hooks get 30s under jsdom (up from 10s); browser mode already defaults to 30s. macOS CI runners stall for seconds at a time (#6073) | `src/main.test.ts` is intentionally a near-empty `export {}`. The `unit-test` builder uses `buildTarget`'s `main` to seed the bundle graph; if it pointed at the real `main.ts`, every component declared in `AppModule` would be type-checked for every spec, surfacing template errors for components no active spec touches. Keeping `main.test.ts` empty narrows the graph to what each spec actually imports. diff --git a/frontend/vitest.browser.config.ts b/frontend/vitest.browser.config.ts index 3fe2c410390..7e8368bb77a 100644 --- a/frontend/vitest.browser.config.ts +++ b/frontend/vitest.browser.config.ts @@ -64,6 +64,13 @@ export default defineConfig({ // browser-mode the runtime has neither, so we install the `buffer` npm // package as a shim). setupFiles: ["src/browser-buffer-polyfill.ts", "src/test-zone-setup.ts"], + // Browser mode already resolves larger defaults than jsdom (15s per test, + // 30s per hook, keyed off `browser.enabled`), but driving a real Chromium + // through playwright is strictly slower than jsdom, so the per-test + // ceiling is lifted to the same 30s the jsdom config uses + // (vitest.config.ts). `hookTimeout` is left alone — its browser-mode + // default is already 30s. See #6073. + testTimeout: 30_000, browser: { enabled: true, provider: playwright(), diff --git a/frontend/vitest.config.ts b/frontend/vitest.config.ts index 9cb2f82f88c..f322177aa0d 100644 --- a/frontend/vitest.config.ts +++ b/frontend/vitest.config.ts @@ -34,6 +34,17 @@ export default defineConfig({ // which Angular's `fakeAsync` requires. Karma+Jasmine installed this // implicitly; the @angular/build:unit-test path doesn't. setupFiles: ["src/test-zone-setup.ts"], + // Vitest defaults (5s per test, 10s per hook) are too tight for the + // macOS runners, which stall for seconds at a time under load: the same + // spec file that takes 240ms on ubuntu-latest has been observed taking + // 11.7s on macos-latest in the same commit's matrix. The stall lands on + // whichever test happens to be running, so raising the ceiling is the + // only fix that isn't whack-a-mole — three different specs have gone + // red this way. A test that legitimately needs >30s is broken, and the + // frontend job's `timeout-minutes: 30` (.github/workflows/build.yml) + // still bounds a true hang. See apache/texera#6073. + testTimeout: 30_000, + hookTimeout: 30_000, // Per-spec exclusions live in `angular.json` (the unit-test builder // applies them at the discovery stage, before Vitest's own filter, // which is what the Vitest team recommends — see the Vite warning