Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ Playwright is a Java library to automate [Chromium](https://www.chromium.org/Hom

| | Linux | macOS | Windows |
| :--- | :---: | :---: | :---: |
| Chromium <!-- GEN:chromium-version -->138.0.7204.23<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Chromium <!-- GEN:chromium-version -->139.0.7258.5<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| WebKit <!-- GEN:webkit-version -->18.5<!-- GEN:stop --> | ✅ | ✅ | ✅ |
| Firefox <!-- GEN:firefox-version -->139.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
| Firefox <!-- GEN:firefox-version -->140.0.2<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |

## Documentation

Expand Down
2 changes: 1 addition & 1 deletion examples/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
<name>Playwright Client Examples</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<playwright.version>1.53.0</playwright.version>
<playwright.version>1.54.0</playwright.version>
</properties>
<dependencies>
<dependency>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -596,7 +596,8 @@ public WaitForPageOptions setTimeout(double timeout) {
*/
List<Page> backgroundPages();
/**
* Returns the browser instance of the context. If it was launched as a persistent context null gets returned.
* Gets the browser instance that owns the context. Returns {@code null} if the context is created outside of normal
* browser, e.g. Android or Electron.
*
* @since v1.8
*/
Expand Down Expand Up @@ -871,6 +872,7 @@ default void exposeBinding(String name, BindingCallback callback) {
* <li> {@code "notifications"}</li>
* <li> {@code "payment-handler"}</li>
* <li> {@code "storage-access"}</li>
* <li> {@code "local-fonts"}</li>
* </ul>
* @since v1.8
*/
Expand Down Expand Up @@ -903,6 +905,7 @@ default void grantPermissions(List<String> permissions) {
* <li> {@code "notifications"}</li>
* <li> {@code "payment-handler"}</li>
* <li> {@code "storage-access"}</li>
* <li> {@code "local-fonts"}</li>
* </ul>
* @since v1.8
*/
Expand Down
5 changes: 5 additions & 0 deletions playwright/src/main/java/com/microsoft/playwright/Mouse.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@
/**
* The Mouse class operates in main-frame CSS pixels relative to the top-left corner of the viewport.
*
* <p> <strong>NOTE:</strong> If you want to debug where the mouse moved, you can use the <a
* href="https://playwright.dev/java/docs/trace-viewer-intro">Trace viewer</a> or <a
* href="https://playwright.dev/java/docs/running-tests">Playwright Inspector</a>. A red dot showing the location of the
* mouse will be shown for every mouse action.
*
* <p> Every {@code page} object has its own Mouse, accessible with {@link com.microsoft.playwright.Page#mouse Page.mouse()}.
* <pre>{@code
* // Using ‘page.mouse’ to trace a 100x100 square.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package com.microsoft.playwright.impl;

import com.microsoft.playwright.PlaywrightException;
import org.opentest4j.AssertionFailedError;
import org.opentest4j.ValueWrapper;

Expand All @@ -29,12 +28,10 @@
import static com.microsoft.playwright.impl.Utils.toJsRegexFlags;
import static java.util.Arrays.asList;

class AssertionsBase {
final LocatorImpl actualLocator;
abstract class AssertionsBase {
final boolean isNot;

AssertionsBase(LocatorImpl actual, boolean isNot) {
this.actualLocator = actual;
AssertionsBase(boolean isNot) {
this.isNot = isNot;
}

Expand All @@ -58,7 +55,7 @@ void expectImpl(String expression, FrameExpectOptions expectOptions, Object expe
if (isNot) {
message = message.replace("expected to", "expected not to");
}
FrameExpectResult result = actualLocator.expect(expression, expectOptions, title);
FrameExpectResult result = doExpect(expression, expectOptions, title);
if (result.matches == isNot) {
Object actual = result.received == null ? null : Serialization.deserialize(result.received);
String log = (result.log == null) ? "" : String.join("\n", result.log);
Expand All @@ -75,7 +72,9 @@ void expectImpl(String expression, FrameExpectOptions expectOptions, Object expe
}
}

private static ValueWrapper formatValue(Object value) {
abstract FrameExpectResult doExpect(String expression, FrameExpectOptions expectOptions, String title);

protected static ValueWrapper formatValue(Object value) {
if (value == null || !value.getClass().isArray()) {
return ValueWrapper.create(value);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,7 @@ private void routeWebSocketImpl(UrlMatcher matcher, Consumer<WebSocketRoute> han

void recordIntoHar(PageImpl page, Path har, RouteFromHAROptions options, HarContentPolicy contentPolicy) {
if (contentPolicy == null) {
contentPolicy = Utils.convertType(options.updateContent, HarContentPolicy.class);;
contentPolicy = Utils.convertType(options.updateContent, HarContentPolicy.class);
}
if (contentPolicy == null) {
contentPolicy = HarContentPolicy.ATTACH;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,10 @@
import com.google.gson.JsonObject;
import com.microsoft.playwright.ConsoleMessage;
import com.microsoft.playwright.JSHandle;
import com.microsoft.playwright.Page;

import java.util.ArrayList;
import java.util.List;

import static com.microsoft.playwright.impl.Serialization.gson;

public class ConsoleMessageImpl implements ConsoleMessage {
private final Connection connection;
private PageImpl page;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -993,7 +993,8 @@ ElementHandle waitForSelectorImpl(String selector, WaitForSelectorOptions option
@Override
public void waitForTimeout(double timeout) {
JsonObject params = new JsonObject();
sendMessage("waitForTimeout", params, timeout);
params.addProperty("waitTimeout", timeout);
sendMessage("waitForTimeout", params, NO_TIMEOUT);
}

@Override
Expand Down Expand Up @@ -1085,4 +1086,16 @@ protected double navigationTimeout(Double timeout) {
}
return new TimeoutSettings().navigationTimeout(timeout);
}

FrameExpectResult expect(String expression, FrameExpectOptions options, String title) {
return withTitle(title, () -> expect(expression, options));
}

FrameExpectResult expect(String expression, FrameExpectOptions options) {
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
params.addProperty("expression", expression);
JsonElement json = sendMessage("expect", params, options.timeout);
FrameExpectResult result = gson().fromJson(json, FrameExpectResult.class);
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,20 @@
import static com.microsoft.playwright.impl.Utils.convertType;

public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAssertions {
LocatorImpl actualLocator;

public LocatorAssertionsImpl(Locator locator) {
this(locator, false);
}

private LocatorAssertionsImpl(Locator locator, boolean isNot) {
super((LocatorImpl) locator, isNot);
super(isNot);
this.actualLocator = (LocatorImpl) locator;
}

@Override
FrameExpectResult doExpect(String expression, FrameExpectOptions expectOptions, String title) {
return actualLocator.expect(expression, expectOptions, title);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -645,7 +645,8 @@ public int hashCode() {
}

FrameExpectResult expect(String expression, FrameExpectOptions options, String title) {
return frame.withTitle(title, () -> expectImpl(expression, options));
options.selector = selector;
return frame.expect(expression, options, title);
}

JsonObject toProtocol() {
Expand All @@ -654,13 +655,4 @@ JsonObject toProtocol() {
result.addProperty("selector", selector);
return result;
}

private FrameExpectResult expectImpl(String expression, FrameExpectOptions options) {
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
params.addProperty("selector", selector);
params.addProperty("expression", expression);
JsonElement json = frame.sendMessage("expect", params, options.timeout);
FrameExpectResult result = gson().fromJson(json, FrameExpectResult.class);
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,16 @@ public PageAssertionsImpl(Page page) {
}

private PageAssertionsImpl(Page page, boolean isNot) {
super((LocatorImpl) page.locator(":root"), isNot);
super(isNot);
this.actualPage = (PageImpl) page;
}

@Override
FrameExpectResult doExpect(String expression, FrameExpectOptions expectOptions, String title) {
FrameImpl frame = (FrameImpl) actualPage.mainFrame();
return frame.expect(expression, expectOptions, title);
}

@Override
public void hasTitle(String title, HasTitleOptions options) {
ExpectedTextValue expected = new ExpectedTextValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@
* limitations under the License.
*/

// This file is generated by generate_java_rpc.js, do not edit manually.
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this not true anymore???

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I couldn't find the generate_java_rpc.js file, so I don't think so :D


package com.microsoft.playwright.impl;

import java.util.List;
Expand Down Expand Up @@ -105,6 +103,7 @@ class ExpectedTextValue {
class FrameExpectOptions {
Object expressionArg;
List<ExpectedTextValue> expectedText;
String selector;
Double expectedNumber;
SerializedArgument expectedValue;
Boolean useInnerText;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ public void register(String name, Path path, RegisterOptions options) {
}

private void registerImpl(String name, String script, RegisterOptions options) {
if (selectorEngines.stream().anyMatch(engine -> name.equals(engine.get("name").getAsString()))) {
throw new PlaywrightException("selectors.register: \"" + name + "\" selector engine has been already registered");
}

JsonObject engine = new JsonObject();
engine.addProperty("name", name);
engine.addProperty("source", script);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,11 @@ void afterHandle() {
return;
}
// Ensure that websocket is "open" and can send messages without an actual server connection.
sendMessageAsync("ensureOpened");
try {
sendMessageAsync("ensureOpened");
} catch (PlaywrightException e) {
// If this happens after the page has been closed, ignore the error.
}
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ public class Cookie {
* Optional.
*/
public SameSiteAttribute sameSite;
/**
* For partitioned third-party cookies (aka <a
* href="https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies">CHIPS</a>), the
* partition key. Optional.
*/
public String partitionKey;

public Cookie(String name, String value) {
this.name = name;
Expand Down Expand Up @@ -103,4 +109,13 @@ public Cookie setSameSite(SameSiteAttribute sameSite) {
this.sameSite = sameSite;
return this;
}
/**
* For partitioned third-party cookies (aka <a
* href="https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies">CHIPS</a>), the
* partition key. Optional.
*/
public Cookie setPartitionKey(String partitionKey) {
this.partitionKey = partitionKey;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ void shouldSupportTimeoutOption() {
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
context.request().get(server.PREFIX + "/slow", RequestOptions.create().setTimeout(100));
});
assertTrue(e.getMessage().contains("Request timed out after 100ms"), e.getMessage());
assertTrue(e.getMessage().contains("Timeout 100ms exceeded"), e.getMessage());
}

@Test
Expand Down Expand Up @@ -468,7 +468,7 @@ void shouldRespectTimeoutAfterRedirects() {

context.setDefaultTimeout(100);
PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.request().get(server.PREFIX + "/redirect"));
assertTrue(e.getMessage().contains("Request timed out after 100ms"), e.getMessage());
assertTrue(e.getMessage().contains("Timeout 100ms exceeded"), e.getMessage());
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,12 +63,22 @@ void shouldRunWithCustomCategoriesIfProvided(@TempDir Path tempDir) throws IOExc
Path outputTraceFile = tempDir.resolve("trace.json");
browser.startTracing(page, new Browser.StartTracingOptions()
.setPath(outputTraceFile)
.setCategories(asList("disabled-by-default-v8.cpu_profiler.hires")));
.setCategories(asList("disabled-by-default-cc.debug")));
page.evaluate("() => 1 + 1");
browser.stopTracing();
try (FileReader fileReader = new FileReader(outputTraceFile.toFile())) {
JsonObject traceJson = new Gson().fromJson(fileReader, JsonObject.class);
assertTrue(traceJson.getAsJsonObject("metadata").get("trace-config")
.getAsString().contains("disabled-by-default-v8.cpu_profiler.hires"));
// NOTE: trace-config is deprecated as per http://crrev.com/c/6628182
boolean hasTraceConfig =
traceJson.getAsJsonObject("metadata").get("trace-config") != null
&& traceJson.getAsJsonObject("metadata").get("trace-config").getAsString().contains("disabled-by-default-cc.debug");
boolean hasTraceEvents = traceJson.getAsJsonArray("traceEvents").asList().stream()
.anyMatch(event -> {
JsonObject eventObj = (JsonObject) event;
return eventObj.has("cat") &&
eventObj.get("cat").getAsString().equals("disabled-by-default-cc.debug");
});
assertTrue(hasTraceConfig || hasTraceEvents);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ void shouldSupportGlobalTimeoutOption() {
APIRequestContext request = playwright.request().newContext(new APIRequest.NewContextOptions().setTimeout(100));
server.setRoute("/empty.html", exchange -> {});
PlaywrightException e = assertThrows(PlaywrightException.class, () -> request.get(server.EMPTY_PAGE));
assertTrue(e.getMessage().contains("Request timed out after 100ms"), e.getMessage());
assertTrue(e.getMessage().contains("Timeout 100ms exceeded"), e.getMessage());
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ public void shouldWaitForHiddenByDefault2() {

PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.locator("#target").click(new Locator.ClickOptions().setTimeout(3_000)));
assertEquals(0, (int) page.evaluate("window.clicked"));
assertThat(page.locator("#interstitial")).isVisible();
assertTrue(page.locator("#interstitial").isVisible());
assertEquals(1, called[0]);
assertTrue(e.getMessage().contains("locator handler has finished, waiting for getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName(\"close\")) to be hidden"), e.getMessage());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.microsoft.playwright.junit.FixtureTest;
import com.microsoft.playwright.junit.UsePlaywright;
import org.junit.jupiter.api.Test;
import org.opentest4j.AssertionFailedError;

import java.util.Arrays;
import java.util.List;
Expand All @@ -12,6 +13,7 @@

import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

@FixtureTest
@UsePlaywright
Expand Down Expand Up @@ -102,4 +104,27 @@ void shouldMatchUrl(Page page) {
"- link:\n" +
" - /url: /.*example.com/");
}

@Test
void shouldHandleTopLevelDeepEqual(Page page) {
// https://github.com/microsoft/playwright/issues/36456
page.setContent("" +
"<ul>\n" +
" <li>\n" +
" <ul>\n" +
" <li>1.1</li>\n" +
" <li>1.2</li>\n" +
" </ul>\n" +
" </li>\n" +
"</ul>");

assertThrows(AssertionFailedError.class, () -> {
assertThat(page.locator("body")).matchesAriaSnapshot("" +
"- /children: deep-equal\n" +
"- list:\n" +
" - listitem:\n" +
" - listitem: \"1.1\"\n" +
" - listitem: \"1.2\"");
});
}
}
Loading
Loading