Skip to content

test(webview): add a timeout for clearCookies in teardown so a busy page can't stall it#41416

Open
dcrousso wants to merge 1 commit into
microsoft:mainfrom
dcrousso:fix-WKWebView-page-timeout
Open

test(webview): add a timeout for clearCookies in teardown so a busy page can't stall it#41416
dcrousso wants to merge 1 commit into
microsoft:mainfrom
dcrousso:fix-WKWebView-page-timeout

Conversation

@dcrousso

Copy link
Copy Markdown
Contributor

tests/page/page-set-content.spec.ts:153:3 › should handle timeout properly will infinitely loop the page

as a result, none of the WebKit inspector protocol messages are handled

context.clearCookies performs multiple round-trips using the WebKit inspector protocol (Page.getCookies and then Page.deleteCookie for each)

when the page is busy, we will end up waiting indefinitely

@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

Comment thread tests/webview/webviewTest.ts Outdated
// The shared Mobile Safari cookie store persists across tests; clear it
// while still on the test's domain (webview cookies are domain-scoped).
await page.context().clearCookies().catch(() => {});
await Promise.race([

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Sounds like the fix should be in clearCookies()

@dcrousso dcrousso force-pushed the fix-WKWebView-page-timeout branch from 9392db6 to 1f976f6 Compare June 23, 2026 17:10
@github-actions

This comment has been minimized.

@github-actions

This comment has been minimized.

@dcrousso dcrousso requested a review from pavelfeldman June 23, 2026 18:48
cookieName: c.name,
url: `${c.secure ? 'https' : 'http'}://${c.domain.replace(/^\./, '')}${c.path}`,
})));
await raceAgainstDeadline(async () => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is still unexpected - it looks like page.deleteCookies can stall when user calls it?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

raceAgainstDeadline does a Promise.race with a setTimeout so this should never take more than 5s

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

also, WVPage.prototype.deleteCookies is not exposed to clients

the only thing clients can invoke is BrowserContext.prototype.clearCookies, which eventually routes to here

if the concern is about somewhere else in playwright using WVPage.prototype.deleteCookies (or WVPage.prototype.getCookies) then yeah i can move the raceAgainstDeadline to be there instead

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Ah, we should rename this page to wvPage to make it clear it is not the one from the page.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Look for "await progress.race(this._context.clearCookies({" and instead of racing externally, plumb the progress as the first argument into the call chain, all the way to WVPage.prototype.deleteCookies, where you will race the protocol call with the progress.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

digging into this a bit more, we actually already have a progress.race(...) inside browserContextDispatcher.clearCookies, which should handle all browsers and platforms, so i dont think we need/want another one here just for iOS

circling back, this fix was just about trying to solve some test timeouts that happened as a result of us attempting to ensure cookies are cleared at the end of each test run

as such, it should only ever affect developers if their test involves infinitely busying the page such that no inspector protocol messages can be received (which is also what one of our tests does)

the only reason we're having issues is because we're using a lower-level clearCookies than what all other developers could use

im happy to move the progress.race(...) to a lower level if you feel that's preferred, but it would be a different approach to almost all other commands

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm lost as to what we are doing here then. Will failing to delete cookies result in error? Should it respect a given timeout that comes with the call?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

the original fix i had in this PR modified the test harness to only wait for this lower-level clearCookies for 5s in the teardown after a test run finishes (i.e. there's no timeout)

ultimately i think the question we need to answer is "should it be considered a test failure if the page is left in a state that we can no longer communicate with it after the test is over?"

if yes then we should close the PR as that's the intended behavior

if no then we could probably use any previously set timeout as a limit on the lower-level clearCookies so that we give it as much time as possible to work while ensuring that it doesn't exceed the overall time limit

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

If we can no longer communicate with the page, this test has failed and we should shut down the worker altogether.

@dcrousso dcrousso requested a review from pavelfeldman June 23, 2026 19:32
… page can't stall it

as part of the test teardown we attempt to clear all cookies

this is done via multiple round-trips using the WebKit inspector protocol (`Page.getCookies` and then `Page.deleteCookie` for each)

`tests/page/page-set-content.spec.ts:153:3 › should handle timeout properly` will infinitely loop the page

as a result, none of the WebKit inspector protocol messages are handled, meaning we will timeout trying to teardown the test

add a timeout limit for clearing cookies so that if it fails it doesn't cause the test to fail
@dcrousso dcrousso force-pushed the fix-WKWebView-page-timeout branch from 1f976f6 to 2833926 Compare June 25, 2026 01:54
@github-actions

Copy link
Copy Markdown
Contributor

Test results for "MCP"

7380 passed, 1122 skipped


Merge workflow run.

@github-actions

Copy link
Copy Markdown
Contributor

Test results for "tests 1"

2 failed
❌ [chromium-library] › library/browsercontext-add-init-script.spec.ts:28 › should work without navigation, after all bindings @chromium-ubuntu-22.04-arm-node20
❌ [chromium-library] › library/browsercontext-expose-function.spec.ts:77 › should be callable from-inside addInitScript @chromium-ubuntu-22.04-arm-node20

4 flaky ⚠️ [chromium-library] › library/beforeunload.spec.ts:130 › should support dismissing the dialog multiple times `@realtime-time-library-chromium-linux`
⚠️ [chromium-library] › library/popup.spec.ts:260 › should not throw when click closes popup `@chromium-ubuntu-22.04-node20`
⚠️ [chromium-library] › library/beforeunload.spec.ts:130 › should support dismissing the dialog multiple times `@chromium-ubuntu-22.04-node22`
⚠️ [firefox-library] › library/heap.spec.ts:223 › should not leak workers `@firefox-ubuntu-22.04-node20`

49054 passed, 1142 skipped


Merge workflow run.

// The shared Mobile Safari cookie store persists across tests; clear it
// while still on the test's domain (webview cookies are domain-scoped).
await page.context().clearCookies().catch(() => {});
// The shared Mobile Safari cookie store persists across tests; clear it while

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I am not sure I follow: this does not clear any tests, does not do proper cleanup for all the visited origins either. If there is a clean way to implement it (reset for reuse-alike), let's do it. Otherwise, let's not add this code.

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