Make instant() resilient to a leaked navigation-testing cookie#95375
Open
unstubbable wants to merge 1 commit into
Open
Make instant() resilient to a leaked navigation-testing cookie#95375unstubbable wants to merge 1 commit into
instant() resilient to a leaked navigation-testing cookie#95375unstubbable wants to merge 1 commit into
Conversation
The Instant Navigation Testing helper threw "An instant() scope is already active" whenever it found the next-instant-navigation-testing cookie set at acquire time. Because Playwright reuses one browser context across every test in a file, a cookie left behind by an earlier scope poisoned the shared jar and made every following instant() call fail fast, cascading through the suite. The cookie can outlive its scope: under the lock, each MPA page load asynchronously re-writes it via cookieStore, and that write can land right after the scope's release deletes it but before the client observes the deletion, resurrecting a captured-state entry that the change handler then ignores. Nesting is now tracked in-process, keyed on the browser context, rather than inferred from cookie presence. The context is the right granularity because the instant cookie is context-scoped: concurrent scopes on the same context share one cookie and conflict, while scopes on separate contexts or browsers are independent and must both run. On acquire we clear any stale cookie instead of throwing, and the release re-reads and re-deletes until the cookie stays gone, defeating the resurrection race. New tests cover recovery from a leaked cookie and concurrent scopes across separate contexts.
Contributor
Stats from current PR🟢 1 improvement
📊 All Metrics📖 Metrics GlossaryDev Server Metrics:
Build Metrics:
Change Thresholds:
⚡ Dev Server
📦 Dev Server (Webpack) (Legacy)📦 Dev Server (Webpack)
⚡ Production Builds
📦 Production Builds (Webpack) (Legacy)📦 Production Builds (Webpack)
📦 Bundle SizesBundle Sizes⚡ TurbopackClient Main Bundles
Server Middleware
Build DetailsBuild Manifests
📦 WebpackClient Main Bundles
Polyfills
Pages
Server Edge SSR
Middleware
Build DetailsBuild Manifests
Build Cache
🔄 Shared (bundler-independent)Runtimes
📎 Tarball URLCommit: f124099 |
Contributor
Tests PassedCommit: f124099 |
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.
The Instant Navigation Testing helper threw
An instant() scope is already activewhenever it found thenext-instant-navigation-testingcookie set at acquire time. Because Playwright reuses one browser context across every test in a file, a cookie left behind by an earlier scope poisoned the shared jar and made every followinginstant()call fail fast, cascading through the suite.The cookie can outlive its scope: under the lock, each MPA page load asynchronously re-writes it via
cookieStore, and that write can land right after the scope's release deletes it but before the client observes the deletion, resurrecting a captured-state entry that the change handler then ignores.Nesting is now tracked in-process, keyed on the browser context, rather than inferred from cookie presence. The context is the right granularity because the instant cookie is context-scoped: concurrent scopes on the same context share one cookie and conflict, while scopes on separate contexts or browsers are independent and must both run. On acquire we clear any stale cookie instead of throwing, and the release re-reads and re-deletes until the cookie stays gone, defeating the resurrection race. New tests cover recovery from a leaked cookie and concurrent scopes across separate contexts.
Stack created with GitHub Stacks CLI • Give Feedback 💬