+ * @deprecated Background pages have been removed from Chromium together with Manifest V2 extensions.
*/
void onBackgroundPage(Consumer handler);
/**
@@ -588,9 +581,7 @@ public WaitForPageOptions setTimeout(double timeout) {
*/
void addInitScript(Path script);
/**
- * NOTE: Background pages are only supported on Chromium-based browsers.
- *
- *
All existing background pages in the context.
+ * @deprecated Background pages have been removed from Chromium together with Manifest V2 extensions.
*
* @since v1.11
*/
diff --git a/playwright/src/main/java/com/microsoft/playwright/Page.java b/playwright/src/main/java/com/microsoft/playwright/Page.java
index 8a00b22ff..aa2ecd0c4 100644
--- a/playwright/src/main/java/com/microsoft/playwright/Page.java
+++ b/playwright/src/main/java/com/microsoft/playwright/Page.java
@@ -5729,6 +5729,20 @@ default boolean isVisible(String selector) {
* @since v1.8
*/
Keyboard keyboard();
+ /**
+ * Returns up to (currently) 200 last console messages from this page. See {@link
+ * com.microsoft.playwright.Page#onConsoleMessage Page.onConsoleMessage()} for more details.
+ *
+ * @since v1.56
+ */
+ List consoleMessages();
+ /**
+ * Returns up to (currently) 200 last page errors from this page. See {@link com.microsoft.playwright.Page#onPageError
+ * Page.onPageError()} for more details.
+ *
+ * @since v1.56
+ */
+ List pageErrors();
/**
* The method returns an element locator that can be used to perform actions on this page / frame. Locator is resolved to
* the element immediately before performing an action, so a series of actions on the same locator can in fact be performed
@@ -6053,6 +6067,21 @@ default ElementHandle querySelector(String selector) {
* @since v1.9
*/
List querySelectorAll(String selector);
+ /**
+ * Returns up to (currently) 100 last network request from this page. See {@link com.microsoft.playwright.Page#onRequest
+ * Page.onRequest()} for more details.
+ *
+ *
Returned requests should be accessed immediately, otherwise they might be collected to prevent unbounded memory growth
+ * as new requests come in. Once collected, retrieving most information about the request is impossible.
+ *
+ *
Note that requests reported through the {@link com.microsoft.playwright.Page#onRequest Page.onRequest()} request are not
+ * collected, so there is a trade off between efficient memory usage with {@link com.microsoft.playwright.Page#requests
+ * Page.requests()} and the amount of available information reported through {@link com.microsoft.playwright.Page#onRequest
+ * Page.onRequest()}.
+ *
+ * @since v1.56
+ */
+ List requests();
/**
* When testing a web page, sometimes unexpected overlays like a "Sign up" dialog appear and block actions you want to
* automate, e.g. clicking a button. These overlays don't always show up in the same way or at the same time, making them
diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/AssertionsBase.java b/playwright/src/main/java/com/microsoft/playwright/impl/AssertionsBase.java
index c97796032..48c6c3f7e 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/AssertionsBase.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/AssertionsBase.java
@@ -62,12 +62,15 @@ void expectImpl(String expression, FrameExpectOptions expectOptions, Object expe
if (!log.isEmpty()) {
log = "\nCall log:\n" + log;
}
+ if (result.errorMessage != null) {
+ message += "\n" + result.errorMessage;
+ }
if (expected == null) {
throw new AssertionFailedError(message + log);
}
ValueWrapper expectedValue = formatValue(expected);
ValueWrapper actualValue = formatValue(actual);
- message += ": " + expectedValue.getStringRepresentation() + "\nReceived: " + actualValue.getStringRepresentation() + "\n";
+ message += "\nExpected: " + expectedValue.getStringRepresentation() + "\nReceived: " + actualValue.getStringRepresentation() + "\n";
throw new AssertionFailedError(message + log, expectedValue, actualValue);
}
}
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 55a1aec42..4edc31fc4 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/BrowserContextImpl.java
@@ -34,8 +34,7 @@
import java.util.function.Predicate;
import java.util.regex.Pattern;
-import static com.microsoft.playwright.impl.Serialization.addHarUrlFilter;
-import static com.microsoft.playwright.impl.Serialization.gson;
+import static com.microsoft.playwright.impl.Serialization.*;
import static com.microsoft.playwright.impl.Utils.*;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.Files.readAllBytes;
@@ -731,9 +730,12 @@ protected void handleEvent(String event, JsonObject params) {
bindingCall.call(binding);
}
} else if ("console".equals(event)) {
- ConsoleMessageImpl message = new ConsoleMessageImpl(connection, params);
+ PageImpl page = null;
+ if (params.has("page")) {
+ page = connection.getExistingObject(params.getAsJsonObject("page").get("guid").getAsString());
+ }
+ ConsoleMessageImpl message = new ConsoleMessageImpl(connection, params, page);
listeners.notify(BrowserContextImpl.EventType.CONSOLE, message);
- PageImpl page = message.page();
if (page != null) {
page.listeners.notify(PageImpl.EventType.CONSOLE, message);
}
@@ -781,14 +783,7 @@ protected void handleEvent(String event, JsonObject params) {
page.listeners.notify(PageImpl.EventType.RESPONSE, response);
}
} else if ("pageError".equals(event)) {
- SerializedError error = gson().fromJson(params.getAsJsonObject("error"), SerializedError.class);
- String errorStr = "";
- if (error.error != null) {
- errorStr = error.error.name + ": " + error.error.message;
- if (error.error.stack != null && !error.error.stack.isEmpty()) {
- errorStr += "\n" + error.error.stack;
- }
- }
+ String errorStr = parseError(params.getAsJsonObject("error"));
PageImpl page;
try {
page = connection.getExistingObject(params.getAsJsonObject("page").get("guid").getAsString());
diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/ConsoleMessageImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/ConsoleMessageImpl.java
index f199c26f8..9097027ae 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/ConsoleMessageImpl.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/ConsoleMessageImpl.java
@@ -26,17 +26,12 @@
public class ConsoleMessageImpl implements ConsoleMessage {
private final Connection connection;
- private PageImpl page;
+ private final PageImpl page;
private final JsonObject initializer;
- public ConsoleMessageImpl(Connection connection, JsonObject initializer) {
+ public ConsoleMessageImpl(Connection connection, JsonObject initializer, PageImpl page) {
this.connection = connection;
- // Note: currently, we only report console messages for pages and they always have a page.
- // However, in the future we might report console messages for service workers or something else,
- // where page() would be null.
- if (initializer.has("page")) {
- page = connection.getExistingObject(initializer.getAsJsonObject("page").get("guid").getAsString());
- }
+ this.page = page;
this.initializer = initializer;
}
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 3b8ae6883..de73ffae3 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/PageImpl.java
@@ -31,6 +31,7 @@
import java.util.regex.Pattern;
import static com.microsoft.playwright.impl.Serialization.gson;
+import static com.microsoft.playwright.impl.Serialization.parseError;
import static com.microsoft.playwright.impl.Utils.*;
import static com.microsoft.playwright.options.ScreenshotType.JPEG;
import static com.microsoft.playwright.options.ScreenshotType.PNG;
@@ -567,6 +568,17 @@ public List querySelectorAll(String selector) {
return mainFrame.querySelectorAll(selector);
}
+ @Override
+ public List requests() {
+ JsonObject json = sendMessage("requests", new JsonObject(), NO_TIMEOUT).getAsJsonObject();
+ JsonArray requests = json.getAsJsonArray("requests");
+ List result = new ArrayList<>();
+ for (JsonElement item : requests) {
+ result.add(connection.getExistingObject(item.getAsJsonObject().get("guid").getAsString()));
+ }
+ return result;
+ }
+
@Override
public void addLocatorHandler(Locator locator, Consumer handler, AddLocatorHandlerOptions options) {
LocatorImpl locatorImpl = (LocatorImpl) locator;
@@ -983,6 +995,29 @@ public Keyboard keyboard() {
return keyboard;
}
+ @Override
+ public List consoleMessages() {
+ JsonObject json = sendMessage("consoleMessages", new JsonObject(), NO_TIMEOUT).getAsJsonObject();
+ JsonArray messages = json.getAsJsonArray("messages");
+ List result = new ArrayList<>();
+ for (JsonElement item : messages) {
+ result.add(new ConsoleMessageImpl(connection, item.getAsJsonObject(), this));
+ }
+ return result;
+ }
+
+ @Override
+ public List pageErrors() {
+ JsonObject json = sendMessage("pageErrors", new JsonObject(), NO_TIMEOUT).getAsJsonObject();
+ JsonArray errors = json.getAsJsonArray("errors");
+ List result = new ArrayList<>();
+ for (JsonElement item : errors) {
+ String errorStr = parseError(item.getAsJsonObject());
+ result.add(errorStr);
+ }
+ return result;
+ }
+
@Override
public Locator locator(String selector, LocatorOptions options) {
return mainFrame.locator(selector, convertType(options, Frame.LocatorOptions.class));
diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java b/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java
index c1a1768b1..e3363f20a 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java
@@ -114,6 +114,7 @@ class FrameExpectOptions {
class FrameExpectResult {
boolean matches;
SerializedValue received;
+ String errorMessage;
List log;
}
diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java b/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java
index 8be93f1c1..b639887f9 100644
--- a/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java
+++ b/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java
@@ -423,6 +423,18 @@ static List parseStringList(JsonArray array) {
return result;
}
+ static String parseError(JsonObject object) {
+ SerializedError error = gson().fromJson(object, SerializedError.class);
+ String errorStr = "";
+ if (error.error != null) {
+ errorStr = error.error.name + ": " + error.error.message;
+ if (error.error.stack != null && !error.error.stack.isEmpty()) {
+ errorStr += "\n" + error.error.stack;
+ }
+ }
+ return errorStr;
+ }
+
private static class OptionalSerializer implements JsonSerializer> {
private static boolean isSupported(Type type) {
return new TypeToken>() {}.getType().getTypeName().equals(type.getTypeName()) ||
diff --git a/playwright/src/test/java/com/microsoft/playwright/TestExpectMisc.java b/playwright/src/test/java/com/microsoft/playwright/TestExpectMisc.java
new file mode 100644
index 000000000..9c9790101
--- /dev/null
+++ b/playwright/src/test/java/com/microsoft/playwright/TestExpectMisc.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) Microsoft Corporation.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.microsoft.playwright;
+
+import org.junit.jupiter.api.Test;
+import org.opentest4j.AssertionFailedError;
+
+import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class TestExpectMisc extends TestBase {
+ @Test
+ void strictModeViolationErrorFormat() {
+ page.setContent("