diff --git a/playwright/src/main/java/com/microsoft/playwright/Frame.java b/playwright/src/main/java/com/microsoft/playwright/Frame.java index 2c87e613..a7820fe4 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Frame.java +++ b/playwright/src/main/java/com/microsoft/playwright/Frame.java @@ -1218,22 +1218,6 @@ public interface Frame { } } class LocatorOptions { - /** - * Matches elements that are above any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator above; - /** - * Matches elements that are below any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator below; /** * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. @@ -1247,53 +1231,7 @@ public interface Frame { * {@code
Playwright
}. */ public Object hasText; - /** - * Matches elements that are to the left of any element matching the inner locator, at any vertical position. Inner locator - * is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator leftOf; - /** - * Matches elements that are near (<= 50 css pixels) any of the elements matching the inner locator. Inner locator is - * queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator near; - /** - * Matches elements that are to the right of any element matching the inner locator, at any vertical position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator rightOf; - /** - * Matches elements that are above any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setAbove(Locator above) { - this.above = above; - return this; - } - /** - * Matches elements that are below any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setBelow(Locator below) { - this.below = below; - return this; - } /** * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. @@ -1322,39 +1260,6 @@ public interface Frame { this.hasText = hasText; return this; } - /** - * Matches elements that are to the left of any element matching the inner locator, at any vertical position. Inner locator - * is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setLeftOf(Locator leftOf) { - this.leftOf = leftOf; - return this; - } - /** - * Matches elements that are near (<= 50 css pixels) any of the elements matching the inner locator. Inner locator is - * queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setNear(Locator near) { - this.near = near; - return this; - } - /** - * Matches elements that are to the right of any element matching the inner locator, at any vertical position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setRightOf(Locator rightOf) { - this.rightOf = rightOf; - return this; - } } class PressOptions { /** diff --git a/playwright/src/main/java/com/microsoft/playwright/FrameLocator.java b/playwright/src/main/java/com/microsoft/playwright/FrameLocator.java index 3f2bdef6..e294e1d9 100644 --- a/playwright/src/main/java/com/microsoft/playwright/FrameLocator.java +++ b/playwright/src/main/java/com/microsoft/playwright/FrameLocator.java @@ -49,22 +49,6 @@ import java.util.regex.Pattern; */ public interface FrameLocator { class LocatorOptions { - /** - * Matches elements that are above any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator above; - /** - * Matches elements that are below any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator below; /** * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. @@ -78,53 +62,7 @@ public interface FrameLocator { * {@code
Playwright
}. */ public Object hasText; - /** - * Matches elements that are to the left of any element matching the inner locator, at any vertical position. Inner locator - * is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator leftOf; - /** - * Matches elements that are near (<= 50 css pixels) any of the elements matching the inner locator. Inner locator is - * queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator near; - /** - * Matches elements that are to the right of any element matching the inner locator, at any vertical position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator rightOf; - /** - * Matches elements that are above any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setAbove(Locator above) { - this.above = above; - return this; - } - /** - * Matches elements that are below any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setBelow(Locator below) { - this.below = below; - return this; - } /** * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. @@ -153,39 +91,6 @@ public interface FrameLocator { this.hasText = hasText; return this; } - /** - * Matches elements that are to the left of any element matching the inner locator, at any vertical position. Inner locator - * is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setLeftOf(Locator leftOf) { - this.leftOf = leftOf; - return this; - } - /** - * Matches elements that are near (<= 50 css pixels) any of the elements matching the inner locator. Inner locator is - * queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setNear(Locator near) { - this.near = near; - return this; - } - /** - * Matches elements that are to the right of any element matching the inner locator, at any vertical position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setRightOf(Locator rightOf) { - this.rightOf = rightOf; - return this; - } } /** * Returns locator to the first matching frame. diff --git a/playwright/src/main/java/com/microsoft/playwright/Locator.java b/playwright/src/main/java/com/microsoft/playwright/Locator.java index 200b4458..667a8797 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Locator.java +++ b/playwright/src/main/java/com/microsoft/playwright/Locator.java @@ -591,22 +591,6 @@ public interface Locator { } } class FilterOptions { - /** - * Matches elements that are above any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator above; - /** - * Matches elements that are below any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator below; /** * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. @@ -620,53 +604,7 @@ public interface Locator { * {@code
Playwright
}. */ public Object hasText; - /** - * Matches elements that are to the left of any element matching the inner locator, at any vertical position. Inner locator - * is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator leftOf; - /** - * Matches elements that are near (<= 50 css pixels) any of the elements matching the inner locator. Inner locator is - * queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator near; - /** - * Matches elements that are to the right of any element matching the inner locator, at any vertical position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator rightOf; - /** - * Matches elements that are above any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public FilterOptions setAbove(Locator above) { - this.above = above; - return this; - } - /** - * Matches elements that are below any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public FilterOptions setBelow(Locator below) { - this.below = below; - return this; - } /** * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. @@ -695,39 +633,6 @@ public interface Locator { this.hasText = hasText; return this; } - /** - * Matches elements that are to the left of any element matching the inner locator, at any vertical position. Inner locator - * is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public FilterOptions setLeftOf(Locator leftOf) { - this.leftOf = leftOf; - return this; - } - /** - * Matches elements that are near (<= 50 css pixels) any of the elements matching the inner locator. Inner locator is - * queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public FilterOptions setNear(Locator near) { - this.near = near; - return this; - } - /** - * Matches elements that are to the right of any element matching the inner locator, at any vertical position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public FilterOptions setRightOf(Locator rightOf) { - this.rightOf = rightOf; - return this; - } } class FocusOptions { /** @@ -1003,22 +908,6 @@ public interface Locator { } } class LocatorOptions { - /** - * Matches elements that are above any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator above; - /** - * Matches elements that are below any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator below; /** * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. @@ -1032,53 +921,7 @@ public interface Locator { * {@code
Playwright
}. */ public Object hasText; - /** - * Matches elements that are to the left of any element matching the inner locator, at any vertical position. Inner locator - * is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator leftOf; - /** - * Matches elements that are near (<= 50 css pixels) any of the elements matching the inner locator. Inner locator is - * queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator near; - /** - * Matches elements that are to the right of any element matching the inner locator, at any vertical position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator rightOf; - /** - * Matches elements that are above any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setAbove(Locator above) { - this.above = above; - return this; - } - /** - * Matches elements that are below any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setBelow(Locator below) { - this.below = below; - return this; - } /** * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. @@ -1107,39 +950,6 @@ public interface Locator { this.hasText = hasText; return this; } - /** - * Matches elements that are to the left of any element matching the inner locator, at any vertical position. Inner locator - * is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setLeftOf(Locator leftOf) { - this.leftOf = leftOf; - return this; - } - /** - * Matches elements that are near (<= 50 css pixels) any of the elements matching the inner locator. Inner locator is - * queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setNear(Locator near) { - this.near = near; - return this; - } - /** - * Matches elements that are to the right of any element matching the inner locator, at any vertical position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setRightOf(Locator rightOf) { - this.rightOf = rightOf; - return this; - } } class PressOptions { /** diff --git a/playwright/src/main/java/com/microsoft/playwright/Page.java b/playwright/src/main/java/com/microsoft/playwright/Page.java index 7af0e549..1d6ee25d 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Page.java +++ b/playwright/src/main/java/com/microsoft/playwright/Page.java @@ -1658,22 +1658,6 @@ public interface Page extends AutoCloseable { } } class LocatorOptions { - /** - * Matches elements that are above any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator above; - /** - * Matches elements that are below any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator below; /** * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. @@ -1687,53 +1671,7 @@ public interface Page extends AutoCloseable { * {@code
Playwright
}. */ public Object hasText; - /** - * Matches elements that are to the left of any element matching the inner locator, at any vertical position. Inner locator - * is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator leftOf; - /** - * Matches elements that are near (<= 50 css pixels) any of the elements matching the inner locator. Inner locator is - * queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator near; - /** - * Matches elements that are to the right of any element matching the inner locator, at any vertical position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public Locator rightOf; - /** - * Matches elements that are above any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setAbove(Locator above) { - this.above = above; - return this; - } - /** - * Matches elements that are below any of the elements matching the inner locator, at any horizontal position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setBelow(Locator below) { - this.below = below; - return this; - } /** * Matches elements containing an element that matches an inner locator. Inner locator is queried against the outer one. * For example, {@code article} that has {@code text=Playwright} matches {@code

Playwright
}. @@ -1762,39 +1700,6 @@ public interface Page extends AutoCloseable { this.hasText = hasText; return this; } - /** - * Matches elements that are to the left of any element matching the inner locator, at any vertical position. Inner locator - * is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setLeftOf(Locator leftOf) { - this.leftOf = leftOf; - return this; - } - /** - * Matches elements that are near (<= 50 css pixels) any of the elements matching the inner locator. Inner locator is - * queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setNear(Locator near) { - this.near = near; - return this; - } - /** - * Matches elements that are to the right of any element matching the inner locator, at any vertical position. Inner - * locator is queried against the same root as the outer one. More details in layout selectors guide. - * - *

Note that outer and inner locators must belong to the same frame. Inner locator must not contain {@code FrameLocator}s. - */ - public LocatorOptions setRightOf(Locator rightOf) { - this.rightOf = rightOf; - return this; - } } class PdfOptions { /** diff --git a/playwright/src/main/java/com/microsoft/playwright/Route.java b/playwright/src/main/java/com/microsoft/playwright/Route.java index d84f6706..f464af89 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Route.java +++ b/playwright/src/main/java/com/microsoft/playwright/Route.java @@ -22,6 +22,8 @@ import java.util.*; /** * Whenever a network route is set up with {@link Page#route Page.route()} or {@link BrowserContext#route * BrowserContext.route()}, the {@code Route} object allows to handle the route. + * + *

Learn more about networking. */ public interface Route { class ResumeOptions { diff --git a/playwright/src/main/java/com/microsoft/playwright/impl/LocatorImpl.java b/playwright/src/main/java/com/microsoft/playwright/impl/LocatorImpl.java index 8d7afecc..1e8a2bef 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/LocatorImpl.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/LocatorImpl.java @@ -32,11 +32,11 @@ class LocatorImpl implements Locator { { try { addFilter("has", "has"); - addFilter("leftOf", "left-of"); - addFilter("rightOf", "right-of"); - addFilter("above", "above"); - addFilter("below", "below"); - addFilter("near", "near"); +// addFilter("leftOf", "left-of"); +// addFilter("rightOf", "right-of"); +// addFilter("above", "above"); +// addFilter("below", "below"); +// addFilter("near", "near"); } catch (NoSuchFieldException e) { throw new InternalError(e); } 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 48162f69..28a69650 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/Protocol.java @@ -43,6 +43,8 @@ class SerializedValue{ } O[] o; Number h; + Integer id; + Integer ref; } class SerializedArgument{ 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 2157d84f..89a7e766 100644 --- a/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java +++ b/playwright/src/main/java/com/microsoft/playwright/impl/Serialization.java @@ -71,82 +71,128 @@ class Serialization { return result; } - private static SerializedValue serializeValue(Object value, List handles, int depth) { - if (depth > 100) { - throw new PlaywrightException("Maximum argument depth exceeded"); + private static class ValueSerializer { + // hashCode() of a map containing itself as a key will throw stackoverflow exception, + // so we user wrappers. + private static class HashableValue { + final Object value; + HashableValue(Object value) { + this.value = value; + } + + @Override + public boolean equals(Object o) { + return value == ((HashableValue) o).value; + } + + @Override + public int hashCode() { + return System.identityHashCode(value); + } } - SerializedValue result = new SerializedValue(); - if (value instanceof JSHandleImpl) { - result.h = handles.size(); - handles.add((JSHandleImpl) value); + private final Map valueToId = new HashMap<>(); + private int lastId = 0; + private final List handles = new ArrayList<>(); + private final SerializedValue serializedValue; + + ValueSerializer(Object value) { + serializedValue = serializeValue(value); + } + + SerializedArgument toSerializedArgument() { + SerializedArgument result = new SerializedArgument(); + result.value = serializedValue; + result.handles = new Channel[handles.size()]; + int i = 0; + for (JSHandleImpl handle : handles) { + result.handles[i] = new Channel(); + result.handles[i].guid = handle.guid; + ++i; + } return result; } - if (value == null) { - result.v = "undefined"; - } else if (value instanceof Double) { - double d = ((Double) value); - if (d == Double.POSITIVE_INFINITY) { - result.v = "Infinity"; - } else if (d == Double.NEGATIVE_INFINITY) { - result.v = "-Infinity"; - } else if (d == -0) { - result.v = "-0"; - } else if (Double.isNaN(d)) { - result.v = "NaN"; + + private SerializedValue serializeValue(Object value) { + SerializedValue result = new SerializedValue(); + if (value instanceof JSHandleImpl) { + result.h = handles.size(); + handles.add((JSHandleImpl) value); + return result; + } + if (value == null) { + result.v = "undefined"; + } else if (value instanceof Double) { + double d = ((Double) value); + if (d == Double.POSITIVE_INFINITY) { + result.v = "Infinity"; + } else if (d == Double.NEGATIVE_INFINITY) { + result.v = "-Infinity"; + } else if (d == -0) { + result.v = "-0"; + } else if (Double.isNaN(d)) { + result.v = "NaN"; + } else { + result.n = d; + } + } else if (value instanceof Boolean) { + result.b = (Boolean) value; + } else if (value instanceof Integer) { + result.n = (Integer) value; + } else if (value instanceof String) { + result.s = (String) value; } else { - result.n = d; + HashableValue mapKey = new HashableValue(value); + Integer id = valueToId.get(mapKey); + if (id != null) { + result.ref = id; + } else { + result.id = ++lastId; + valueToId.put(mapKey, lastId); + if (value instanceof List) { + List list = new ArrayList<>(); + for (Object o : (List) value) { + list.add(serializeValue(o)); + } + result.a = list.toArray(new SerializedValue[0]); + } else if (value instanceof Map) { + List list = new ArrayList<>(); + @SuppressWarnings("unchecked") + Map map = (Map) value; + for (Map.Entry e : map.entrySet()) { + SerializedValue.O o = new SerializedValue.O(); + o.k = e.getKey(); + o.v = serializeValue(e.getValue()); + list.add(o); + } + result.o = list.toArray(new SerializedValue.O[0]); + } else if (value instanceof Object[]) { + List list = new ArrayList<>(); + for (Object o : (Object[]) value) { + list.add(serializeValue(o)); + } + result.a = list.toArray(new SerializedValue[0]); + } else { + throw new PlaywrightException("Unsupported type of argument: " + value); + } + } } - } else if (value instanceof Boolean) { - result.b = (Boolean) value; - } else if (value instanceof Integer) { - result.n = (Integer) value; - } else if (value instanceof String) { - result.s = (String) value; - } else if (value instanceof List) { - List list = new ArrayList<>(); - for (Object o : (List) value) { - list.add(serializeValue(o, handles, depth + 1)); - } - result.a = list.toArray(new SerializedValue[0]); - } else if (value instanceof Map) { - List list = new ArrayList<>(); - @SuppressWarnings("unchecked") - Map map = (Map) value; - for (Map.Entry e : map.entrySet()) { - SerializedValue.O o = new SerializedValue.O(); - o.k = e.getKey(); - o.v = serializeValue(e.getValue(), handles, depth + 1); - list.add(o); - } - result.o = list.toArray(new SerializedValue.O[0]); - } else if (value instanceof Object[]) { - List list = new ArrayList<>(); - for (Object o : (Object[]) value) { - list.add(serializeValue(o, handles, depth + 1)); - } - result.a = list.toArray(new SerializedValue[0]); - } else { - throw new PlaywrightException("Unsupported type of argument: " + value); + return result; } - return result; } static SerializedArgument serializeArgument(Object arg) { - SerializedArgument result = new SerializedArgument(); - List handles = new ArrayList<>(); - result.value = serializeValue(arg, handles, 0); - result.handles = new Channel[handles.size()]; - int i = 0; - for (JSHandleImpl handle : handles) { - result.handles[i] = new Channel(); - result.handles[i].guid = handle.guid; - ++i; - } - return result; + return new ValueSerializer(arg).toSerializedArgument(); + } + + static T deserialize(SerializedValue value) { + return deserialize(value, new HashMap<>()); } @SuppressWarnings("unchecked") - static T deserialize(SerializedValue value) { + private static T deserialize(SerializedValue value, Map idToValue) { + if (value.ref != null) { + return (T) idToValue.get(value.ref); + } if (value.n != null) { if (value.n.doubleValue() == (double) value.n.intValue()) { return (T) Integer.valueOf(value.n.intValue()); @@ -177,15 +223,17 @@ class Serialization { } if (value.a != null) { List list = new ArrayList<>(); + idToValue.put(value.id, list); for (SerializedValue v : value.a) { - list.add(deserialize(v)); + list.add(deserialize(v, idToValue)); } return (T) list; } if (value.o != null) { Map map = new LinkedHashMap<>(); + idToValue.put(value.id, map); for (SerializedValue.O o : value.o) { - map.put(o.k, deserialize(o.v)); + map.put(o.k, deserialize(o.v, idToValue)); } return (T) map; } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageEvaluate.java b/playwright/src/test/java/com/microsoft/playwright/TestPageEvaluate.java index c6e8d31d..29345a6e 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestPageEvaluate.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestPageEvaluate.java @@ -345,31 +345,13 @@ public class TestPageEvaluate extends TestBase { @Test void shouldReturnUndefinedForNonSerializableObjects() { - assertEquals(null, page.evaluate("() => window")); - } - - @Test - void shouldFailForCircularObject() { - Object result = page.evaluate("() => {\n" + - " const a = {};\n" + - " const b = { a };\n" + - " a.b = b;\n" + - " return a;\n" + - "}"); - assertNull(result); + assertEquals(null, page.evaluate("() => () => {}")); + assertEquals("ref: ", page.evaluate("() => window")); } @Test void shouldBeAbleToThrowATrickyError() { - JSHandle windowHandle = page.evaluateHandle("() => window"); - String errorText = null; - try { - windowHandle.jsonValue(); - fail("did not throw"); - } catch (PlaywrightException e) { - errorText = e.getMessage(); - } - assertNotNull(errorText); + String errorText = "My error"; try { page.evaluate("errorText => {\n" + " throw new Error(errorText);\n" + @@ -619,4 +601,23 @@ public class TestPageEvaluate extends TestBase { JSHandle resultHandle = page.evaluateHandle("() => ({ toJSON: () => 'string', data: 'data' })"); assertEquals(mapOf("data", "data", "toJSON", emptyMap()), resultHandle.jsonValue()); } + + @Test + void shouldAliasWindowDocumentAndNode() { + Object object = page.evaluate("[window, document, document.body]"); + assertEquals(asList("ref: ", "ref: ", "ref: "), object); + } + + @Test + void shouldWorkForCircularObject() { + Object result = page.evaluate("() => {\n" + + " const a = {};\n" + + " a.b = a;\n" + + " return a;\n" + + " }"); + + Map map = (Map) result; + assertEquals(1, map.size()); + assertTrue(map == map.get("b")); + } } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestPageExposeFunction.java b/playwright/src/test/java/com/microsoft/playwright/TestPageExposeFunction.java index 4a128f4d..38748f99 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestPageExposeFunction.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestPageExposeFunction.java @@ -227,5 +227,15 @@ public class TestPageExposeFunction extends TestBase { assertTrue(e.getMessage().contains("exposeBindingHandle supports a single argument, 2 received")); } } + + @Test + void shouldSerializeCycles() { + Object[] object = { null }; + page.exposeBinding("log", (source, obj) -> object[0] = obj[0]); + page.evaluate("const a = {}; a.b = a; window.log(a)"); + Map map = (Map) object[0]; + assertEquals(1, map.size()); + assertTrue(map == map.get("b")); + } } diff --git a/playwright/src/test/java/com/microsoft/playwright/TestSelectorsMisc.java b/playwright/src/test/java/com/microsoft/playwright/TestSelectorsMisc.java index ca4925e9..74988533 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestSelectorsMisc.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestSelectorsMisc.java @@ -65,114 +65,114 @@ public class TestSelectorsMisc extends TestBase { " }", boxes); assertEquals("id7", page.evalOnSelector("div:right-of(#id6)", "e => e.id")); - assertEquals("id7", page.evalOnSelector("div >> right-of=\"#id6\"", "e => e.id")); - assertEquals("id7", page.locator("div", new Page.LocatorOptions().setRightOf(page.locator("#id6"))) - .first().evaluate("e => e.id")); +// assertEquals("id7", page.evalOnSelector("div >> right-of=\"#id6\"", "e => e.id")); +// assertEquals("id7", page.locator("div", new Page.LocatorOptions().setRightOf(page.locator("#id6"))) +// .first().evaluate("e => e.id")); assertEquals("id2", page.evalOnSelector("div:right-of(#id1)", "e => e.id")); - assertEquals("id2", page.evalOnSelector("div >> right-of=\"#id1\"", "e => e.id")); +// assertEquals("id2", page.evalOnSelector("div >> right-of=\"#id1\"", "e => e.id")); assertEquals("id4", page.evalOnSelector("div:right-of(#id3)", "e => e.id")); - assertEquals("id4", page.evalOnSelector("div >> right-of=\"#id3\"", "e => e.id")); +// assertEquals("id4", page.evalOnSelector("div >> right-of=\"#id3\"", "e => e.id")); assertNull(page.querySelector("div:right-of(#id4)")); - assertNull(page.querySelector("div >> right-of=\"#id4\"")); +// assertNull(page.querySelector("div >> right-of=\"#id4\"")); assertEquals("id7", page.evalOnSelector("div:right-of(#id0)", "e => e.id")); - assertEquals("id7", page.evalOnSelector("div >> right-of=\"#id0\"", "e => e.id")); +// assertEquals("id7", page.evalOnSelector("div >> right-of=\"#id0\"", "e => e.id")); assertEquals("id9", page.evalOnSelector("div:right-of(#id8)", "e => e.id")); - assertEquals("id9", page.evalOnSelector("div >> right-of=\"#id8\"", "e => e.id")); +// assertEquals("id9", page.evalOnSelector("div >> right-of=\"#id8\"", "e => e.id")); assertEquals("id4,id2,id5,id7,id8,id9", page.evalOnSelectorAll("div:right-of(#id3)", "els => els.map(e => e.id).join(',')")); - assertEquals("id4,id2,id5,id7,id8,id9", page.evalOnSelectorAll("div >> right-of=\"#id3\"", "els => els.map(e => e.id).join(',')")); - assertEquals("4,2,5,7,8,9", page.locator("div", - new Page.LocatorOptions().setRightOf(page.locator("#id3"))).locator("span") - .evaluateAll("els => els.map(e => e.textContent).join(',')")); +// assertEquals("id4,id2,id5,id7,id8,id9", page.evalOnSelectorAll("div >> right-of=\"#id3\"", "els => els.map(e => e.id).join(',')")); +// assertEquals("4,2,5,7,8,9", page.locator("div", +// new Page.LocatorOptions().setRightOf(page.locator("#id3"))).locator("span") +// .evaluateAll("els => els.map(e => e.textContent).join(',')")); assertEquals("id2,id5,id7,id8", page.evalOnSelectorAll("div:right-of(#id3, 50)", "els => els.map(e => e.id).join(',')")); - assertEquals("id2,id5,id7,id8", page.evalOnSelectorAll("div >> right-of=\"#id3\",50", "els => els.map(e => e.id).join(',')")); - assertEquals("2,5,7,8", page.evalOnSelectorAll("div >> right-of=\"#id3\",50 >> span", "els => els.map(e => e.textContent).join(',')")); +// assertEquals("id2,id5,id7,id8", page.evalOnSelectorAll("div >> right-of=\"#id3\",50", "els => els.map(e => e.id).join(',')")); +// assertEquals("2,5,7,8", page.evalOnSelectorAll("div >> right-of=\"#id3\",50 >> span", "els => els.map(e => e.textContent).join(',')")); // assertEquals("4,2,5,7,8,9", page.locator("div", new Page.LocatorOptions().setRightOf(page.locator("#id3"))) // .locator("span").evaluateAll("els => els.map(e => e.textContent).join(',')")); assertEquals("id7,id8", page.evalOnSelectorAll("div:right-of(#id3, 49)", "els => els.map(e => e.id).join(',')")); - assertEquals("id7,id8", page.evalOnSelectorAll("div >> right-of=\"#id3\",49", "els => els.map(e => e.id).join(',')")); - assertEquals("7,8", page.evalOnSelectorAll("div >> right-of=\"#id3\",49 >> span", "els => els.map(e => e.textContent).join(',')")); - assertEquals("4,2,5,7,8,9", page.locator("div", new Page.LocatorOptions().setRightOf(page.locator("#id3"))) - .locator("span").evaluateAll("els => els.map(e => e.textContent).join(',')")); +// assertEquals("id7,id8", page.evalOnSelectorAll("div >> right-of=\"#id3\",49", "els => els.map(e => e.id).join(',')")); +// assertEquals("7,8", page.evalOnSelectorAll("div >> right-of=\"#id3\",49 >> span", "els => els.map(e => e.textContent).join(',')")); +// assertEquals("4,2,5,7,8,9", page.locator("div", new Page.LocatorOptions().setRightOf(page.locator("#id3"))) +// .locator("span").evaluateAll("els => els.map(e => e.textContent).join(',')")); assertEquals("id1", page.evalOnSelector("div:left-of(#id2)", "e => e.id")); - assertEquals("id1", page.evalOnSelector("div >> left-of=\"#id2\"", "e => e.id")); - assertEquals("id1", page.locator("div", new Page.LocatorOptions().setLeftOf(page.locator("#id2"))).first().evaluate("e => e.id")); +// assertEquals("id1", page.evalOnSelector("div >> left-of=\"#id2\"", "e => e.id")); +// assertEquals("id1", page.locator("div", new Page.LocatorOptions().setLeftOf(page.locator("#id2"))).first().evaluate("e => e.id")); assertNull(page.querySelector("div:left-of(#id0)")); - assertNull(page.querySelector("div >> left-of=\"#id0\"")); +// assertNull(page.querySelector("div >> left-of=\"#id0\"")); assertEquals("id0", page.evalOnSelector("div:left-of(#id5)", "e => e.id")); - assertEquals("id0", page.evalOnSelector("div >> left-of=\"#id5\"", "e => e.id")); +// assertEquals("id0", page.evalOnSelector("div >> left-of=\"#id5\"", "e => e.id")); assertEquals("id8", page.evalOnSelector("div:left-of(#id9)", "e => e.id")); - assertEquals("id8", page.evalOnSelector("div >> left-of=\"#id9\"", "e => e.id")); +// assertEquals("id8", page.evalOnSelector("div >> left-of=\"#id9\"", "e => e.id")); assertEquals("id3", page.evalOnSelector("div:left-of(#id4)", "e => e.id")); - assertEquals("id3", page.evalOnSelector("div >> left-of=\"#id4\"", "e => e.id")); +// assertEquals("id3", page.evalOnSelector("div >> left-of=\"#id4\"", "e => e.id")); assertEquals("id0,id7,id3,id1,id6,id8", page.evalOnSelectorAll("div:left-of(#id5)", "els => els.map(e => e.id).join(',')")); - assertEquals("id0,id7,id3,id1,id6,id8", page.evalOnSelectorAll("div >> left-of=\"#id5\"", "els => els.map(e => e.id).join(',')")); +// assertEquals("id0,id7,id3,id1,id6,id8", page.evalOnSelectorAll("div >> left-of=\"#id5\"", "els => els.map(e => e.id).join(',')")); assertEquals("id7,id8", page.evalOnSelectorAll("div:left-of(#id5, 3)", "els => els.map(e => e.id).join(',')")); - assertEquals("id7,id8", page.evalOnSelectorAll("div >> left-of=\"#id5\",3", "els => els.map(e => e.id).join(',')")); - assertEquals("7,8", page.evalOnSelectorAll("div >> left-of=\"#id5\",3 >> span", "els => els.map(e => e.textContent).join(',')")); +// assertEquals("id7,id8", page.evalOnSelectorAll("div >> left-of=\"#id5\",3", "els => els.map(e => e.id).join(',')")); +// assertEquals("7,8", page.evalOnSelectorAll("div >> left-of=\"#id5\",3 >> span", "els => els.map(e => e.textContent).join(',')")); assertEquals("id3", page.evalOnSelector("div:above(#id0)", "e => e.id")); - assertEquals("id3", page.evalOnSelector("div >> above=\"#id0\"", "e => e.id")); - assertEquals("id3", page.locator("div", new Page.LocatorOptions().setAbove(page.locator("#id0"))) - .first().evaluate("e => e.id")); +// assertEquals("id3", page.evalOnSelector("div >> above=\"#id0\"", "e => e.id")); +// assertEquals("id3", page.locator("div", new Page.LocatorOptions().setAbove(page.locator("#id0"))) +// .first().evaluate("e => e.id")); assertEquals("id4", page.evalOnSelector("div:above(#id5)", "e => e.id")); - assertEquals("id4", page.evalOnSelector("div >> above=\"#id5\"", "e => e.id")); +// assertEquals("id4", page.evalOnSelector("div >> above=\"#id5\"", "e => e.id")); assertEquals("id5", page.evalOnSelector("div:above(#id7)", "e => e.id")); - assertEquals("id5", page.evalOnSelector("div >> above=\"#id7\"", "e => e.id")); +// assertEquals("id5", page.evalOnSelector("div >> above=\"#id7\"", "e => e.id")); assertEquals("id0", page.evalOnSelector("div:above(#id8)", "e => e.id")); - assertEquals("id0", page.evalOnSelector("div >> above=\"#id8\"", "e => e.id")); +// assertEquals("id0", page.evalOnSelector("div >> above=\"#id8\"", "e => e.id")); assertEquals("id8", page.evalOnSelector("div:above(#id9)", "e => e.id")); - assertEquals("id8", page.evalOnSelector("div >> above=\"#id9\"", "e => e.id")); +// assertEquals("id8", page.evalOnSelector("div >> above=\"#id9\"", "e => e.id")); assertNull(page.querySelector("div:above(#id2)")); - assertNull(page.querySelector("div >> above=\"#id2\"")); +// assertNull(page.querySelector("div >> above=\"#id2\"")); assertEquals("id4,id2,id3,id1", page.evalOnSelectorAll("div:above(#id5)", "els => els.map(e => e.id).join(',')")); - assertEquals("id4,id2,id3,id1", page.evalOnSelectorAll("div >> above=\"#id5\"", "els => els.map(e => e.id).join(',')")); +// assertEquals("id4,id2,id3,id1", page.evalOnSelectorAll("div >> above=\"#id5\"", "els => els.map(e => e.id).join(',')")); assertEquals("id4,id3", page.evalOnSelectorAll("div:above(#id5, 20)", "els => els.map(e => e.id).join(',')")); - assertEquals("id4,id3", page.evalOnSelectorAll("div >> above=\"#id5\",20", "els => els.map(e => e.id).join(',')")); +// assertEquals("id4,id3", page.evalOnSelectorAll("div >> above=\"#id5\",20", "els => els.map(e => e.id).join(',')")); assertEquals("id5", page.evalOnSelector("div:below(#id4)", "e => e.id")); - assertEquals("id5", page.evalOnSelector("div >> below=\"#id4\"", "e => e.id")); - assertEquals("id5", page.locator("div", new Page.LocatorOptions().setBelow(page.locator("#id4"))) - .first().evaluate("e => e.id")); +// assertEquals("id5", page.evalOnSelector("div >> below=\"#id4\"", "e => e.id")); +// assertEquals("id5", page.locator("div", new Page.LocatorOptions().setBelow(page.locator("#id4"))) +// .first().evaluate("e => e.id")); assertEquals("id0", page.evalOnSelector("div:below(#id3)", "e => e.id")); - assertEquals("id0", page.evalOnSelector("div >> below=\"#id3\"", "e => e.id")); +// assertEquals("id0", page.evalOnSelector("div >> below=\"#id3\"", "e => e.id")); assertEquals("id4", page.evalOnSelector("div:below(#id2)", "e => e.id")); - assertEquals("id4", page.evalOnSelector("div >> below=\"#id2\"", "e => e.id")); +// assertEquals("id4", page.evalOnSelector("div >> below=\"#id2\"", "e => e.id")); assertEquals("id8", page.evalOnSelector("div:below(#id6)", "e => e.id")); - assertEquals("id8", page.evalOnSelector("div >> below=\"#id6\"", "e => e.id")); +// assertEquals("id8", page.evalOnSelector("div >> below=\"#id6\"", "e => e.id")); assertEquals("id8", page.evalOnSelector("div:below(#id7)", "e => e.id")); - assertEquals("id8", page.evalOnSelector("div >> below=\"#id7\"", "e => e.id")); +// assertEquals("id8", page.evalOnSelector("div >> below=\"#id7\"", "e => e.id")); assertEquals("id9", page.evalOnSelector("div:below(#id8)", "e => e.id")); - assertEquals("id9", page.evalOnSelector("div >> below=\"#id8\"", "e => e.id")); +// assertEquals("id9", page.evalOnSelector("div >> below=\"#id8\"", "e => e.id")); assertNull(page.querySelector("div:below(#id9)")); - assertNull(page.querySelector("div >> below=\"#id9\"")); +// assertNull(page.querySelector("div >> below=\"#id9\"")); assertEquals("id0,id5,id6,id7,id8,id9", page.evalOnSelectorAll("div:below(#id3)", "els => els.map(e => e.id).join(',')")); - assertEquals("id0,id5,id6,id7,id8,id9", page.evalOnSelectorAll("div >> below=\"#id3\"", "els => els.map(e => e.id).join(',')")); +// assertEquals("id0,id5,id6,id7,id8,id9", page.evalOnSelectorAll("div >> below=\"#id3\"", "els => els.map(e => e.id).join(',')")); assertEquals("id0,id5,id6,id7", page.evalOnSelectorAll("div:below(#id3, 105)", "els => els.map(e => e.id).join(',')")); - assertEquals("id0,id5,id6,id7", page.evalOnSelectorAll("div >> below=\"#id3\" , 105", "els => els.map(e => e.id).join(',')")); +// assertEquals("id0,id5,id6,id7", page.evalOnSelectorAll("div >> below=\"#id3\" , 105", "els => els.map(e => e.id).join(',')")); assertEquals("id3", page.evalOnSelector("div:near(#id0)", "e => e.id")); - assertEquals("id3", page.evalOnSelector("div >> near=\"#id0\"", "e => e.id")); - assertEquals("id3", page.locator("div", new Page.LocatorOptions().setNear(page.locator("#id0"))) - .first().evaluate("e => e.id")); +// assertEquals("id3", page.evalOnSelector("div >> near=\"#id0\"", "e => e.id")); +// assertEquals("id3", page.locator("div", new Page.LocatorOptions().setNear(page.locator("#id0"))) +// .first().evaluate("e => e.id")); assertEquals("id0,id5,id3,id6", page.evalOnSelectorAll("div:near(#id7)", "els => els.map(e => e.id).join(',')")); - assertEquals("id0,id5,id3,id6", page.evalOnSelectorAll("div >> near=\"#id7\"", "els => els.map(e => e.id).join(',')")); +// assertEquals("id0,id5,id3,id6", page.evalOnSelectorAll("div >> near=\"#id7\"", "els => els.map(e => e.id).join(',')")); assertEquals("id3,id6,id7,id8,id1,id5", page.evalOnSelectorAll("div:near(#id0)", "els => els.map(e => e.id).join(',')")); - assertEquals("id3,id6,id7,id8,id1,id5", page.evalOnSelectorAll("div >> near=\"#id0\"", "els => els.map(e => e.id).join(',')")); +// assertEquals("id3,id6,id7,id8,id1,id5", page.evalOnSelectorAll("div >> near=\"#id0\"", "els => els.map(e => e.id).join(',')")); assertEquals("id0,id3,id7", page.evalOnSelectorAll("div:near(#id6)", "els => els.map(e => e.id).join(',')")); - assertEquals("id0,id3,id7", page.evalOnSelectorAll("div >> near=\"#id6\"", "els => els.map(e => e.id).join(',')")); +// assertEquals("id0,id3,id7", page.evalOnSelectorAll("div >> near=\"#id6\"", "els => els.map(e => e.id).join(',')")); assertEquals("id0", page.evalOnSelectorAll("div:near(#id6, 10)", "els => els.map(e => e.id).join(',')")); - assertEquals("id0", page.evalOnSelectorAll("div >> near=\"#id6\",10", "els => els.map(e => e.id).join(',')")); +// assertEquals("id0", page.evalOnSelectorAll("div >> near=\"#id6\",10", "els => els.map(e => e.id).join(',')")); assertEquals("id3,id6,id7,id8,id1,id5,id4,id2", page.evalOnSelectorAll("div:near(#id0, 100)", "els => els.map(e => e.id).join(',')")); - assertEquals("id3,id6,id7,id8,id1,id5,id4,id2", page.evalOnSelectorAll("div >> near=\"#id0\",100", "els => els.map(e => e.id).join(',')")); +// assertEquals("id3,id6,id7,id8,id1,id5,id4,id2", page.evalOnSelectorAll("div >> near=\"#id0\",100", "els => els.map(e => e.id).join(',')")); assertEquals("id7,id6", page.evalOnSelectorAll("div:below(#id5):above(#id8)", "els => els.map(e => e.id).join(',')")); - assertEquals("id7,id6", page.evalOnSelectorAll("div >> below=\"#id5\" >> above=\"#id8\"", "els => els.map(e => e.id).join(',')")); +// assertEquals("id7,id6", page.evalOnSelectorAll("div >> below=\"#id5\" >> above=\"#id8\"", "els => els.map(e => e.id).join(',')")); assertEquals("id7", page.evalOnSelector("div:below(#id5):above(#id8)", "e => e.id")); - assertEquals("id7", page.evalOnSelector("div >> below=\"#id5\" >> above=\"#id8\"", "e => e.id")); - assertEquals("id7", page.locator("div", new Page.LocatorOptions() - .setBelow(page.locator("#id5")) - .setAbove(page.locator("#id8"))).first().evaluate("e => e.id")); +// assertEquals("id7", page.evalOnSelector("div >> below=\"#id5\" >> above=\"#id8\"", "e => e.id")); +// assertEquals("id7", page.locator("div", new Page.LocatorOptions() +// .setBelow(page.locator("#id5")) +// .setAbove(page.locator("#id8"))).first().evaluate("e => e.id")); assertEquals("id5,id6,id3", page.evalOnSelectorAll("div:right-of(#id0) + div:above(#id8)", "els => els.map(e => e.id).join(',')")); diff --git a/playwright/src/test/java/com/microsoft/playwright/TestWheel.java b/playwright/src/test/java/com/microsoft/playwright/TestWheel.java index 587a882b..54883502 100644 --- a/playwright/src/test/java/com/microsoft/playwright/TestWheel.java +++ b/playwright/src/test/java/com/microsoft/playwright/TestWheel.java @@ -24,6 +24,24 @@ import static com.microsoft.playwright.Utils.mapOf; import static org.junit.jupiter.api.Assertions.assertEquals; public class TestWheel extends TestBase { + private void expectEvent(Map expected) { + // Chromium reports deltaX/deltaY scaled by host device scale factor. + // https://bugs.chromium.org/p/chromium/issues/detail?id=1324819 + // https://github.com/microsoft/playwright/issues/7362 + // Different bots have different scale factors (usually 1 or 2), so we just ignore the values + // instead of guessing the host scale factor. + // This first appeared in Chromium 102. + boolean ignoreDelta = isChromium() && isMac; + Map received = (Map) page.evaluate("window.lastEvent"); + if (ignoreDelta) { + expected.remove("deltaX"); + expected.remove("deltaY"); + received.remove("deltaX"); + received.remove("deltaY"); + } + assertEquals(expected, received); + } + @Test void shouldDispatchWheelEvents() { page.setContent("
"); @@ -42,7 +60,7 @@ public class TestWheel extends TestBase { "altKey", false, "metaKey", false); page.waitForFunction("window.scrollY === 100"); - assertEquals(expected, page.evaluate("window.lastEvent")); + expectEvent(expected); } @Test @@ -71,7 +89,7 @@ public class TestWheel extends TestBase { "shiftKey", true, "altKey", false, "metaKey", false); - assertEquals(expected, page.evaluate("window.lastEvent")); + expectEvent(expected); } @Test @@ -90,7 +108,7 @@ public class TestWheel extends TestBase { "shiftKey", false, "altKey", false, "metaKey", false); - assertEquals(expected, page.evaluate("window.lastEvent")); + expectEvent(expected); page.waitForFunction("window.scrollX === 100"); } @@ -113,7 +131,7 @@ public class TestWheel extends TestBase { "shiftKey", false, "altKey", false, "metaKey", false); - assertEquals(expected, page.evaluate("window.lastEvent")); + expectEvent(expected); // give the page a chacne to scroll page.waitForTimeout(100); // ensure that it did not. diff --git a/scripts/CLI_VERSION b/scripts/CLI_VERSION index d6cb93dc..92274064 100644 --- a/scripts/CLI_VERSION +++ b/scripts/CLI_VERSION @@ -1 +1 @@ -1.22.0-alpha-1652115973000 +1.22.0-beta-1652379237000