Skip to content

[finding] turbo.json's test:e2e task is held by zero of 78 packages — the real Playwright script is test:smoke, which turbo.json does not configure at all #12373

Description

@yinlianghui

Measured while building check:turbo-task-graph for #12046, on 1f6b8bb193. Filed unassigned; recording the gap, not claiming it. Nothing is red today.

What was measured

turbo.json declares a generic test:e2e task:

"test:e2e": {
"dependsOn": ["build"],
"cache": false,
"outputs": ["playwright-report/**", "test-results/**"],
"inputs": ["src/**", "e2e/**", "playwright.config.ts"]
}

Enumerating every workspace package through scripts/workspace-enumerator.mjs and counting which ones declare each generic task as a script:

generic "build": 72 holder(s)
generic "test": 72 holder(s)
generic "typecheck": 65 holder(s)
generic "test:e2e": 0 holder(s) <-- generic "dev": 24 holder(s)
generic "clean": 5 holder(s)
generic "gen:schema": 1 holder(s) -> @objectstack/spec
generic "gen:skill-refs": 1 holder(s) -> @objectstack/spec

Root package.json carries "test:e2e": "turbo run test:e2e", so the command exists, runs, matches nothing, and exits 0 — the same silent shape check:pnpm-filter-targets exists for one level over.

The repo does have a Playwright suite. examples/app-showcase holds playwright.config.ts and declares it as:

"test:smoke": "playwright test --config=playwright.config.ts"

So the task turbo.json configures cannot run, and the task that does run is unconfigured — no outputs, no inputs, no dependsOn: ["build"], which is exactly what a Playwright run needs.

Why this is not merely tidy-up

Two live consequences, neither of which reports anything today:

  1. pnpm test:e2e at the root is a no-op that exits 0. Anyone (agent or human) who runs it as evidence that the e2e suite passes is reading a green from a command that ran nothing — check:react-declaration-parity 是唯一没接进任何 workflow 的源码审计门禁,且无 MANIFEST 时静默 skip 退出 0 —— 它现在永远不可能红 #4690's family.
  2. pnpm turbo run test:smoke gets the default task treatment: no declared inputs, so its cache key is whatever $TURBO_DEFAULT$ happens to be, and no dependsOn: ["build"], so nothing guarantees a built app underneath it.

Why it is filed rather than fixed in place

The remedy is an edit to turbo.json, which was not in #12046's declared file surface. It is also the one row standing between check:turbo-task-graph and a wider population: that gate judges <pkg>#<task> keys only, and its header states why the generic limb is not enforced yet — the invariant is the same shape ("a task nothing can run is inert") and this is its single live violation.

Suggested disposition (not a decision)

Two readings, and they differ in what they assert about intent:

  • The task name is wrong. Rename test:e2etest:smoke in turbo.json (and the root script), so the entry configures the suite that exists. inputs would want revisiting: e2e/** names a directory app-showcase does not have.
  • The script name is wrong. Rename app-showcase's test:smoketest:e2e. Cheaper in turbo.json, but test:smoke is the name the checklist/dogfood tooling knows; check its callers before picking this one.

Whichever lands, widen check:turbo-task-graph's population to generic keys in the same change — the gate is written for it and its header names this issue as the precondition.

Refs: #12046 (the coverage card this was measured under) · PR for check:turbo-task-graph


Generated by Claude Code

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions