diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java index 0f898ee9..f893ac8b 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java @@ -47,7 +47,8 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext { private final APIRequestContextImpl request; final List pages = new ArrayList<>(); final Router routes = new Router(); - private boolean isClosedOrClosing; + private boolean closeWasCalled; + private final WaitableEvent closePromise; final Map bindings = new HashMap<>(); PageImpl ownerPage; private static final Map eventSubscriptions() { @@ -90,8 +91,9 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext { } else { browser = null; } - this.tracing = connection.getExistingObject(initializer.getAsJsonObject("tracing").get("guid").getAsString()); - this.request = connection.getExistingObject(initializer.getAsJsonObject("requestContext").get("guid").getAsString()); + tracing = connection.getExistingObject(initializer.getAsJsonObject("tracing").get("guid").getAsString()); + request = connection.getExistingObject(initializer.getAsJsonObject("requestContext").get("guid").getAsString()); + closePromise = new WaitableEvent<>(listeners, EventType.CLOSE); } void setRecordHar(Path path, HarContentPolicy policy) { @@ -199,11 +201,8 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext { } private void closeImpl() { - if (isClosedOrClosing) { - return; - } - isClosedOrClosing = true; - try { + if (!closeWasCalled) { + closeWasCalled = true; for (Map.Entry entry : harRecorders.entrySet()) { JsonObject params = new JsonObject(); params.addProperty("harId", entry.getKey()); @@ -225,13 +224,9 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext { } artifact.delete(); } - sendMessage("close"); - } catch (PlaywrightException e) { - if (!isSafeCloseError(e)) { - throw e; - } } + runUntil(() -> {}, closePromise); } @Override @@ -624,7 +619,6 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext { } void didClose() { - isClosedOrClosing = true; if (browser != null) { browser.contexts.remove(this); } diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java index 311a61ec..e5c9b012 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java @@ -511,19 +511,21 @@ public class PageImpl extends ChannelOwner implements Page { @Override public void close(CloseOptions options) { - if (isClosed) { - return; + if (options == null) { + options = new CloseOptions(); } - JsonObject params = options == null ? new JsonObject() : gson().toJsonTree(options).getAsJsonObject(); try { - sendMessage("close", params); - } catch (PlaywrightException exception) { - if (!isSafeCloseError(exception)) { - throw exception; + if (ownedContext != null) { + ownedContext.close(); + } else { + JsonObject params = gson().toJsonTree(options).getAsJsonObject(); + sendMessage("close", params); } - } - if (ownedContext != null) { - ownedContext.close(); + } catch (PlaywrightException exception) { + if (isSafeCloseError(exception) && (options.runBeforeUnload == null || !options.runBeforeUnload)) { + return; + } + throw exception; } } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java b/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java index 00b3a5e9..1d275ccb 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestBrowserTypeConnect.java @@ -349,40 +349,7 @@ public class TestBrowserTypeConnect extends TestBase { } browser.close(); } - - @Test - void shouldNotThrowOnContextCloseAfterDisconnect() throws InterruptedException { - BrowserServer remoteServer = launchBrowserServer(browserType); - Browser browser = browserType.connect(remoteServer.wsEndpoint); - BrowserContext context = browser.newContext(); - Page page = context.newPage(); - - remoteServer.kill(); - while (browser.isConnected()) { - try { - page.waitForTimeout(10); - } catch (PlaywrightException e) { - } - } - context.close(); - } - - @Test - void shouldNotThrowOnPageCloseAfterDisconnect() throws InterruptedException { - BrowserServer remoteServer = launchBrowserServer(browserType); - Browser browser = browserType.connect(remoteServer.wsEndpoint); - Page page = browser.newPage(); - - remoteServer.kill(); - while (browser.isConnected()) { - try { - page.waitForTimeout(10); - } catch (PlaywrightException e) { - } - } - page.close(); - } - + @Test void shouldSaveAsVideosFromRemoteBrowser(@TempDir Path tempDir) { Path videosPath = tempDir.resolve("videosPath");