fix(reuse): ignore late bindings after dispatchers were disposed (#22838)
When reusing the context, we first dispose all dispatchers, and then reset the page/context. If bindings are triggered during the reset, they try to send messages on disposed dispatchers. Since there is no way to unregister bindings, just ignore them after disposal. Fixes #22803.
This commit is contained in:
parent
236c329ea9
commit
2393602e8c
|
|
@ -169,6 +169,10 @@ export class BrowserContextDispatcher extends Dispatcher<BrowserContext, channel
|
|||
|
||||
async exposeBinding(params: channels.BrowserContextExposeBindingParams): Promise<void> {
|
||||
await this._context.exposeBinding(params.name, !!params.needsHandle, (source, ...args) => {
|
||||
// When reusing the context, we might have some bindings called late enough,
|
||||
// after context and page dispatchers have been disposed.
|
||||
if (this._disposed)
|
||||
return;
|
||||
const pageDispatcher = PageDispatcher.from(this, source.page);
|
||||
const binding = new BindingCallDispatcher(pageDispatcher, params.name, !!params.needsHandle, source, args);
|
||||
this._dispatchEvent('bindingCall', { binding });
|
||||
|
|
|
|||
|
|
@ -111,6 +111,10 @@ export class PageDispatcher extends Dispatcher<Page, channels.PageChannel, Brows
|
|||
|
||||
async exposeBinding(params: channels.PageExposeBindingParams, metadata: CallMetadata): Promise<void> {
|
||||
await this._page.exposeBinding(params.name, !!params.needsHandle, (source, ...args) => {
|
||||
// When reusing the context, we might have some bindings called late enough,
|
||||
// after context and page dispatchers have been disposed.
|
||||
if (this._disposed)
|
||||
return;
|
||||
const binding = new BindingCallDispatcher(this, params.name, !!params.needsHandle, source, args);
|
||||
this._dispatchEvent('bindingCall', { binding });
|
||||
return binding.promise();
|
||||
|
|
|
|||
|
|
@ -182,3 +182,23 @@ test('should not cache resources', async ({ reusedContext, server }) => {
|
|||
expect(requestCountMap.get('/simple.json')).toBe(2);
|
||||
}
|
||||
});
|
||||
|
||||
test('should ignore binding from beforeunload', async ({ reusedContext }) => {
|
||||
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/22803' });
|
||||
|
||||
let context = await reusedContext();
|
||||
|
||||
let called = false;
|
||||
await context.exposeFunction('binding', () => called = true);
|
||||
|
||||
let page = await context.newPage();
|
||||
await page.evaluate(() => {
|
||||
window.addEventListener('beforeunload', () => window['binding']());
|
||||
});
|
||||
|
||||
context = await reusedContext();
|
||||
page = context.pages()[0];
|
||||
await page.setContent('hello');
|
||||
|
||||
expect(called).toBe(false);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in a new issue