README.md

Parameter matching regression coverage

These suites test the contract across build, request handling, caches, client navigation, and deployment. Emitting the expected matcher or returning HTTP 200 is not sufficient: an admitted request must reach the right page with the right params, and a rejected request must not render that page's nested not-found UI.

The new regression assertions are intentionally not gated on the presence of a bug. Keep the tests unchanged when fixing the implementation. Mode gates only exclude unavailable capabilities, such as prefetching in development or reading local build artifacts from a deployment.

Request and deployment boundaries

ContractFixture and assertions
A closed prefix does not close its open suffixThis suite: lang: not-found, top: blocking, bottom: fallback; seeded and on-demand-only pages; both en and es; cold and repeated document requests
Dynamic suffixes are not captured in prerendersThis suite: different bottom values beneath the same generated or novel top; runtime suite: compare shell generations across top and bottom changes
Parameter encoding survives routing and cache lookupThis suite: multi-part catch-all with spaces and a literal percent sign; preserve existing URI-encoded server params with and without matching configuration
Routing rejection applies to every request formThis suite: documents, RSC, route-tree prefetches, unmatched static segments, and nested not-found boundaries
Client route discovery preserves admissionThis suite: prefetch a 404 before navigating to an allowed open suffix; prefetch an allowed suffix before navigating to a rejected prefix; compare with refresh
Cache invalidation does not change route admissionThis suite: revalidatePath for fully closed and partially closed routes, including runtime-generated outputs and invalid URLs; route-pattern invalidation regenerates a shared dynamic-tail shell without capturing either request's dynamic value
Expected misses are not internal server errorsThis suite: inspect local server output after a routing 404
Blocking means concrete generation before the responseRuntime suite: seeded and seedless routes, different cold keys, concurrent cold requests, and warm requests
Fallback and upgrade are distinct operationsRuntime suite: shared first-visitor HTML, concrete response params, subsequent upgrade when Partial Prefetching is enabled, and unchanged shared shell when it is disabled
An unresolved root must not contaminate cached computationsRoot-param suite: cached and uncached root reads for seeded and novel languages; repeated visits, cross-root navigation, and refresh
Deployment cache-key names agree with routingRoot-param suite: every allowQuery key on the root fallback is actually forwarded by the corresponding routing destination
Non-URL tree depth does not change policy orderParallel/group suite: identical URL policies with aligned branches, a group in the named slot, and a group in children; static and generated exports

The root tests describe the currently accepted lang: fallback configuration. If root fallbacks are deliberately prohibited instead, that is an API decision, not a reason to weaken assertions about corrupted cached content.

Existing compiler and validation coverage

These tests complement, rather than replace, the existing suites:

  • Main API suite: inheritance and explicit overrides, uniform policies, inferred policies, holes, dynamic tails, emitted matchers, root/catch-all/optional-catch-all routes, parallel agreement, typegen key visibility, feature/Cache Components requirements, export restrictions, empty-shell validation, and anonymized dev validation.
  • Export validation: static versus generated exports, invalid return values, parameter visibility, and checking the feature flag before executing a generator.
  • Not-found coherence: missing sibling/ancestor/parallel declarations, route groups, generated declarations, inherited overrides, explicit disagreement, and independent parameters with the same name.
  • Parallel inheritance: preserve each branch's inherited policy while combining parallel branches.
  • Unseeded prefixes: explicit policies extend the prerenderable prefix; empty/nonempty shell inference; unconfigured tails stay dynamic.
  • Inferred root behavior: inferred root blocking and policies beneath a known root.
  • Closed client routes and legacy dynamicParams: client-cache admission and the non-Cache Components comparison.

Verification matrix

Run the runtime and routing suites with both bundlers and with Partial Prefetching enabled and disabled. Their default configuration enables it; __NEXT_TEST_AXIS=A disables it. Assertions about explicit policy do not change between the two configurations. The upgrade assertions account separately for the existing Partial-Prefetching-only upgrade feature.

pnpm test-start-turbo test/e2e/app-dir/param-matching-runtime test/e2e/app-dir/param-matching-routing
__NEXT_TEST_AXIS=A pnpm test-start-turbo test/e2e/app-dir/param-matching-runtime test/e2e/app-dir/param-matching-routing
pnpm test-start-webpack test/e2e/app-dir/param-matching-runtime test/e2e/app-dir/param-matching-routing
__NEXT_TEST_AXIS=A pnpm test-start-webpack test/e2e/app-dir/param-matching-runtime test/e2e/app-dir/param-matching-routing

pnpm test-start-turbo test/e2e/app-dir/param-matching-root-params test/production/app-dir/param-matching-route-groups
pnpm test-start-webpack test/e2e/app-dir/param-matching-root-params test/production/app-dir/param-matching-route-groups

pnpm test-dev-turbo test/e2e/app-dir/generate-prerender-matching test/e2e/app-dir/param-matching-exports test/e2e/app-dir/param-matching-root-params test/e2e/app-dir/param-matching-routing
pnpm test-dev-webpack test/e2e/app-dir/generate-prerender-matching test/e2e/app-dir/param-matching-exports test/e2e/app-dir/param-matching-root-params test/e2e/app-dir/param-matching-routing

Run the existing production suites above as well. They cover configuration and validation combinations that the request fixtures intentionally keep simple.

Deployment is a separate acceptance check

The routing and root-param HTTP/browser assertions also support deployment mode. The query-contract assertion is local-only and must not substitute for a real adapter deployment:

NEXT_ENABLE_ADAPTER=1 pnpm test-deploy-turbo test/e2e/app-dir/param-matching-routing test/e2e/app-dir/param-matching-root-params
NEXT_ENABLE_ADAPTER=1 pnpm test-deploy-webpack test/e2e/app-dir/param-matching-routing test/e2e/app-dir/param-matching-root-params

Use the configured deployment-test credentials. Do not embed a local adapter checkout, substitute a mocked function launcher, or change metadata in a test adapter to make these requests pass.

A local next start pass does not establish adapter compatibility. Before declaring the closed-prefix deployment issue fixed, confirm the deployment actually uses grouped functions and exercises the cold open suffixes in this fixture. Function grouping and routing-level rejection without function/ISR invocation require deployment evidence; this suite does not infer either from HTTP status alone. Revalidation and cold requests must work on that deployment with the unchanged adapter; captured routing regexes alone cannot prove this.

Rendered from the public repository vercel/next.js on GitHub; content belongs to its authors. Cached for up to an hour.

test/e2e/app-dir/param-matching-routing/README.md · vercel/next.js | Docs MD