diff --git a/playwright/src/main/java/com/microsoft/playwright/Frame.java b/playwright/src/main/java/com/microsoft/playwright/Frame.java index 006821b3..08180a00 100644 --- a/playwright/src/main/java/com/microsoft/playwright/Frame.java +++ b/playwright/src/main/java/com/microsoft/playwright/Frame.java @@ -142,6 +142,11 @@ public interface Frame { * element. */ public Position position; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -170,6 +175,10 @@ public interface Frame { this.position = position; return this; } + public CheckOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public CheckOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -213,6 +222,11 @@ public interface Frame { * element. */ public Position position; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -257,6 +271,10 @@ public interface Frame { this.position = position; return this; } + public ClickOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public ClickOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -296,6 +314,11 @@ public interface Frame { * element. */ public Position position; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -336,6 +359,10 @@ public interface Frame { this.position = position; return this; } + public DblclickOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public DblclickOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -346,6 +373,11 @@ public interface Frame { } } class DispatchEventOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -353,6 +385,10 @@ public interface Frame { */ public Double timeout; + public DispatchEventOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public DispatchEventOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -370,6 +406,11 @@ public interface Frame { * inaccessible pages. Defaults to {@code false}. */ public Boolean noWaitAfter; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -391,6 +432,10 @@ public interface Frame { this.noWaitAfter = noWaitAfter; return this; } + public DragAndDropOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public DragAndDropOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -400,6 +445,18 @@ public interface Frame { return this; } } + class EvalOnSelectorOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; + + public EvalOnSelectorOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } + } class FillOptions { /** * Whether to bypass the actionability checks. Defaults to @@ -412,6 +469,11 @@ public interface Frame { * inaccessible pages. Defaults to {@code false}. */ public Boolean noWaitAfter; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -427,6 +489,10 @@ public interface Frame { this.noWaitAfter = noWaitAfter; return this; } + public FillOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public FillOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -434,18 +500,10 @@ public interface Frame { } class FocusOptions { /** - * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by - * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout - * Page.setDefaultTimeout()} methods. + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. */ - public Double timeout; - - public FocusOptions setTimeout(double timeout) { - this.timeout = timeout; - return this; - } - } - class GetAttributeOptions { + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -453,6 +511,32 @@ public interface Frame { */ public Double timeout; + public FocusOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } + public FocusOptions setTimeout(double timeout) { + this.timeout = timeout; + return this; + } + } + class GetAttributeOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; + /** + * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by + * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout + * Page.setDefaultTimeout()} methods. + */ + public Double timeout; + + public GetAttributeOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public GetAttributeOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -510,6 +594,11 @@ public interface Frame { * element. */ public Position position; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -538,6 +627,10 @@ public interface Frame { this.position = position; return this; } + public HoverOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public HoverOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -548,6 +641,11 @@ public interface Frame { } } class InnerHTMLOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -555,12 +653,21 @@ public interface Frame { */ public Double timeout; + public InnerHTMLOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public InnerHTMLOptions setTimeout(double timeout) { this.timeout = timeout; return this; } } class InnerTextOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -568,12 +675,21 @@ public interface Frame { */ public Double timeout; + public InnerTextOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public InnerTextOptions setTimeout(double timeout) { this.timeout = timeout; return this; } } class InputValueOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -581,12 +697,21 @@ public interface Frame { */ public Double timeout; + public InputValueOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public InputValueOptions setTimeout(double timeout) { this.timeout = timeout; return this; } } class IsCheckedOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -594,12 +719,21 @@ public interface Frame { */ public Double timeout; + public IsCheckedOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public IsCheckedOptions setTimeout(double timeout) { this.timeout = timeout; return this; } } class IsDisabledOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -607,12 +741,21 @@ public interface Frame { */ public Double timeout; + public IsDisabledOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public IsDisabledOptions setTimeout(double timeout) { this.timeout = timeout; return this; } } class IsEditableOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -620,12 +763,21 @@ public interface Frame { */ public Double timeout; + public IsEditableOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public IsEditableOptions setTimeout(double timeout) { this.timeout = timeout; return this; } } class IsEnabledOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -633,6 +785,10 @@ public interface Frame { */ public Double timeout; + public IsEnabledOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public IsEnabledOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -640,18 +796,10 @@ public interface Frame { } class IsHiddenOptions { /** - * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by - * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout - * Page.setDefaultTimeout()} methods. + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. */ - public Double timeout; - - public IsHiddenOptions setTimeout(double timeout) { - this.timeout = timeout; - return this; - } - } - class IsVisibleOptions { + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -659,6 +807,32 @@ public interface Frame { */ public Double timeout; + public IsHiddenOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } + public IsHiddenOptions setTimeout(double timeout) { + this.timeout = timeout; + return this; + } + } + class IsVisibleOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; + /** + * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by + * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout + * Page.setDefaultTimeout()} methods. + */ + public Double timeout; + + public IsVisibleOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public IsVisibleOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -675,6 +849,11 @@ public interface Frame { * inaccessible pages. Defaults to {@code false}. */ public Boolean noWaitAfter; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -690,11 +869,27 @@ public interface Frame { this.noWaitAfter = noWaitAfter; return this; } + public PressOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public PressOptions setTimeout(double timeout) { this.timeout = timeout; return this; } } + class QuerySelectorOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; + + public QuerySelectorOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } + } class SelectOptionOptions { /** * Whether to bypass the actionability checks. Defaults to @@ -707,6 +902,11 @@ public interface Frame { * inaccessible pages. Defaults to {@code false}. */ public Boolean noWaitAfter; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -722,6 +922,10 @@ public interface Frame { this.noWaitAfter = noWaitAfter; return this; } + public SelectOptionOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public SelectOptionOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -761,6 +965,11 @@ public interface Frame { * inaccessible pages. Defaults to {@code false}. */ public Boolean noWaitAfter; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -772,6 +981,10 @@ public interface Frame { this.noWaitAfter = noWaitAfter; return this; } + public SetInputFilesOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public SetInputFilesOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -799,6 +1012,11 @@ public interface Frame { * element. */ public Position position; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -831,6 +1049,10 @@ public interface Frame { this.position = position; return this; } + public TapOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public TapOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -841,6 +1063,11 @@ public interface Frame { } } class TextContentOptions { + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -848,6 +1075,10 @@ public interface Frame { */ public Double timeout; + public TextContentOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public TextContentOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -864,6 +1095,11 @@ public interface Frame { * inaccessible pages. Defaults to {@code false}. */ public Boolean noWaitAfter; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -879,6 +1115,10 @@ public interface Frame { this.noWaitAfter = noWaitAfter; return this; } + public TypeOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public TypeOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -901,6 +1141,11 @@ public interface Frame { * element. */ public Position position; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -929,6 +1174,10 @@ public interface Frame { this.position = position; return this; } + public UncheckOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public UncheckOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -1029,6 +1278,11 @@ public interface Frame { * */ public WaitForSelectorState state; + /** + * When true, the call requires selector to resolve to a single element. If given selector resolves to more then one + * element, the call throws an exception. + */ + public Boolean strict; /** * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout @@ -1040,6 +1294,10 @@ public interface Frame { this.state = state; return this; } + public WaitForSelectorOptions setStrict(boolean strict) { + this.strict = strict; + return this; + } public WaitForSelectorOptions setTimeout(double timeout) { this.timeout = timeout; return this; @@ -1351,6 +1609,33 @@ public interface Frame { dragAndDrop(source, target, null); } void dragAndDrop(String source, String target, DragAndDropOptions options); + /** + * Returns the return value of {@code expression}. + * + *
The method finds an element matching the specified selector within the frame and passes it as a first argument to + * {@code expression}. See Working with selectors for more details. If + * no elements match the selector, the method throws an error. + * + *
If {@code expression} returns a Promise, then {@link + * Frame#evalOnSelector Frame.evalOnSelector()} would wait for the promise to resolve and return its value. + * + *
Examples: + *
{@code
+ * String searchValue = (String) frame.evalOnSelector("#search", "el => el.value");
+ * String preloadHref = (String) frame.evalOnSelector("link[rel=preload]", "el => el.href");
+ * String html = (String) frame.evalOnSelector(".main-container", "(e, suffix) => e.outerHTML + suffix", "hello");
+ * }
+ *
+ * @param selector A selector to query for. See working with selectors for more
+ * details.
+ * @param expression JavaScript expression to be evaluated in the browser context. If it looks like a function declaration, it is interpreted
+ * as a function. Otherwise, evaluated as an expression.
+ * @param arg Optional argument to pass to {@code expression}.
+ */
+ default Object evalOnSelector(String selector, String expression, Object arg) {
+ return evalOnSelector(selector, expression, arg, null);
+ }
/**
* Returns the return value of {@code expression}.
*
@@ -1401,7 +1686,7 @@ public interface Frame {
* as a function. Otherwise, evaluated as an expression.
* @param arg Optional argument to pass to {@code expression}.
*/
- Object evalOnSelector(String selector, String expression, Object arg);
+ Object evalOnSelector(String selector, String expression, Object arg, EvalOnSelectorOptions options);
/**
* Returns the return value of {@code expression}.
*
@@ -1917,6 +2202,17 @@ public interface Frame {
* working with selectors for more details.
*/
boolean isVisible(String selector, IsVisibleOptions options);
+ /**
+ * The method returns an element locator that can be used to perform actions in the 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 on
+ * different DOM elements. That would happen if the DOM structure between those actions has changed.
+ *
+ * Note that locator always implies visibility, so it will always be locating visible elements. + * + * @param selector A selector to use when resolving DOM element. See working with + * selectors for more details. + */ + Locator locator(String selector); /** * Returns frame's name attribute as specified in the tag. * @@ -1993,7 +2289,20 @@ public interface Frame { * @param selector A selector to query for. See working with selectors for more * details. */ - ElementHandle querySelector(String selector); + default ElementHandle querySelector(String selector) { + return querySelector(selector, null); + } + /** + * Returns the ElementHandle pointing to the frame element. + * + *
The method finds an element matching the specified selector within the frame. See Working with selectors for more details. If no elements match the + * selector, returns {@code null}. + * + * @param selector A selector to query for. See working with selectors for more + * details. + */ + ElementHandle querySelector(String selector, QuerySelectorOptions options); /** * Returns the ElementHandles pointing to the frame elements. * diff --git a/playwright/src/main/java/com/microsoft/playwright/Locator.java b/playwright/src/main/java/com/microsoft/playwright/Locator.java new file mode 100644 index 00000000..7340e434 --- /dev/null +++ b/playwright/src/main/java/com/microsoft/playwright/Locator.java @@ -0,0 +1,2155 @@ +/* + * 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 com.microsoft.playwright.options.*; +import java.nio.file.Path; +import java.util.*; + +/** + * Locator represents a view to the element(s) on the page. It captures the logic sufficient to retrieve the element at any + * given moment. Locator can be created with the {@link Page#locator Page.locator()} method. + * + *
The difference between the Locator and {@code ElementHandle} is that the latter points to a particular element, while Locator + * only captures the logic of how to retrieve an element at any given moment. + * + *
In the example below, handle points to a particular DOM element on page. If that element changes text or is used by + * React to render an entirely different component, handle is still pointing to that very DOM element. + *
{@code
+ * ElementHandle handle = page.querySelector("text=Submit");
+ * handle.hover();
+ * handle.click();
+ * }
+ *
+ * With the locator, every time the {@code element} is used, corresponding DOM element is located in the page using given + * selector. So in the snippet below, underlying DOM element is going to be located twice, using the given selector. + *
{@code
+ * Locator element = page.locator("text=Submit");
+ * element.hover();
+ * element.click();
+ * }
+ */
+public interface Locator {
+ class BoundingBoxOptions {
+ /**
+ * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by
+ * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout
+ * Page.setDefaultTimeout()} methods.
+ */
+ public Double timeout;
+
+ public BoundingBoxOptions setTimeout(double timeout) {
+ this.timeout = timeout;
+ return this;
+ }
+ }
+ class CheckOptions {
+ /**
+ * Whether to bypass the actionability checks. Defaults to
+ * {@code false}.
+ */
+ public Boolean force;
+ /**
+ * Actions that initiate navigations are waiting for these navigations to happen and for pages to start loading. You can
+ * opt out of waiting via setting this flag. You would only need this option in the exceptional cases such as navigating to
+ * inaccessible pages. Defaults to {@code false}.
+ */
+ public Boolean noWaitAfter;
+ /**
+ * A point to use relative to the top-left corner of element padding box. If not specified, uses some visible point of the
+ * element.
+ */
+ public Position position;
+ /**
+ * Maximum time in milliseconds, defaults to 30 seconds, pass {@code 0} to disable timeout. The default value can be changed by
+ * using the {@link BrowserContext#setDefaultTimeout BrowserContext.setDefaultTimeout()} or {@link Page#setDefaultTimeout
+ * Page.setDefaultTimeout()} methods.
+ */
+ public Double timeout;
+ /**
+ * When set, this method only performs the actionability
+ * checks and skips the action. Defaults to {@code false}. Useful to wait until the element is ready for the action without
+ * performing it.
+ */
+ public Boolean trial;
+
+ public CheckOptions setForce(boolean force) {
+ this.force = force;
+ return this;
+ }
+ public CheckOptions setNoWaitAfter(boolean noWaitAfter) {
+ this.noWaitAfter = noWaitAfter;
+ return this;
+ }
+ public CheckOptions setPosition(double x, double y) {
+ return setPosition(new Position(x, y));
+ }
+ public CheckOptions setPosition(Position position) {
+ this.position = position;
+ return this;
+ }
+ public CheckOptions setTimeout(double timeout) {
+ this.timeout = timeout;
+ return this;
+ }
+ public CheckOptions setTrial(boolean trial) {
+ this.trial = trial;
+ return this;
+ }
+ }
+ class ClickOptions {
+ /**
+ * Defaults to {@code left}.
+ */
+ public MouseButton button;
+ /**
+ * defaults to 1. See [UIEvent.detail].
+ */
+ public Integer clickCount;
+ /**
+ * Time to wait between {@code mousedown} and {@code mouseup} in milliseconds. Defaults to 0.
+ */
+ public Double delay;
+ /**
+ * Whether to bypass the actionability checks. Defaults to
+ * {@code false}.
+ */
+ public Boolean force;
+ /**
+ * Modifier keys to press. Ensures that only these modifiers are pressed during the operation, and then restores current
+ * modifiers back. If not specified, currently pressed modifiers are used.
+ */
+ public ListScrolling affects the returned bonding box, similarly to Element.getBoundingClientRect. + * That means {@code x} and/or {@code y} may be negative. + * + *
Elements from child frames return the bounding box relative to the main frame, unlike the Element.getBoundingClientRect. + * + *
Assuming the page is static, it is safe to use bounding box coordinates to perform input. For example, the following + * snippet should click the center of the element. + *
{@code
+ * BoundingBox box = element.boundingBox();
+ * page.mouse().click(box.x + box.width / 2, box.y + box.height / 2);
+ * }
+ */
+ default BoundingBox boundingBox() {
+ return boundingBox(null);
+ }
+ /**
+ * This method returns the bounding box of the element, or {@code null} if the element is not visible. The bounding box is
+ * calculated relative to the main frame viewport - which is usually the same as the browser window.
+ *
+ * Scrolling affects the returned bonding box, similarly to Element.getBoundingClientRect. + * That means {@code x} and/or {@code y} may be negative. + * + *
Elements from child frames return the bounding box relative to the main frame, unlike the Element.getBoundingClientRect. + * + *
Assuming the page is static, it is safe to use bounding box coordinates to perform input. For example, the following + * snippet should click the center of the element. + *
{@code
+ * BoundingBox box = element.boundingBox();
+ * page.mouse().click(box.x + box.width / 2, box.y + box.height / 2);
+ * }
+ */
+ BoundingBox boundingBox(BoundingBoxOptions options);
+ /**
+ * This method checks the element by performing the following steps:
+ * If the element is detached from the DOM at any moment during the action, this method throws. + * + *
When all steps combined have not finished during the specified {@code timeout}, this method throws a {@code TimeoutError}. Passing + * zero timeout disables this. + */ + default void check() { + check(null); + } + /** + * This method checks the element by performing the following steps: + *
If the element is detached from the DOM at any moment during the action, this method throws. + * + *
When all steps combined have not finished during the specified {@code timeout}, this method throws a {@code TimeoutError}. Passing + * zero timeout disables this. + */ + void check(CheckOptions options); + /** + * This method clicks the element by performing the following steps: + *
If the element is detached from the DOM at any moment during the action, this method throws. + * + *
When all steps combined have not finished during the specified {@code timeout}, this method throws a {@code TimeoutError}. Passing + * zero timeout disables this. + */ + default void click() { + click(null); + } + /** + * This method clicks the element by performing the following steps: + *
If the element is detached from the DOM at any moment during the action, this method throws. + * + *
When all steps combined have not finished during the specified {@code timeout}, this method throws a {@code TimeoutError}. Passing + * zero timeout disables this. + */ + void click(ClickOptions options); + /** + * Returns the number of elements matching given selector. + */ + int count(); + /** + * This method double clicks the element by performing the following steps: + *
If the element is detached from the DOM at any moment during the action, this method throws. + * + *
When all steps combined have not finished during the specified {@code timeout}, this method throws a {@code TimeoutError}. Passing + * zero timeout disables this. + * + *
NOTE: {@code element.dblclick()} dispatches two {@code click} events and a single {@code dblclick} event. + */ + default void dblclick() { + dblclick(null); + } + /** + * This method double clicks the element by performing the following steps: + *
If the element is detached from the DOM at any moment during the action, this method throws. + * + *
When all steps combined have not finished during the specified {@code timeout}, this method throws a {@code TimeoutError}. Passing + * zero timeout disables this. + * + *
NOTE: {@code element.dblclick()} dispatches two {@code click} events and a single {@code dblclick} event. + */ + void dblclick(DblclickOptions options); + /** + * The snippet below dispatches the {@code click} event on the element. Regardless of the visibility state of the element, + * {@code click} is dispatched. This is equivalent to calling element.click(). + *
{@code
+ * element.dispatchEvent("click");
+ * }
+ *
+ * Under the hood, it creates an instance of an event based on the given {@code type}, initializes it with {@code eventInit} properties + * and dispatches it on the element. Events are {@code composed}, {@code cancelable} and bubble by default. + * + *
Since {@code eventInit} is event-specific, please refer to the events documentation for the lists of initial properties: + *
You can also specify {@code JSHandle} as the property value if you want live objects to be passed into the event: + *
{@code
+ * // Note you can only create DataTransfer in Chromium and Firefox
+ * JSHandle dataTransfer = page.evaluateHandle("() => new DataTransfer()");
+ * Map arg = new HashMap<>();
+ * arg.put("dataTransfer", dataTransfer);
+ * element.dispatchEvent("dragstart", arg);
+ * }
+ *
+ * @param type DOM event type: {@code "click"}, {@code "dragstart"}, etc.
+ * @param eventInit Optional event-specific initialization properties.
+ */
+ default void dispatchEvent(String type, Object eventInit) {
+ dispatchEvent(type, eventInit, null);
+ }
+ /**
+ * The snippet below dispatches the {@code click} event on the element. Regardless of the visibility state of the element,
+ * {@code click} is dispatched. This is equivalent to calling element.click().
+ * {@code
+ * element.dispatchEvent("click");
+ * }
+ *
+ * Under the hood, it creates an instance of an event based on the given {@code type}, initializes it with {@code eventInit} properties + * and dispatches it on the element. Events are {@code composed}, {@code cancelable} and bubble by default. + * + *
Since {@code eventInit} is event-specific, please refer to the events documentation for the lists of initial properties: + *
You can also specify {@code JSHandle} as the property value if you want live objects to be passed into the event: + *
{@code
+ * // Note you can only create DataTransfer in Chromium and Firefox
+ * JSHandle dataTransfer = page.evaluateHandle("() => new DataTransfer()");
+ * Map arg = new HashMap<>();
+ * arg.put("dataTransfer", dataTransfer);
+ * element.dispatchEvent("dragstart", arg);
+ * }
+ *
+ * @param type DOM event type: {@code "click"}, {@code "dragstart"}, etc.
+ */
+ default void dispatchEvent(String type) {
+ dispatchEvent(type, null);
+ }
+ /**
+ * The snippet below dispatches the {@code click} event on the element. Regardless of the visibility state of the element,
+ * {@code click} is dispatched. This is equivalent to calling element.click().
+ * {@code
+ * element.dispatchEvent("click");
+ * }
+ *
+ * Under the hood, it creates an instance of an event based on the given {@code type}, initializes it with {@code eventInit} properties + * and dispatches it on the element. Events are {@code composed}, {@code cancelable} and bubble by default. + * + *
Since {@code eventInit} is event-specific, please refer to the events documentation for the lists of initial properties: + *
You can also specify {@code JSHandle} as the property value if you want live objects to be passed into the event: + *
{@code
+ * // Note you can only create DataTransfer in Chromium and Firefox
+ * JSHandle dataTransfer = page.evaluateHandle("() => new DataTransfer()");
+ * Map arg = new HashMap<>();
+ * arg.put("dataTransfer", dataTransfer);
+ * element.dispatchEvent("dragstart", arg);
+ * }
+ *
+ * @param type DOM event type: {@code "click"}, {@code "dragstart"}, etc.
+ * @param eventInit Optional event-specific initialization properties.
+ */
+ void dispatchEvent(String type, Object eventInit, DispatchEventOptions options);
+ /**
+ * Resolves given locator to the first matching DOM element. If no elements matching the query are visible, waits for them
+ * up to a given timeout. If multiple elements match the selector, throws.
+ */
+ default ElementHandle elementHandle() {
+ return elementHandle(null);
+ }
+ /**
+ * Resolves given locator to the first matching DOM element. If no elements matching the query are visible, waits for them
+ * up to a given timeout. If multiple elements match the selector, throws.
+ */
+ ElementHandle elementHandle(ElementHandleOptions options);
+ /**
+ * Resolves given locator to all matching DOM elements.
+ */
+ ListThis method passes this handle as the first argument to {@code expression}. + * + *
If {@code expression} returns a Promise, then + * {@code handle.evaluate} would wait for the promise to resolve and return its value. + * + *
Examples: + *
{@code
+ * Locator tweets = page.locator(".tweet .retweets");
+ * assertEquals("10 retweets", tweets.evaluate("node => node.innerText"));
+ * }
+ *
+ * @param expression JavaScript expression to be evaluated in the browser context. If it looks like a function declaration, it is interpreted
+ * as a function. Otherwise, evaluated as an expression.
+ * @param arg Optional argument to pass to {@code expression}.
+ */
+ default Object evaluate(String expression, Object arg) {
+ return evaluate(expression, arg, null);
+ }
+ /**
+ * Returns the return value of {@code expression}.
+ *
+ * This method passes this handle as the first argument to {@code expression}. + * + *
If {@code expression} returns a Promise, then + * {@code handle.evaluate} would wait for the promise to resolve and return its value. + * + *
Examples: + *
{@code
+ * Locator tweets = page.locator(".tweet .retweets");
+ * assertEquals("10 retweets", tweets.evaluate("node => node.innerText"));
+ * }
+ *
+ * @param expression JavaScript expression to be evaluated in the browser context. If it looks like a function declaration, it is interpreted
+ * as a function. Otherwise, evaluated as an expression.
+ */
+ default Object evaluate(String expression) {
+ return evaluate(expression, null);
+ }
+ /**
+ * Returns the return value of {@code expression}.
+ *
+ * This method passes this handle as the first argument to {@code expression}. + * + *
If {@code expression} returns a Promise, then + * {@code handle.evaluate} would wait for the promise to resolve and return its value. + * + *
Examples: + *
{@code
+ * Locator tweets = page.locator(".tweet .retweets");
+ * assertEquals("10 retweets", tweets.evaluate("node => node.innerText"));
+ * }
+ *
+ * @param expression JavaScript expression to be evaluated in the browser context. If it looks like a function declaration, it is interpreted
+ * as a function. Otherwise, evaluated as an expression.
+ * @param arg Optional argument to pass to {@code expression}.
+ */
+ Object evaluate(String expression, Object arg, EvaluateOptions options);
+ /**
+ * The method finds all elements matching the specified locator and passes an array of matched elements as a first argument
+ * to {@code expression}. Returns the result of {@code expression} invocation.
+ *
+ * If {@code expression} returns a Promise, then + * [{@code Locator.evaluateAll}] would wait for the promise to resolve and return its value. + * + *
Examples: + *
{@code
+ * Locator elements = page.locator("div");
+ * boolean divCounts = (boolean) elements.evaluateAll("(divs, min) => divs.length >= min", 10);
+ * }
+ *
+ * @param expression JavaScript expression to be evaluated in the browser context. If it looks like a function declaration, it is interpreted
+ * as a function. Otherwise, evaluated as an expression.
+ */
+ default Object evaluateAll(String expression) {
+ return evaluateAll(expression, null);
+ }
+ /**
+ * The method finds all elements matching the specified locator and passes an array of matched elements as a first argument
+ * to {@code expression}. Returns the result of {@code expression} invocation.
+ *
+ * If {@code expression} returns a Promise, then + * [{@code Locator.evaluateAll}] would wait for the promise to resolve and return its value. + * + *
Examples: + *
{@code
+ * Locator elements = page.locator("div");
+ * boolean divCounts = (boolean) elements.evaluateAll("(divs, min) => divs.length >= min", 10);
+ * }
+ *
+ * @param expression JavaScript expression to be evaluated in the browser context. If it looks like a function declaration, it is interpreted
+ * as a function. Otherwise, evaluated as an expression.
+ * @param arg Optional argument to pass to {@code expression}.
+ */
+ Object evaluateAll(String expression, Object arg);
+ /**
+ * Returns the return value of {@code expression} as a {@code JSHandle}.
+ *
+ * This method passes this handle as the first argument to {@code expression}. + * + *
The only difference between {@link Locator#evaluate Locator.evaluate()} and {@link Locator#evaluateHandle + * Locator.evaluateHandle()} is that {@link Locator#evaluateHandle Locator.evaluateHandle()} returns {@code JSHandle}. + * + *
If the function passed to the {@link Locator#evaluateHandle Locator.evaluateHandle()} returns a Promise, then {@link + * Locator#evaluateHandle Locator.evaluateHandle()} would wait for the promise to resolve and return its value. + * + *
See {@link Page#evaluateHandle Page.evaluateHandle()} for more details. + * + * @param expression JavaScript expression to be evaluated in the browser context. If it looks like a function declaration, it is interpreted + * as a function. Otherwise, evaluated as an expression. + * @param arg Optional argument to pass to {@code expression}. + */ + default JSHandle evaluateHandle(String expression, Object arg) { + return evaluateHandle(expression, arg, null); + } + /** + * Returns the return value of {@code expression} as a {@code JSHandle}. + * + *
This method passes this handle as the first argument to {@code expression}. + * + *
The only difference between {@link Locator#evaluate Locator.evaluate()} and {@link Locator#evaluateHandle + * Locator.evaluateHandle()} is that {@link Locator#evaluateHandle Locator.evaluateHandle()} returns {@code JSHandle}. + * + *
If the function passed to the {@link Locator#evaluateHandle Locator.evaluateHandle()} returns a Promise, then {@link + * Locator#evaluateHandle Locator.evaluateHandle()} would wait for the promise to resolve and return its value. + * + *
See {@link Page#evaluateHandle Page.evaluateHandle()} for more details. + * + * @param expression JavaScript expression to be evaluated in the browser context. If it looks like a function declaration, it is interpreted + * as a function. Otherwise, evaluated as an expression. + */ + default JSHandle evaluateHandle(String expression) { + return evaluateHandle(expression, null); + } + /** + * Returns the return value of {@code expression} as a {@code JSHandle}. + * + *
This method passes this handle as the first argument to {@code expression}. + * + *
The only difference between {@link Locator#evaluate Locator.evaluate()} and {@link Locator#evaluateHandle + * Locator.evaluateHandle()} is that {@link Locator#evaluateHandle Locator.evaluateHandle()} returns {@code JSHandle}. + * + *
If the function passed to the {@link Locator#evaluateHandle Locator.evaluateHandle()} returns a Promise, then {@link + * Locator#evaluateHandle Locator.evaluateHandle()} would wait for the promise to resolve and return its value. + * + *
See {@link Page#evaluateHandle Page.evaluateHandle()} for more details. + * + * @param expression JavaScript expression to be evaluated in the browser context. If it looks like a function declaration, it is interpreted + * as a function. Otherwise, evaluated as an expression. + * @param arg Optional argument to pass to {@code expression}. + */ + JSHandle evaluateHandle(String expression, Object arg, EvaluateHandleOptions options); + /** + * This method waits for actionability checks, focuses the + * element, fills it and triggers an {@code input} event after filling. Note that you can pass an empty string to clear the input + * field. + * + *
If the target element is not an {@code }, {@code