Add isolated Redis e2e suite for registerInitialCache and handler-level correctness - #240
Merged
Conversation
Adds a self-contained Playwright suite (examples/redis-minimal/e2e/isolated) that boots its own ephemeral Redis container and next start process to verify registerInitialCache actually writes build-time artifacts to Redis on boot, plus the setOnlyIfNotExists option's behavior - previously untested anywhere in the repo since the shared e2e suite only observes an already-running, already-mutated server/Redis.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a self-contained Playwright suite (
examples/redis-minimal/e2e/isolated/) that manages its own ephemeral Redis container(s) andnext startprocess(es), independent of the existing shared e2e suite's server/Redis. It proves behavior the shared suite can't reach because it only observes an already-running, already-mutated server:registerInitialCacheactually populates Redis on boot — asserted directly against Redis before any HTTP request is made, for both App Router and Pages Router (fallback: false) routes, plus fetch-cache-derived tags.setOnlyIfNotExistsbehaves correctly in both directions — a pre-existing key survives when the flag istrueand is overwritten when left at its defaultfalse, using the identical seeded input in both cases (a real A/B control, not just a single-condition observation).sharedTagsKey/sharedTagsTtlKeypopulation rules and real Redis TTL, tested via direct construction of theredis-stringshandler (the same public@fortedigital/nextjs-cache-handler/redis-stringssubpath export the example app's owncache-handler.mjsuses) against a real Redis instance — nonext startneeded, so it can cover a full matrix ofrevalidatevalues and thelifespan: nullpermanent-key case that's unreachable via any real route at runtime.revalidateTagmechanics — selective deletion (untouched entries proven byte-for-byte unchanged), safe no-op on no match, and the non-obvious distinction between an implicit tag (_N_T_...) that matches an existing entry (eagerly deleted, same as any tag) versus one that doesn't (only bookkeeping is written — the genuinely lazy path) — plus the TTL-expiry sweep that runs as a side effect of everyrevalidateTagcall.revalidateTagthrough the real/api/revalidateHTTP route and asserts the Redis deletion directly, rather than inferring it from a timestamp change.Also:
redis-minimal-e2ejob into two parallel jobs (main suite + isolated suite), each fully self-contained.dorny/test-reporter) to bothintegration-tests.ymlandnode.js.yml, surfaced as GitHub Check runs.docker run -d -pcould swallow an entire retry budget on Linux CI), and a port-collision race between sequential spec files (fixed by allocating a genuinely free OS-assigned port per container/server instead of sharing hardcoded ports).next startvs. direct handler construction) in thenew-e2e-testskill for future additions.Test plan
tsc --noEmitcleanpnpm test:e2e:isolatedverified to correctly trigger the Turborepo build chain from a clean.next/dist(this is what CI actually invokes)