Skip to content
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
This repository was archived by the owner on Nov 4, 2026. It is now read-only.

Type-check coverage gap: e2e/ is outside every tsconfig, so 30 Playwright specs are compiled by nothing #4471

Closed

Description

@yinlianghui

Found while landing #4456 (PR #4470), which closed the lint half of this gap for e2e/. The type-check half is still open, and it is the same defect one gate over.

Measurement

At b4d3c2204, no tsconfig in the repo reaches e2e/:

$ grep -l '"e2e' tsconfig*.json apps/*/tsconfig*.json packages/*/tsconfig*.json
(no matches)

tsconfig.json                 include: ["packages", "examples", "apps"]
tsconfig.scripts.json         include: ["scripts/**/*.ts"]
tsconfig.vitest-setup.json    include: ["./vitest.setup*.ts", "./vitest.setup*.tsx"]
tsconfig.node.json            (no include/files)

e2e/ is not a workspace package, so turbo run type-check structurally cannot reach it either — the same reason given verbatim in tsconfig.scripts.json's header. Playwright transpiles specs without type-checking them, so the 30 .ts files under e2e/ (including e2e/live/global-setup.ts, which runs before every live-suite run) have never been compiled by anything.

Why this is the #3494 shape

#3494 found exactly this for scripts/: "not a workspace package, so turbo run type-check never reaches it, and scripts/__tests__ is matched by no include in the repo". Its resolution is the ready-made remedy shape here:

  • a dedicated tsconfig.scripts.json with include: ["scripts/**/*.ts"] — a glob, not a file list, so a new file cannot land outside every program again;
  • a named root script type-check:scripts so it is runnable locally, not CI-only;
  • a step in ci.yml's type-check job;
  • a pin test (scripts/__tests__/scripts-type-check.test.ts) holding the config's parse and glob reach in place.

An e2e twin of that would be a near-mechanical port. Also worth folding in: check-type-check-coverage.mjs has no notion of e2e/ (it derives from workspace packages), so nothing reports this gap the way check-lint-coverage.mjs reports an unlinted package.

One concrete trap for whoever takes it, already measured

The new { cause: e } in e2e/live/global-setup.ts (added by PR #4470 for preserve-caught-error) needs lib: ES2022 or newer — ErrorOptions does not exist in ES2020, and the root tsconfig.json is on target/lib: ES2020:

$ tsc --lib ES2020,DOM ... e2e/live/global-setup.ts
e2e/live/global-setup.ts(28,7): error TS2554: Expected 0-1 arguments, but got 2.

$ tsc --lib ES2022,DOM ... e2e/live/global-setup.ts
(no such error)

So an e2e tsconfig must not simply inherit the root's ES2020 lib. tsconfig.scripts.json already settled the same question the right way for the same reason — "Node 22 (engines.node: ">=22") is what actually runs these files" — and pins target/lib: ES2022. Expect a handful of other standing errors to surface on first compile; that surfacing is the point.

Filed unassigned as a finding while working #4456; not fixed there because it is outside that card's surface (lint wiring plus the 3 error sites).


Generated by Claude Code

Activity

  1. self-assigned this
    on Aug 12, 2026
  2. yinlianghui commented on Aug 12, 2026

    @yinlianghui
    ContributorAuthor

    CLAIM — session session_017Qqyix2QcnpUC9XeYVDzx3, branch claude/issue-4471-e2e-tsconfig.

    Ruling: close the gap with the #3494 remedy shape the card itself names — a root tsconfig.e2e.json covering e2e/**, a type-check:e2e script, wired into the turbo type-check pipeline the same way //#lint:root was wired for #4456 (measure the existing type-check:scripts wiring and mirror it; the turbo guard suites will tell you what a new task owes). Constraints from the card's own measurements: lib must be ES2022 (global-setup.ts's { cause } reds under ES2020 — that IS part of the red-first evidence); Playwright types needed. Red-first: the first full tsc -p tsconfig.e2e.json run over 30 never-compiled specs — capture its verbatim output; mechanical type errors get fixed in e2e/**; if any error reveals a REAL test bug (an assertion that cannot do what it claims), stop on that spec and report it instead of silently "fixing" the test. A pin test in the #3494 family style so the coverage cannot silently regress.

    Grading: no changeset owed expected (root config + e2e-internal; confirm via check-changeset-presence).

    Surface (mutual exclusion): root tsconfig.e2e.json (new) + root package.json/turbo.json wiring + e2e/** type fixes + scripts/__tests__/ pin + guard-suite docblock updates the partition demands. Disjoint from in-flight #4431/#4463/#4472/#4473 (none touch root configs or e2e/). Note the root package.json/turbo.json were just touched by PR #4470 — branch from current origin/main and you inherit that cleanly.


    Generated by Claude Code


    Generated by Claude Code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions