Skip to content

Commit 2ebc19a

Browse files
authored
fix(binding): do not fail when the page was closed before the binding result arrived (#2022)
1 parent 1e592bb commit 2ebc19a

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

‎playwright/src/main/java/com/microsoft/playwright/impl/BindingCall.java‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ void call(BindingCallback binding) {
7171
params.add("error", gson().toJsonTree(serializeError(exception)));
7272
method = "reject";
7373
}
74-
sendMessage(method, params, NO_TIMEOUT);
74+
// Like the Node client, do not fail when the page was closed before the result arrived.
75+
sendMessageAsync(method, params);
7576
}
7677

7778
private Object invoke(BindingCallback binding) {

‎playwright/src/test/java/com/microsoft/playwright/TestBrowserContextExposeFunction.java‎

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,24 @@ void shouldBeCallableFromInsideAddInitScript(BrowserContext context) {
9292
assertEquals(asList("context", "page"), actualArgs);
9393
}
9494

95+
@PlaywrightTest
96+
void shouldNotDispatchBindingOnAClosedPage(Browser browser, Server server) {
97+
try (BrowserContext context = browser.newContext()) {
98+
Boolean[] wasClosed = new Boolean[1];
99+
context.exposeBinding("add", (source, args) -> {
100+
wasClosed[0] = source.page().isClosed();
101+
return ((Number) args[0]).intValue() + ((Number) args[1]).intValue();
102+
});
103+
Page page = context.newPage();
104+
page.navigate(server.EMPTY_PAGE);
105+
page.waitForPopup(() -> page.evaluate("async () => {\n" +
106+
" const win = window.open('about:blank');\n" +
107+
" win['add'](9, 4);\n" +
108+
" win.close();\n" +
109+
"}"));
110+
// Give it a chance to dispatch the binding on the closed page.
111+
page.waitForTimeout(1000);
112+
assertFalse(Boolean.TRUE.equals(wasClosed[0]));
113+
}
114+
}
95115
}

0 commit comments

Comments
 (0)