diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/BindingCall.java b/playwright/src/main/java/com/microsoft/playwright/impl/BindingCall.java index b000a5085..2b1a44e55 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/BindingCall.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/BindingCall.java @@ -71,7 +71,8 @@ void call(BindingCallback binding) { params.add("error", gson().toJsonTree(serializeError(exception))); method = "reject"; } - sendMessage(method, params, NO_TIMEOUT); + // Like the Node client, do not fail when the page was closed before the result arrived. + sendMessageAsync(method, params); } private Object invoke(BindingCallback binding) { diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextExposeFunction.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextExposeFunction.java index 9d3402772..9e38eb81e 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextExposeFunction.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserContextExposeFunction.java @@ -92,4 +92,24 @@ void shouldBeCallableFromInsideAddInitScript(BrowserContext context) { assertEquals(asList("context", "page"), actualArgs); } + @PlaywrightTest + void shouldNotDispatchBindingOnAClosedPage(Browser browser, Server server) { + try (BrowserContext context = browser.newContext()) { + Boolean[] wasClosed = new Boolean[1]; + context.exposeBinding("add", (source, args) -> { + wasClosed[0] = source.page().isClosed(); + return ((Number) args[0]).intValue() + ((Number) args[1]).intValue(); + }); + Page page = context.newPage(); + page.navigate(server.EMPTY_PAGE); + page.waitForPopup(() -> page.evaluate("async () => {\n" + + " const win = window.open('about:blank');\n" + + " win['add'](9, 4);\n" + + " win.close();\n" + + "}")); + // Give it a chance to dispatch the binding on the closed page. + page.waitForTimeout(1000); + assertFalse(Boolean.TRUE.equals(wasClosed[0])); + } + } }