Skip to content

test(suites): run the extension and react tests the unit suite owns - #4018

Merged
kojiwakayama merged 14 commits into
mainfrom
ci/run-extension-unit-tests
Aug 23, 2026
Merged

kojiwakayama merged 14 commits into
mainfrom
ci/run-extension-unit-tests

Conversation

@kojiwakayama

Copy link
Copy Markdown
Contributor

90 extension test files and react/react.test.ts have never run in CI, while extensions/*/src/** still counted toward the 80% coverage gate. The gate was scoring code whose tests it silently skipped.

The drift

Four declarations, one disagreement:

Source Lists extensions/ + react/?
pathSelectors in suites.ts
test.include in deno.json
suites.test.ts — asserts resolveLeafSuiteOwners{level: unit, suite: unit}
UNIT_ROOTS in run-suite.ts

Ownership said unit suite; execution disagreed. The existing tests only validated ownership, never that an owned root contributed a file, so the gap was invisible.

Why it mattered beyond the dead tests

deno coverage --include=src/ matches on path substring, so it also selects extensions/*/src/**. Measured from the shard artifacts of CI run 32627256834:

Prefix Covered Lines Coverage
src 376,659 435,945 86.4%
extensions 8,371 23,654 35.4%
gate total 385,039 459,608 83.8%

23,654 lines of extension source sat in the gate's denominator at 35%, holding the number 2.63 points below what src/ alone measures — precisely because the tests that would have covered it were never selected.

Safety

All 90 extension files and react/react.test.ts pass today under the unit suite's exact flags — verified before changing anything:

ok | 183 passed (1231 steps) | 0 failed     # extensions/
ok |   2 passed              | 0 failed     # react/react.test.ts

Planning goes from 1,950 files to 2,044. The gate number should rise, since these tests cover source already in the denominator.

scripts/ deliberately excluded

deno.json's root exclude lists scripts/, so those files are undiscoverable under the main config — deno test returns "No test modules found". They keep running through the dedicated test:scripts task with scripts/test.deno.json. Documented in the code rather than left as a silent asymmetry.

Test changes

The suite-parity helpers hardcoded the same three roots, so they pinned the planner to the legacy commands' own blind spot — parity with a legacy command is only worth asserting where the legacy command was right. Both now read LEGACY_UNIT_ROOTS, and a new case asserts every owned root contributes at least one planned file, so this cannot drift again silently.

run-suite.test.ts, suites.test.ts, test-layout.test.ts: 7 passed, 38 steps, 0 failed.

Relationship to the other open PRs

Independent — branches from main and touches neither coverage-ci.ts nor codecov.yml, so it does not conflict with #4013/#4015/#4016.

Worth noting this supersedes the fix I first considered: excluding extension source from coverage. That would have hidden the symptom and left 90 tests dead. Running them is the fix.

kwakayama and others added 2 commits August 23, 2026 10:14
The runtime critical-flow harness packs only the root `veryfront` package and
points the fixture at that tarball. The root pins its co-published extensions to
its own exact version, so npm resolves those pins from the registry -- and on a
release-cut branch that version is not published yet, because publishing is what
the release PR unlocks. Every version bump fails identically:

  npm error code ETARGET
  npm error notarget No matching version found for
                     @veryfront/ext-bundler-esbuild@0.1.1252-rc

It passes on main only because main's version is already on npm. #3977 added the
harness after the last release cut merged, so veryfront-code#4012 is the first
bump to hit it.

Pack the co-published extensions alongside the root and name them in the fixture
manifest, so nothing is fetched from a registry. `npm exec` gets the same set,
since it resolves the CLI's dependencies into its own prefix.

The set comes from the built root manifest, not a directory listing: the build
emits 29 extension packages and the root co-publishes 6. Installing the other 23
would change what the fixture exercises.

Nothing mutates the build output. The fixture manifest is a generated test input
the harness already writes, so there is no artifact to restore afterwards.

Verified against the real build by bumping npm/ to an unpublished 0.1.9999-rc:

  root tarball only      npm error code ETARGET
                         No matching version found for
                         @veryfront/ext-bundler-esbuild@0.1.9999-rc
  root + co-published    added 64 packages in 7s
                         veryfront 0.1.9999-rc, ext-bundler-esbuild 0.1.9999-rc,
                         ext-parser-babel 0.1.9999-rc, ext-yaml 0.1.9999-rc
`UNIT_ROOTS` in run-suite.ts listed only src/, cli/ and templates/, while
three other declarations put extensions/ and react/ in the unit suite:
`pathSelectors` in suites.ts, `test.include` in deno.json, and
suites.test.ts, which asserts `resolveLeafSuiteOwners` returns
`{level: unit, suite: unit}` for both.

Ownership and execution had drifted, so 90 extension test files and
react/react.test.ts never ran in CI. `extensions/*/src/**` still reached
the coverage report, because `deno coverage --include=src/` matches on
path substring: 23,654 lines at 35% covered, holding the gate 2.63 points
below what src/ alone measures. The gate was scoring code whose tests it
silently skipped.

All 90 extension files and react/react.test.ts pass under the unit
suite's flags today: 185 tests, 1,233 steps, 0 failures. Planning goes
from 1,950 files to 2,044.

scripts/ stays out. deno.json's root `exclude` lists scripts/, so those
files are undiscoverable under the main config; `deno test` reports "No
test modules found" for them. They keep running through `test:scripts`
with scripts/test.deno.json.

The suite-parity helpers hardcoded the same three roots, so they pinned
the planner to the legacy commands' blind spot. Both now read
LEGACY_UNIT_ROOTS, and a new case asserts every owned root contributes at
least one planned file.
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@kojiwakayama, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 38 minutes

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 726f3c0d-3861-48de-be64-e6e2abbecd12

📥 Commits

Reviewing files that changed from the base of the PR and between e076467 and b550efa.

📒 Files selected for processing (9)
  • deno.json
  • scripts/test/run-suite.test.ts
  • scripts/test/run-suite.ts
  • scripts/test/runtime-e2e-helpers.ts
  • scripts/test/runtime-inference-critical-flow.test.ts
  • scripts/test/template-runtime-e2e.test.ts
  • scripts/test/template-runtime-e2e.ts
  • scripts/test/test-semantic-audit-migration.ts
  • tests/e2e/regressions/dev-ui-browser-bundle.test.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

Copy link
Copy Markdown

📦 Client bundle boundary

Entrypoint Modules Source size Server leaks
src/index.client.ts 327 1962 KiB ✅ 0

A server module in a client graph aborts hydration in the browser. New leaks fail CI; known leaks are tracked in scripts/lint/client-bundle-baseline.json to burn down.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 5c6c376658

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread scripts/test/run-suite.test.ts Outdated
Addresses Codex P2 on #4018. The first version hardcoded the roots in
run-suite.ts and restated them in run-suite.test.ts, so a `pathSelector`
added to or removed from the unit suite in suites.ts would leave both
copies stale: the regression test would keep passing while UNIT_ROOTS
drifted from ownership again, which is the exact failure the test exists
to prevent.

UNIT_ROOTS now reads the unit suite's own `pathSelectors` and subtracts
UNPLANNABLE_UNIT_ROOTS, and the test derives its expectation from the
same registry instead of a second hand-kept list. A newly owned root is
planned without a second edit, and one that cannot yield files fails the
guard.

Per AGENTS.md, reuse the existing registry rather than adding a parallel
source of truth.
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

Addressed the P2 in 60da813ff.

You were right that the guard could not do its job. UNIT_ROOTS was hardcoded in run-suite.ts and the roots were restated in run-suite.test.ts, so a pathSelector added to or removed from the unit suite in suites.ts would have left both copies stale — the test would keep passing while UNIT_ROOTS drifted from ownership again, which is precisely the failure it was written to catch.

Both now read the registry:

const UNPLANNABLE_UNIT_ROOTS = new Set(["scripts/"]);

const UNIT_ROOTS = (() => {
  const unit = LEAF_TEST_SUITES.find((suite) => suite.id === "unit");
  if (!unit) {
    throw new Error("The leaf suite registry no longer defines a unit suite.");
  }
  return unit.pathSelectors.filter((root) => !UNPLANNABLE_UNIT_ROOTS.has(root));
})();

The test derives its expectation the same way rather than keeping a second list, so a newly owned root is planned without a second edit, and one that cannot yield files fails the guard.

The scripts/ exception is applied as you suggested — as a documented subtraction from the registry rather than an independent list. Reason is on UNPLANNABLE_UNIT_ROOTS: deno.json's root exclude lists scripts/, so those files are undiscoverable under the main config and run through test:scripts with scripts/test.deno.json.

Planning is unchanged at 2,044 files (src 1760, cli 184, extensions 90, templates 9, react 1). run-suite.test.ts and suites.test.ts pass.

@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

…hards

CI caught what a local run could not: ext-dev-ui-react's browser-bundle
test drives a real Chromium through tests/_helpers/playwright.ts, and
only the browser e2e jobs run `playwright install`. In a coverage shard
it fails with "Playwright browser bridge exited before reporting an
endpoint". It passed locally because a Chromium was already present.

It is the only test under a unit root that reaches for a browser -- every
other Playwright test lives under tests/e2e/ -- and nothing noticed
because extensions/ was never planned.

Excluded through BROWSER_DEPENDENT_TESTS, exported so the suite-parity
helpers filter on the same set instead of repeating the path. Named
rather than dropped silently: the test still needs a home in a
browser-capable job, which is follow-up work, not this change.

coverage:unit now plans 2,043 files (extensions 89).
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

Pushed 3e4102d3d. CI caught a failure my local run could not.

extensions/ext-dev-ui-react/src/browser-bundle.test.ts drives a real Chromium through tests/_helpers/playwright.ts, and only the browser e2e jobs run playwright install. In a coverage shard it fails with "Playwright browser bridge exited before reporting an endpoint". It passed locally because I already had a Chromium present — the shard environment does not.

It is the only test under a unit root that reaches for a browser (every other Playwright test lives under tests/e2e/), and nothing surfaced it because extensions/ was never planned in the first place.

Excluded via BROWSER_DEPENDENT_TESTS, exported so the suite-parity helpers filter on the same set rather than repeating the path — same reasoning as your earlier P2 about not keeping a second hand-maintained list. Named explicitly rather than dropped silently: the test still needs a home in a browser-capable job, which is follow-up rather than part of this change.

coverage:unit now plans 2,043 files (extensions 89).

Separately, for anyone reading the red checks: tests (runtime critical flow: node|deno|bun) also fails on main (run 32628763361) and is unrelated to this PR.

@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Hooray!

Reviewed commit: 3e4102d3df

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

kojiwakayama and others added 6 commits August 23, 2026 11:20
Addresses Codex P1 and P2 on #4017.

P1 -- the Deno matrix still reached the registry. `scaffoldProject`
forwarded only `packed.root` to `usePackedVeryfrontDenoTasks`, which
extracts that tarball and runs `deno install` inside
`.veryfront-packed-cli/package`. That manifest still pins the six
co-published extensions to its own version, so the sibling tarballs
already on disk were never declared to that install and it resolved them
from the registry. `redirectCoPublishedPins` now rewrites those pins to
`file:` before the install; it only touches pins the manifest already
declares, so it cannot widen what gets pulled in.

P2 -- templates add first-party extensions the root does not depend on:
`minimal` installs @veryfront/ext-content-mdx, `docs-agent` installs
@veryfront/ext-document-kreuzberg. Those pins carry the build's version
and fail the same way. `localiseTemplateExtensions` packs them from the
generated manifest, so only the selected template's extensions are packed
and unrelated ones stay out. It runs before the runtime-specific wiring
because both paths install from that manifest.

Not verifiable by this PR's CI: its head is 0.1.1251, which is published,
so the release-cut path cannot reproduce there. Both fixes are aimed at
the unpublished-version case that CI does not currently exercise.

The two TS2307 errors in cli/utils/terminal-select.ts are pre-existing --
2 before and after this change on the same file set.
The extension-suite branch must rerun CI against an unpublished release candidate. Merge the reviewed runtime harness fix so Bun, Deno, and Node resolve co-published extensions from local tarballs instead of the registry.

Constraint: Current main identifies an unpublished release candidate
Rejected: Ignore the three runtime failures | required checks must exercise the real package flow
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Drop this temporary dependency merge after #4017 lands on main
Tested: #4017 Bun critical flow passed locally; #4017 Node and Deno critical checks passed in CI
Not-tested: Exact #4018 combined head pending CI
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

Please review exact head a54382478f06a05816fcce3a212200006c7dbea6. The extension-suite change and its prior thread are unchanged; the new merge carries #4017 so release-version runtime checks resolve local co-published extension tarballs across Deno, Node, and Bun.

…' into fix/pack-copublished-extensions

# Conflicts:
#	scripts/test/runtime-e2e-helpers.ts
#	scripts/test/template-runtime-e2e.ts
The finalized package harness introduced three non-ASCII dashes in explanatory comments. Rephrase them with periods and commas so the runtime fix follows the repository-wide public-copy constraint without changing behavior.

Constraint: AGENTS.md forbids em and en dash characters
Rejected: Leave comments unchanged because they are not runtime output | repository copy rules cover source comments too
Confidence: high
Scope-risk: narrow
Reversibility: clean
Tested: Focused runtime/template tests passed (3 tests, 27 steps); format, lint, and diff checks passed
Not-tested: Exact pushed head full CI pending
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: a54382478f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Current main advanced through the semantic-audit PR while extension-suite CI was running. Merge the conflict-resolved and standards-clean #4017 head so this branch remains mergeable and exercises local extension tarballs across every runtime.

Constraint: #4009 merged an earlier runtime harness revision into main
Rejected: Resolve the duplicated harness independently here | #4017 owns the canonical conflict resolution
Confidence: high
Scope-risk: moderate
Reversibility: clean
Directive: Keep #4017 as the source of truth for runtime harness conflicts
Tested: #4017 exact head has 0 Standards findings, 0 Spec findings, and focused tests pass
Not-tested: Exact #4018 combined head full CI pending
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

Please review exact head 32e0019c282b06e4828ab932ba69ddeef658846a. It preserves the reviewed unit-suite planner changes, reconciles current main through canonical #4017, and includes the #4017 standards-only copy cleanup.

The Chromium-backed Dev UI bundle check could not run safely in unit shards, but excluding it from unit and coverage planning left it without an executable suite owner. Move it into the existing Deno browser e2e regression lane, wire that task explicitly, and remove the special unowned exclusion.

Constraint: tests/README requires every executable test path to map to exactly one leaf suite and runner owner.

Rejected: Keep BROWSER_DEPENDENT_TESTS as a silent unit exclusion | it preserves the unowned-test gap that triggered the review.

Rejected: Rename to .playwright.ts | this file uses Deno.test with the repository Chromium helper, not Playwright test() fixtures.

Confidence: high

Scope-risk: narrow

Directive: Browser-backed Deno tests should live under an e2e/browser task instead of being excluded from unit ownership.

Tested: red-first run-suite regression failed before the move.

Tested: VF_DISABLE_LRU_INTERVAL=1 deno test --config=scripts/test.deno.json --no-check --allow-read --allow-write --allow-run=bash scripts/test/run-suite.test.ts

Tested: DENO_TESTING=1 VF_DISABLE_LRU_INTERVAL=1 SSR_TRANSFORM_PER_PROJECT_LIMIT=0 REVALIDATION_PER_PROJECT_LIMIT=0 NODE_ENV=production LOG_FORMAT=text deno test --no-check --allow-all tests/e2e/regressions/dev-ui-browser-bundle.test.ts --unstable-worker-options --unstable-net

Tested: deno task test:e2e:rsc-browser

Tested: VF_DISABLE_LRU_INTERVAL=1 deno task test:layout

Tested: VF_DISABLE_LRU_INTERVAL=1 deno task lint:test-semantic-dispositions

Tested: deno fmt --check deno.json scripts/test/run-suite.ts scripts/test/run-suite.test.ts scripts/test/test-semantic-audit-migration.ts tests/e2e/regressions/dev-ui-browser-bundle.test.ts && deno lint --no-config scripts/test/run-suite.ts scripts/test/run-suite.test.ts scripts/test/test-semantic-audit-migration.ts tests/e2e/regressions/dev-ui-browser-bundle.test.ts

Not-tested: full CI matrix locally
@kojiwakayama

Copy link
Copy Markdown
Contributor Author

@codex review

@coderabbitai review

Please review exact head b550efaef8821b5ae6be720f449a0f15fa8fc373.

This head fixes the hard ownership issue from the standards review: extensions/ext-dev-ui-react/src/browser-bundle.test.ts is no longer excluded through BROWSER_DEPENDENT_TESTS without an alternate owner. It has moved to tests/e2e/regressions/dev-ui-browser-bundle.test.ts, is wired into the existing browser-capable test:e2e:rsc-browser task, and the stale semantic-unit disposition was removed.

Verification:

  • red-first scripts/test/run-suite.test.ts regression failed before the move because the browser e2e task did not own the test
  • VF_DISABLE_LRU_INTERVAL=1 deno test --config=scripts/test.deno.json --no-check --allow-read --allow-write --allow-run=bash scripts/test/run-suite.test.ts -> pass, 2 tests / 14 steps
  • moved test direct run -> pass, 2 tests / 0 failed
  • deno task test:e2e:rsc-browser -> pass, 6 tests / 9 steps
  • VF_DISABLE_LRU_INTERVAL=1 deno task test:layout -> pass, 2348 executable / 2297 canonical / 51 migration
  • VF_DISABLE_LRU_INTERVAL=1 deno task lint:test-semantic-dispositions -> pass, 2141 considered / 762 disposed
  • focused fmt/lint + git diff --check -> pass

Review threads are currently all resolved (1/1).

@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

@kojiwakayama I will review commit b550efaef8821b5ae6be720f449a0f15fa8fc373 on #4018.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: b550efaef8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@codecov

codecov Bot commented Aug 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@kojiwakayama
kojiwakayama added this pull request to the merge queue Aug 23, 2026
Merged via the queue into main with commit 863a449 Aug 23, 2026
47 of 48 checks passed
@kojiwakayama
kojiwakayama deleted the ci/run-extension-unit-tests branch August 23, 2026 10:31
kojiwakayama added a commit that referenced this pull request Aug 23, 2026
Integrate the latest mainline suite planner and Dev UI browser E2E relocation before publishing the semantic hardening. The combined inventory ratchets from the current base without restoring either migrated test to the unit boundary.

Constraint: PR #4018 advanced main and removed an adjacent semantic inventory entry.\nConfidence: high\nScope-risk: moderate\nDirective: Re-measure semantic and layout baselines whenever concurrent migration PRs land.\nTested: semantic audit 4 tests/84 steps; suite planner 2 tests/14 steps; fmt/typecheck; semantic audit 2140/762; layout 2348/2297/51.\nNot-tested: Full repository pre-push gate runs on this merge commit.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants