Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 6b385a17b1 |
@@ -1,10 +1,6 @@
|
||||
trigger: none
|
||||
pr: none
|
||||
|
||||
trigger:
|
||||
tags:
|
||||
include:
|
||||
- '*'
|
||||
|
||||
resources:
|
||||
repositories:
|
||||
- repository: 1esPipelines
|
||||
@@ -37,8 +33,8 @@ extends:
|
||||
artifact: esrp-build
|
||||
steps:
|
||||
- bash: |
|
||||
if [[ ! "$CURRENT_BRANCH" =~ ^v1\..* ]]; then
|
||||
echo "Can only publish from a release tag branch (v1.*)."
|
||||
if [[ ! "$CURRENT_BRANCH" =~ ^release-.* ]]; then
|
||||
echo "Can only publish from a release branch."
|
||||
echo "Unexpected branch name: $CURRENT_BRANCH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
@@ -20,19 +20,16 @@ jobs:
|
||||
test:
|
||||
name: Test
|
||||
timeout-minutes: 120
|
||||
runs-on: ${{ matrix.runs-on }}
|
||||
runs-on: ubuntu-22.04
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
flavor: [jammy, noble]
|
||||
runs-on: [ubuntu-24.04, ubuntu-24.04-arm]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Build Docker image
|
||||
run: |
|
||||
ARCH="${{ matrix.runs-on == 'ubuntu-24.04-arm' && 'arm64' || 'amd64' }}"
|
||||
bash utils/docker/build.sh --$ARCH ${{ matrix.flavor }} playwright-java:localbuild-${{ matrix.flavor }}
|
||||
run: bash utils/docker/build.sh --amd64 ${{ matrix.flavor }} playwright-java:localbuild-${{ matrix.flavor }}
|
||||
- name: Test
|
||||
run: |
|
||||
CONTAINER_ID="$(docker run --rm -e CI --ipc=host -v $(pwd):/root/playwright --name playwright-docker-test -d -t playwright-java:localbuild-${{ matrix.flavor }} /bin/bash)"
|
||||
CONTAINER_ID="$(docker run --rm --ipc=host -v $(pwd):/root/playwright --name playwright-docker-test -d -t playwright-java:localbuild-${{ matrix.flavor }} /bin/bash)"
|
||||
docker exec "${CONTAINER_ID}" /root/playwright/tools/test-local-installation/create_project_and_run_tests.sh
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
name: "Internal Tests"
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- release-*
|
||||
|
||||
jobs:
|
||||
trigger:
|
||||
name: "trigger"
|
||||
runs-on: ubuntu-24.04
|
||||
steps:
|
||||
- uses: actions/create-github-app-token@v1
|
||||
id: app-token
|
||||
with:
|
||||
app-id: ${{ vars.PLAYWRIGHT_APP_ID }}
|
||||
private-key: ${{ secrets.PLAYWRIGHT_PRIVATE_KEY }}
|
||||
repositories: playwright-browsers
|
||||
- run: |
|
||||
curl -X POST --fail \
|
||||
-H "Accept: application/vnd.github.v3+json" \
|
||||
-H "Authorization: token ${GH_TOKEN}" \
|
||||
--data "{\"event_type\": \"playwright_tests_java\", \"client_payload\": {\"ref\": \"${GITHUB_SHA}\"}}" \
|
||||
https://api.github.com/repos/microsoft/playwright-browsers/dispatches
|
||||
env:
|
||||
GH_TOKEN: ${{ steps.app-token.outputs.token }}
|
||||
@@ -1,3 +0,0 @@
|
||||
path_classifiers:
|
||||
tests:
|
||||
- "playwright/src/test/**"
|
||||
@@ -10,9 +10,9 @@ Playwright is a Java library to automate [Chromium](https://www.chromium.org/Hom
|
||||
|
||||
| | Linux | macOS | Windows |
|
||||
| :--- | :---: | :---: | :---: |
|
||||
| Chromium <!-- GEN:chromium-version -->139.0.7258.5<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| WebKit <!-- GEN:webkit-version -->26.0<!-- GEN:stop --> | ✅ | ✅ | ✅ |
|
||||
| Firefox <!-- GEN:firefox-version -->140.0.2<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Chromium <!-- GEN:chromium-version -->136.0.7103.25<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| WebKit <!-- GEN:webkit-version -->18.4<!-- GEN:stop --> | ✅ | ✅ | ✅ |
|
||||
| Firefox <!-- GEN:firefox-version -->137.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
|
||||
## Documentation
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.microsoft.playwright</groupId>
|
||||
<artifactId>parent-pom</artifactId>
|
||||
<version>1.54.0</version>
|
||||
<version>1.52.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>driver-bundle</artifactId>
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.microsoft.playwright</groupId>
|
||||
<artifactId>parent-pom</artifactId>
|
||||
<version>1.54.0</version>
|
||||
<version>1.52.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>driver</artifactId>
|
||||
|
||||
+2
-2
@@ -6,11 +6,11 @@
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>examples</artifactId>
|
||||
<version>1.54.0</version>
|
||||
<version>1.52.0</version>
|
||||
<name>Playwright Client Examples</name>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<playwright.version>1.54.0</playwright.version>
|
||||
<playwright.version>1.51.0</playwright.version>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.microsoft.playwright</groupId>
|
||||
<artifactId>parent-pom</artifactId>
|
||||
<version>1.54.0</version>
|
||||
<version>1.52.0</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>playwright</artifactId>
|
||||
|
||||
@@ -596,8 +596,7 @@ public interface BrowserContext extends AutoCloseable {
|
||||
*/
|
||||
List<Page> backgroundPages();
|
||||
/**
|
||||
* Gets the browser instance that owns the context. Returns {@code null} if the context is created outside of normal
|
||||
* browser, e.g. Android or Electron.
|
||||
* Returns the browser instance of the context. If it was launched as a persistent context null gets returned.
|
||||
*
|
||||
* @since v1.8
|
||||
*/
|
||||
@@ -872,7 +871,6 @@ public interface BrowserContext extends AutoCloseable {
|
||||
* <li> {@code "notifications"}</li>
|
||||
* <li> {@code "payment-handler"}</li>
|
||||
* <li> {@code "storage-access"}</li>
|
||||
* <li> {@code "local-fonts"}</li>
|
||||
* </ul>
|
||||
* @since v1.8
|
||||
*/
|
||||
@@ -905,7 +903,6 @@ public interface BrowserContext extends AutoCloseable {
|
||||
* <li> {@code "notifications"}</li>
|
||||
* <li> {@code "payment-handler"}</li>
|
||||
* <li> {@code "storage-access"}</li>
|
||||
* <li> {@code "local-fonts"}</li>
|
||||
* </ul>
|
||||
* @since v1.8
|
||||
*/
|
||||
|
||||
@@ -209,9 +209,6 @@ public interface BrowserType {
|
||||
/**
|
||||
* Firefox user preferences. Learn more about the Firefox user preferences at <a
|
||||
* href="https://support.mozilla.org/en-US/kb/about-config-editor-firefox">{@code about:config}</a>.
|
||||
*
|
||||
* <p> You can also provide a path to a custom <a href="https://mozilla.github.io/policy-templates/">{@code policies.json}
|
||||
* file</a> via {@code PLAYWRIGHT_FIREFOX_POLICIES_JSON} environment variable.
|
||||
*/
|
||||
public Map<String, Object> firefoxUserPrefs;
|
||||
/**
|
||||
@@ -342,9 +339,6 @@ public interface BrowserType {
|
||||
/**
|
||||
* Firefox user preferences. Learn more about the Firefox user preferences at <a
|
||||
* href="https://support.mozilla.org/en-US/kb/about-config-editor-firefox">{@code about:config}</a>.
|
||||
*
|
||||
* <p> You can also provide a path to a custom <a href="https://mozilla.github.io/policy-templates/">{@code policies.json}
|
||||
* file</a> via {@code PLAYWRIGHT_FIREFOX_POLICIES_JSON} environment variable.
|
||||
*/
|
||||
public LaunchOptions setFirefoxUserPrefs(Map<String, Object> firefoxUserPrefs) {
|
||||
this.firefoxUserPrefs = firefoxUserPrefs;
|
||||
@@ -541,9 +535,6 @@ public interface BrowserType {
|
||||
/**
|
||||
* Firefox user preferences. Learn more about the Firefox user preferences at <a
|
||||
* href="https://support.mozilla.org/en-US/kb/about-config-editor-firefox">{@code about:config}</a>.
|
||||
*
|
||||
* <p> You can also provide a path to a custom <a href="https://mozilla.github.io/policy-templates/">{@code policies.json}
|
||||
* file</a> via {@code PLAYWRIGHT_FIREFOX_POLICIES_JSON} environment variable.
|
||||
*/
|
||||
public Map<String, Object> firefoxUserPrefs;
|
||||
/**
|
||||
@@ -890,9 +881,6 @@ public interface BrowserType {
|
||||
/**
|
||||
* Firefox user preferences. Learn more about the Firefox user preferences at <a
|
||||
* href="https://support.mozilla.org/en-US/kb/about-config-editor-firefox">{@code about:config}</a>.
|
||||
*
|
||||
* <p> You can also provide a path to a custom <a href="https://mozilla.github.io/policy-templates/">{@code policies.json}
|
||||
* file</a> via {@code PLAYWRIGHT_FIREFOX_POLICIES_JSON} environment variable.
|
||||
*/
|
||||
public LaunchPersistentContextOptions setFirefoxUserPrefs(Map<String, Object> firefoxUserPrefs) {
|
||||
this.firefoxUserPrefs = firefoxUserPrefs;
|
||||
|
||||
@@ -30,6 +30,11 @@ import java.util.regex.Pattern;
|
||||
*/
|
||||
public interface Locator {
|
||||
class AriaSnapshotOptions {
|
||||
/**
|
||||
* Generate symbolic reference for each element. One can use {@code aria-ref=<ref>} locator immediately after capturing the
|
||||
* snapshot to perform actions on the element.
|
||||
*/
|
||||
public Boolean ref;
|
||||
/**
|
||||
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
|
||||
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
|
||||
@@ -38,6 +43,14 @@ public interface Locator {
|
||||
*/
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* Generate symbolic reference for each element. One can use {@code aria-ref=<ref>} locator immediately after capturing the
|
||||
* snapshot to perform actions on the element.
|
||||
*/
|
||||
public AriaSnapshotOptions setRef(boolean ref) {
|
||||
this.ref = ref;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Maximum time in milliseconds. Defaults to {@code 30000} (30 seconds). Pass {@code 0} to disable timeout. The default
|
||||
* value can be changed by using the {@link com.microsoft.playwright.BrowserContext#setDefaultTimeout
|
||||
@@ -2602,20 +2615,6 @@ public interface Locator {
|
||||
* @since v1.14
|
||||
*/
|
||||
void dblclick(DblclickOptions options);
|
||||
/**
|
||||
* Describes the locator, description is used in the trace viewer and reports. Returns the locator pointing to the same
|
||||
* element.
|
||||
*
|
||||
* <p> <strong>Usage</strong>
|
||||
* <pre>{@code
|
||||
* Locator button = page.getByTestId("btn-sub").describe("Subscribe button");
|
||||
* button.click();
|
||||
* }</pre>
|
||||
*
|
||||
* @param description Locator description.
|
||||
* @since v1.53
|
||||
*/
|
||||
Locator describe(String description);
|
||||
/**
|
||||
* Programmatically dispatch an event on the matching element.
|
||||
*
|
||||
@@ -2862,14 +2861,6 @@ public interface Locator {
|
||||
*
|
||||
* <p> <strong>Usage</strong>
|
||||
*
|
||||
* <p> Passing argument to {@code expression}:
|
||||
* <pre>{@code
|
||||
* Object result = page.getByTestId("myId").evaluate("(element, [x, y]) => {\n" +
|
||||
* " return element.textContent + ' ' + x * y;\n" +
|
||||
* "}", Arrays.asList(7, 8));
|
||||
* System.out.println(result); // prints "myId text 56"
|
||||
* }</pre>
|
||||
*
|
||||
* @param expression JavaScript expression to be evaluated in the browser context. If the expression evaluates to a function, the function is
|
||||
* automatically invoked.
|
||||
* @param arg Optional argument to pass to {@code expression}.
|
||||
@@ -2894,14 +2885,6 @@ public interface Locator {
|
||||
*
|
||||
* <p> <strong>Usage</strong>
|
||||
*
|
||||
* <p> Passing argument to {@code expression}:
|
||||
* <pre>{@code
|
||||
* Object result = page.getByTestId("myId").evaluate("(element, [x, y]) => {\n" +
|
||||
* " return element.textContent + ' ' + x * y;\n" +
|
||||
* "}", Arrays.asList(7, 8));
|
||||
* System.out.println(result); // prints "myId text 56"
|
||||
* }</pre>
|
||||
*
|
||||
* @param expression JavaScript expression to be evaluated in the browser context. If the expression evaluates to a function, the function is
|
||||
* automatically invoked.
|
||||
* @since v1.14
|
||||
@@ -2925,14 +2908,6 @@ public interface Locator {
|
||||
*
|
||||
* <p> <strong>Usage</strong>
|
||||
*
|
||||
* <p> Passing argument to {@code expression}:
|
||||
* <pre>{@code
|
||||
* Object result = page.getByTestId("myId").evaluate("(element, [x, y]) => {\n" +
|
||||
* " return element.textContent + ' ' + x * y;\n" +
|
||||
* "}", Arrays.asList(7, 8));
|
||||
* System.out.println(result); // prints "myId text 56"
|
||||
* }</pre>
|
||||
*
|
||||
* @param expression JavaScript expression to be evaluated in the browser context. If the expression evaluates to a function, the function is
|
||||
* automatically invoked.
|
||||
* @param arg Optional argument to pass to {@code expression}.
|
||||
|
||||
@@ -21,11 +21,6 @@ import com.microsoft.playwright.options.*;
|
||||
/**
|
||||
* The Mouse class operates in main-frame CSS pixels relative to the top-left corner of the viewport.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> If you want to debug where the mouse moved, you can use the <a
|
||||
* href="https://playwright.dev/java/docs/trace-viewer-intro">Trace viewer</a> or <a
|
||||
* href="https://playwright.dev/java/docs/running-tests">Playwright Inspector</a>. A red dot showing the location of the
|
||||
* mouse will be shown for every mouse action.
|
||||
*
|
||||
* <p> Every {@code page} object has its own Mouse, accessible with {@link com.microsoft.playwright.Page#mouse Page.mouse()}.
|
||||
* <pre>{@code
|
||||
* // Using ‘page.mouse’ to trace a 100x100 square.
|
||||
|
||||
@@ -23,12 +23,6 @@ import java.nio.file.Path;
|
||||
* API for collecting and saving Playwright traces. Playwright traces can be opened in <a
|
||||
* href="https://playwright.dev/java/docs/trace-viewer">Trace Viewer</a> after Playwright script runs.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> You probably want to <a href="https://playwright.dev/docs/api/class-testoptions#test-options-trace">enable tracing in
|
||||
* your config file</a> instead of using {@code context.tracing}.The {@code context.tracing} API captures browser operations and network activity, but it doesn't record test assertions
|
||||
* (like {@code expect} calls). We recommend <a
|
||||
* href="https://playwright.dev/docs/api/class-testoptions#test-options-trace">enabling tracing through Playwright Test
|
||||
* configuration</a>, which includes those assertions and provides a more complete trace for debugging test failures.
|
||||
*
|
||||
* <p> Start recording a trace before performing actions. At the end, stop tracing and save it to a file.
|
||||
* <pre>{@code
|
||||
* Browser browser = chromium.launch();
|
||||
@@ -206,12 +200,6 @@ public interface Tracing {
|
||||
/**
|
||||
* Start tracing.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> You probably want to <a href="https://playwright.dev/docs/api/class-testoptions#test-options-trace">enable tracing in
|
||||
* your config file</a> instead of using {@code Tracing.start}.The {@code context.tracing} API captures browser operations and network activity, but it doesn't record test assertions
|
||||
* (like {@code expect} calls). We recommend <a
|
||||
* href="https://playwright.dev/docs/api/class-testoptions#test-options-trace">enabling tracing through Playwright Test
|
||||
* configuration</a>, which includes those assertions and provides a more complete trace for debugging test failures.
|
||||
*
|
||||
* <p> <strong>Usage</strong>
|
||||
* <pre>{@code
|
||||
* context.tracing().start(new Tracing.StartOptions()
|
||||
@@ -231,12 +219,6 @@ public interface Tracing {
|
||||
/**
|
||||
* Start tracing.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> You probably want to <a href="https://playwright.dev/docs/api/class-testoptions#test-options-trace">enable tracing in
|
||||
* your config file</a> instead of using {@code Tracing.start}.The {@code context.tracing} API captures browser operations and network activity, but it doesn't record test assertions
|
||||
* (like {@code expect} calls). We recommend <a
|
||||
* href="https://playwright.dev/docs/api/class-testoptions#test-options-trace">enabling tracing through Playwright Test
|
||||
* configuration</a>, which includes those assertions and provides a more complete trace for debugging test failures.
|
||||
*
|
||||
* <p> <strong>Usage</strong>
|
||||
* <pre>{@code
|
||||
* context.tracing().start(new Tracing.StartOptions()
|
||||
|
||||
@@ -27,7 +27,7 @@ import java.util.function.Consumer;
|
||||
*
|
||||
* <p> <strong>Mocking</strong>
|
||||
*
|
||||
* <p> By default, the routed WebSocket will not connect to the server. This way, you can mock entire communication over the
|
||||
* <p> By default, the routed WebSocket will not connect to the server. This way, you can mock entire communcation over the
|
||||
* WebSocket. Here is an example that responds to a {@code "request"} with a {@code "response"}.
|
||||
* <pre>{@code
|
||||
* page.routeWebSocket("wss://example.com/ws", ws -> {
|
||||
|
||||
+12
-12
@@ -885,7 +885,7 @@ public interface LocatorAssertions {
|
||||
* <p> When an array is passed, the method asserts that the list of elements located matches the corresponding list of expected
|
||||
* class lists. Each element's class attribute is matched against the corresponding class in the array:
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".list > .component")).containsClass(new String[] {"inactive", "active", "inactive"});
|
||||
* assertThat(page.locator("list > .component")).containsClass(new String[] {"inactive", "active", "inactive"});
|
||||
* }</pre>
|
||||
*
|
||||
* @param expected A string containing expected class names, separated by spaces, or a list of such strings to assert multiple elements.
|
||||
@@ -909,7 +909,7 @@ public interface LocatorAssertions {
|
||||
* <p> When an array is passed, the method asserts that the list of elements located matches the corresponding list of expected
|
||||
* class lists. Each element's class attribute is matched against the corresponding class in the array:
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".list > .component")).containsClass(new String[] {"inactive", "active", "inactive"});
|
||||
* assertThat(page.locator("list > .component")).containsClass(new String[] {"inactive", "active", "inactive"});
|
||||
* }</pre>
|
||||
*
|
||||
* @param expected A string containing expected class names, separated by spaces, or a list of such strings to assert multiple elements.
|
||||
@@ -931,7 +931,7 @@ public interface LocatorAssertions {
|
||||
* <p> When an array is passed, the method asserts that the list of elements located matches the corresponding list of expected
|
||||
* class lists. Each element's class attribute is matched against the corresponding class in the array:
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".list > .component")).containsClass(new String[] {"inactive", "active", "inactive"});
|
||||
* assertThat(page.locator("list > .component")).containsClass(new String[] {"inactive", "active", "inactive"});
|
||||
* }</pre>
|
||||
*
|
||||
* @param expected A string containing expected class names, separated by spaces, or a list of such strings to assert multiple elements.
|
||||
@@ -955,7 +955,7 @@ public interface LocatorAssertions {
|
||||
* <p> When an array is passed, the method asserts that the list of elements located matches the corresponding list of expected
|
||||
* class lists. Each element's class attribute is matched against the corresponding class in the array:
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".list > .component")).containsClass(new String[] {"inactive", "active", "inactive"});
|
||||
* assertThat(page.locator("list > .component")).containsClass(new String[] {"inactive", "active", "inactive"});
|
||||
* }</pre>
|
||||
*
|
||||
* @param expected A string containing expected class names, separated by spaces, or a list of such strings to assert multiple elements.
|
||||
@@ -1565,7 +1565,7 @@ public interface LocatorAssertions {
|
||||
* class values. Each element's class attribute is matched against the corresponding string or regular expression in the
|
||||
* array:
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* assertThat(page.locator("list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* }</pre>
|
||||
*
|
||||
* @param expected Expected class or RegExp or a list of those.
|
||||
@@ -1589,7 +1589,7 @@ public interface LocatorAssertions {
|
||||
* class values. Each element's class attribute is matched against the corresponding string or regular expression in the
|
||||
* array:
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* assertThat(page.locator("list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* }</pre>
|
||||
*
|
||||
* @param expected Expected class or RegExp or a list of those.
|
||||
@@ -1611,7 +1611,7 @@ public interface LocatorAssertions {
|
||||
* class values. Each element's class attribute is matched against the corresponding string or regular expression in the
|
||||
* array:
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* assertThat(page.locator("list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* }</pre>
|
||||
*
|
||||
* @param expected Expected class or RegExp or a list of those.
|
||||
@@ -1635,7 +1635,7 @@ public interface LocatorAssertions {
|
||||
* class values. Each element's class attribute is matched against the corresponding string or regular expression in the
|
||||
* array:
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* assertThat(page.locator("list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* }</pre>
|
||||
*
|
||||
* @param expected Expected class or RegExp or a list of those.
|
||||
@@ -1657,7 +1657,7 @@ public interface LocatorAssertions {
|
||||
* class values. Each element's class attribute is matched against the corresponding string or regular expression in the
|
||||
* array:
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* assertThat(page.locator("list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* }</pre>
|
||||
*
|
||||
* @param expected Expected class or RegExp or a list of those.
|
||||
@@ -1681,7 +1681,7 @@ public interface LocatorAssertions {
|
||||
* class values. Each element's class attribute is matched against the corresponding string or regular expression in the
|
||||
* array:
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* assertThat(page.locator("list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* }</pre>
|
||||
*
|
||||
* @param expected Expected class or RegExp or a list of those.
|
||||
@@ -1703,7 +1703,7 @@ public interface LocatorAssertions {
|
||||
* class values. Each element's class attribute is matched against the corresponding string or regular expression in the
|
||||
* array:
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* assertThat(page.locator("list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* }</pre>
|
||||
*
|
||||
* @param expected Expected class or RegExp or a list of those.
|
||||
@@ -1727,7 +1727,7 @@ public interface LocatorAssertions {
|
||||
* class values. Each element's class attribute is matched against the corresponding string or regular expression in the
|
||||
* array:
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* assertThat(page.locator("list > .component")).hasClass(new String[] {"component", "component selected", "component"});
|
||||
* }</pre>
|
||||
*
|
||||
* @param expected Expected class or RegExp or a list of those.
|
||||
|
||||
@@ -39,8 +39,6 @@ class APIRequestContextImpl extends ChannelOwner implements APIRequestContext {
|
||||
private final TracingImpl tracing;
|
||||
private String disposeReason;
|
||||
|
||||
protected TimeoutSettings timeoutSettings = new TimeoutSettings();
|
||||
|
||||
APIRequestContextImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
this.tracing = connection.getExistingObject(initializer.getAsJsonObject("tracing").get("guid").getAsString());
|
||||
@@ -53,17 +51,21 @@ class APIRequestContextImpl extends ChannelOwner implements APIRequestContext {
|
||||
|
||||
@Override
|
||||
public void dispose(DisposeOptions options) {
|
||||
withLogging("APIRequestContext.dispose", () -> disposeImpl(options));
|
||||
}
|
||||
|
||||
private void disposeImpl(DisposeOptions options) {
|
||||
if (options == null) {
|
||||
options = new DisposeOptions();
|
||||
}
|
||||
disposeReason = options.reason;
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("dispose", params, NO_TIMEOUT);
|
||||
sendMessage("dispose", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public APIResponse fetch(String urlOrRequest, RequestOptions options) {
|
||||
return fetchImpl(urlOrRequest, (RequestOptionsImpl) options);
|
||||
return withLogging("APIRequestContext.fetch", () -> fetchImpl(urlOrRequest, (RequestOptionsImpl) options));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -91,7 +93,6 @@ class APIRequestContextImpl extends ChannelOwner implements APIRequestContext {
|
||||
if (options == null) {
|
||||
options = new RequestOptionsImpl();
|
||||
}
|
||||
options.timeout = timeoutSettings.timeout(options.timeout);
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("url", url);
|
||||
if (options.params != null) {
|
||||
@@ -131,6 +132,9 @@ class APIRequestContextImpl extends ChannelOwner implements APIRequestContext {
|
||||
if (options.multipart != null) {
|
||||
params.add("multipartData", serializeMultipartData(options.multipart.fields));
|
||||
}
|
||||
if (options.timeout != null) {
|
||||
params.addProperty("timeout", options.timeout);
|
||||
}
|
||||
if (options.failOnStatusCode != null) {
|
||||
params.addProperty("failOnStatusCode", options.failOnStatusCode);
|
||||
}
|
||||
@@ -149,7 +153,7 @@ class APIRequestContextImpl extends ChannelOwner implements APIRequestContext {
|
||||
}
|
||||
params.addProperty("maxRetries", options.maxRetries);
|
||||
}
|
||||
JsonObject json = sendMessage("fetch", params, timeoutSettings.timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("fetch", params).getAsJsonObject();
|
||||
return new APIResponseImpl(this, json.getAsJsonObject("response"));
|
||||
}
|
||||
|
||||
@@ -215,12 +219,14 @@ class APIRequestContextImpl extends ChannelOwner implements APIRequestContext {
|
||||
|
||||
@Override
|
||||
public String storageState(StorageStateOptions options) {
|
||||
JsonElement json = sendMessage("storageState");
|
||||
String storageState = json.toString();
|
||||
if (options != null && options.path != null) {
|
||||
Utils.writeToFile(storageState.getBytes(StandardCharsets.UTF_8), options.path);
|
||||
}
|
||||
return storageState;
|
||||
return withLogging("APIRequestContext.storageState", () -> {
|
||||
JsonElement json = sendMessage("storageState");
|
||||
String storageState = json.toString();
|
||||
if (options != null && options.path != null) {
|
||||
Utils.writeToFile(storageState.getBytes(StandardCharsets.UTF_8), options.path);
|
||||
}
|
||||
return storageState;
|
||||
});
|
||||
}
|
||||
|
||||
private static RequestOptionsImpl ensureOptions(RequestOptions options, String method) {
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.microsoft.playwright.impl;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.microsoft.playwright.APIRequest;
|
||||
import com.microsoft.playwright.PlaywrightException;
|
||||
@@ -25,11 +26,12 @@ import com.microsoft.playwright.options.ClientCertificate;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.util.Base64;
|
||||
import java.util.List;
|
||||
|
||||
import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT;
|
||||
import static com.microsoft.playwright.impl.Serialization.gson;
|
||||
import static com.microsoft.playwright.impl.Utils.addToProtocol;
|
||||
import static java.nio.file.Files.readAllBytes;
|
||||
|
||||
class APIRequestImpl implements APIRequest {
|
||||
private final PlaywrightImpl playwright;
|
||||
@@ -40,6 +42,10 @@ class APIRequestImpl implements APIRequest {
|
||||
|
||||
@Override
|
||||
public APIRequestContextImpl newContext(NewContextOptions options) {
|
||||
return playwright.withLogging("APIRequest.newContext", () -> newContextImpl(options));
|
||||
}
|
||||
|
||||
private APIRequestContextImpl newContextImpl(NewContextOptions options) {
|
||||
if (options == null) {
|
||||
options = new NewContextOptions();
|
||||
} else {
|
||||
@@ -61,17 +67,13 @@ class APIRequestImpl implements APIRequest {
|
||||
}
|
||||
List<ClientCertificate> clientCertificateList = options.clientCertificates;
|
||||
options.clientCertificates = null;
|
||||
Double timeout = options.timeout;
|
||||
// Timeout is handled on the client.
|
||||
options.timeout = null;
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
if (storageState != null) {
|
||||
params.add("storageState", storageState);
|
||||
}
|
||||
addToProtocol(params, clientCertificateList);
|
||||
JsonObject result = playwright.sendMessage("newRequest", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject result = playwright.sendMessage("newRequest", params).getAsJsonObject();
|
||||
APIRequestContextImpl context = playwright.connection.getExistingObject(result.getAsJsonObject("request").get("guid").getAsString());
|
||||
context.timeoutSettings.setDefaultTimeout(timeout);
|
||||
return context;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
package com.microsoft.playwright.impl;
|
||||
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import com.microsoft.playwright.APIResponse;
|
||||
@@ -28,7 +29,6 @@ import java.util.Base64;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT;
|
||||
import static com.microsoft.playwright.impl.Serialization.gson;
|
||||
import static com.microsoft.playwright.impl.Utils.isSafeCloseError;
|
||||
import static java.util.Arrays.asList;
|
||||
@@ -49,7 +49,7 @@ class APIResponseImpl implements APIResponse {
|
||||
try {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("fetchUid", fetchUid());
|
||||
JsonObject json = context.sendMessage("fetchResponseBody", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = context.sendMessage("fetchResponseBody", params).getAsJsonObject();
|
||||
if (!json.has("binary")) {
|
||||
throw new PlaywrightException("Response has been disposed");
|
||||
}
|
||||
@@ -64,9 +64,11 @@ class APIResponseImpl implements APIResponse {
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("fetchUid", fetchUid());
|
||||
context.sendMessage("disposeAPIResponse", params, NO_TIMEOUT);
|
||||
context.withLogging("APIResponse.dispose", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("fetchUid", fetchUid());
|
||||
context.sendMessage("disposeAPIResponse", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -112,7 +114,7 @@ class APIResponseImpl implements APIResponse {
|
||||
List<String> fetchLog() {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("fetchUid", fetchUid());
|
||||
JsonObject json = context.sendMessage("fetchLog", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = context.sendMessage("fetchLog", params).getAsJsonObject();
|
||||
JsonArray log = json.get("log").getAsJsonArray();
|
||||
return gson().fromJson(log, new TypeToken<List<String>>() {}.getType());
|
||||
}
|
||||
|
||||
@@ -86,6 +86,6 @@ class ArtifactImpl extends ChannelOwner {
|
||||
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("path", path.toString());
|
||||
sendMessage("saveAs", params, NO_TIMEOUT);
|
||||
sendMessage("saveAs", params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.microsoft.playwright.impl;
|
||||
|
||||
import com.microsoft.playwright.PlaywrightException;
|
||||
import org.opentest4j.AssertionFailedError;
|
||||
import org.opentest4j.ValueWrapper;
|
||||
|
||||
@@ -28,26 +29,28 @@ import java.util.stream.Collectors;
|
||||
import static com.microsoft.playwright.impl.Utils.toJsRegexFlags;
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
abstract class AssertionsBase {
|
||||
class AssertionsBase {
|
||||
final LocatorImpl actualLocator;
|
||||
final boolean isNot;
|
||||
|
||||
AssertionsBase(boolean isNot) {
|
||||
AssertionsBase(LocatorImpl actual, boolean isNot) {
|
||||
this.actualLocator = actual;
|
||||
this.isNot = isNot;
|
||||
}
|
||||
|
||||
void expectImpl(String expression, ExpectedTextValue textValue, Object expected, String message, FrameExpectOptions options, String title) {
|
||||
expectImpl(expression, asList(textValue), expected, message, options, title);
|
||||
void expectImpl(String expression, ExpectedTextValue textValue, Object expected, String message, FrameExpectOptions options) {
|
||||
expectImpl(expression, asList(textValue), expected, message, options);
|
||||
}
|
||||
|
||||
void expectImpl(String expression, List<ExpectedTextValue> expectedText, Object expected, String message, FrameExpectOptions options, String title) {
|
||||
void expectImpl(String expression, List<ExpectedTextValue> expectedText, Object expected, String message, FrameExpectOptions options) {
|
||||
if (options == null) {
|
||||
options = new FrameExpectOptions();
|
||||
}
|
||||
options.expectedText = expectedText;
|
||||
expectImpl(expression, options, expected, message, title);
|
||||
expectImpl(expression, options, expected, message);
|
||||
}
|
||||
|
||||
void expectImpl(String expression, FrameExpectOptions expectOptions, Object expected, String message, String title) {
|
||||
void expectImpl(String expression, FrameExpectOptions expectOptions, Object expected, String message) {
|
||||
if (expectOptions.timeout == null) {
|
||||
expectOptions.timeout = AssertionsTimeout.defaultTimeout;
|
||||
}
|
||||
@@ -55,7 +58,7 @@ abstract class AssertionsBase {
|
||||
if (isNot) {
|
||||
message = message.replace("expected to", "expected not to");
|
||||
}
|
||||
FrameExpectResult result = doExpect(expression, expectOptions, title);
|
||||
FrameExpectResult result = actualLocator.expect(expression, expectOptions);
|
||||
if (result.matches == isNot) {
|
||||
Object actual = result.received == null ? null : Serialization.deserialize(result.received);
|
||||
String log = (result.log == null) ? "" : String.join("\n", result.log);
|
||||
@@ -72,9 +75,7 @@ abstract class AssertionsBase {
|
||||
}
|
||||
}
|
||||
|
||||
abstract FrameExpectResult doExpect(String expression, FrameExpectOptions expectOptions, String title);
|
||||
|
||||
protected static ValueWrapper formatValue(Object value) {
|
||||
private static ValueWrapper formatValue(Object value) {
|
||||
if (value == null || !value.getClass().isArray()) {
|
||||
return ValueWrapper.create(value);
|
||||
}
|
||||
|
||||
@@ -78,11 +78,11 @@ class BindingCall extends ChannelOwner {
|
||||
|
||||
JsonObject params = new JsonObject();
|
||||
params.add("result", gson().toJsonTree(serializeArgument(result)));
|
||||
sendMessage("resolve", params, NO_TIMEOUT);
|
||||
sendMessage("resolve", params);
|
||||
} catch (RuntimeException exception) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.add("error", gson().toJsonTree(serializeError(exception)));
|
||||
sendMessage("reject", params, NO_TIMEOUT);
|
||||
sendMessage("reject", params);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ import static java.nio.file.Files.readAllBytes;
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
protected BrowserImpl browser;
|
||||
private final BrowserImpl browser;
|
||||
private final TracingImpl tracing;
|
||||
private final APIRequestContextImpl request;
|
||||
private final ClockImpl clock;
|
||||
@@ -51,7 +51,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
|
||||
final Router routes = new Router();
|
||||
final WebSocketRouter webSocketRoutes = new WebSocketRouter();
|
||||
private boolean closingOrClosed;
|
||||
private boolean closeWasCalled;
|
||||
private final WaitableEvent<EventType, ?> closePromise;
|
||||
final Map<String, BindingCallback> bindings = new HashMap<>();
|
||||
PageImpl ownerPage;
|
||||
@@ -69,6 +69,8 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
}
|
||||
private final ListenerCollection<EventType> listeners = new ListenerCollection<>(eventSubscriptions(), this);
|
||||
final TimeoutSettings timeoutSettings = new TimeoutSettings();
|
||||
Path videosDir;
|
||||
URL baseUrl;
|
||||
final Map<String, HarRecorder> harRecorders = new HashMap<>();
|
||||
|
||||
static class HarRecorder {
|
||||
@@ -96,30 +98,29 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
|
||||
BrowserContextImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
if (parent instanceof BrowserImpl) {
|
||||
browser = (BrowserImpl) parent;
|
||||
} else {
|
||||
browser = null;
|
||||
}
|
||||
tracing = connection.getExistingObject(initializer.getAsJsonObject("tracing").get("guid").getAsString());
|
||||
request = connection.getExistingObject(initializer.getAsJsonObject("requestContext").get("guid").getAsString());
|
||||
request.timeoutSettings = timeoutSettings;
|
||||
clock = new ClockImpl(this);
|
||||
closePromise = new WaitableEvent<>(listeners, EventType.CLOSE);
|
||||
}
|
||||
|
||||
Path videosDir() {
|
||||
JsonObject recordVideo = initializer.getAsJsonObject("options").getAsJsonObject("recordVideo");
|
||||
if (recordVideo == null) {
|
||||
return null;
|
||||
void setRecordHar(Path path, HarContentPolicy policy) {
|
||||
if (path != null) {
|
||||
harRecorders.put("", new HarRecorder(path, policy));
|
||||
}
|
||||
return Paths.get(recordVideo.get("dir").getAsString());
|
||||
}
|
||||
|
||||
URL baseUrl() {
|
||||
JsonElement url = initializer.getAsJsonObject("options").get("baseURL");
|
||||
if (url != null) {
|
||||
try {
|
||||
return new URL(url.getAsString());
|
||||
} catch (MalformedURLException e) {
|
||||
}
|
||||
void setBaseUrl(String spec) {
|
||||
try {
|
||||
this.baseUrl = new URL(spec);
|
||||
} catch (MalformedURLException e) {
|
||||
this.baseUrl = null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
String effectiveCloseReason() {
|
||||
@@ -261,7 +262,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
public CDPSession newCDPSession(Page page) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.add("page", ((PageImpl) page).toProtocolRef());
|
||||
JsonObject result = sendMessage("newCDPSession", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject result = sendMessage("newCDPSession", params).getAsJsonObject();
|
||||
return connection.getExistingObject(result.getAsJsonObject("session").get("guid").getAsString());
|
||||
}
|
||||
|
||||
@@ -269,14 +270,23 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
public CDPSession newCDPSession(Frame frame) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.add("frame", ((FrameImpl) frame).toProtocolRef());
|
||||
JsonObject result = sendMessage("newCDPSession", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject result = sendMessage("newCDPSession", params).getAsJsonObject();
|
||||
return connection.getExistingObject(result.getAsJsonObject("session").get("guid").getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close(CloseOptions options) {
|
||||
if (!closingOrClosed) {
|
||||
closingOrClosed = true;
|
||||
withLogging("BrowserContext.close", () -> closeImpl(options));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cookie> cookies(String url) {
|
||||
return cookies(url == null ? new ArrayList<>() : Collections.singletonList(url));
|
||||
}
|
||||
|
||||
private void closeImpl(CloseOptions options) {
|
||||
if (!closeWasCalled) {
|
||||
closeWasCalled = true;
|
||||
if (options == null) {
|
||||
options = new CloseOptions();
|
||||
}
|
||||
@@ -285,7 +295,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
for (Map.Entry<String, HarRecorder> entry : harRecorders.entrySet()) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("harId", entry.getKey());
|
||||
JsonObject json = sendMessage("harExport", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = sendMessage("harExport", params).getAsJsonObject();
|
||||
ArtifactImpl artifact = connection.getExistingObject(json.getAsJsonObject("artifact").get("guid").getAsString());
|
||||
// Server side will compress artifact if content is attach or if file is .zip.
|
||||
HarRecorder harParams = entry.getValue();
|
||||
@@ -297,46 +307,42 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
JsonObject unzipParams = new JsonObject();
|
||||
unzipParams.addProperty("zipFile", tmpPath);
|
||||
unzipParams.addProperty("harFile", harParams.path.toString());
|
||||
connection.localUtils.sendMessage("harUnzip", unzipParams, NO_TIMEOUT);
|
||||
connection.localUtils.sendMessage("harUnzip", unzipParams);
|
||||
} else {
|
||||
artifact.saveAs(harParams.path);
|
||||
}
|
||||
artifact.delete();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("close", params, NO_TIMEOUT);
|
||||
sendMessage("close", params);
|
||||
}
|
||||
runUntil(() -> {}, closePromise);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cookie> cookies(String url) {
|
||||
return cookies(url == null ? new ArrayList<>() : Collections.singletonList(url));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void addCookies(List<Cookie> cookies) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.add("cookies", gson().toJsonTree(cookies));
|
||||
sendMessage("addCookies", params, NO_TIMEOUT);
|
||||
withLogging("BrowserContext.addCookies", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.add("cookies", gson().toJsonTree(cookies));
|
||||
sendMessage("addCookies", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInitScript(String script) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("source", script);
|
||||
sendMessage("addInitScript", params, NO_TIMEOUT);
|
||||
withLogging("BrowserContext.addInitScript", () -> addInitScriptImpl(script));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInitScript(Path path) {
|
||||
try {
|
||||
byte[] bytes = readAllBytes(path);
|
||||
addInitScript(new String(bytes, UTF_8));
|
||||
} catch (IOException e) {
|
||||
throw new PlaywrightException("Failed to read script from file", e);
|
||||
}
|
||||
withLogging("BrowserContext.addInitScript", () -> {
|
||||
try {
|
||||
byte[] bytes = readAllBytes(path);
|
||||
addInitScriptImpl(new String(bytes, UTF_8));
|
||||
} catch (IOException e) {
|
||||
throw new PlaywrightException("Failed to read script from file", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -344,6 +350,12 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
return new ArrayList<>(backgroundPages);
|
||||
}
|
||||
|
||||
private void addInitScriptImpl(String script) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("source", script);
|
||||
sendMessage("addInitScript", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BrowserImpl browser() {
|
||||
return browser;
|
||||
@@ -351,6 +363,10 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
|
||||
@Override
|
||||
public void clearCookies(ClearCookiesOptions options) {
|
||||
withLogging("BrowserContext.clearCookies", () -> clearCookiesImpl(options));
|
||||
}
|
||||
|
||||
private void clearCookiesImpl(ClearCookiesOptions options) {
|
||||
if (options == null) {
|
||||
options = new ClearCookiesOptions();
|
||||
}
|
||||
@@ -358,7 +374,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
setStringOrRegex(params, "name", options.name);
|
||||
setStringOrRegex(params, "domain", options.domain);
|
||||
setStringOrRegex(params, "path", options.path);
|
||||
sendMessage("clearCookies", params, NO_TIMEOUT);
|
||||
sendMessage("clearCookies", params);
|
||||
}
|
||||
|
||||
private static void setStringOrRegex(JsonObject params, String name, Object value) {
|
||||
@@ -373,24 +389,28 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
|
||||
@Override
|
||||
public void clearPermissions() {
|
||||
sendMessage("clearPermissions");
|
||||
withLogging("BrowserContext.clearPermissions", () -> sendMessage("clearPermissions"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Cookie> cookies(List<String> urls) {
|
||||
return withLogging("BrowserContext.cookies", () -> cookiesImpl(urls));
|
||||
}
|
||||
|
||||
private List<Cookie> cookiesImpl(List<String> urls) {
|
||||
JsonObject params = new JsonObject();
|
||||
if (urls == null) {
|
||||
urls = new ArrayList<>();
|
||||
}
|
||||
params.add("urls", gson().toJsonTree(urls));
|
||||
JsonObject json = sendMessage("cookies", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = sendMessage("cookies", params).getAsJsonObject();
|
||||
Cookie[] cookies = gson().fromJson(json.getAsJsonArray("cookies"), Cookie[].class);
|
||||
return asList(cookies);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exposeBinding(String name, BindingCallback playwrightBinding, ExposeBindingOptions options) {
|
||||
exposeBindingImpl(name, playwrightBinding, options);
|
||||
withLogging("BrowserContext.exposeBinding", () -> exposeBindingImpl(name, playwrightBinding, options));
|
||||
}
|
||||
|
||||
private void exposeBindingImpl(String name, BindingCallback playwrightBinding, ExposeBindingOptions options) {
|
||||
@@ -409,16 +429,21 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
if (options != null && options.handle != null && options.handle) {
|
||||
params.addProperty("needsHandle", true);
|
||||
}
|
||||
sendMessage("exposeBinding", params, NO_TIMEOUT);
|
||||
sendMessage("exposeBinding", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exposeFunction(String name, FunctionCallback playwrightFunction) {
|
||||
exposeBindingImpl(name, (BindingCallback.Source source, Object... args) -> playwrightFunction.call(args), null);
|
||||
withLogging("BrowserContext.exposeFunction",
|
||||
() -> exposeBindingImpl(name, (BindingCallback.Source source, Object... args) -> playwrightFunction.call(args), null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void grantPermissions(List<String> permissions, GrantPermissionsOptions options) {
|
||||
withLogging("BrowserContext.grantPermissions", () -> grantPermissionsImpl(permissions, options));
|
||||
}
|
||||
|
||||
private void grantPermissionsImpl(List<String> permissions, GrantPermissionsOptions options) {
|
||||
if (options == null) {
|
||||
options = new GrantPermissionsOptions();
|
||||
}
|
||||
@@ -427,11 +452,15 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.add("permissions", gson().toJsonTree(permissions));
|
||||
sendMessage("grantPermissions", params, NO_TIMEOUT);
|
||||
sendMessage("grantPermissions", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PageImpl newPage() {
|
||||
return withLogging("BrowserContext.newPage", () -> newPageImpl());
|
||||
}
|
||||
|
||||
private PageImpl newPageImpl() {
|
||||
if (ownerPage != null) {
|
||||
throw new PlaywrightException("Please use browser.newContext()");
|
||||
}
|
||||
@@ -451,7 +480,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
|
||||
@Override
|
||||
public void route(String url, Consumer<Route> handler, RouteOptions options) {
|
||||
route(UrlMatcher.forGlob(baseUrl(), url, this.connection.localUtils, false), handler, options);
|
||||
route(UrlMatcher.forGlob(baseUrl, url, this.connection.localUtils, false), handler, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -470,23 +499,25 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
options = new RouteFromHAROptions();
|
||||
}
|
||||
if (options.update != null && options.update) {
|
||||
recordIntoHar(null, har, options, null);
|
||||
recordIntoHar(null, har, options);
|
||||
return;
|
||||
}
|
||||
UrlMatcher matcher = UrlMatcher.forOneOf(baseUrl(), options.url, this.connection.localUtils, false);
|
||||
UrlMatcher matcher = UrlMatcher.forOneOf(baseUrl, options.url, this.connection.localUtils, false);
|
||||
HARRouter harRouter = new HARRouter(connection.localUtils, har, options.notFound);
|
||||
onClose(context -> harRouter.dispose());
|
||||
route(matcher, route -> harRouter.handle(route), null);
|
||||
}
|
||||
|
||||
private void route(UrlMatcher matcher, Consumer<Route> handler, RouteOptions options) {
|
||||
routes.add(matcher, handler, options == null ? null : options.times);
|
||||
updateInterceptionPatterns();
|
||||
withLogging("BrowserContext.route", () -> {
|
||||
routes.add(matcher, handler, options == null ? null : options.times);
|
||||
updateInterceptionPatterns();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void routeWebSocket(String url, Consumer<WebSocketRoute> handler) {
|
||||
routeWebSocketImpl(UrlMatcher.forGlob(baseUrl(), url, this.connection.localUtils, true), handler);
|
||||
routeWebSocketImpl(UrlMatcher.forGlob(baseUrl, url, this.connection.localUtils, true), handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -500,82 +531,108 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
}
|
||||
|
||||
private void routeWebSocketImpl(UrlMatcher matcher, Consumer<WebSocketRoute> handler) {
|
||||
webSocketRoutes.add(matcher, handler);
|
||||
updateWebSocketInterceptionPatterns();
|
||||
withLogging("BrowserContext.routeWebSocket", () -> {
|
||||
webSocketRoutes.add(matcher, handler);
|
||||
updateWebSocketInterceptionPatterns();
|
||||
});
|
||||
}
|
||||
|
||||
void recordIntoHar(PageImpl page, Path har, RouteFromHAROptions options, HarContentPolicy contentPolicy) {
|
||||
if (contentPolicy == null) {
|
||||
contentPolicy = Utils.convertType(options.updateContent, HarContentPolicy.class);
|
||||
}
|
||||
if (contentPolicy == null) {
|
||||
contentPolicy = HarContentPolicy.ATTACH;
|
||||
}
|
||||
|
||||
void recordIntoHar(PageImpl page, Path har, RouteFromHAROptions options) {
|
||||
JsonObject params = new JsonObject();
|
||||
if (page != null) {
|
||||
params.add("page", page.toProtocolRef());
|
||||
}
|
||||
JsonObject recordHarArgs = new JsonObject();
|
||||
recordHarArgs.addProperty("zip", har.toString().endsWith(".zip"));
|
||||
recordHarArgs.addProperty("content", contentPolicy.name().toLowerCase());
|
||||
recordHarArgs.addProperty("mode", (options.updateMode == null ? HarMode.MINIMAL : options.updateMode).name().toLowerCase());
|
||||
addHarUrlFilter(recordHarArgs, options.url);
|
||||
|
||||
params.add("options", recordHarArgs);
|
||||
JsonObject json = sendMessage("harStart", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject jsonOptions = new JsonObject();
|
||||
jsonOptions.addProperty("path", har.toAbsolutePath().toString());
|
||||
jsonOptions.addProperty("content", options.updateContent == null ?
|
||||
HarContentPolicy.ATTACH.name().toLowerCase() :
|
||||
options.updateContent.name().toLowerCase());
|
||||
jsonOptions.addProperty("mode", options.updateMode == null ?
|
||||
HarMode.MINIMAL.name().toLowerCase() :
|
||||
options.updateMode.name().toLowerCase());
|
||||
addHarUrlFilter(jsonOptions, options.url);
|
||||
params.add("options", jsonOptions);
|
||||
JsonObject json = sendMessage("harStart", params).getAsJsonObject();
|
||||
String harId = json.get("harId").getAsString();
|
||||
harRecorders.put(harId, new HarRecorder(har, contentPolicy));
|
||||
harRecorders.put(harId, new HarRecorder(har, HarContentPolicy.ATTACH));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultNavigationTimeout(double timeout) {
|
||||
timeoutSettings.setDefaultNavigationTimeout(timeout);
|
||||
setDefaultNavigationTimeoutImpl(timeout);
|
||||
}
|
||||
|
||||
void setDefaultNavigationTimeoutImpl(Double timeout) {
|
||||
withLogging("BrowserContext.setDefaultNavigationTimeout", () -> {
|
||||
timeoutSettings.setDefaultNavigationTimeout(timeout);
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("timeout", timeout);
|
||||
sendMessage("setDefaultNavigationTimeoutNoReply", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultTimeout(double timeout) {
|
||||
timeoutSettings.setDefaultTimeout(timeout);
|
||||
setDefaultTimeoutImpl(timeout);
|
||||
}
|
||||
|
||||
void setDefaultTimeoutImpl(Double timeout) {
|
||||
withLogging("BrowserContext.setDefaultTimeout", () -> {
|
||||
timeoutSettings.setDefaultTimeout(timeout);
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("timeout", timeout);
|
||||
sendMessage("setDefaultTimeoutNoReply", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraHTTPHeaders(Map<String, String> headers) {
|
||||
JsonObject params = new JsonObject();
|
||||
JsonArray jsonHeaders = new JsonArray();
|
||||
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||
JsonObject header = new JsonObject();
|
||||
header.addProperty("name", e.getKey());
|
||||
header.addProperty("value", e.getValue());
|
||||
jsonHeaders.add(header);
|
||||
}
|
||||
params.add("headers", jsonHeaders);
|
||||
sendMessage("setExtraHTTPHeaders", params, NO_TIMEOUT);
|
||||
withLogging("BrowserContext.setExtraHTTPHeaders", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
JsonArray jsonHeaders = new JsonArray();
|
||||
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||
JsonObject header = new JsonObject();
|
||||
header.addProperty("name", e.getKey());
|
||||
header.addProperty("value", e.getValue());
|
||||
jsonHeaders.add(header);
|
||||
}
|
||||
params.add("headers", jsonHeaders);
|
||||
sendMessage("setExtraHTTPHeaders", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGeolocation(Geolocation geolocation) {
|
||||
JsonObject params = new JsonObject();
|
||||
if (geolocation != null) {
|
||||
params.add("geolocation", gson().toJsonTree(geolocation));
|
||||
}
|
||||
sendMessage("setGeolocation", params, NO_TIMEOUT);
|
||||
withLogging("BrowserContext.setGeolocation", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
if (geolocation != null) {
|
||||
params.add("geolocation", gson().toJsonTree(geolocation));
|
||||
}
|
||||
sendMessage("setGeolocation", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setOffline(boolean offline) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("offline", offline);
|
||||
sendMessage("setOffline", params, NO_TIMEOUT);
|
||||
withLogging("BrowserContext.setOffline", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("offline", offline);
|
||||
sendMessage("setOffline", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String storageState(StorageStateOptions options) {
|
||||
return withLogging("BrowserContext.storageState", () -> storageStateImpl(options));
|
||||
}
|
||||
|
||||
private String storageStateImpl(StorageStateOptions options) {
|
||||
if (options == null) {
|
||||
options = new StorageStateOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.remove("path");
|
||||
JsonElement json = sendMessage("storageState", params, NO_TIMEOUT);
|
||||
JsonElement json = sendMessage("storageState", params);
|
||||
|
||||
String storageState = json.toString();
|
||||
if (options.path != null) {
|
||||
@@ -591,13 +648,15 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
|
||||
@Override
|
||||
public void unrouteAll() {
|
||||
routes.removeAll();
|
||||
updateInterceptionPatterns();
|
||||
withLogging("BrowserContext.unrouteAll", () -> {
|
||||
routes.removeAll();
|
||||
updateInterceptionPatterns();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unroute(String url, Consumer<Route> handler) {
|
||||
unroute(UrlMatcher.forGlob(this.baseUrl(), url, this.connection.localUtils, false), handler);
|
||||
unroute(UrlMatcher.forGlob(this.baseUrl, url, this.connection.localUtils, false), handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -643,16 +702,18 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
}
|
||||
|
||||
private void unroute(UrlMatcher matcher, Consumer<Route> handler) {
|
||||
routes.remove(matcher, handler);
|
||||
updateInterceptionPatterns();
|
||||
withLogging("BrowserContext.unroute", () -> {
|
||||
routes.remove(matcher, handler);
|
||||
updateInterceptionPatterns();
|
||||
});
|
||||
}
|
||||
|
||||
private void updateInterceptionPatterns() {
|
||||
sendMessage("setNetworkInterceptionPatterns", routes.interceptionPatterns(), NO_TIMEOUT);
|
||||
sendMessage("setNetworkInterceptionPatterns", routes.interceptionPatterns());
|
||||
}
|
||||
|
||||
private void updateWebSocketInterceptionPatterns() {
|
||||
sendMessage("setWebSocketInterceptionPatterns", webSocketRoutes.interceptionPatterns(), NO_TIMEOUT);
|
||||
sendMessage("setWebSocketInterceptionPatterns", webSocketRoutes.interceptionPatterns());
|
||||
}
|
||||
|
||||
void handleRoute(RouteImpl route) {
|
||||
@@ -805,10 +866,8 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
}
|
||||
|
||||
void didClose() {
|
||||
closingOrClosed = true;
|
||||
if (browser != null) {
|
||||
browser.contexts.remove(this);
|
||||
browser.browserType.playwright.selectors.contextsForSelectors.remove(this);
|
||||
}
|
||||
listeners.notify(EventType.CLOSE, this);
|
||||
}
|
||||
@@ -817,49 +876,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("name", name);
|
||||
params.addProperty("lastModifiedMs", lastModifiedMs);
|
||||
JsonObject json = sendMessage("createTempFile", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = sendMessage("createTempFile", params).getAsJsonObject();
|
||||
return connection.getExistingObject(json.getAsJsonObject("writableStream").get("guid").getAsString());
|
||||
}
|
||||
|
||||
protected void initializeHarFromOptions(Browser.NewContextOptions options) {
|
||||
if (options.recordHarPath == null) {
|
||||
if (options.recordHarOmitContent != null) {
|
||||
throw new PlaywrightException("recordHarOmitContent is set but recordHarPath is null");
|
||||
}
|
||||
if (options.recordHarUrlFilter != null) {
|
||||
throw new PlaywrightException("recordHarUrlFilter is set but recordHarPath is null");
|
||||
}
|
||||
if (options.recordHarMode != null) {
|
||||
throw new PlaywrightException("recordHarMode is set but recordHarPath is null");
|
||||
}
|
||||
if (options.recordHarContent != null) {
|
||||
throw new PlaywrightException("recordHarContent is set but recordHarPath is null");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
HarContentPolicy contentPolicy = options.recordHarContent;
|
||||
if (contentPolicy == null && options.recordHarOmitContent != null && options.recordHarOmitContent == true) {
|
||||
contentPolicy = HarContentPolicy.OMIT;
|
||||
}
|
||||
if (contentPolicy == null) {
|
||||
contentPolicy = options.recordHarPath.endsWith(".zip") ? HarContentPolicy.ATTACH : HarContentPolicy.EMBED;
|
||||
}
|
||||
RouteFromHAROptions routeFromHAROptions = new RouteFromHAROptions();
|
||||
|
||||
if (options.recordHarUrlFilter instanceof String) {
|
||||
routeFromHAROptions.setUrl((String) options.recordHarUrlFilter);
|
||||
} else if (options.recordHarUrlFilter instanceof Pattern) {
|
||||
routeFromHAROptions.setUrl((Pattern) options.recordHarUrlFilter);
|
||||
}
|
||||
|
||||
if (options.recordHarMode != null) {
|
||||
routeFromHAROptions.updateMode = options.recordHarMode;
|
||||
} else {
|
||||
routeFromHAROptions.updateMode = HarMode.FULL;
|
||||
}
|
||||
routeFromHAROptions.url = options.recordHarUrlFilter;
|
||||
|
||||
recordIntoHar(null, options.recordHarPath, routeFromHAROptions, contentPolicy);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.microsoft.playwright.*;
|
||||
import com.microsoft.playwright.options.HarContentPolicy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
@@ -28,8 +29,10 @@ import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static com.microsoft.playwright.impl.Serialization.addHarUrlFilter;
|
||||
import static com.microsoft.playwright.impl.Serialization.gson;
|
||||
import static com.microsoft.playwright.impl.Utils.*;
|
||||
import static com.microsoft.playwright.impl.Utils.convertType;
|
||||
|
||||
class BrowserImpl extends ChannelOwner implements Browser {
|
||||
final Set<BrowserContextImpl> contexts = new HashSet<>();
|
||||
@@ -66,6 +69,10 @@ class BrowserImpl extends ChannelOwner implements Browser {
|
||||
|
||||
@Override
|
||||
public void close(CloseOptions options) {
|
||||
withLogging("Browser.close", () -> closeImpl(options));
|
||||
}
|
||||
|
||||
private void closeImpl(CloseOptions options) {
|
||||
if (options == null) {
|
||||
options = new CloseOptions();
|
||||
}
|
||||
@@ -110,20 +117,16 @@ class BrowserImpl extends ChannelOwner implements Browser {
|
||||
|
||||
@Override
|
||||
public BrowserContextImpl newContext(NewContextOptions options) {
|
||||
return withLogging("Browser.newContext", () -> newContextImpl(options));
|
||||
}
|
||||
|
||||
private BrowserContextImpl newContextImpl(NewContextOptions options) {
|
||||
if (options == null) {
|
||||
options = new NewContextOptions();
|
||||
} else {
|
||||
// Make a copy so that we can nullify some fields below.
|
||||
options = convertType(options, NewContextOptions.class);
|
||||
}
|
||||
|
||||
NewContextOptions harOptions = Utils.clone(options);
|
||||
options.recordHarContent = null;
|
||||
options.recordHarMode = null;
|
||||
options.recordHarPath = null;
|
||||
options.recordHarOmitContent = null;
|
||||
options.recordHarUrlFilter = null;
|
||||
|
||||
if (options.storageStatePath != null) {
|
||||
try {
|
||||
byte[] bytes = Files.readAllBytes(options.storageStatePath);
|
||||
@@ -138,10 +141,51 @@ class BrowserImpl extends ChannelOwner implements Browser {
|
||||
storageState = new Gson().fromJson(options.storageState, JsonObject.class);
|
||||
options.storageState = null;
|
||||
}
|
||||
JsonObject recordHar = null;
|
||||
Path recordHarPath = options.recordHarPath;
|
||||
HarContentPolicy harContentPolicy = null;
|
||||
if (options.recordHarPath != null) {
|
||||
recordHar = new JsonObject();
|
||||
recordHar.addProperty("path", options.recordHarPath.toString());
|
||||
if (options.recordHarContent != null) {
|
||||
harContentPolicy = options.recordHarContent;
|
||||
} else if (options.recordHarOmitContent != null && options.recordHarOmitContent) {
|
||||
harContentPolicy = HarContentPolicy.OMIT;
|
||||
}
|
||||
if (harContentPolicy != null) {
|
||||
recordHar.addProperty("content", harContentPolicy.name().toLowerCase());
|
||||
}
|
||||
if (options.recordHarMode != null) {
|
||||
recordHar.addProperty("mode", options.recordHarMode.name().toLowerCase());
|
||||
}
|
||||
addHarUrlFilter(recordHar, options.recordHarUrlFilter);
|
||||
options.recordHarPath = null;
|
||||
options.recordHarMode = null;
|
||||
options.recordHarOmitContent = null;
|
||||
options.recordHarContent = null;
|
||||
options.recordHarUrlFilter = null;
|
||||
} else {
|
||||
if (options.recordHarOmitContent != null) {
|
||||
throw new PlaywrightException("recordHarOmitContent is set but recordHarPath is null");
|
||||
}
|
||||
if (options.recordHarUrlFilter != null) {
|
||||
throw new PlaywrightException("recordHarUrlFilter is set but recordHarPath is null");
|
||||
}
|
||||
if (options.recordHarMode != null) {
|
||||
throw new PlaywrightException("recordHarMode is set but recordHarPath is null");
|
||||
}
|
||||
if (options.recordHarContent != null) {
|
||||
throw new PlaywrightException("recordHarContent is set but recordHarPath is null");
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
if (storageState != null) {
|
||||
params.add("storageState", storageState);
|
||||
}
|
||||
if (recordHar != null) {
|
||||
params.add("recordHar", recordHar);
|
||||
}
|
||||
if (options.recordVideoDir != null) {
|
||||
JsonObject recordVideo = new JsonObject();
|
||||
recordVideo.addProperty("dir", options.recordVideoDir.toAbsolutePath().toString());
|
||||
@@ -169,21 +213,31 @@ class BrowserImpl extends ChannelOwner implements Browser {
|
||||
if (options.acceptDownloads != null) {
|
||||
params.addProperty("acceptDownloads", options.acceptDownloads ? "accept" : "deny");
|
||||
}
|
||||
params.add("selectorEngines", gson().toJsonTree(browserType.playwright.selectors.selectorEngines));
|
||||
params.addProperty("testIdAttributeName", browserType.playwright.selectors.testIdAttributeName);
|
||||
JsonElement result = sendMessage("newContext", params, NO_TIMEOUT);
|
||||
JsonElement result = sendMessage("newContext", params);
|
||||
BrowserContextImpl context = connection.getExistingObject(result.getAsJsonObject().getAsJsonObject("context").get("guid").getAsString());
|
||||
context.initializeHarFromOptions(harOptions);
|
||||
context.videosDir = options.recordVideoDir;
|
||||
if (options.baseURL != null) {
|
||||
context.setBaseUrl(options.baseURL);
|
||||
}
|
||||
context.setRecordHar(recordHarPath, harContentPolicy);
|
||||
if (launchOptions != null) {
|
||||
context.tracing().setTracesDir(launchOptions.tracesDir);
|
||||
}
|
||||
contexts.add(context);
|
||||
return context;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Page newPage(NewPageOptions options) {
|
||||
return withTitle("Create Page", () -> newPageImpl(options));
|
||||
return withLogging("Browser.newPage", () -> newPageImpl(options));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void startTracing(Page page, StartTracingOptions options) {
|
||||
withLogging("Browser.startTracing", () -> startTracingImpl(page, options));
|
||||
}
|
||||
|
||||
private void startTracingImpl(Page page, StartTracingOptions options) {
|
||||
if (options == null) {
|
||||
options = new StartTracingOptions();
|
||||
}
|
||||
@@ -192,11 +246,15 @@ class BrowserImpl extends ChannelOwner implements Browser {
|
||||
if (page != null) {
|
||||
params.add("page", ((PageImpl) page).toProtocolRef());
|
||||
}
|
||||
sendMessage("startTracing", params, NO_TIMEOUT);
|
||||
sendMessage("startTracing", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] stopTracing() {
|
||||
return withLogging("Browser.stopTracing", () -> stopTracingImpl());
|
||||
}
|
||||
|
||||
private byte[] stopTracingImpl() {
|
||||
JsonObject json = sendMessage("stopTracing").getAsJsonObject();
|
||||
ArtifactImpl artifact = connection.getExistingObject(json.getAsJsonObject().getAsJsonObject("artifact").get("guid").getAsString());
|
||||
byte[] data = artifact.readAllBytes();
|
||||
@@ -237,46 +295,18 @@ class BrowserImpl extends ChannelOwner implements Browser {
|
||||
|
||||
@Override
|
||||
void handleEvent(String event, JsonObject parameters) {
|
||||
switch (event) {
|
||||
case "context":
|
||||
didCreateContext(connection.getExistingObject(parameters.getAsJsonObject("context").get("guid").getAsString()));
|
||||
break;
|
||||
case "close":
|
||||
didClose();
|
||||
break;
|
||||
if ("close".equals(event)) {
|
||||
didClose();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public CDPSession newBrowserCDPSession() {
|
||||
JsonObject params = new JsonObject();
|
||||
JsonObject result = sendMessage("newBrowserCDPSession", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject result = sendMessage("newBrowserCDPSession", params).getAsJsonObject();
|
||||
return connection.getExistingObject(result.getAsJsonObject("session").get("guid").getAsString());
|
||||
}
|
||||
|
||||
protected void connectToBrowserType(BrowserTypeImpl browserType, Path tracesDir){
|
||||
// Note: when using connect(), `browserType` is different from `this.parent`.
|
||||
// This is why browser type is not wired up in the constructor, and instead this separate method is called later on.
|
||||
this.browserType = browserType;
|
||||
this.tracePath = tracesDir;
|
||||
|
||||
for (BrowserContextImpl context : contexts) {
|
||||
context.tracing().setTracesDir(tracesDir);
|
||||
browserType.playwright.selectors.contextsForSelectors.add(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void didCreateContext(BrowserContextImpl context) {
|
||||
context.browser = this;
|
||||
contexts.add(context);
|
||||
// Note: when connecting to a browser, initial contexts arrive before `_browserType` is set,
|
||||
// and will be configured later in `ConnectToBrowserType`.
|
||||
if (browserType != null) {
|
||||
context.tracing().setTracesDir(tracePath);
|
||||
browserType.playwright.selectors.contextsForSelectors.add(context);
|
||||
}
|
||||
}
|
||||
|
||||
private void didClose() {
|
||||
isConnected = false;
|
||||
listeners.notify(EventType.DISCONNECTED, this);
|
||||
|
||||
@@ -22,30 +22,34 @@ import com.google.gson.JsonObject;
|
||||
import com.microsoft.playwright.Browser;
|
||||
import com.microsoft.playwright.BrowserType;
|
||||
import com.microsoft.playwright.PlaywrightException;
|
||||
import com.microsoft.playwright.options.HarContentPolicy;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.function.Consumer;
|
||||
|
||||
import static com.microsoft.playwright.impl.Serialization.addHarUrlFilter;
|
||||
import static com.microsoft.playwright.impl.Serialization.gson;
|
||||
import static com.microsoft.playwright.impl.Utils.addToProtocol;
|
||||
import static com.microsoft.playwright.impl.Utils.convertType;
|
||||
|
||||
class BrowserTypeImpl extends ChannelOwner implements BrowserType {
|
||||
protected PlaywrightImpl playwright;
|
||||
|
||||
BrowserTypeImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BrowserImpl launch(LaunchOptions options) {
|
||||
return withLogging("BrowserType.launch", () -> launchImpl(options));
|
||||
}
|
||||
|
||||
private BrowserImpl launchImpl(LaunchOptions options) {
|
||||
if (options == null) {
|
||||
options = new LaunchOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
JsonElement result = sendMessage("launch", params, TimeoutSettings.launchTimeout(options.timeout));
|
||||
JsonElement result = sendMessage("launch", params);
|
||||
BrowserImpl browser = connection.getExistingObject(result.getAsJsonObject().getAsJsonObject("browser").get("guid").getAsString());
|
||||
browser.browserType = this;
|
||||
browser.launchOptions = options;
|
||||
@@ -54,6 +58,10 @@ class BrowserTypeImpl extends ChannelOwner implements BrowserType {
|
||||
|
||||
@Override
|
||||
public Browser connect(String wsEndpoint, ConnectOptions options) {
|
||||
return withLogging("BrowserType.connect", () -> connectImpl(wsEndpoint, options));
|
||||
}
|
||||
|
||||
private Browser connectImpl(String wsEndpoint, ConnectOptions options) {
|
||||
if (options == null) {
|
||||
options = new ConnectOptions();
|
||||
}
|
||||
@@ -76,12 +84,7 @@ class BrowserTypeImpl extends ChannelOwner implements BrowserType {
|
||||
headers.addProperty("x-playwright-browser", name());
|
||||
}
|
||||
|
||||
Double timeout = options.timeout;
|
||||
if (timeout == null) {
|
||||
timeout = 0.0;
|
||||
}
|
||||
|
||||
JsonObject json = connection.localUtils().sendMessage("connect", params, timeout).getAsJsonObject();
|
||||
JsonObject json = connection.localUtils().sendMessage("connect", params).getAsJsonObject();
|
||||
JsonPipe pipe = connection.getExistingObject(json.getAsJsonObject("pipe").get("guid").getAsString());
|
||||
Connection connection = new Connection(pipe, this.connection.env, this.connection.localUtils);
|
||||
PlaywrightImpl playwright = connection.initializePlaywright();
|
||||
@@ -93,13 +96,14 @@ class BrowserTypeImpl extends ChannelOwner implements BrowserType {
|
||||
}
|
||||
throw new PlaywrightException("Malformed endpoint. Did you use launchServer method?");
|
||||
}
|
||||
playwright.selectors = this.playwright.selectors;
|
||||
playwright.initSharedSelectors(this.connection.getExistingObject("Playwright"));
|
||||
BrowserImpl browser = connection.getExistingObject(playwright.initializer.getAsJsonObject("preLaunchedBrowser").get("guid").getAsString());
|
||||
browser.isConnectedOverWebSocket = true;
|
||||
browser.connectToBrowserType(this, null);
|
||||
browser.browserType = this;
|
||||
Consumer<JsonPipe> connectionCloseListener = t -> browser.notifyRemoteClosed();
|
||||
pipe.onClose(connectionCloseListener);
|
||||
browser.onDisconnected(b -> {
|
||||
playwright.unregisterSelectors();
|
||||
pipe.offClose(connectionCloseListener);
|
||||
try {
|
||||
connection.close();
|
||||
@@ -115,16 +119,25 @@ class BrowserTypeImpl extends ChannelOwner implements BrowserType {
|
||||
if (!"chromium".equals(name())) {
|
||||
throw new PlaywrightException("Connecting over CDP is only supported in Chromium.");
|
||||
}
|
||||
return withLogging("BrowserType.connectOverCDP", () -> connectOverCDPImpl(endpointURL, options));
|
||||
}
|
||||
|
||||
private Browser connectOverCDPImpl(String endpointURL, ConnectOverCDPOptions options) {
|
||||
if (options == null) {
|
||||
options = new ConnectOverCDPOptions();
|
||||
}
|
||||
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("endpointURL", endpointURL);
|
||||
JsonObject json = sendMessage("connectOverCDP", params, TimeoutSettings.launchTimeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("connectOverCDP", params).getAsJsonObject();
|
||||
|
||||
BrowserImpl browser = connection.getExistingObject(json.getAsJsonObject("browser").get("guid").getAsString());
|
||||
browser.connectToBrowserType(this, null);
|
||||
browser.browserType = this;
|
||||
if (json.has("defaultContext")) {
|
||||
String contextId = json.getAsJsonObject("defaultContext").get("guid").getAsString();
|
||||
BrowserContextImpl defaultContext = connection.getExistingObject(contextId);
|
||||
browser.contexts.add(defaultContext);
|
||||
}
|
||||
return browser;
|
||||
}
|
||||
|
||||
@@ -134,19 +147,54 @@ class BrowserTypeImpl extends ChannelOwner implements BrowserType {
|
||||
|
||||
@Override
|
||||
public BrowserContextImpl launchPersistentContext(Path userDataDir, LaunchPersistentContextOptions options) {
|
||||
return withLogging("BrowserType.launchPersistentContext",
|
||||
() -> launchPersistentContextImpl(userDataDir, options));
|
||||
}
|
||||
|
||||
private BrowserContextImpl launchPersistentContextImpl(Path userDataDir, LaunchPersistentContextOptions options) {
|
||||
if (options == null) {
|
||||
options = new LaunchPersistentContextOptions();
|
||||
} else {
|
||||
// Make a copy so that we can nullify some fields below.
|
||||
options = convertType(options, LaunchPersistentContextOptions.class);
|
||||
}
|
||||
|
||||
Browser.NewContextOptions harOptions = convertType(options, Browser.NewContextOptions.class);
|
||||
options.recordHarContent = null;
|
||||
options.recordHarMode = null;
|
||||
options.recordHarPath = null;
|
||||
options.recordHarOmitContent = null;
|
||||
options.recordHarUrlFilter = null;
|
||||
JsonObject recordHar = null;
|
||||
Path recordHarPath = options.recordHarPath;
|
||||
HarContentPolicy harContentPolicy = null;
|
||||
if (options.recordHarPath != null) {
|
||||
recordHar = new JsonObject();
|
||||
recordHar.addProperty("path", options.recordHarPath.toString());
|
||||
if (options.recordHarContent != null) {
|
||||
harContentPolicy = options.recordHarContent;
|
||||
} else if (options.recordHarOmitContent != null && options.recordHarOmitContent) {
|
||||
harContentPolicy = HarContentPolicy.OMIT;
|
||||
}
|
||||
if (harContentPolicy != null) {
|
||||
recordHar.addProperty("content", harContentPolicy.name().toLowerCase());
|
||||
}
|
||||
if (options.recordHarMode != null) {
|
||||
recordHar.addProperty("mode", options.recordHarMode.toString().toLowerCase());
|
||||
}
|
||||
addHarUrlFilter(recordHar, options.recordHarUrlFilter);
|
||||
options.recordHarPath = null;
|
||||
options.recordHarMode = null;
|
||||
options.recordHarOmitContent = null;
|
||||
options.recordHarContent = null;
|
||||
options.recordHarUrlFilter = null;
|
||||
} else {
|
||||
if (options.recordHarOmitContent != null) {
|
||||
throw new PlaywrightException("recordHarOmitContent is set but recordHarPath is null");
|
||||
}
|
||||
if (options.recordHarUrlFilter != null) {
|
||||
throw new PlaywrightException("recordHarUrlFilter is set but recordHarPath is null");
|
||||
}
|
||||
if (options.recordHarMode != null) {
|
||||
throw new PlaywrightException("recordHarMode is set but recordHarPath is null");
|
||||
}
|
||||
if (options.recordHarContent != null) {
|
||||
throw new PlaywrightException("recordHarContent is set but recordHarPath is null");
|
||||
}
|
||||
}
|
||||
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
if (!userDataDir.isAbsolute() && !userDataDir.toString().isEmpty()) {
|
||||
@@ -154,6 +202,9 @@ class BrowserTypeImpl extends ChannelOwner implements BrowserType {
|
||||
userDataDir = cwd.resolve(userDataDir);
|
||||
}
|
||||
params.addProperty("userDataDir", userDataDir.toString());
|
||||
if (recordHar != null) {
|
||||
params.add("recordHar", recordHar);
|
||||
}
|
||||
if (options.recordVideoDir != null) {
|
||||
JsonObject recordVideo = new JsonObject();
|
||||
recordVideo.addProperty("dir", options.recordVideoDir.toAbsolutePath().toString());
|
||||
@@ -181,13 +232,13 @@ class BrowserTypeImpl extends ChannelOwner implements BrowserType {
|
||||
if (options.acceptDownloads != null) {
|
||||
params.addProperty("acceptDownloads", options.acceptDownloads ? "accept" : "deny");
|
||||
}
|
||||
params.add("selectorEngines", gson().toJsonTree(playwright.selectors.selectorEngines));
|
||||
params.addProperty("testIdAttributeName", playwright.selectors.testIdAttributeName);
|
||||
JsonObject json = sendMessage("launchPersistentContext", params, TimeoutSettings.launchTimeout(options.timeout)).getAsJsonObject();
|
||||
BrowserImpl browser = connection.getExistingObject(json.getAsJsonObject("browser").get("guid").getAsString());
|
||||
browser.connectToBrowserType(this, options.tracesDir);
|
||||
JsonObject json = sendMessage("launchPersistentContext", params).getAsJsonObject();
|
||||
BrowserContextImpl context = connection.getExistingObject(json.getAsJsonObject("context").get("guid").getAsString());
|
||||
context.initializeHarFromOptions(harOptions);
|
||||
context.videosDir = options.recordVideoDir;
|
||||
if (options.baseURL != null) {
|
||||
context.setBaseUrl(options.baseURL);
|
||||
}
|
||||
context.setRecordHar(recordHarPath, harContentPolicy);
|
||||
context.tracing().setTracesDir(options.tracesDir);
|
||||
return context;
|
||||
}
|
||||
|
||||
@@ -35,8 +35,7 @@ class ChannelOwner extends LoggingSupport {
|
||||
final String guid;
|
||||
final JsonObject initializer;
|
||||
private boolean wasCollected;
|
||||
|
||||
static Double NO_TIMEOUT = null;
|
||||
private boolean isInternalType;
|
||||
|
||||
protected ChannelOwner(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
this(parent.connection, parent, type, guid, initializer);
|
||||
@@ -60,6 +59,10 @@ class ChannelOwner extends LoggingSupport {
|
||||
}
|
||||
}
|
||||
|
||||
void markAsInternalType() {
|
||||
isInternalType = true;
|
||||
}
|
||||
|
||||
void disposeChannelOwner(boolean wasGarbageCollected) {
|
||||
// Clean up from parent and connection.
|
||||
if (parent != null) {
|
||||
@@ -84,20 +87,16 @@ class ChannelOwner extends LoggingSupport {
|
||||
return new WaitForEventLogger<>(this, apiName, code).get();
|
||||
}
|
||||
|
||||
|
||||
void withTitle(String title, Runnable code) {
|
||||
withTitle(title, () -> {
|
||||
code.run();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
<T> T withTitle(String title, Supplier<T> code) {
|
||||
String previousTitle = connection.setTitle(title);
|
||||
@Override
|
||||
<T> T withLogging(String apiName, Supplier<T> code) {
|
||||
if (isInternalType) {
|
||||
apiName = null;
|
||||
}
|
||||
String previousApiName = connection.setApiName(apiName);
|
||||
try {
|
||||
return code.get();
|
||||
return super.withLogging(apiName, code);
|
||||
} finally {
|
||||
connection.setTitle(previousTitle);
|
||||
connection.setApiName(previousApiName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -111,16 +110,11 @@ class ChannelOwner extends LoggingSupport {
|
||||
}
|
||||
|
||||
JsonElement sendMessage(String method) {
|
||||
return sendMessage(method, new JsonObject(), NO_TIMEOUT);
|
||||
return sendMessage(method, new JsonObject());
|
||||
}
|
||||
|
||||
JsonElement sendMessage(String method, JsonObject params, Double timeout) {
|
||||
JsonElement sendMessage(String method, JsonObject params) {
|
||||
checkNotCollected();
|
||||
if (timeout != null) {
|
||||
params.addProperty("timeout", timeout);
|
||||
} else if (params.has("timeout")) {
|
||||
throw new PlaywrightException("Internal error: timeout must be passed explicitly.");
|
||||
}
|
||||
return connection.sendMessage(guid, method, params);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@ import com.microsoft.playwright.Clock;
|
||||
|
||||
import java.util.Date;
|
||||
|
||||
import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT;
|
||||
|
||||
class ClockImpl implements Clock {
|
||||
private final ChannelOwner browserContext;
|
||||
|
||||
@@ -16,7 +14,8 @@ class ClockImpl implements Clock {
|
||||
|
||||
private void sendMessageWithLogging(String method, JsonObject params) {
|
||||
String capitalizedMethod = method.substring(0, 1).toUpperCase() + method.substring(1);
|
||||
browserContext.sendMessage("clock" + capitalizedMethod, params, NO_TIMEOUT);
|
||||
browserContext.withLogging("Clock." + method,
|
||||
() -> browserContext.sendMessage("clock" + capitalizedMethod, params));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,6 +19,7 @@ import com.google.gson.Gson;
|
||||
import com.google.gson.JsonArray;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.microsoft.playwright.Playwright;
|
||||
import com.microsoft.playwright.PlaywrightException;
|
||||
import com.microsoft.playwright.TimeoutError;
|
||||
|
||||
@@ -63,8 +64,7 @@ public class Connection {
|
||||
private int lastId = 0;
|
||||
private final StackTraceCollector stackTraceCollector;
|
||||
private final Map<Integer, WaitableResult<JsonElement>> callbacks = new HashMap<>();
|
||||
private String title;
|
||||
private boolean titleReported = false;
|
||||
private String apiName;
|
||||
private static final boolean isLogging;
|
||||
static {
|
||||
String debug = System.getenv("DEBUG");
|
||||
@@ -83,7 +83,7 @@ public class Connection {
|
||||
PlaywrightImpl initialize() {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("sdkLanguage", "java");
|
||||
JsonElement result = sendMessage("initialize", params.getAsJsonObject(), NO_TIMEOUT);
|
||||
JsonElement result = sendMessage("initialize", params.getAsJsonObject());
|
||||
return this.connection.getExistingObject(result.getAsJsonObject().getAsJsonObject("playwright").get("guid").getAsString());
|
||||
}
|
||||
}
|
||||
@@ -116,10 +116,9 @@ public class Connection {
|
||||
}
|
||||
}
|
||||
|
||||
String setTitle(String newTitle) {
|
||||
String previous = title;
|
||||
titleReported = false;
|
||||
title = newTitle;
|
||||
String setApiName(String name) {
|
||||
String previous = apiName;
|
||||
apiName = name;
|
||||
return previous;
|
||||
}
|
||||
|
||||
@@ -147,14 +146,12 @@ public class Connection {
|
||||
JsonObject metadata = new JsonObject();
|
||||
metadata.addProperty("wallTime", currentTimeMillis());
|
||||
JsonArray stack = null;
|
||||
if (titleReported) {
|
||||
if (apiName == null) {
|
||||
metadata.addProperty("internal", true);
|
||||
} else {
|
||||
if (title != null) {
|
||||
metadata.addProperty("title", title);
|
||||
// All but first message in a custom-titled API call are considered internal and will be hidden from the inspector.
|
||||
titleReported = true;
|
||||
}
|
||||
metadata.addProperty("apiName", apiName);
|
||||
// All but first message in an API call are considered internal and will be hidden from the inspector.
|
||||
apiName = null;
|
||||
if (stackTraceCollector != null) {
|
||||
stack = stackTraceCollector.currentStackTrace();
|
||||
if (!stack.isEmpty()) {
|
||||
@@ -376,6 +373,9 @@ public class Connection {
|
||||
case "Stream":
|
||||
result = new Stream(parent, type, guid, initializer);
|
||||
break;
|
||||
case "Selectors":
|
||||
result = new SelectorsImpl(parent, type, guid, initializer);
|
||||
break;
|
||||
case "SocksSupport":
|
||||
break;
|
||||
case "Tracing":
|
||||
|
||||
@@ -20,10 +20,13 @@ import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.microsoft.playwright.ConsoleMessage;
|
||||
import com.microsoft.playwright.JSHandle;
|
||||
import com.microsoft.playwright.Page;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static com.microsoft.playwright.impl.Serialization.gson;
|
||||
|
||||
public class ConsoleMessageImpl implements ConsoleMessage {
|
||||
private final Connection connection;
|
||||
private PageImpl page;
|
||||
|
||||
@@ -34,16 +34,18 @@ class DialogImpl extends ChannelOwner implements Dialog {
|
||||
|
||||
@Override
|
||||
public void accept(String promptText) {
|
||||
JsonObject params = new JsonObject();
|
||||
if (promptText != null) {
|
||||
params.addProperty("promptText", promptText);
|
||||
}
|
||||
sendMessage("accept", params, NO_TIMEOUT);
|
||||
withLogging("Dialog.accept", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
if (promptText != null) {
|
||||
params.addProperty("promptText", promptText);
|
||||
}
|
||||
sendMessage("accept", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dismiss() {
|
||||
sendMessage("dismiss");
|
||||
withLogging("Dialog.dismiss", () -> sendMessage("dismiss"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -46,22 +46,22 @@ class DownloadImpl implements Download {
|
||||
|
||||
@Override
|
||||
public void cancel() {
|
||||
artifact.cancel();
|
||||
page.withLogging("Download.cancel", () -> artifact.cancel());
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream createReadStream() {
|
||||
return artifact.createReadStream();
|
||||
return page.withLogging("Download.createReadStream", () -> artifact.createReadStream());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
artifact.delete();
|
||||
page.withLogging("Download.delete", () -> artifact.delete());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String failure() {
|
||||
return artifact.failure();
|
||||
return page.withLogging("Download.failure", () -> artifact.failure());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -71,11 +71,11 @@ class DownloadImpl implements Download {
|
||||
|
||||
@Override
|
||||
public Path path() {
|
||||
return artifact.pathAfterFinished();
|
||||
return page.withLogging("Download.path", () -> artifact.pathAfterFinished());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAs(Path path) {
|
||||
artifact.saveAs(path);
|
||||
page.withLogging("Download.saveAs", () -> artifact.saveAs(path));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,11 +40,8 @@ import static com.microsoft.playwright.options.ScreenshotType.JPEG;
|
||||
import static com.microsoft.playwright.options.ScreenshotType.PNG;
|
||||
|
||||
public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
private final FrameImpl frame;
|
||||
|
||||
ElementHandleImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
this.frame = (FrameImpl)parent;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -54,83 +51,105 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
|
||||
@Override
|
||||
public ElementHandle querySelector(String selector) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonElement json = sendMessage("querySelector", params, NO_TIMEOUT);
|
||||
JsonObject element = json.getAsJsonObject().getAsJsonObject("element");
|
||||
if (element == null) {
|
||||
return null;
|
||||
}
|
||||
return connection.getExistingObject(element.get("guid").getAsString());
|
||||
return withLogging("ElementHandle.querySelector", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonElement json = sendMessage("querySelector", params);
|
||||
JsonObject element = json.getAsJsonObject().getAsJsonObject("element");
|
||||
if (element == null) {
|
||||
return null;
|
||||
}
|
||||
return connection.getExistingObject(element.get("guid").getAsString());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ElementHandle> querySelectorAll(String selector) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonElement json = sendMessage("querySelectorAll", params, NO_TIMEOUT);
|
||||
JsonArray elements = json.getAsJsonObject().getAsJsonArray("elements");
|
||||
if (elements == null) {
|
||||
return null;
|
||||
}
|
||||
List<ElementHandle> handles = new ArrayList<>();
|
||||
for (JsonElement item : elements) {
|
||||
handles.add(connection.getExistingObject(item.getAsJsonObject().get("guid").getAsString()));
|
||||
}
|
||||
return handles;
|
||||
return withLogging("ElementHandle.<", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonElement json = sendMessage("querySelectorAll", params);
|
||||
JsonArray elements = json.getAsJsonObject().getAsJsonArray("elements");
|
||||
if (elements == null) {
|
||||
return null;
|
||||
}
|
||||
List<ElementHandle> handles = new ArrayList<>();
|
||||
for (JsonElement item : elements) {
|
||||
handles.add(connection.getExistingObject(item.getAsJsonObject().get("guid").getAsString()));
|
||||
}
|
||||
return handles;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object evalOnSelector(String selector, String pageFunction, Object arg) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evalOnSelector", params, NO_TIMEOUT);
|
||||
SerializedValue value = gson().fromJson(json.getAsJsonObject().get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
return withLogging("ElementHandle.evalOnSelector", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evalOnSelector", params);
|
||||
SerializedValue value = gson().fromJson(json.getAsJsonObject().get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object evalOnSelectorAll(String selector, String pageFunction, Object arg) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evalOnSelectorAll", params, NO_TIMEOUT);
|
||||
SerializedValue value = gson().fromJson(json.getAsJsonObject().get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
return withLogging("ElementHandle.evalOnSelectorAll", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evalOnSelectorAll", params);
|
||||
SerializedValue value = gson().fromJson(json.getAsJsonObject().get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoundingBox boundingBox() {
|
||||
JsonObject json = sendMessage("boundingBox").getAsJsonObject();
|
||||
if (!json.has("value")) {
|
||||
return null;
|
||||
}
|
||||
return gson().fromJson(json.get("value"), BoundingBox.class);
|
||||
return withLogging("ElementHandle.boundingBox", () -> {
|
||||
JsonObject json = sendMessage("boundingBox").getAsJsonObject();
|
||||
if (!json.has("value")) {
|
||||
return null;
|
||||
}
|
||||
return gson().fromJson(json.get("value"), BoundingBox.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(CheckOptions options) {
|
||||
withLogging("ElementHandle.check", () -> checkImpl(options));
|
||||
}
|
||||
|
||||
private void checkImpl(CheckOptions options) {
|
||||
if (options == null) {
|
||||
options = new CheckOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("check", params, frame.timeout(options.timeout));
|
||||
sendMessage("check", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(ClickOptions options) {
|
||||
withLogging("ElementHandle.click", () -> clickImpl(options));
|
||||
}
|
||||
|
||||
private void clickImpl(ClickOptions options) {
|
||||
if (options == null) {
|
||||
options = new ClickOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("click", params, frame.timeout(options.timeout));
|
||||
sendMessage("click", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Frame contentFrame() {
|
||||
return withLogging("ElementHandle.contentFrame", () -> contentFrameImpl());
|
||||
}
|
||||
|
||||
private Frame contentFrameImpl() {
|
||||
JsonObject json = sendMessage("contentFrame").getAsJsonObject();
|
||||
if (!json.has("frame")) {
|
||||
return null;
|
||||
@@ -140,132 +159,177 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
|
||||
@Override
|
||||
public void dblclick(DblclickOptions options) {
|
||||
withLogging("ElementHandle.dblclick", () -> dblclickImpl(options));
|
||||
}
|
||||
|
||||
private void dblclickImpl(DblclickOptions options) {
|
||||
if (options == null) {
|
||||
options = new DblclickOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("dblclick", params, frame.timeout(options.timeout));
|
||||
sendMessage("dblclick", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchEvent(String type, Object eventInit) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("type", type);
|
||||
params.add("eventInit", gson().toJsonTree(serializeArgument(eventInit)));
|
||||
sendMessage("dispatchEvent", params, NO_TIMEOUT);
|
||||
withLogging("ElementHandle.dispatchEvent", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("type", type);
|
||||
params.add("eventInit", gson().toJsonTree(serializeArgument(eventInit)));
|
||||
sendMessage("dispatchEvent", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(String value, FillOptions options) {
|
||||
withLogging("ElementHandle.fill", () -> fillImpl(value, options));
|
||||
}
|
||||
|
||||
private void fillImpl(String value, FillOptions options) {
|
||||
if (options == null) {
|
||||
options = new FillOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("value", value);
|
||||
sendMessage("fill", params, frame.timeout(options.timeout));
|
||||
sendMessage("fill", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focus() {
|
||||
sendMessage("focus");
|
||||
withLogging("ElementHandle.focus", () -> sendMessage("focus"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttribute(String name) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("name", name);
|
||||
JsonObject json = sendMessage("getAttribute", params, NO_TIMEOUT).getAsJsonObject();
|
||||
return json.has("value") ? json.get("value").getAsString() : null;
|
||||
return withLogging("ElementHandle.getAttribute", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("name", name);
|
||||
JsonObject json = sendMessage("getAttribute", params).getAsJsonObject();
|
||||
return json.has("value") ? json.get("value").getAsString() : null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hover(HoverOptions options) {
|
||||
withLogging("ElementHandle.hover", () -> hoverImpl(options));
|
||||
}
|
||||
|
||||
private void hoverImpl(HoverOptions options) {
|
||||
if (options == null) {
|
||||
options = new HoverOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("hover", params, frame.timeout(options.timeout));
|
||||
sendMessage("hover", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String innerHTML() {
|
||||
JsonObject json = sendMessage("innerHTML").getAsJsonObject();
|
||||
return json.get("value").getAsString();
|
||||
return withLogging("ElementHandle.innerHTML", () -> {
|
||||
JsonObject json = sendMessage("innerHTML").getAsJsonObject();
|
||||
return json.get("value").getAsString();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String innerText() {
|
||||
JsonObject json = sendMessage("innerText").getAsJsonObject();
|
||||
return json.get("value").getAsString();
|
||||
return withLogging("ElementHandle.innerText", () -> {
|
||||
JsonObject json = sendMessage("innerText").getAsJsonObject();
|
||||
return json.get("value").getAsString();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public String inputValue(InputValueOptions options) {
|
||||
return withLogging("ElementHandle.inputValue", () -> inputValueImpl(options));
|
||||
}
|
||||
|
||||
private String inputValueImpl(InputValueOptions options) {
|
||||
if (options == null) {
|
||||
options = new InputValueOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
JsonObject json = sendMessage("inputValue", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = sendMessage("inputValue", params).getAsJsonObject();
|
||||
return json.get("value").getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked() {
|
||||
JsonObject json = sendMessage("isChecked").getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
return withLogging("ElementHandle.isChecked", () -> {
|
||||
JsonObject json = sendMessage("isChecked").getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isDisabled() {
|
||||
JsonObject json = sendMessage("isDisabled").getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
return withLogging("ElementHandle.isDisabled", () -> {
|
||||
JsonObject json = sendMessage("isDisabled").getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditable() {
|
||||
JsonObject json = sendMessage("isEditable").getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
return withLogging("ElementHandle.isEditable", () -> {
|
||||
JsonObject json = sendMessage("isEditable").getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled() {
|
||||
JsonObject json = sendMessage("isEnabled").getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
return withLogging("ElementHandle.isEnabled", () -> {
|
||||
JsonObject json = sendMessage("isEnabled").getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden() {
|
||||
JsonObject json = sendMessage("isHidden").getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
return withLogging("ElementHandle.isHidden", () -> {
|
||||
JsonObject json = sendMessage("isHidden").getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible() {
|
||||
JsonObject json = sendMessage("isVisible").getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
return withLogging("ElementHandle.isVisible", () -> {
|
||||
JsonObject json = sendMessage("isVisible").getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public FrameImpl ownerFrame() {
|
||||
JsonObject json = sendMessage("ownerFrame").getAsJsonObject();
|
||||
if (!json.has("frame")) {
|
||||
return null;
|
||||
}
|
||||
return connection.getExistingObject(json.getAsJsonObject("frame").get("guid").getAsString());
|
||||
return withLogging("ElementHandle.ownerFrame", () -> {
|
||||
JsonObject json = sendMessage("ownerFrame").getAsJsonObject();
|
||||
if (!json.has("frame")) {
|
||||
return null;
|
||||
}
|
||||
return connection.getExistingObject(json.getAsJsonObject("frame").get("guid").getAsString());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void press(String key, PressOptions options) {
|
||||
withLogging("ElementHandle.press", () -> pressImpl(key, options));
|
||||
}
|
||||
private void pressImpl(String key, PressOptions options) {
|
||||
if (options == null) {
|
||||
options = new PressOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("key", key);
|
||||
sendMessage("press", params, frame.timeout(options.timeout));
|
||||
sendMessage("press", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] screenshot(ScreenshotOptions options) {
|
||||
return withLogging("ElementHandle.screenshot", () -> screenshotImpl(options));
|
||||
}
|
||||
|
||||
private byte[] screenshotImpl(ScreenshotOptions options) {
|
||||
if (options == null) {
|
||||
options = new ScreenshotOptions();
|
||||
}
|
||||
@@ -284,7 +348,7 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.remove("path");
|
||||
JsonObject json = sendMessage("screenshot", params, frame.timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("screenshot", params).getAsJsonObject();
|
||||
|
||||
byte[] buffer = Base64.getDecoder().decode(json.get("binary").getAsString());
|
||||
if (options.path != null) {
|
||||
@@ -295,11 +359,7 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
|
||||
@Override
|
||||
public void scrollIntoViewIfNeeded(ScrollIntoViewIfNeededOptions options) {
|
||||
if (options == null) {
|
||||
options = new ScrollIntoViewIfNeededOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("scrollIntoViewIfNeeded", params, frame.timeout(options.timeout));
|
||||
withLogging("ElementHandle.scrollIntoViewIfNeeded", () -> scrollIntoViewIfNeededImpl(options));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -323,7 +383,7 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
if (values != null) {
|
||||
params.add("options", toSelectValueOrLabel(values));
|
||||
}
|
||||
return selectOption(params, options.timeout);
|
||||
return selectOption(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -332,6 +392,13 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
return selectOption(values, options);
|
||||
}
|
||||
|
||||
private void scrollIntoViewIfNeededImpl(ScrollIntoViewIfNeededOptions options) {
|
||||
if (options == null) {
|
||||
options = new ScrollIntoViewIfNeededOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("scrollIntoViewIfNeeded", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> selectOption(SelectOption[] values, SelectOptionOptions options) {
|
||||
@@ -342,7 +409,7 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
if (values != null) {
|
||||
params.add("options", gson().toJsonTree(values));
|
||||
}
|
||||
return selectOption(params, options.timeout);
|
||||
return selectOption(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -354,21 +421,19 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
if (values != null) {
|
||||
params.add("elements", Serialization.toProtocol(values));
|
||||
}
|
||||
return selectOption(params, options.timeout);
|
||||
return selectOption(params);
|
||||
}
|
||||
|
||||
private List<String> selectOption(JsonObject params, Double timeout) {
|
||||
JsonObject json = sendMessage("selectOption", params, frame.timeout(timeout)).getAsJsonObject();
|
||||
return parseStringList(json.getAsJsonArray("values"));
|
||||
private List<String> selectOption(JsonObject params) {
|
||||
return withLogging("SelectOption", () -> {
|
||||
JsonObject json = sendMessage("selectOption", params).getAsJsonObject();
|
||||
return parseStringList(json.getAsJsonArray("values"));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void selectText(SelectTextOptions options) {
|
||||
if (options == null) {
|
||||
options = new SelectTextOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("selectText", params, frame.timeout(options.timeout));
|
||||
withLogging("ElementHandle.selectText", () -> selectTextImpl(options));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -385,9 +450,20 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
setInputFiles(new Path[]{files}, options);
|
||||
}
|
||||
|
||||
private void selectTextImpl(SelectTextOptions options) {
|
||||
if (options == null) {
|
||||
options = new SelectTextOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("selectText", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputFiles(Path[] files, SetInputFilesOptions options) {
|
||||
withLogging("ElementHandle.setInputFiles", () -> setInputFilesImpl(files, options));
|
||||
}
|
||||
|
||||
void setInputFilesImpl(Path[] files, SetInputFilesOptions options) {
|
||||
FrameImpl frame = ownerFrame();
|
||||
if (frame == null) {
|
||||
throw new Error("Cannot set input files to detached element");
|
||||
@@ -397,7 +473,7 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
addFilePathUploadParams(files, params, frame.page().context());
|
||||
sendMessage("setInputFiles", params, frame.timeout(options.timeout));
|
||||
sendMessage("setInputFiles", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -407,51 +483,77 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
|
||||
@Override
|
||||
public void setInputFiles(FilePayload[] files, SetInputFilesOptions options) {
|
||||
withLogging("ElementHandle.setInputFiles", () -> setInputFilesImpl(files, options));
|
||||
}
|
||||
|
||||
void setInputFilesImpl(FilePayload[] files, SetInputFilesOptions options) {
|
||||
checkFilePayloadSize(files);
|
||||
if (options == null) {
|
||||
options = new SetInputFilesOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.add("payloads", Serialization.toJsonArray(files));
|
||||
sendMessage("setInputFiles", params, frame.timeout(options.timeout));
|
||||
sendMessage("setInputFiles", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tap(TapOptions options) {
|
||||
withLogging("ElementHandle.tap", () -> tapImpl(options));
|
||||
}
|
||||
|
||||
private void tapImpl(TapOptions options) {
|
||||
if (options == null) {
|
||||
options = new TapOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("tap", params, frame.timeout(options.timeout));
|
||||
sendMessage("tap", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String textContent() {
|
||||
JsonObject json = sendMessage("textContent").getAsJsonObject();
|
||||
return json.has("value") ? json.get("value").getAsString() : null;
|
||||
return withLogging("ElementHandle.textContent", () -> textContentImpl());
|
||||
}
|
||||
|
||||
private String textContentImpl() {
|
||||
return withLogging("ElementHandle.textContent", () -> {
|
||||
JsonObject json = sendMessage("textContent").getAsJsonObject();
|
||||
return json.has("value") ? json.get("value").getAsString() : null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void type(String text, TypeOptions options) {
|
||||
withLogging("ElementHandle.type", () -> typeImpl(text, options));
|
||||
}
|
||||
|
||||
private void typeImpl(String text, TypeOptions options) {
|
||||
if (options == null) {
|
||||
options = new TypeOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("text", text);
|
||||
sendMessage("type", params, frame.timeout(options.timeout));
|
||||
sendMessage("type", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncheck(UncheckOptions options) {
|
||||
withLogging("ElementHandle.uncheck", () -> uncheckImpl(options));
|
||||
}
|
||||
|
||||
private void uncheckImpl(UncheckOptions options) {
|
||||
if (options == null) {
|
||||
options = new UncheckOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("uncheck", params, frame.timeout(options.timeout));
|
||||
sendMessage("uncheck", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitForElementState(ElementState state, WaitForElementStateOptions options) {
|
||||
withLogging("ElementHandle.waitForElementState", () -> waitForElementStateImpl(state, options));
|
||||
}
|
||||
|
||||
private void waitForElementStateImpl(ElementState state, WaitForElementStateOptions options) {
|
||||
if (options == null) {
|
||||
options = new WaitForElementStateOptions();
|
||||
}
|
||||
@@ -460,7 +562,7 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("state", toProtocol(state));
|
||||
sendMessage("waitForElementState", params, frame.timeout(options.timeout));
|
||||
sendMessage("waitForElementState", params);
|
||||
}
|
||||
|
||||
private static String toProtocol(ElementState state) {
|
||||
@@ -469,12 +571,16 @@ public class ElementHandleImpl extends JSHandleImpl implements ElementHandle {
|
||||
|
||||
@Override
|
||||
public ElementHandle waitForSelector(String selector, WaitForSelectorOptions options) {
|
||||
return withLogging("ElementHandle.waitForSelector", () -> waitForSelectorImpl(selector, options));
|
||||
}
|
||||
|
||||
private ElementHandle waitForSelectorImpl(String selector, WaitForSelectorOptions options) {
|
||||
if (options == null) {
|
||||
options = new WaitForSelectorOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonElement json = sendMessage("waitForSelector", params, frame.timeout(options.timeout)).getAsJsonObject();
|
||||
JsonElement json = sendMessage("waitForSelector", params);
|
||||
JsonObject element = json.getAsJsonObject().getAsJsonObject("element");
|
||||
if (element == null) {
|
||||
return null;
|
||||
|
||||
@@ -58,7 +58,8 @@ class FileChooserImpl implements FileChooser {
|
||||
|
||||
@Override
|
||||
public void setFiles(Path[] files, SetFilesOptions options) {
|
||||
element.setInputFiles(files, convertType(options, ElementHandle.SetInputFilesOptions.class));
|
||||
page.withLogging("FileChooser.setInputFiles",
|
||||
() -> element.setInputFilesImpl(files, convertType(options, ElementHandle.SetInputFilesOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -68,6 +69,7 @@ class FileChooserImpl implements FileChooser {
|
||||
|
||||
@Override
|
||||
public void setFiles(FilePayload[] files, SetFilesOptions options) {
|
||||
element.setInputFiles(files, convertType(options, ElementHandle.SetInputFilesOptions.class));
|
||||
page.withLogging("FileChooser.setInputFiles",
|
||||
() -> element.setInputFilesImpl(files, convertType(options, ElementHandle.SetInputFilesOptions.class)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,12 +74,16 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public ElementHandle querySelector(String selector, QuerySelectorOptions options) {
|
||||
return withLogging("Frame.querySelector", () -> querySelectorImpl(selector, options));
|
||||
}
|
||||
|
||||
ElementHandleImpl querySelectorImpl(String selector, QuerySelectorOptions options) {
|
||||
if (options == null) {
|
||||
options = new QuerySelectorOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonElement json = sendMessage("querySelector", params, NO_TIMEOUT);
|
||||
JsonElement json = sendMessage("querySelector", params);
|
||||
JsonObject element = json.getAsJsonObject().getAsJsonObject("element");
|
||||
if (element == null) {
|
||||
return null;
|
||||
@@ -89,18 +93,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public List<ElementHandle> querySelectorAll(String selector) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonElement json = sendMessage("querySelectorAll", params, NO_TIMEOUT);
|
||||
JsonArray elements = json.getAsJsonObject().getAsJsonArray("elements");
|
||||
if (elements == null) {
|
||||
return null;
|
||||
}
|
||||
List<ElementHandle> handles = new ArrayList<>();
|
||||
for (JsonElement item : elements) {
|
||||
handles.add(connection.getExistingObject(item.getAsJsonObject().get("guid").getAsString()));
|
||||
}
|
||||
return handles;
|
||||
return withLogging("Frame.querySelectorAll", () -> querySelectorAllImpl(selector));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,7 +110,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public List<String> selectOption(String selector, String[] values, SelectOptionOptions options) {
|
||||
return selectOptionImpl(selector, values, options);
|
||||
return withLogging("Frame.selectOption", () -> selectOptionImpl(selector, values, options));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -126,10 +119,24 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
return selectOption(selector, values, options);
|
||||
}
|
||||
|
||||
List<ElementHandle> querySelectorAllImpl(String selector) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonElement json = sendMessage("querySelectorAll", params);
|
||||
JsonArray elements = json.getAsJsonObject().getAsJsonArray("elements");
|
||||
if (elements == null) {
|
||||
return null;
|
||||
}
|
||||
List<ElementHandle> handles = new ArrayList<>();
|
||||
for (JsonElement item : elements) {
|
||||
handles.add(connection.getExistingObject(item.getAsJsonObject().get("guid").getAsString()));
|
||||
}
|
||||
return handles;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object evalOnSelector(String selector, String pageFunction, Object arg, EvalOnSelectorOptions options) {
|
||||
return evalOnSelectorImpl(selector, pageFunction, arg, options);
|
||||
return withLogging("Frame.evalOnSelector", () -> evalOnSelectorImpl(selector, pageFunction, arg, options));
|
||||
}
|
||||
|
||||
Object evalOnSelectorImpl(String selector, String pageFunction, Object arg, EvalOnSelectorOptions options) {
|
||||
@@ -140,14 +147,14 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evalOnSelector", params, NO_TIMEOUT);
|
||||
JsonElement json = sendMessage("evalOnSelector", params);
|
||||
SerializedValue value = gson().fromJson(json.getAsJsonObject().get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object evalOnSelectorAll(String selector, String pageFunction, Object arg) {
|
||||
return evalOnSelectorAllImpl(selector, pageFunction, arg);
|
||||
return withLogging("Frame.evalOnSelectorAll", () -> evalOnSelectorAllImpl(selector, pageFunction, arg));
|
||||
}
|
||||
|
||||
Object evalOnSelectorAllImpl(String selector, String pageFunction, Object arg) {
|
||||
@@ -155,14 +162,14 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evalOnSelectorAll", params, NO_TIMEOUT);
|
||||
JsonElement json = sendMessage("evalOnSelectorAll", params);
|
||||
SerializedValue value = gson().fromJson(json.getAsJsonObject().get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementHandle addScriptTag(AddScriptTagOptions options){
|
||||
return addScriptTagImpl(options);
|
||||
return withLogging("Frame.addScriptTag", () -> addScriptTagImpl(options));
|
||||
}
|
||||
|
||||
ElementHandle addScriptTagImpl(AddScriptTagOptions options) {
|
||||
@@ -182,13 +189,13 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
content = addSourceUrlToScript(content, options.path);
|
||||
jsonOptions.addProperty("content", content);
|
||||
}
|
||||
JsonElement json = sendMessage("addScriptTag", jsonOptions, NO_TIMEOUT);
|
||||
JsonElement json = sendMessage("addScriptTag", jsonOptions);
|
||||
return connection.getExistingObject(json.getAsJsonObject().getAsJsonObject("element").get("guid").getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementHandle addStyleTag(AddStyleTagOptions options){
|
||||
return addStyleTagImpl(options);
|
||||
return withLogging("Frame.addStyleTag", () -> addStyleTagImpl(options));
|
||||
}
|
||||
|
||||
ElementHandle addStyleTagImpl(AddStyleTagOptions options) {
|
||||
@@ -208,18 +215,22 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
content += "/*# sourceURL=" + options.path.toString().replace("\n", "") + "*/";
|
||||
jsonOptions.addProperty("content", content);
|
||||
}
|
||||
JsonElement json = sendMessage("addStyleTag", jsonOptions, NO_TIMEOUT);
|
||||
JsonElement json = sendMessage("addStyleTag", jsonOptions);
|
||||
return connection.getExistingObject(json.getAsJsonObject().getAsJsonObject("element").get("guid").getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(String selector, CheckOptions options){
|
||||
withLogging("Frame.check", () -> checkImpl(selector, options));
|
||||
}
|
||||
|
||||
void checkImpl(String selector, CheckOptions options) {
|
||||
if (options == null) {
|
||||
options = new CheckOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
sendMessage("check", params, timeout(options.timeout));
|
||||
sendMessage("check", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -229,7 +240,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public void click(String selector, ClickOptions options) {
|
||||
clickImpl(selector, options);
|
||||
withLogging("Frame.click", () -> clickImpl(selector, options));
|
||||
}
|
||||
|
||||
void clickImpl(String selector, ClickOptions options) {
|
||||
@@ -238,26 +249,38 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
sendMessage("click", params, timeout(options.timeout));
|
||||
sendMessage("click", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String content() {
|
||||
return withLogging("Frame.content", () -> contentImpl());
|
||||
}
|
||||
|
||||
String contentImpl() {
|
||||
return sendMessage("content").getAsJsonObject().get("value").getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dblclick(String selector, DblclickOptions options) {
|
||||
withLogging("Frame.dblclick", () -> dblclickImpl(selector, options));
|
||||
}
|
||||
|
||||
void dblclickImpl(String selector, DblclickOptions options) {
|
||||
if (options == null) {
|
||||
options = new DblclickOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
sendMessage("dblclick", params, timeout(options.timeout));
|
||||
sendMessage("dblclick", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchEvent(String selector, String type, Object eventInit, DispatchEventOptions options) {
|
||||
withLogging("Frame.dispatchEvent", () -> dispatchEventImpl(selector, type, eventInit, options));
|
||||
}
|
||||
|
||||
void dispatchEventImpl(String selector, String type, Object eventInit, DispatchEventOptions options) {
|
||||
if (options == null) {
|
||||
options = new DispatchEventOptions();
|
||||
}
|
||||
@@ -265,55 +288,71 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("type", type);
|
||||
params.add("eventInit", gson().toJsonTree(serializeArgument(eventInit)));
|
||||
sendMessage("dispatchEvent", params, timeout(options.timeout));
|
||||
sendMessage("dispatchEvent", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object evaluate(String expression, Object arg) {
|
||||
return withLogging("Frame.evaluate", () -> evaluateImpl(expression, arg));
|
||||
}
|
||||
|
||||
Object evaluateImpl(String expression, Object arg) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("expression", expression);
|
||||
params.addProperty("world", "main");
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evaluateExpression", params, NO_TIMEOUT);
|
||||
JsonElement json = sendMessage("evaluateExpression", params);
|
||||
SerializedValue value = gson().fromJson(json.getAsJsonObject().get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSHandle evaluateHandle(String pageFunction, Object arg) {
|
||||
return withLogging("Frame.evaluateHandle", () -> evaluateHandleImpl(pageFunction, arg));
|
||||
}
|
||||
|
||||
JSHandle evaluateHandleImpl(String pageFunction, Object arg) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.addProperty("world", "main");
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evaluateExpressionHandle", params, NO_TIMEOUT);
|
||||
JsonElement json = sendMessage("evaluateExpressionHandle", params);
|
||||
return connection.getExistingObject(json.getAsJsonObject().getAsJsonObject("handle").get("guid").getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(String selector, String value, FillOptions options) {
|
||||
withLogging("Frame.fill", () -> fillImpl(selector, value, options));
|
||||
}
|
||||
|
||||
void fillImpl(String selector, String value, FillOptions options) {
|
||||
if (options == null) {
|
||||
options = new FillOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("value", value);
|
||||
sendMessage("fill", params, timeout(options.timeout));
|
||||
sendMessage("fill", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focus(String selector, FocusOptions options) {
|
||||
withLogging("Frame.focus", () -> focusImpl(selector, options));
|
||||
}
|
||||
|
||||
void focusImpl(String selector, FocusOptions options) {
|
||||
if (options == null) {
|
||||
options = new FocusOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
sendMessage("focus", params, timeout(options.timeout));
|
||||
sendMessage("focus", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementHandle frameElement() {
|
||||
JsonObject json = sendMessage("frameElement").getAsJsonObject();
|
||||
return connection.getExistingObject(json.getAsJsonObject("element").get("guid").getAsString());
|
||||
return withLogging("Frame.frameElement", () -> frameElementImpl());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -321,9 +360,14 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
return new FrameLocatorImpl(this, selector);
|
||||
}
|
||||
|
||||
ElementHandle frameElementImpl() {
|
||||
JsonObject json = sendMessage("frameElement").getAsJsonObject();
|
||||
return connection.getExistingObject(json.getAsJsonObject("element").get("guid").getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAttribute(String selector, String name, GetAttributeOptions options) {
|
||||
return getAttributeImpl(selector, name, options);
|
||||
return withLogging("Frame.getAttribute", () -> getAttributeImpl(selector, name, options));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -398,7 +442,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("name", name);
|
||||
JsonObject json = sendMessage("getAttribute", params, timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("getAttribute", params).getAsJsonObject();
|
||||
if (json.has("value")) {
|
||||
return json.get("value").getAsString();
|
||||
}
|
||||
@@ -407,7 +451,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public ResponseImpl navigate(String url, NavigateOptions options) {
|
||||
return navigateImpl(url, options);
|
||||
return withLogging("Page.navigate", () -> navigateImpl(url, options));
|
||||
}
|
||||
|
||||
ResponseImpl navigateImpl(String url, NavigateOptions options) {
|
||||
@@ -416,7 +460,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("url", url);
|
||||
JsonElement result = sendMessage("goto", params, navigationTimeout(options.timeout));
|
||||
JsonElement result = sendMessage("goto", params);
|
||||
JsonObject jsonResponse = result.getAsJsonObject().getAsJsonObject("response");
|
||||
if (jsonResponse == null) {
|
||||
return null;
|
||||
@@ -426,7 +470,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public void hover(String selector, HoverOptions options) {
|
||||
hoverImpl(selector, options);
|
||||
withLogging("Frame.hover", () -> hoverImpl(selector, options));
|
||||
}
|
||||
|
||||
void hoverImpl(String selector, HoverOptions options) {
|
||||
@@ -435,12 +479,12 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
sendMessage("hover", params, timeout(options.timeout));
|
||||
sendMessage("hover", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragAndDrop(String source, String target, DragAndDropOptions options) {
|
||||
dragAndDropImpl(source, target, options);
|
||||
withLogging("Frame.dragAndDrop", () -> dragAndDropImpl(source, target, options));
|
||||
}
|
||||
|
||||
void dragAndDropImpl(String source, String target, DragAndDropOptions options) {
|
||||
@@ -450,12 +494,12 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("source", source);
|
||||
params.addProperty("target", target);
|
||||
sendMessage("dragAndDrop", params, timeout(options.timeout));
|
||||
sendMessage("dragAndDrop", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String innerHTML(String selector, InnerHTMLOptions options) {
|
||||
return innerHTMLImpl(selector, options);
|
||||
return withLogging("Frame.innerHTML", () -> innerHTMLImpl(selector, options));
|
||||
}
|
||||
|
||||
String innerHTMLImpl(String selector, InnerHTMLOptions options) {
|
||||
@@ -464,13 +508,13 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonObject json = sendMessage("innerHTML", params, timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("innerHTML", params).getAsJsonObject();
|
||||
return json.get("value").getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String innerText(String selector, InnerTextOptions options) {
|
||||
return innerTextImpl(selector, options);
|
||||
return withLogging("Frame.innerText", () -> innerTextImpl(selector, options));
|
||||
}
|
||||
|
||||
String innerTextImpl(String selector, InnerTextOptions options) {
|
||||
@@ -479,13 +523,13 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonObject json = sendMessage("innerText", params, timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("innerText", params).getAsJsonObject();
|
||||
return json.get("value").getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String inputValue(String selector, InputValueOptions options) {
|
||||
return inputValueImpl(selector, options);
|
||||
return withLogging("Frame.inputValue", () -> inputValueImpl(selector, options));
|
||||
}
|
||||
|
||||
String inputValueImpl(String selector, InputValueOptions options) {
|
||||
@@ -494,13 +538,13 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonObject json = sendMessage("inputValue", params, timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("inputValue", params).getAsJsonObject();
|
||||
return json.get("value").getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked(String selector, IsCheckedOptions options) {
|
||||
return isCheckedImpl(selector, options);
|
||||
return withLogging("Page.isChecked", () -> isCheckedImpl(selector, options));
|
||||
}
|
||||
|
||||
boolean isCheckedImpl(String selector, IsCheckedOptions options) {
|
||||
@@ -509,7 +553,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonObject json = sendMessage("isChecked", params, timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("isChecked", params).getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
}
|
||||
|
||||
@@ -520,7 +564,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public boolean isDisabled(String selector, IsDisabledOptions options) {
|
||||
return isDisabledImpl(selector, options);
|
||||
return withLogging("Page.isDisabled", () -> isDisabledImpl(selector, options));
|
||||
}
|
||||
|
||||
boolean isDisabledImpl(String selector, IsDisabledOptions options) {
|
||||
@@ -529,13 +573,13 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonObject json = sendMessage("isDisabled", params, timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("isDisabled", params).getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditable(String selector, IsEditableOptions options) {
|
||||
return isEditableImpl(selector, options);
|
||||
return withLogging("Page.isEditable", () -> isEditableImpl(selector, options));
|
||||
}
|
||||
|
||||
boolean isEditableImpl(String selector, IsEditableOptions options) {
|
||||
@@ -544,13 +588,13 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonObject json = sendMessage("isEditable", params, timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("isEditable", params).getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(String selector, IsEnabledOptions options) {
|
||||
return isEnabledImpl(selector, options);
|
||||
return withLogging("Page.isEnabled", () -> isEnabledImpl(selector, options));
|
||||
}
|
||||
|
||||
boolean isEnabledImpl(String selector, IsEnabledOptions options) {
|
||||
@@ -559,13 +603,13 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonObject json = sendMessage("isEnabled", params, timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("isEnabled", params).getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden(String selector, IsHiddenOptions options) {
|
||||
return isHiddenImpl(selector, options);
|
||||
return withLogging("Page.isHidden", () -> isHiddenImpl(selector, options));
|
||||
}
|
||||
|
||||
boolean isHiddenImpl(String selector, IsHiddenOptions options) {
|
||||
@@ -574,13 +618,13 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonObject json = sendMessage("isHidden", params, timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("isHidden", params).getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible(String selector, IsVisibleOptions options) {
|
||||
return isVisibleImpl(selector, options);
|
||||
return withLogging("Page.isVisible", () -> isVisibleImpl(selector, options));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -594,7 +638,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonObject json = sendMessage("isVisible", params, timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("isVisible", params).getAsJsonObject();
|
||||
return json.get("value").getAsBoolean();
|
||||
}
|
||||
|
||||
@@ -615,7 +659,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public void press(String selector, String key, PressOptions options) {
|
||||
pressImpl(selector, key, options);
|
||||
withLogging("Frame.press", () -> pressImpl(selector, key, options));
|
||||
}
|
||||
|
||||
void pressImpl(String selector, String key, PressOptions options) {
|
||||
@@ -625,12 +669,12 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("key", key);
|
||||
sendMessage("press", params, timeout(options.timeout));
|
||||
sendMessage("press", params);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<String> selectOption(String selector, SelectOption[] values, SelectOptionOptions options) {
|
||||
return selectOptionImpl(selector, values, options);
|
||||
return withLogging("Frame.selectOption", () -> selectOptionImpl(selector, values, options));
|
||||
}
|
||||
|
||||
List<String> selectOptionImpl(String selector, SelectOption[] values, SelectOptionOptions options) {
|
||||
@@ -642,7 +686,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
if (values != null) {
|
||||
params.add("options", gson().toJsonTree(values));
|
||||
}
|
||||
return selectOption(params, options.timeout);
|
||||
return selectOption(params);
|
||||
}
|
||||
|
||||
List<String> selectOptionImpl(String selector, String[] values, SelectOptionOptions options) {
|
||||
@@ -654,12 +698,12 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
if (values != null) {
|
||||
params.add("options", toSelectValueOrLabel(values));
|
||||
}
|
||||
return selectOption(params, options.timeout);
|
||||
return selectOption(params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> selectOption(String selector, ElementHandle[] values, SelectOptionOptions options) {
|
||||
return selectOptionImpl(selector, values, options);
|
||||
return withLogging("Frame.selectOption", () -> selectOptionImpl(selector, values, options));
|
||||
}
|
||||
|
||||
List<String> selectOptionImpl(String selector, ElementHandle[] values, SelectOptionOptions options) {
|
||||
@@ -671,35 +715,30 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
if (values != null) {
|
||||
params.add("elements", Serialization.toProtocol(values));
|
||||
}
|
||||
return selectOption(params, options.timeout);
|
||||
return selectOption(params);
|
||||
}
|
||||
|
||||
private List<String> selectOption(JsonObject params, Double timeout) {
|
||||
JsonObject json = sendMessage("selectOption", params, timeout(timeout)).getAsJsonObject();
|
||||
private List<String> selectOption(JsonObject params) {
|
||||
JsonObject json = sendMessage("selectOption", params).getAsJsonObject();
|
||||
return parseStringList(json.getAsJsonArray("values"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChecked(String selector, boolean checked, SetCheckedOptions options) {
|
||||
setCheckedImpl(selector, checked, options);
|
||||
withLogging("Frame.setChecked", () -> setCheckedImpl(selector, checked, options));
|
||||
}
|
||||
|
||||
void setCheckedImpl(String selector, boolean checked, SetCheckedOptions options) {
|
||||
if (checked) {
|
||||
check(selector, convertType(options, CheckOptions.class));
|
||||
checkImpl(selector, convertType(options, CheckOptions.class));
|
||||
} else {
|
||||
uncheck(selector, convertType(options, UncheckOptions.class));
|
||||
uncheckImpl(selector, convertType(options, UncheckOptions.class));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContent(String html, SetContentOptions options) {
|
||||
if (options == null) {
|
||||
options = new SetContentOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("html", html);
|
||||
sendMessage("setContent", params, navigationTimeout(options.timeout));
|
||||
withLogging("Frame.setContent", () -> setContentImpl(html, options));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -707,9 +746,18 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
setInputFiles(selector, new Path[] {files}, options);
|
||||
}
|
||||
|
||||
void setContentImpl(String html, SetContentOptions options) {
|
||||
if (options == null) {
|
||||
options = new SetContentOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("html", html);
|
||||
sendMessage("setContent", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setInputFiles(String selector, Path[] files, SetInputFilesOptions options) {
|
||||
setInputFilesImpl(selector, files, options);
|
||||
withLogging("Frame.setInputFiles", () -> setInputFilesImpl(selector, files, options));
|
||||
}
|
||||
|
||||
void setInputFilesImpl(String selector, Path[] files, SetInputFilesOptions options) {
|
||||
@@ -719,7 +767,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
addFilePathUploadParams(files, params, page.context());
|
||||
params.addProperty("selector", selector);
|
||||
sendMessage("setInputFiles", params, timeout(options.timeout));
|
||||
sendMessage("setInputFiles", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -729,7 +777,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public void setInputFiles(String selector, FilePayload[] files, SetInputFilesOptions options) {
|
||||
setInputFilesImpl(selector, files, options);
|
||||
withLogging("Frame.setInputFiles", () -> setInputFilesImpl(selector, files, options));
|
||||
}
|
||||
|
||||
void setInputFilesImpl(String selector, FilePayload[] files, SetInputFilesOptions options) {
|
||||
@@ -740,54 +788,73 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
params.add("payloads", toJsonArray(files));
|
||||
sendMessage("setInputFiles", params, timeout(options.timeout));
|
||||
sendMessage("setInputFiles", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tap(String selector, TapOptions options) {
|
||||
withLogging("Frame.tap", () -> tapImpl(selector, options));
|
||||
}
|
||||
void tapImpl(String selector, TapOptions options) {
|
||||
if (options == null) {
|
||||
options = new TapOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
sendMessage("tap", params, timeout(options.timeout));
|
||||
sendMessage("tap", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String textContent(String selector, TextContentOptions options) {
|
||||
return withLogging("Frame.textContent", () -> textContentImpl(selector, options));
|
||||
}
|
||||
|
||||
String textContentImpl(String selector, TextContentOptions options) {
|
||||
if (options == null) {
|
||||
options = new TextContentOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
return sendMessage("textContent", params, timeout(options.timeout)).getAsJsonObject().get("value").getAsString();
|
||||
return sendMessage("textContent", params).getAsJsonObject().get("value").getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String title() {
|
||||
return withLogging("Frame.title", () -> titleImpl());
|
||||
}
|
||||
|
||||
String titleImpl() {
|
||||
JsonElement json = sendMessage("title");
|
||||
return json.getAsJsonObject().get("value").getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void type(String selector, String text, TypeOptions options) {
|
||||
withLogging("Frame.type", () -> typeImpl(selector, text, options));
|
||||
}
|
||||
|
||||
void typeImpl(String selector, String text, TypeOptions options) {
|
||||
if (options == null) {
|
||||
options = new TypeOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("text", text);
|
||||
sendMessage("type", params, timeout(options.timeout));
|
||||
sendMessage("type", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncheck(String selector, UncheckOptions options) {
|
||||
withLogging("Frame.uncheck", () -> uncheckImpl(selector, options));
|
||||
}
|
||||
|
||||
void uncheckImpl(String selector, UncheckOptions options) {
|
||||
if (options == null) {
|
||||
options = new UncheckOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
sendMessage("uncheck", params, timeout(options.timeout));
|
||||
sendMessage("uncheck", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -797,13 +864,17 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public JSHandle waitForFunction(String pageFunction, Object arg, WaitForFunctionOptions options) {
|
||||
return withLogging("Frame.waitForFunction", () -> waitForFunctionImpl(pageFunction, arg, options));
|
||||
}
|
||||
|
||||
JSHandle waitForFunctionImpl(String pageFunction, Object arg, WaitForFunctionOptions options) {
|
||||
if (options == null) {
|
||||
options = new WaitForFunctionOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("waitForFunction", params, timeout(options.timeout));
|
||||
JsonElement json = sendMessage("waitForFunction", params);
|
||||
JsonObject element = json.getAsJsonObject().getAsJsonObject("handle");
|
||||
return connection.getExistingObject(element.get("guid").getAsString());
|
||||
}
|
||||
@@ -960,7 +1031,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
List<Waitable<Response>> waitables = new ArrayList<>();
|
||||
if (matcher == null) {
|
||||
matcher = UrlMatcher.forOneOf(page.context().baseUrl(), options.url, this.connection.localUtils, false);
|
||||
matcher = UrlMatcher.forOneOf(page.context().baseUrl, options.url, this.connection.localUtils, false);
|
||||
}
|
||||
logger.log("waiting for navigation " + matcher);
|
||||
waitables.add(new WaitForNavigationHelper(matcher, options.waitUntil, logger));
|
||||
@@ -972,6 +1043,10 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public ElementHandle waitForSelector(String selector, WaitForSelectorOptions options) {
|
||||
return withLogging("Frame.waitForSelector", () -> waitForSelectorImpl(selector, options));
|
||||
}
|
||||
|
||||
ElementHandle waitForSelectorImpl(String selector, WaitForSelectorOptions options) {
|
||||
return waitForSelectorImpl(selector, options, false);
|
||||
}
|
||||
|
||||
@@ -982,7 +1057,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("omitReturnValue", omitReturnValue);
|
||||
JsonElement json = sendMessage("waitForSelector", params, timeout(options.timeout));
|
||||
JsonElement json = sendMessage("waitForSelector", params);
|
||||
JsonObject element = json.getAsJsonObject().getAsJsonObject("element");
|
||||
if (element == null) {
|
||||
return null;
|
||||
@@ -992,14 +1067,18 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public void waitForTimeout(double timeout) {
|
||||
withLogging("Frame.waitForTimeout", () -> waitForTimeoutImpl(timeout));
|
||||
}
|
||||
|
||||
void waitForTimeoutImpl(double timeout) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("waitTimeout", timeout);
|
||||
sendMessage("waitForTimeout", params, NO_TIMEOUT);
|
||||
params.addProperty("timeout", timeout);
|
||||
sendMessage("waitForTimeout", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitForURL(String url, WaitForURLOptions options) {
|
||||
waitForURL(UrlMatcher.forGlob(page.context().baseUrl(), url, this.connection.localUtils, false), options);
|
||||
waitForURL(UrlMatcher.forGlob(page.context().baseUrl, url, this.connection.localUtils, false), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1034,14 +1113,14 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
int queryCount(String selector) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonObject result = sendMessage("queryCount", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject result = sendMessage("queryCount", params).getAsJsonObject();
|
||||
return result.get("value").getAsInt();
|
||||
}
|
||||
|
||||
void highlightImpl(String selector) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
sendMessage("highlight", params, NO_TIMEOUT);
|
||||
sendMessage("highlight", params);
|
||||
}
|
||||
|
||||
protected void handleEvent(String event, JsonObject params) {
|
||||
@@ -1072,30 +1151,4 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
internalListeners.notify(InternalEventType.NAVIGATED, params);
|
||||
}
|
||||
}
|
||||
|
||||
protected double timeout(Double timeout) {
|
||||
if (page != null) {
|
||||
return page.timeoutSettings.timeout(timeout);
|
||||
}
|
||||
return new TimeoutSettings().timeout(timeout);
|
||||
}
|
||||
|
||||
protected double navigationTimeout(Double timeout) {
|
||||
if (page != null) {
|
||||
return page.timeoutSettings.navigationTimeout(timeout);
|
||||
}
|
||||
return new TimeoutSettings().navigationTimeout(timeout);
|
||||
}
|
||||
|
||||
FrameExpectResult expect(String expression, FrameExpectOptions options, String title) {
|
||||
return withTitle(title, () -> expect(expression, options));
|
||||
}
|
||||
|
||||
FrameExpectResult expect(String expression, FrameExpectOptions options) {
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("expression", expression);
|
||||
JsonElement json = sendMessage("expect", params, options.timeout);
|
||||
FrameExpectResult result = gson().fromJson(json, FrameExpectResult.class);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ import java.nio.file.Path;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT;
|
||||
import static com.microsoft.playwright.impl.LoggingSupport.*;
|
||||
import static com.microsoft.playwright.impl.Serialization.fromNameValues;
|
||||
import static com.microsoft.playwright.impl.Serialization.gson;
|
||||
@@ -42,7 +41,7 @@ public class HARRouter {
|
||||
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("file", harFile.toString());
|
||||
JsonObject json = localUtils.sendMessage("harOpen", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = localUtils.sendMessage("harOpen", params).getAsJsonObject();
|
||||
if (json.has("error")) {
|
||||
throw new PlaywrightException(json.get("error").getAsString());
|
||||
}
|
||||
@@ -62,7 +61,7 @@ public class HARRouter {
|
||||
params.addProperty("postData", base64);
|
||||
}
|
||||
params.addProperty("isNavigationRequest", request.isNavigationRequest());
|
||||
JsonObject response = localUtils.sendMessage("harLookup", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject response = localUtils.sendMessage("harLookup", params).getAsJsonObject();
|
||||
|
||||
String action = response.get("action").getAsString();
|
||||
if ("redirect".equals(action)) {
|
||||
|
||||
@@ -41,58 +41,70 @@ public class JSHandleImpl extends ChannelOwner implements JSHandle {
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
try {
|
||||
sendMessage("dispose");
|
||||
} catch (TargetClosedError e) {
|
||||
}
|
||||
withLogging("JSHandle.dispose", () -> {
|
||||
try {
|
||||
sendMessage("dispose");
|
||||
} catch (TargetClosedError e) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object evaluate(String pageFunction, Object arg) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.addProperty("world", "main");
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evaluateExpression", params, NO_TIMEOUT);
|
||||
SerializedValue value = gson().fromJson(json.getAsJsonObject().get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
return withLogging("JSHandle.evaluate", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.addProperty("world", "main");
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evaluateExpression", params);
|
||||
SerializedValue value = gson().fromJson(json.getAsJsonObject().get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSHandle evaluateHandle(String pageFunction, Object arg) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.addProperty("world", "main");
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evaluateExpressionHandle", params, NO_TIMEOUT);
|
||||
return connection.getExistingObject(json.getAsJsonObject().getAsJsonObject("handle").get("guid").getAsString());
|
||||
return withLogging("JSHandle.evaluateHandle", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.addProperty("world", "main");
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evaluateExpressionHandle", params);
|
||||
return connection.getExistingObject(json.getAsJsonObject().getAsJsonObject("handle").get("guid").getAsString());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, JSHandle> getProperties() {
|
||||
JsonObject json = sendMessage("getPropertyList").getAsJsonObject();
|
||||
Map<String, JSHandle> result = new HashMap<>();
|
||||
for (JsonElement e : json.getAsJsonArray("properties")) {
|
||||
JsonObject item = e.getAsJsonObject();
|
||||
JSHandle value = connection.getExistingObject(item.getAsJsonObject("value").get("guid").getAsString());
|
||||
result.put(item.get("name").getAsString(), value);
|
||||
}
|
||||
return result;
|
||||
return withLogging("JSHandle.getProperties", () -> {
|
||||
JsonObject json = sendMessage("getPropertyList").getAsJsonObject();
|
||||
Map<String, JSHandle> result = new HashMap<>();
|
||||
for (JsonElement e : json.getAsJsonArray("properties")) {
|
||||
JsonObject item = e.getAsJsonObject();
|
||||
JSHandle value = connection.getExistingObject(item.getAsJsonObject("value").get("guid").getAsString());
|
||||
result.put(item.get("name").getAsString(), value);
|
||||
}
|
||||
return result;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSHandle getProperty(String propertyName) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("name", propertyName);
|
||||
JsonObject json = sendMessage("getProperty", params, NO_TIMEOUT).getAsJsonObject();
|
||||
return connection.getExistingObject(json.getAsJsonObject("handle").get("guid").getAsString());
|
||||
return withLogging("JSHandle.getProperty", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("name", propertyName);
|
||||
JsonObject json = sendMessage("getProperty", params).getAsJsonObject();
|
||||
return connection.getExistingObject(json.getAsJsonObject("handle").get("guid").getAsString());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object jsonValue() {
|
||||
JsonObject json = sendMessage("jsonValue").getAsJsonObject();
|
||||
SerializedValue value = gson().fromJson(json.get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
return withLogging("JSHandle.jsonValue", () -> {
|
||||
JsonObject json = sendMessage("jsonValue").getAsJsonObject();
|
||||
SerializedValue value = gson().fromJson(json.get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -44,7 +44,7 @@ class JsonPipe extends ChannelOwner implements Transport {
|
||||
checkIfClosed();
|
||||
JsonObject params = new JsonObject();
|
||||
params.add("message", message);
|
||||
sendMessage("send", params, NO_TIMEOUT);
|
||||
sendMessage("send", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.microsoft.playwright.impl;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.microsoft.playwright.Keyboard;
|
||||
|
||||
import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT;
|
||||
import static com.microsoft.playwright.impl.Serialization.gson;
|
||||
|
||||
class KeyboardImpl implements Keyboard {
|
||||
@@ -31,21 +30,25 @@ class KeyboardImpl implements Keyboard {
|
||||
|
||||
@Override
|
||||
public void down(String key) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("key", key);
|
||||
page.sendMessage("keyboardDown", params, NO_TIMEOUT);
|
||||
page.withLogging("Keyboard.down", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("key", key);
|
||||
page.sendMessage("keyboardDown", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void insertText(String text) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("text", text);
|
||||
page.sendMessage("keyboardInsertText", params, NO_TIMEOUT);
|
||||
page.withLogging("Keyboard.insertText", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("text", text);
|
||||
page.sendMessage("keyboardInsertText", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void press(String key, PressOptions options) {
|
||||
pressImpl(key, options);
|
||||
page.withLogging("Keyboard.press", () -> pressImpl(key, options));
|
||||
}
|
||||
|
||||
private void pressImpl(String key, PressOptions options) {
|
||||
@@ -54,12 +57,12 @@ class KeyboardImpl implements Keyboard {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("key", key);
|
||||
page.sendMessage("keyboardPress", params, NO_TIMEOUT);
|
||||
page.sendMessage("keyboardPress", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void type(String text, TypeOptions options) {
|
||||
typeImpl(text, options);
|
||||
page.withLogging("Keyboard.type", () -> typeImpl(text, options));
|
||||
}
|
||||
|
||||
private void typeImpl(String text, TypeOptions options) {
|
||||
@@ -68,13 +71,15 @@ class KeyboardImpl implements Keyboard {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("text", text);
|
||||
page.sendMessage("keyboardType", params, NO_TIMEOUT);
|
||||
page.sendMessage("keyboardType", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void up(String key) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("key", key);
|
||||
page.sendMessage("keyboardUp", params, NO_TIMEOUT);
|
||||
page.withLogging("Keyboard.up", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("key", key);
|
||||
page.sendMessage("keyboardUp", params);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ import static com.microsoft.playwright.impl.Serialization.gson;
|
||||
public class LocalUtils extends ChannelOwner {
|
||||
LocalUtils(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
markAsInternalType();
|
||||
}
|
||||
|
||||
JsonArray deviceDescriptors() {
|
||||
@@ -41,13 +42,13 @@ public class LocalUtils extends ChannelOwner {
|
||||
params.addProperty("mode", appendMode ? "append" : "write");
|
||||
params.addProperty("stacksId", stacksId);
|
||||
params.addProperty("includeSources", includeSources);
|
||||
sendMessage("zip", params, NO_TIMEOUT);
|
||||
sendMessage("zip", params);
|
||||
}
|
||||
|
||||
void traceDiscarded(String stacksId) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("stacksId", stacksId);
|
||||
sendMessage("traceDiscarded", params, NO_TIMEOUT);
|
||||
sendMessage("traceDiscarded", params);
|
||||
}
|
||||
|
||||
String tracingStarted(String tracesDir, String traceName) {
|
||||
@@ -56,7 +57,7 @@ public class LocalUtils extends ChannelOwner {
|
||||
params.addProperty("tracesDir", "");
|
||||
}
|
||||
params.addProperty("traceName", traceName);
|
||||
JsonObject json = connection.localUtils().sendMessage("tracingStarted", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = connection.localUtils().sendMessage("tracingStarted", params).getAsJsonObject();
|
||||
return json.get("stacksId").getAsString();
|
||||
}
|
||||
|
||||
@@ -67,7 +68,7 @@ public class LocalUtils extends ChannelOwner {
|
||||
params.addProperty("baseURL", baseURL);
|
||||
}
|
||||
params.addProperty("webSocketUrl", webSocketUrl);
|
||||
JsonObject json = connection.localUtils().sendMessage("globToRegex", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = connection.localUtils().sendMessage("globToRegex", params).getAsJsonObject();
|
||||
String regex = json.get("regex").getAsString();
|
||||
return Pattern.compile(regex);
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ import com.microsoft.playwright.Locator;
|
||||
import com.microsoft.playwright.assertions.LocatorAssertions;
|
||||
import com.microsoft.playwright.options.AriaRole;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -30,20 +31,12 @@ import static com.microsoft.playwright.impl.Serialization.serializeArgument;
|
||||
import static com.microsoft.playwright.impl.Utils.convertType;
|
||||
|
||||
public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAssertions {
|
||||
LocatorImpl actualLocator;
|
||||
|
||||
public LocatorAssertionsImpl(Locator locator) {
|
||||
this(locator, false);
|
||||
}
|
||||
|
||||
private LocatorAssertionsImpl(Locator locator, boolean isNot) {
|
||||
super(isNot);
|
||||
this.actualLocator = (LocatorImpl) locator;
|
||||
}
|
||||
|
||||
@Override
|
||||
FrameExpectResult doExpect(String expression, FrameExpectOptions expectOptions, String title) {
|
||||
return actualLocator.expect(expression, expectOptions, title);
|
||||
super((LocatorImpl) locator, isNot);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,7 +44,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
public void containsClass(String classname, ContainsClassOptions options) {
|
||||
ExpectedTextValue expected = new ExpectedTextValue();
|
||||
expected.string = classname;
|
||||
expectImpl("to.contain.class", expected, classname, "Locator expected to contain class", convertType(options, FrameExpectOptions.class), "Assert \"containsClass\"");
|
||||
expectImpl("to.contain.class", expected, classname, "Locator expected to contain class", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -62,7 +55,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.string = text;
|
||||
list.add(expected);
|
||||
}
|
||||
expectImpl("to.contain.class.array", list, classnames, "Locator expected to contain classes", convertType(options, FrameExpectOptions.class), "Assert \"containsClass\"");
|
||||
expectImpl("to.contain.class.array", list, classnames, "Locator expected to contain classes", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -72,7 +65,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.ignoreCase = shouldIgnoreCase(options);
|
||||
expected.matchSubstring = true;
|
||||
expected.normalizeWhiteSpace = true;
|
||||
expectImpl("to.have.text", expected, text, "Locator expected to contain text", convertType(options, FrameExpectOptions.class), "Assert \"containsText\"");
|
||||
expectImpl("to.have.text", expected, text, "Locator expected to contain text", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -81,7 +74,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.ignoreCase = shouldIgnoreCase(options);
|
||||
expected.matchSubstring = true;
|
||||
expected.normalizeWhiteSpace = true;
|
||||
expectImpl("to.have.text", expected, pattern, "Locator expected to contain regex", convertType(options, FrameExpectOptions.class), "Assert \"containsText\"");
|
||||
expectImpl("to.have.text", expected, pattern, "Locator expected to contain regex", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -95,7 +88,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.normalizeWhiteSpace = true;
|
||||
list.add(expected);
|
||||
}
|
||||
expectImpl("to.contain.text.array", list, strings, "Locator expected to contain text", convertType(options, FrameExpectOptions.class), "Assert \"containsText\"");
|
||||
expectImpl("to.contain.text.array", list, strings, "Locator expected to contain text", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -108,7 +101,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.normalizeWhiteSpace = true;
|
||||
list.add(expected);
|
||||
}
|
||||
expectImpl("to.contain.text.array", list, patterns, "Locator expected to contain text", convertType(options, FrameExpectOptions.class), "Assert \"containsText\"");
|
||||
expectImpl("to.contain.text.array", list, patterns, "Locator expected to contain text", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -117,7 +110,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.string = description;
|
||||
expected.ignoreCase = shouldIgnoreCase(options);
|
||||
expected.normalizeWhiteSpace = true;
|
||||
expectImpl("to.have.accessible.description", expected, description, "Locator expected to have accessible description", convertType(options, FrameExpectOptions.class), "Assert \"hasAccessibleDescription\"");
|
||||
expectImpl("to.have.accessible.description", expected, description, "Locator expected to have accessible description", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -125,7 +118,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
ExpectedTextValue expected = expectedRegex(pattern);
|
||||
expected.ignoreCase = shouldIgnoreCase(options);
|
||||
expected.normalizeWhiteSpace = true;
|
||||
expectImpl("to.have.accessible.description", expected, pattern, "Locator expected to have accessible description", convertType(options, FrameExpectOptions.class), "Assert \"hasAccessibleDescription\"");
|
||||
expectImpl("to.have.accessible.description", expected, pattern, "Locator expected to have accessible description", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -134,7 +127,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.string = errorMessage;
|
||||
expected.ignoreCase = shouldIgnoreCase(options);
|
||||
expected.normalizeWhiteSpace = true;
|
||||
expectImpl("to.have.accessible.error.message", expected, errorMessage, "Locator expected to have accessible error message", convertType(options, FrameExpectOptions.class), "Assert \"hasAccessibleErrorMessage\"");
|
||||
expectImpl("to.have.accessible.error.message", expected, errorMessage, "Locator expected to have accessible error message", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -142,7 +135,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
ExpectedTextValue expected = expectedRegex(pattern);
|
||||
expected.ignoreCase = shouldIgnoreCase(options);
|
||||
expected.normalizeWhiteSpace = true;
|
||||
expectImpl("to.have.accessible.error.message", expected, pattern, "Locator expected to have accessible error message", convertType(options, FrameExpectOptions.class), "Assert \"hasAccessibleErrorMessage\"");
|
||||
expectImpl("to.have.accessible.error.message", expected, pattern, "Locator expected to have accessible error message", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -151,7 +144,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.string = name;
|
||||
expected.ignoreCase = shouldIgnoreCase(options);
|
||||
expected.normalizeWhiteSpace = true;
|
||||
expectImpl("to.have.accessible.name", expected, name, "Locator expected to have accessible name", convertType(options, FrameExpectOptions.class), "Assert \"hasAccessibleName\"");
|
||||
expectImpl("to.have.accessible.name", expected, name, "Locator expected to have accessible name", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -159,7 +152,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
ExpectedTextValue expected = expectedRegex(pattern);
|
||||
expected.ignoreCase = shouldIgnoreCase(options);
|
||||
expected.normalizeWhiteSpace = true;
|
||||
expectImpl("to.have.accessible.name", expected, pattern, "Locator expected to have accessible name", convertType(options, FrameExpectOptions.class), "Assert \"hasAccessibleName\"");
|
||||
expectImpl("to.have.accessible.name", expected, pattern, "Locator expected to have accessible name", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -187,20 +180,20 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
if (expectedValue instanceof Pattern) {
|
||||
message += " matching regex";
|
||||
}
|
||||
expectImpl("to.have.attribute.value", expectedText, expectedValue, message, commonOptions, "Assert \"hasAttribute\"");
|
||||
expectImpl("to.have.attribute.value", expectedText, expectedValue, message, commonOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasClass(String text, HasClassOptions options) {
|
||||
ExpectedTextValue expected = new ExpectedTextValue();
|
||||
expected.string = text;
|
||||
expectImpl("to.have.class", expected, text, "Locator expected to have class", convertType(options, FrameExpectOptions.class), "Assert \"hasClass\"");
|
||||
expectImpl("to.have.class", expected, text, "Locator expected to have class", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasClass(Pattern pattern, HasClassOptions options) {
|
||||
ExpectedTextValue expected = expectedRegex(pattern);
|
||||
expectImpl("to.have.class", expected, pattern, "Locator expected to have class matching regex", convertType(options, FrameExpectOptions.class), "Assert \"hasClass\"");
|
||||
expectImpl("to.have.class", expected, pattern, "Locator expected to have class matching regex", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -211,7 +204,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.string = text;
|
||||
list.add(expected);
|
||||
}
|
||||
expectImpl("to.have.class.array", list, strings, "Locator expected to have class", convertType(options, FrameExpectOptions.class), "Assert \"hasClass\"");
|
||||
expectImpl("to.have.class.array", list, strings, "Locator expected to have class", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -221,7 +214,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
ExpectedTextValue expected = expectedRegex(pattern);
|
||||
list.add(expected);
|
||||
}
|
||||
expectImpl("to.have.class.array", list, patterns, "Locator expected to have class matching regex", convertType(options, FrameExpectOptions.class), "Assert \"hasClass\"");
|
||||
expectImpl("to.have.class.array", list, patterns, "Locator expected to have class matching regex", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -232,7 +225,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
FrameExpectOptions commonOptions = convertType(options, FrameExpectOptions.class);
|
||||
commonOptions.expectedNumber = (double) count;
|
||||
List<ExpectedTextValue> expectedText = null;
|
||||
expectImpl("to.have.count", expectedText, count, "Locator expected to have count", commonOptions, "Assert \"hasCount\"");
|
||||
expectImpl("to.have.count", expectedText, count, "Locator expected to have count", commonOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -258,20 +251,20 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
if (expectedValue instanceof Pattern) {
|
||||
message += " matching regex";
|
||||
}
|
||||
expectImpl("to.have.css", expectedText, expectedValue, message, commonOptions, "Assert \"hasCSS\"");
|
||||
expectImpl("to.have.css", expectedText, expectedValue, message, commonOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasId(String id, HasIdOptions options) {
|
||||
ExpectedTextValue expected = new ExpectedTextValue();
|
||||
expected.string = id;
|
||||
expectImpl("to.have.id", expected, id, "Locator expected to have ID", convertType(options, FrameExpectOptions.class), "Assert \"hasId\"");
|
||||
expectImpl("to.have.id", expected, id, "Locator expected to have ID", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasId(Pattern pattern, HasIdOptions options) {
|
||||
ExpectedTextValue expected = expectedRegex(pattern);
|
||||
expectImpl("to.have.id", expected, pattern, "Locator expected to have ID matching regex", convertType(options, FrameExpectOptions.class), "Assert \"hasId\"");
|
||||
expectImpl("to.have.id", expected, pattern, "Locator expected to have ID matching regex", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -283,14 +276,14 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
commonOptions.expressionArg = name;
|
||||
commonOptions.expectedValue = serializeArgument(value);
|
||||
List<ExpectedTextValue> list = null;
|
||||
expectImpl("to.have.property", list, value, "Locator expected to have JavaScript property '" + name + "'", commonOptions, "Assert \"hasJSProperty\"");
|
||||
expectImpl("to.have.property", list, value, "Locator expected to have JavaScript property '" + name + "'", commonOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasRole(AriaRole role, HasRoleOptions options) {
|
||||
ExpectedTextValue expected = new ExpectedTextValue();
|
||||
expected.string = role.toString().toLowerCase();
|
||||
expectImpl("to.have.role", expected, expected.string, "Locator expected to have role", convertType(options, FrameExpectOptions.class), "Assert \"hasRole\"");
|
||||
expectImpl("to.have.role", expected, expected.string, "Locator expected to have role", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -300,7 +293,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.ignoreCase = shouldIgnoreCase(options);
|
||||
expected.matchSubstring = false;
|
||||
expected.normalizeWhiteSpace = true;
|
||||
expectImpl("to.have.text", expected, text, "Locator expected to have text", convertType(options, FrameExpectOptions.class), "Assert \"hasText\"");
|
||||
expectImpl("to.have.text", expected, text, "Locator expected to have text", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -310,7 +303,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
// Just match substring, same as containsText.
|
||||
expected.matchSubstring = true;
|
||||
expected.normalizeWhiteSpace = true;
|
||||
expectImpl("to.have.text", expected, pattern, "Locator expected to have text matching regex", convertType(options, FrameExpectOptions.class), "Assert \"hasText\"");
|
||||
expectImpl("to.have.text", expected, pattern, "Locator expected to have text matching regex", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -324,7 +317,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.normalizeWhiteSpace = true;
|
||||
list.add(expected);
|
||||
}
|
||||
expectImpl("to.have.text.array", list, strings, "Locator expected to have text", convertType(options, FrameExpectOptions.class), "Assert \"hasText\"");
|
||||
expectImpl("to.have.text.array", list, strings, "Locator expected to have text", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -337,20 +330,20 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.normalizeWhiteSpace = true;
|
||||
list.add(expected);
|
||||
}
|
||||
expectImpl("to.have.text.array", list, patterns, "Locator expected to have text matching regex", convertType(options, FrameExpectOptions.class), "Assert \"hasText\"");
|
||||
expectImpl("to.have.text.array", list, patterns, "Locator expected to have text matching regex", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasValue(String value, HasValueOptions options) {
|
||||
ExpectedTextValue expected = new ExpectedTextValue();
|
||||
expected.string = value;
|
||||
expectImpl("to.have.value", expected, value, "Locator expected to have value", convertType(options, FrameExpectOptions.class), "Assert \"hasValue\"");
|
||||
expectImpl("to.have.value", expected, value, "Locator expected to have value", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasValue(Pattern pattern, HasValueOptions options) {
|
||||
ExpectedTextValue expected = expectedRegex(pattern);
|
||||
expectImpl("to.have.value", expected, pattern, "Locator expected to have value matching regex", convertType(options, FrameExpectOptions.class), "Assert \"hasValue\"");
|
||||
expectImpl("to.have.value", expected, pattern, "Locator expected to have value matching regex", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -361,7 +354,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.string = text;
|
||||
list.add(expected);
|
||||
}
|
||||
expectImpl("to.have.values", list, values, "Locator expected to have values", convertType(options, FrameExpectOptions.class), "Assert \"hasValues\"");
|
||||
expectImpl("to.have.values", list, values, "Locator expected to have values", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -372,7 +365,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
expected.matchSubstring = true;
|
||||
list.add(expected);
|
||||
}
|
||||
expectImpl("to.have.values", list, patterns, "Locator expected to have values matching regex", convertType(options, FrameExpectOptions.class), "Assert \"hasValues\"");
|
||||
expectImpl("to.have.values", list, patterns, "Locator expected to have values matching regex", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -382,7 +375,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
}
|
||||
FrameExpectOptions options = convertType(snapshotOptions, FrameExpectOptions.class);
|
||||
options.expectedValue = serializeArgument(expected);
|
||||
expectImpl("to.match.aria", options, expected,"Locator expected to match Aria snapshot", "Assert \"matchesAriaSnapshot\"");
|
||||
expectImpl("to.match.aria", options, expected,"Locator expected to match Aria snapshot");
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -410,12 +403,12 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
String message = "Locator expected to be";
|
||||
FrameExpectOptions expectOptions = convertType(options, FrameExpectOptions.class);
|
||||
expectOptions.expectedValue = serializeArgument(expectedValue);
|
||||
expectImpl("to.be.checked", expectOptions, expected, message, "Assert \"isChecked\"");
|
||||
expectImpl("to.be.checked", expectOptions, expected, message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isDisabled(IsDisabledOptions options) {
|
||||
expectTrue("to.be.disabled", "Locator expected to be disabled", convertType(options, FrameExpectOptions.class), "Assert \"isDisabled\"");
|
||||
expectTrue("to.be.disabled", "Locator expected to be disabled", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -423,12 +416,12 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
FrameExpectOptions frameOptions = convertType(options, FrameExpectOptions.class);
|
||||
boolean editable = options == null || options.editable == null || options.editable == true;
|
||||
String message = "Locator expected to be " + (editable ? "editable" : "readonly");
|
||||
expectTrue(editable ? "to.be.editable" : "to.be.readonly", message, frameOptions, "Assert \"isEditable\"");
|
||||
expectTrue(editable ? "to.be.editable" : "to.be.readonly", message, frameOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isEmpty(IsEmptyOptions options) {
|
||||
expectTrue("to.be.empty", "Locator expected to be empty", convertType(options, FrameExpectOptions.class), "Assert \"isEmpty\"");
|
||||
expectTrue("to.be.empty", "Locator expected to be empty", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -436,17 +429,17 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
FrameExpectOptions frameOptions = convertType(options, FrameExpectOptions.class);
|
||||
boolean enabled = options == null || options.enabled == null || options.enabled == true;
|
||||
String message = "Locator expected to be " + (enabled ? "enabled" : "disabled");
|
||||
expectTrue(enabled ? "to.be.enabled" : "to.be.disabled", message, frameOptions, "Assert \"isEnabled\"");
|
||||
expectTrue(enabled ? "to.be.enabled" : "to.be.disabled", message, frameOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isFocused(IsFocusedOptions options) {
|
||||
expectTrue("to.be.focused", "Locator expected to be focused", convertType(options, FrameExpectOptions.class), "Assert \"isFocused\"");
|
||||
expectTrue("to.be.focused", "Locator expected to be focused", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void isHidden(IsHiddenOptions options) {
|
||||
expectTrue("to.be.hidden", "Locator expected to be hidden", convertType(options, FrameExpectOptions.class), "Assert \"isHidden\"");
|
||||
expectTrue("to.be.hidden", "Locator expected to be hidden", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -455,7 +448,7 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
if (options != null && options.ratio != null) {
|
||||
expectOptions.expectedNumber = options.ratio;
|
||||
}
|
||||
expectTrue("to.be.in.viewport", "Locator expected to be in viewport", expectOptions, "Assert \"isInViewport\"");
|
||||
expectTrue("to.be.in.viewport", "Locator expected to be in viewport", expectOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -463,12 +456,12 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
FrameExpectOptions frameOptions = convertType(options, FrameExpectOptions.class);
|
||||
boolean visible = options == null || options.visible == null || options.visible == true;
|
||||
String message = "Locator expected to be " + (visible ? "visible" : "hidden");
|
||||
expectTrue(visible ? "to.be.visible" : "to.be.hidden", message, frameOptions, "Assert \"isVisible\"");
|
||||
expectTrue(visible ? "to.be.visible" : "to.be.hidden", message, frameOptions);
|
||||
}
|
||||
|
||||
private void expectTrue(String expression, String message, FrameExpectOptions options, String title) {
|
||||
private void expectTrue(String expression, String message, FrameExpectOptions options) {
|
||||
List<ExpectedTextValue> expectedText = null;
|
||||
expectImpl(expression, expectedText, null, message, options, title);
|
||||
expectImpl(expression, expectedText, null, message, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -481,6 +474,6 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
FrameExpectOptions frameOptions = convertType(options, FrameExpectOptions.class);
|
||||
boolean attached = options == null || options.attached == null || options.attached == true;
|
||||
String message = "Locator expected to be " + (attached ? "attached" : "detached");
|
||||
expectTrue(attached ? "to.be.attached" : "to.be.detached", message, frameOptions, "Assert \"isAttached\"");
|
||||
expectTrue(attached ? "to.be.attached" : "to.be.detached", message, frameOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,25 +67,27 @@ class LocatorImpl implements Locator {
|
||||
this.selector = selector;
|
||||
}
|
||||
|
||||
private <R, O> R withElement(BiFunction<ElementHandle, O, R> callback, O options, String title) {
|
||||
return frame.withTitle(title, () -> {
|
||||
ElementHandleOptions handleOptions = convertType(options, ElementHandleOptions.class);
|
||||
// TODO: support deadline based timeout
|
||||
// Double timeout = null;
|
||||
// if (handleOptions != null) {
|
||||
// timeout = handleOptions.timeout;
|
||||
// }
|
||||
// timeout = frame.page.timeoutSettings.timeout(timeout);
|
||||
// long deadline = System.nanoTime() + (long) timeout.doubleValue() * 1_000_000;
|
||||
ElementHandle handle = elementHandle(handleOptions);
|
||||
try {
|
||||
return callback.apply(handle, options);
|
||||
} finally {
|
||||
if (handle != null) {
|
||||
handle.dispose();
|
||||
}
|
||||
private static String escapeWithQuotes(String text) {
|
||||
return gson().toJson(text);
|
||||
}
|
||||
|
||||
private <R, O> R withElement(BiFunction<ElementHandle, O, R> callback, O options) {
|
||||
ElementHandleOptions handleOptions = convertType(options, ElementHandleOptions.class);
|
||||
// TODO: support deadline based timeout
|
||||
// Double timeout = null;
|
||||
// if (handleOptions != null) {
|
||||
// timeout = handleOptions.timeout;
|
||||
// }
|
||||
// timeout = frame.page.timeoutSettings.timeout(timeout);
|
||||
// long deadline = System.nanoTime() + (long) timeout.doubleValue() * 1_000_000;
|
||||
ElementHandle handle = elementHandle(handleOptions);
|
||||
try {
|
||||
return callback.apply(handle, options);
|
||||
} finally {
|
||||
if (handle != null) {
|
||||
handle.dispose();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -118,29 +120,37 @@ class LocatorImpl implements Locator {
|
||||
|
||||
@Override
|
||||
public String ariaSnapshot(AriaSnapshotOptions options) {
|
||||
return frame.withLogging("Locator.ariaSnapshot", () -> ariaSnapshotImpl(options));
|
||||
}
|
||||
|
||||
private String ariaSnapshotImpl(AriaSnapshotOptions options) {
|
||||
if (options == null) {
|
||||
options = new AriaSnapshotOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
JsonObject result = frame.sendMessage("ariaSnapshot", params, frame.timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject result = frame.sendMessage("ariaSnapshot", params).getAsJsonObject();
|
||||
return result.get("snapshot").getAsString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void blur(BlurOptions options) {
|
||||
frame.withLogging("Locator.blur", () -> blurImpl(options));
|
||||
}
|
||||
|
||||
private void blurImpl(BlurOptions options) {
|
||||
if (options == null) {
|
||||
options = new BlurOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("strict", true);
|
||||
frame.sendMessage("blur", params, frame.timeout(options.timeout));
|
||||
frame.sendMessage("blur", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public BoundingBox boundingBox(BoundingBoxOptions options) {
|
||||
return withElement((h, o) -> h.boundingBox(), options, "Bounding Box");
|
||||
return withElement((h, o) -> h.boundingBox(), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -153,7 +163,7 @@ class LocatorImpl implements Locator {
|
||||
|
||||
@Override
|
||||
public void clear(ClearOptions options) {
|
||||
frame.withTitle("Clear", () -> fill("", convertType(options, FillOptions.class)));
|
||||
fill("", convertType(options, FillOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -169,11 +179,6 @@ class LocatorImpl implements Locator {
|
||||
return frame.queryCount(selector);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator describe(String description) {
|
||||
return locator(describeSelector(description));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dblclick(DblclickOptions options) {
|
||||
if (options == null) {
|
||||
@@ -223,7 +228,7 @@ class LocatorImpl implements Locator {
|
||||
|
||||
@Override
|
||||
public Object evaluate(String expression, Object arg, EvaluateOptions options) {
|
||||
return withElement((h, o) -> h.evaluate(expression, arg), options, "Evaluate");
|
||||
return withElement((h, o) -> h.evaluate(expression, arg), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -233,7 +238,7 @@ class LocatorImpl implements Locator {
|
||||
|
||||
@Override
|
||||
public JSHandle evaluateHandle(String expression, Object arg, EvaluateHandleOptions options) {
|
||||
return withElement((h, o) -> h.evaluateHandle(expression, arg), options, "Evaluate");
|
||||
return withElement((h, o) -> h.evaluateHandle(expression, arg), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -478,7 +483,7 @@ class LocatorImpl implements Locator {
|
||||
|
||||
@Override
|
||||
public byte[] screenshot(ScreenshotOptions options) {
|
||||
return withElement((h, o) -> h.screenshot(o), convertType(options, ElementHandle.ScreenshotOptions.class), "Screenshot");
|
||||
return withElement((h, o) -> h.screenshot(o), convertType(options, ElementHandle.ScreenshotOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -486,7 +491,7 @@ class LocatorImpl implements Locator {
|
||||
withElement((h, o) -> {
|
||||
h.scrollIntoViewIfNeeded(o);
|
||||
return null;
|
||||
}, convertType(options, ElementHandle.ScrollIntoViewIfNeededOptions.class), "Scroll into view");
|
||||
}, convertType(options, ElementHandle.ScrollIntoViewIfNeededOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -542,7 +547,7 @@ class LocatorImpl implements Locator {
|
||||
withElement((h, o) -> {
|
||||
h.selectText(o);
|
||||
return null;
|
||||
}, convertType(options, ElementHandle.SelectTextOptions.class), "Select text");
|
||||
}, convertType(options, ElementHandle.SelectTextOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -622,7 +627,11 @@ class LocatorImpl implements Locator {
|
||||
if (options == null) {
|
||||
options = new WaitForOptions();
|
||||
}
|
||||
frame.waitForSelectorImpl(selector, convertType(options, Frame.WaitForSelectorOptions.class).setStrict(true), true);
|
||||
waitForImpl(options);
|
||||
}
|
||||
|
||||
private void waitForImpl(WaitForOptions options) {
|
||||
frame.withLogging("Locator.waitFor", () -> frame.waitForSelectorImpl(selector, convertType(options, Frame.WaitForSelectorOptions.class).setStrict(true), true));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -644,9 +653,8 @@ class LocatorImpl implements Locator {
|
||||
return frame.hashCode() ^ selector.hashCode();
|
||||
}
|
||||
|
||||
FrameExpectResult expect(String expression, FrameExpectOptions options, String title) {
|
||||
options.selector = selector;
|
||||
return frame.expect(expression, options, title);
|
||||
FrameExpectResult expect(String expression, FrameExpectOptions options) {
|
||||
return frame.withLogging("Locator.expect", () -> expectImpl(expression, options));
|
||||
}
|
||||
|
||||
JsonObject toProtocol() {
|
||||
@@ -655,4 +663,13 @@ class LocatorImpl implements Locator {
|
||||
result.addProperty("selector", selector);
|
||||
return result;
|
||||
}
|
||||
|
||||
private FrameExpectResult expectImpl(String expression, FrameExpectOptions options) {
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("selector", selector);
|
||||
params.addProperty("expression", expression);
|
||||
JsonElement json = frame.sendMessage("expect", params);
|
||||
FrameExpectResult result = gson().fromJson(json, FrameExpectResult.class);
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,12 +39,9 @@ public class LocatorUtils {
|
||||
return "internal:attr=[" + attrName + "=" + escapeForAttributeSelector(value, exact) + "]";
|
||||
}
|
||||
|
||||
static String describeSelector(String description) {
|
||||
return "internal:describe=" + gson().toJson(description);
|
||||
}
|
||||
|
||||
static String getByTestIdSelector(Object testId, PlaywrightImpl playwright) {
|
||||
return getByAttributeTextSelector(playwright.selectors.testIdAttributeName, testId, true);
|
||||
String testIdAttributeName = ((SharedSelectors) playwright.selectors()).testIdAttributeName;
|
||||
return getByAttributeTextSelector(testIdAttributeName, testId, true);
|
||||
}
|
||||
|
||||
static String getByAltTextSelector(Object text, Locator.GetByAltTextOptions options) {
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.microsoft.playwright.impl;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
class LoggingSupport {
|
||||
private static final boolean isEnabled;
|
||||
@@ -30,6 +31,29 @@ class LoggingSupport {
|
||||
private static final DateTimeFormatter timestampFormat = DateTimeFormatter.ofPattern(
|
||||
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX").withZone(ZoneId.of("UTC"));
|
||||
|
||||
void withLogging(String apiName, Runnable code) {
|
||||
withLogging(apiName, () -> {
|
||||
code.run();
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
<T> T withLogging(String apiName, Supplier<T> code) {
|
||||
if (isEnabled) {
|
||||
logApi("=> " + apiName + " started");
|
||||
}
|
||||
boolean success = false;
|
||||
try {
|
||||
T result = code.get();
|
||||
success = true;
|
||||
return result;
|
||||
} finally {
|
||||
if (isEnabled) {
|
||||
logApi("<= " + apiName + (success ? " succeeded" : " failed"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void logWithTimestamp(String message) {
|
||||
// This matches log format produced by the server.
|
||||
String timestamp = ZonedDateTime.now().format(timestampFormat);
|
||||
|
||||
@@ -19,7 +19,6 @@ package com.microsoft.playwright.impl;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.microsoft.playwright.Mouse;
|
||||
|
||||
import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT;
|
||||
import static com.microsoft.playwright.impl.Serialization.gson;
|
||||
import static com.microsoft.playwright.impl.Utils.convertType;
|
||||
|
||||
@@ -32,18 +31,22 @@ class MouseImpl implements Mouse {
|
||||
|
||||
@Override
|
||||
public void click(double x, double y, ClickOptions options) {
|
||||
page.withLogging("Mouse.click", () -> clickImpl(x, y, options));
|
||||
}
|
||||
|
||||
private void clickImpl(double x, double y, ClickOptions options) {
|
||||
if (options == null) {
|
||||
options = new ClickOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("x", x);
|
||||
params.addProperty("y", y);
|
||||
page.sendMessage("mouseClick", params, NO_TIMEOUT);
|
||||
page.sendMessage("mouseClick", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dblclick(double x, double y, DblclickOptions options) {
|
||||
page.withTitle("Double click", () -> dblclickImpl(x, y, options));
|
||||
page.withLogging("Mouse.dblclick", () -> dblclickImpl(x, y, options));
|
||||
}
|
||||
|
||||
private void dblclickImpl(double x, double y, DblclickOptions options) {
|
||||
@@ -59,38 +62,52 @@ class MouseImpl implements Mouse {
|
||||
|
||||
@Override
|
||||
public void down(DownOptions options) {
|
||||
page.withLogging("Mouse.down", () -> downImpl(options));
|
||||
}
|
||||
|
||||
private void downImpl(DownOptions options) {
|
||||
if (options == null) {
|
||||
options = new DownOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
page.sendMessage("mouseDown", params, NO_TIMEOUT);
|
||||
page.sendMessage("mouseDown", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void move(double x, double y, MoveOptions options) {
|
||||
page.withLogging("Mouse.move", () -> moveImpl(x, y, options));
|
||||
}
|
||||
|
||||
private void moveImpl(double x, double y, MoveOptions options) {
|
||||
if (options == null) {
|
||||
options = new MoveOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("x", x);
|
||||
params.addProperty("y", y);
|
||||
page.sendMessage("mouseMove", params, NO_TIMEOUT);
|
||||
page.sendMessage("mouseMove", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void up(UpOptions options) {
|
||||
if (options == null) {
|
||||
options = new UpOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
page.sendMessage("mouseUp", params, NO_TIMEOUT);
|
||||
page.withLogging("Mouse.up", () -> upImpl(options));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void wheel(double deltaX, double deltaY) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("deltaX", deltaX);
|
||||
params.addProperty("deltaY", deltaY);
|
||||
page.sendMessage("mouseWheel", params, NO_TIMEOUT);
|
||||
page.withLogging("Mouse.wheel", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("deltaX", deltaX);
|
||||
params.addProperty("deltaY", deltaY);
|
||||
page.sendMessage("mouseWheel", params);
|
||||
});
|
||||
}
|
||||
|
||||
private void upImpl(UpOptions options) {
|
||||
if (options == null) {
|
||||
options = new UpOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
page.sendMessage("mouseUp", params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.microsoft.playwright.assertions.PageAssertions;
|
||||
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static com.microsoft.playwright.impl.LocatorAssertionsImpl.shouldIgnoreCase;
|
||||
import static com.microsoft.playwright.impl.UrlMatcher.resolveUrl;
|
||||
import static com.microsoft.playwright.impl.Utils.convertType;
|
||||
|
||||
@@ -32,45 +33,39 @@ public class PageAssertionsImpl extends AssertionsBase implements PageAssertions
|
||||
}
|
||||
|
||||
private PageAssertionsImpl(Page page, boolean isNot) {
|
||||
super(isNot);
|
||||
super((LocatorImpl) page.locator(":root"), isNot);
|
||||
this.actualPage = (PageImpl) page;
|
||||
}
|
||||
|
||||
@Override
|
||||
FrameExpectResult doExpect(String expression, FrameExpectOptions expectOptions, String title) {
|
||||
FrameImpl frame = (FrameImpl) actualPage.mainFrame();
|
||||
return frame.expect(expression, expectOptions, title);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasTitle(String title, HasTitleOptions options) {
|
||||
ExpectedTextValue expected = new ExpectedTextValue();
|
||||
expected.string = title;
|
||||
expected.normalizeWhiteSpace = true;
|
||||
expectImpl("to.have.title", expected, title, "Page title expected to be", convertType(options, FrameExpectOptions.class), "Assert \"hasTitle\"");
|
||||
expectImpl("to.have.title", expected, title, "Page title expected to be", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasTitle(Pattern pattern, HasTitleOptions options) {
|
||||
ExpectedTextValue expected = expectedRegex(pattern);
|
||||
expectImpl("to.have.title", expected, pattern, "Page title expected to match regex", convertType(options, FrameExpectOptions.class), "Assert \"hasTitle\"");
|
||||
expectImpl("to.have.title", expected, pattern, "Page title expected to match regex", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasURL(String url, HasURLOptions options) {
|
||||
ExpectedTextValue expected = new ExpectedTextValue();
|
||||
if (actualPage.context().baseUrl() != null) {
|
||||
url = resolveUrl(actualPage.context().baseUrl(), url);
|
||||
if (actualPage.context().baseUrl != null) {
|
||||
url = resolveUrl(actualPage.context().baseUrl, url);
|
||||
}
|
||||
expected.string = url;
|
||||
expected.ignoreCase = shouldIgnoreCase(options);
|
||||
expectImpl("to.have.url", expected, url, "Page URL expected to be", convertType(options, FrameExpectOptions.class), "Assert \"hasURL\"");
|
||||
expectImpl("to.have.url", expected, url, "Page URL expected to be", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hasURL(Pattern pattern, HasURLOptions options) {
|
||||
ExpectedTextValue expected = expectedRegex(pattern);
|
||||
expectImpl("to.have.url", expected, pattern, "Page URL expected to match regex", convertType(options, FrameExpectOptions.class), "Assert \"hasURL\"");
|
||||
expectImpl("to.have.url", expected, pattern, "Page URL expected to match regex", convertType(options, FrameExpectOptions.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -95,7 +95,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
BrowserContextImpl ownedContext;
|
||||
private boolean isClosed;
|
||||
final Set<Worker> workers = new HashSet<>();
|
||||
protected final TimeoutSettings timeoutSettings;
|
||||
private final TimeoutSettings timeoutSettings;
|
||||
private VideoImpl video;
|
||||
private final PageImpl opener;
|
||||
private String closeReason;
|
||||
@@ -546,7 +546,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
ownedContext.close();
|
||||
} else {
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("close", params, NO_TIMEOUT);
|
||||
sendMessage("close", params);
|
||||
}
|
||||
} catch (PlaywrightException exception) {
|
||||
if (isSafeCloseError(exception) && (options.runBeforeUnload == null || !options.runBeforeUnload)) {
|
||||
@@ -558,13 +558,13 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public ElementHandle querySelector(String selector, QuerySelectorOptions options) {
|
||||
return mainFrame.querySelector(
|
||||
selector, convertType(options, Frame.QuerySelectorOptions.class));
|
||||
return withLogging("Page.querySelector", () -> mainFrame.querySelectorImpl(
|
||||
selector, convertType(options, Frame.QuerySelectorOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ElementHandle> querySelectorAll(String selector) {
|
||||
return mainFrame.querySelectorAll(selector);
|
||||
return withLogging("Page.querySelectorAll", () -> mainFrame.querySelectorAllImpl(selector));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -580,15 +580,17 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
return;
|
||||
}
|
||||
AddLocatorHandlerOptions finalOptions = options;
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", locatorImpl.selector);
|
||||
if (finalOptions.noWaitAfter != null && finalOptions.noWaitAfter) {
|
||||
params.addProperty("noWaitAfter", true);
|
||||
}
|
||||
params.addProperty("selector", locatorImpl.selector);
|
||||
JsonObject json = (JsonObject) sendMessage("registerLocatorHandler", params, NO_TIMEOUT);
|
||||
int uid = json.get("uid").getAsInt();
|
||||
locatorHandlers.put(uid, new LocatorHandler(locator, handler, finalOptions.times));
|
||||
withLogging("Page.addLocatorHandler", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("selector", locatorImpl.selector);
|
||||
if (finalOptions.noWaitAfter != null && finalOptions.noWaitAfter) {
|
||||
params.addProperty("noWaitAfter", true);
|
||||
}
|
||||
params.addProperty("selector", locatorImpl.selector);
|
||||
JsonObject json = (JsonObject) sendMessage("registerLocatorHandler", params);
|
||||
int uid = json.get("uid").getAsInt();
|
||||
locatorHandlers.put(uid, new LocatorHandler(locator, handler, finalOptions.times));
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -599,7 +601,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("uid", entry.getKey());
|
||||
try {
|
||||
sendMessage("unregisterLocatorHandler", params, NO_TIMEOUT);
|
||||
sendMessage("unregisterLocatorHandler", params);
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
}
|
||||
@@ -624,65 +626,71 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Object evalOnSelector(String selector, String pageFunction, Object arg, EvalOnSelectorOptions options) {
|
||||
return mainFrame.evalOnSelectorImpl(
|
||||
selector, pageFunction, arg, convertType(options, Frame.EvalOnSelectorOptions.class));
|
||||
return withLogging("Page.evalOnSelector", () -> mainFrame.evalOnSelectorImpl(
|
||||
selector, pageFunction, arg, convertType(options, Frame.EvalOnSelectorOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object evalOnSelectorAll(String selector, String pageFunction, Object arg) {
|
||||
return mainFrame.evalOnSelectorAllImpl(selector, pageFunction, arg);
|
||||
return withLogging("Page.evalOnSelectorAll", () -> mainFrame.evalOnSelectorAllImpl(selector, pageFunction, arg));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInitScript(String script) {
|
||||
addInitScriptImpl(script);
|
||||
withLogging("Page.addInitScript", () -> addInitScriptImpl(script));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addInitScript(Path path) {
|
||||
try {
|
||||
byte[] bytes = readAllBytes(path);
|
||||
String script = addSourceUrlToScript(new String(bytes, UTF_8), path);
|
||||
addInitScriptImpl(script);
|
||||
} catch (IOException e) {
|
||||
throw new PlaywrightException("Failed to read script from file", e);
|
||||
}
|
||||
withLogging("Page.addInitScript", () -> {
|
||||
try {
|
||||
byte[] bytes = readAllBytes(path);
|
||||
String script = addSourceUrlToScript(new String(bytes, UTF_8), path);
|
||||
addInitScriptImpl(script);
|
||||
} catch (IOException e) {
|
||||
throw new PlaywrightException("Failed to read script from file", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void addInitScriptImpl(String script) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("source", script);
|
||||
sendMessage("addInitScript", params, NO_TIMEOUT);
|
||||
sendMessage("addInitScript", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementHandle addScriptTag(AddScriptTagOptions options) {
|
||||
return mainFrame.addScriptTagImpl(convertType(options, Frame.AddScriptTagOptions.class));
|
||||
return withLogging("Page.addScriptTag",
|
||||
() -> mainFrame.addScriptTagImpl(convertType(options, Frame.AddScriptTagOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ElementHandle addStyleTag(AddStyleTagOptions options) {
|
||||
return mainFrame.addStyleTagImpl(convertType(options, Frame.AddStyleTagOptions.class));
|
||||
return withLogging("Page.addStyleTag",
|
||||
() -> mainFrame.addStyleTagImpl(convertType(options, Frame.AddStyleTagOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bringToFront() {
|
||||
sendMessage("bringToFront");
|
||||
withLogging("Page.bringToFront", () -> sendMessage("bringToFront"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void check(String selector, CheckOptions options) {
|
||||
mainFrame.check(selector, convertType(options, Frame.CheckOptions.class));
|
||||
withLogging("Page.check",
|
||||
() -> mainFrame.checkImpl(selector, convertType(options, Frame.CheckOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void click(String selector, ClickOptions options) {
|
||||
mainFrame.clickImpl(selector, convertType(options, Frame.ClickOptions.class));
|
||||
withLogging("Page.click",
|
||||
() -> mainFrame.clickImpl(selector, convertType(options, Frame.ClickOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String content() {
|
||||
return mainFrame.content();
|
||||
return withLogging("Page.content", () -> mainFrame.contentImpl());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -692,17 +700,19 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void dblclick(String selector, DblclickOptions options) {
|
||||
mainFrame.dblclick(selector, convertType(options, Frame.DblclickOptions.class));
|
||||
withLogging("Page.dblclick",
|
||||
() -> mainFrame.dblclickImpl(selector, convertType(options, Frame.DblclickOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispatchEvent(String selector, String type, Object eventInit, DispatchEventOptions options) {
|
||||
mainFrame.dispatchEvent(selector, type, eventInit, convertType(options, Frame.DispatchEventOptions.class));
|
||||
withLogging("Page.dispatchEvent",
|
||||
() -> mainFrame.dispatchEventImpl(selector, type, eventInit, convertType(options, Frame.DispatchEventOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emulateMedia(EmulateMediaOptions options) {
|
||||
emulateMediaImpl(options);
|
||||
withLogging("Page.emulateMedia", () -> emulateMediaImpl(options));
|
||||
}
|
||||
|
||||
private void emulateMediaImpl(EmulateMediaOptions options) {
|
||||
@@ -710,22 +720,22 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
options = new EmulateMediaOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
sendMessage("emulateMedia", params, NO_TIMEOUT);
|
||||
sendMessage("emulateMedia", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object evaluate(String expression, Object arg) {
|
||||
return mainFrame.evaluate(expression, arg);
|
||||
return withLogging("Page.evaluate", () -> mainFrame.evaluateImpl(expression, arg));
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSHandle evaluateHandle(String pageFunction, Object arg) {
|
||||
return mainFrame.evaluateHandle(pageFunction, arg);
|
||||
return withLogging("Page.evaluateHandle", () -> mainFrame.evaluateHandleImpl(pageFunction, arg));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exposeBinding(String name, BindingCallback playwrightBinding, ExposeBindingOptions options) {
|
||||
exposeBindingImpl(name, playwrightBinding, options);
|
||||
withLogging("Page.exposeBinding", () -> exposeBindingImpl(name, playwrightBinding, options));
|
||||
}
|
||||
|
||||
private void exposeBindingImpl(String name, BindingCallback playwrightBinding, ExposeBindingOptions options) {
|
||||
@@ -742,22 +752,25 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
if (options != null && options.handle != null && options.handle) {
|
||||
params.addProperty("needsHandle", true);
|
||||
}
|
||||
sendMessage("exposeBinding", params, NO_TIMEOUT);
|
||||
sendMessage("exposeBinding", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exposeFunction(String name, FunctionCallback playwrightFunction) {
|
||||
exposeBindingImpl(name, (BindingCallback.Source source, Object... args) -> playwrightFunction.call(args), null);
|
||||
withLogging("Page.exposeFunction",
|
||||
() -> exposeBindingImpl(name, (BindingCallback.Source source, Object... args) -> playwrightFunction.call(args), null));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fill(String selector, String value, FillOptions options) {
|
||||
mainFrame.fill(selector, value, convertType(options, Frame.FillOptions.class));
|
||||
withLogging("Page.fill",
|
||||
() -> mainFrame.fillImpl(selector, value, convertType(options, Frame.FillOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void focus(String selector, FocusOptions options) {
|
||||
mainFrame.focus(selector, convertType(options, Frame.FocusOptions.class));
|
||||
withLogging("Page.focus",
|
||||
() -> mainFrame.focusImpl(selector, convertType(options, Frame.FocusOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -772,7 +785,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Frame frameByUrl(String glob) {
|
||||
return frameFor(UrlMatcher.forGlob(browserContext.baseUrl(), glob, this.connection.localUtils, false));
|
||||
return frameFor(UrlMatcher.forGlob(browserContext.baseUrl, glob, this.connection.localUtils, false));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -806,77 +819,89 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public String getAttribute(String selector, String name, GetAttributeOptions options) {
|
||||
return mainFrame.getAttributeImpl(selector, name, convertType(options, Frame.GetAttributeOptions.class));
|
||||
return withLogging("Page.getAttribute",
|
||||
() -> mainFrame.getAttributeImpl(selector, name, convertType(options, Frame.GetAttributeOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByAltText(String text, GetByAltTextOptions options) {
|
||||
return mainFrame.getByAltText(text, convertType(options, Frame.GetByAltTextOptions.class));
|
||||
return withLogging("Page.getAttribute",
|
||||
() -> mainFrame.getByAltText(text, convertType(options, Frame.GetByAltTextOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByAltText(Pattern text, GetByAltTextOptions options) {
|
||||
return mainFrame.getByAltText(text, convertType(options, Frame.GetByAltTextOptions.class));
|
||||
return withLogging("Page.getByAltText",
|
||||
() -> mainFrame.getByAltText(text, convertType(options, Frame.GetByAltTextOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByLabel(String text, GetByLabelOptions options) {
|
||||
return mainFrame.getByLabel(text, convertType(options, Frame.GetByLabelOptions.class));
|
||||
return withLogging("Page.getByLabel",
|
||||
() -> mainFrame.getByLabel(text, convertType(options, Frame.GetByLabelOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByLabel(Pattern text, GetByLabelOptions options) {
|
||||
return mainFrame.getByLabel(text, convertType(options, Frame.GetByLabelOptions.class));
|
||||
return withLogging("Page.getByLabel",
|
||||
() -> mainFrame.getByLabel(text, convertType(options, Frame.GetByLabelOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByPlaceholder(String text, GetByPlaceholderOptions options) {
|
||||
return mainFrame.getByPlaceholder(text, convertType(options, Frame.GetByPlaceholderOptions.class));
|
||||
return withLogging("Page.getByPlaceholder",
|
||||
() -> mainFrame.getByPlaceholder(text, convertType(options, Frame.GetByPlaceholderOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByPlaceholder(Pattern text, GetByPlaceholderOptions options) {
|
||||
return mainFrame.getByPlaceholder(text, convertType(options, Frame.GetByPlaceholderOptions.class));
|
||||
return withLogging("Page.getByPlaceholder",
|
||||
() -> mainFrame.getByPlaceholder(text, convertType(options, Frame.GetByPlaceholderOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByRole(AriaRole role, GetByRoleOptions options) {
|
||||
return mainFrame.getByRole(role, convertType(options, Frame.GetByRoleOptions.class));
|
||||
return withLogging("Page.getByRole",
|
||||
() -> mainFrame.getByRole(role, convertType(options, Frame.GetByRoleOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByTestId(String testId) {
|
||||
return mainFrame.getByTestId(testId);
|
||||
return withLogging("Page.getByTestId", () -> mainFrame.getByTestId(testId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByTestId(Pattern testId) {
|
||||
return mainFrame.getByTestId(testId);
|
||||
return withLogging("Page.getByTestId", () -> mainFrame.getByTestId(testId));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByText(String text, GetByTextOptions options) {
|
||||
return mainFrame.getByText(text, convertType(options, Frame.GetByTextOptions.class));
|
||||
return withLogging("Page.getByText",
|
||||
() -> mainFrame.getByText(text, convertType(options, Frame.GetByTextOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByText(Pattern text, GetByTextOptions options) {
|
||||
return mainFrame.getByText(text, convertType(options, Frame.GetByTextOptions.class));
|
||||
return withLogging("Page.getByText",
|
||||
() -> mainFrame.getByText(text, convertType(options, Frame.GetByTextOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByTitle(String text, GetByTitleOptions options) {
|
||||
return mainFrame.getByTitle(text, convertType(options, Frame.GetByTitleOptions.class));
|
||||
return withLogging("Page.getByTitle",
|
||||
() -> mainFrame.getByTitle(text, convertType(options, Frame.GetByTitleOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Locator getByTitle(Pattern text, GetByTitleOptions options) {
|
||||
return mainFrame.getByTitle(text, convertType(options, Frame.GetByTitleOptions.class));
|
||||
return withLogging("Page.getByTitle",
|
||||
() -> mainFrame.getByTitle(text, convertType(options, Frame.GetByTitleOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response goBack(GoBackOptions options) {
|
||||
return goBackImpl(options);
|
||||
return withLogging("Page.goBack", () -> goBackImpl(options));
|
||||
}
|
||||
|
||||
Response goBackImpl(GoBackOptions options) {
|
||||
@@ -884,7 +909,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
options = new GoBackOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
JsonObject json = sendMessage("goBack", params, timeoutSettings.navigationTimeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("goBack", params).getAsJsonObject();
|
||||
if (json.has("response")) {
|
||||
return connection.getExistingObject(json.getAsJsonObject("response").get("guid").getAsString());
|
||||
}
|
||||
@@ -893,7 +918,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Response goForward(GoForwardOptions options) {
|
||||
return goForwardImpl(options);
|
||||
return withLogging("Page.goForward", () -> goForwardImpl(options));
|
||||
}
|
||||
|
||||
Response goForwardImpl(GoForwardOptions options) {
|
||||
@@ -901,7 +926,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
options = new GoForwardOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
JsonObject json = sendMessage("goForward", params, timeoutSettings.navigationTimeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("goForward", params).getAsJsonObject();
|
||||
if (json.has("response")) {
|
||||
return connection.getExistingObject(json.getAsJsonObject("response").get("guid").getAsString());
|
||||
}
|
||||
@@ -910,42 +935,46 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void requestGC() {
|
||||
sendMessage("requestGC");
|
||||
withLogging("Page.requestGC", () -> sendMessage("requestGC"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResponseImpl navigate(String url, NavigateOptions options) {
|
||||
return mainFrame.navigateImpl(url, convertType(options, Frame.NavigateOptions.class));
|
||||
return withLogging("Page.navigate", () -> mainFrame.navigateImpl(url, convertType(options, Frame.NavigateOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void hover(String selector, HoverOptions options) {
|
||||
mainFrame.hoverImpl(selector, convertType(options, Frame.HoverOptions.class));
|
||||
withLogging("Page.hover", () -> mainFrame.hoverImpl(selector, convertType(options, Frame.HoverOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dragAndDrop(String source, String target, DragAndDropOptions options) {
|
||||
mainFrame.dragAndDropImpl(source, target, convertType(options, Frame.DragAndDropOptions.class));
|
||||
withLogging("Page.dragAndDrop", () -> mainFrame.dragAndDropImpl(source, target, convertType(options, Frame.DragAndDropOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String innerHTML(String selector, InnerHTMLOptions options) {
|
||||
return mainFrame.innerHTMLImpl(selector, convertType(options, Frame.InnerHTMLOptions.class));
|
||||
return withLogging("Page.innerHTML",
|
||||
() -> mainFrame.innerHTMLImpl(selector, convertType(options, Frame.InnerHTMLOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String innerText(String selector, InnerTextOptions options) {
|
||||
return mainFrame.innerTextImpl(selector, convertType(options, Frame.InnerTextOptions.class));
|
||||
return withLogging("Page.innerText",
|
||||
() -> mainFrame.innerTextImpl(selector, convertType(options, Frame.InnerTextOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String inputValue(String selector, InputValueOptions options) {
|
||||
return mainFrame.inputValueImpl(selector, convertType(options, Frame.InputValueOptions.class));
|
||||
return withLogging("Page.inputValue",
|
||||
() -> mainFrame.inputValueImpl(selector, convertType(options, Frame.InputValueOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isChecked(String selector, IsCheckedOptions options) {
|
||||
return mainFrame.isCheckedImpl(selector, convertType(options, Frame.IsCheckedOptions.class));
|
||||
return withLogging("Page.isChecked",
|
||||
() -> mainFrame.isCheckedImpl(selector, convertType(options, Frame.IsCheckedOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -955,27 +984,32 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public boolean isDisabled(String selector, IsDisabledOptions options) {
|
||||
return mainFrame.isDisabledImpl(selector, convertType(options, Frame.IsDisabledOptions.class));
|
||||
return withLogging("Page.isDisabled",
|
||||
() -> mainFrame.isDisabledImpl(selector, convertType(options, Frame.IsDisabledOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEditable(String selector, IsEditableOptions options) {
|
||||
return mainFrame.isEditableImpl(selector, convertType(options, Frame.IsEditableOptions.class));
|
||||
return withLogging("Page.isEditable",
|
||||
() -> mainFrame.isEditableImpl(selector, convertType(options, Frame.IsEditableOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(String selector, IsEnabledOptions options) {
|
||||
return mainFrame.isEnabledImpl(selector, convertType(options, Frame.IsEnabledOptions.class));
|
||||
return withLogging("Page.isEnabled",
|
||||
() -> mainFrame.isEnabledImpl(selector, convertType(options, Frame.IsEnabledOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isHidden(String selector, IsHiddenOptions options) {
|
||||
return mainFrame.isHiddenImpl(selector, convertType(options, Frame.IsHiddenOptions.class));
|
||||
return withLogging("Page.isHidden",
|
||||
() -> mainFrame.isHiddenImpl(selector, convertType(options, Frame.IsHiddenOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isVisible(String selector, IsVisibleOptions options) {
|
||||
return mainFrame.isVisibleImpl(selector, convertType(options, Frame.IsVisibleOptions.class));
|
||||
return withLogging("Page.isVisible",
|
||||
() -> mainFrame.isVisibleImpl(selector, convertType(options, Frame.IsVisibleOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1008,21 +1042,23 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void pause() {
|
||||
Double defaultNavigationTimeout = browserContext.timeoutSettings.defaultNavigationTimeout();
|
||||
Double defaultTimeout = browserContext.timeoutSettings.defaultTimeout();
|
||||
browserContext.setDefaultNavigationTimeout(0.0);
|
||||
browserContext.setDefaultTimeout(0.0);
|
||||
try {
|
||||
runUntil(() -> {}, new WaitableRace<>(asList(context().pause(), (Waitable<JsonElement>) waitableClosedOrCrashed)));
|
||||
} finally {
|
||||
browserContext.setDefaultNavigationTimeout(defaultNavigationTimeout);
|
||||
browserContext.setDefaultTimeout(defaultTimeout);
|
||||
}
|
||||
withLogging("Page.pause", () -> {
|
||||
Double defaultNavigationTimeout = browserContext.timeoutSettings.defaultNavigationTimeout();
|
||||
Double defaultTimeout = browserContext.timeoutSettings.defaultTimeout();
|
||||
browserContext.setDefaultNavigationTimeoutImpl(0.0);
|
||||
browserContext.setDefaultTimeoutImpl(0.0);
|
||||
try {
|
||||
runUntil(() -> {}, new WaitableRace<>(asList(context().pause(), (Waitable<JsonElement>) waitableClosedOrCrashed)));
|
||||
} finally {
|
||||
browserContext.setDefaultNavigationTimeoutImpl(defaultNavigationTimeout);
|
||||
browserContext.setDefaultTimeoutImpl(defaultTimeout);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] pdf(PdfOptions options) {
|
||||
return pdfImpl(options);
|
||||
return withLogging("Page.pdf", () -> pdfImpl(options));
|
||||
}
|
||||
|
||||
private byte[] pdfImpl(PdfOptions options) {
|
||||
@@ -1031,7 +1067,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.remove("path");
|
||||
JsonObject json = sendMessage("pdf", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = sendMessage("pdf", params).getAsJsonObject();
|
||||
byte[] buffer = Base64.getDecoder().decode(json.get("pdf").getAsString());
|
||||
if (options.path != null) {
|
||||
Utils.writeToFile(buffer, options.path);
|
||||
@@ -1041,12 +1077,13 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void press(String selector, String key, PressOptions options) {
|
||||
mainFrame.pressImpl(selector, key, convertType(options, Frame.PressOptions.class));
|
||||
withLogging("Page.press",
|
||||
() -> mainFrame.pressImpl(selector, key, convertType(options, Frame.PressOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response reload(ReloadOptions options) {
|
||||
return reloadImpl(options);
|
||||
return withLogging("Page.reload", () -> reloadImpl(options));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1059,7 +1096,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
options = new ReloadOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
JsonObject json = sendMessage("reload", params, timeoutSettings.navigationTimeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("reload", params).getAsJsonObject();
|
||||
if (json.has("response")) {
|
||||
return connection.getExistingObject(json.getAsJsonObject("response").get("guid").getAsString());
|
||||
}
|
||||
@@ -1068,7 +1105,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void route(String url, Consumer<Route> handler, RouteOptions options) {
|
||||
route(UrlMatcher.forGlob(browserContext.baseUrl(), url, this.connection.localUtils, false), handler, options);
|
||||
route(UrlMatcher.forGlob(browserContext.baseUrl, url, this.connection.localUtils, false), handler, options);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1087,23 +1124,25 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
options = new RouteFromHAROptions();
|
||||
}
|
||||
if (options.update != null && options.update) {
|
||||
browserContext.recordIntoHar(this, har, convertType(options, BrowserContext.RouteFromHAROptions.class), null);
|
||||
browserContext.recordIntoHar(this, har, convertType(options, BrowserContext.RouteFromHAROptions.class));
|
||||
return;
|
||||
}
|
||||
UrlMatcher matcher = UrlMatcher.forOneOf(browserContext.baseUrl(), options.url, this.connection.localUtils, false);
|
||||
UrlMatcher matcher = UrlMatcher.forOneOf(browserContext.baseUrl, options.url, this.connection.localUtils, false);
|
||||
HARRouter harRouter = new HARRouter(connection.localUtils, har, options.notFound);
|
||||
onClose(context -> harRouter.dispose());
|
||||
route(matcher, route -> harRouter.handle(route), null);
|
||||
}
|
||||
|
||||
private void route(UrlMatcher matcher, Consumer<Route> handler, RouteOptions options) {
|
||||
routes.add(matcher, handler, options == null ? null : options.times);
|
||||
updateInterceptionPatterns();
|
||||
withLogging("Page.route", () -> {
|
||||
routes.add(matcher, handler, options == null ? null : options.times);
|
||||
updateInterceptionPatterns();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void routeWebSocket(String url, Consumer<WebSocketRoute> handler) {
|
||||
routeWebSocketImpl(UrlMatcher.forGlob(browserContext.baseUrl(), url, this.connection.localUtils, true), handler);
|
||||
routeWebSocketImpl(UrlMatcher.forGlob(browserContext.baseUrl, url, this.connection.localUtils, true), handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1117,13 +1156,15 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
}
|
||||
|
||||
private void routeWebSocketImpl(UrlMatcher matcher, Consumer<WebSocketRoute> handler) {
|
||||
webSocketRoutes.add(matcher, handler);
|
||||
updateWebSocketInterceptionPatterns();
|
||||
withLogging("Page.routeWebSocket", () -> {
|
||||
webSocketRoutes.add(matcher, handler);
|
||||
updateWebSocketInterceptionPatterns();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] screenshot(ScreenshotOptions options) {
|
||||
return screenshotImpl(options);
|
||||
return withLogging("Page.screenshot", () -> screenshotImpl(options));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1140,7 +1181,8 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public List<String> selectOption(String selector, String[] values, SelectOptionOptions options) {
|
||||
return mainFrame.selectOptionImpl(selector, values, convertType(options, Frame.SelectOptionOptions.class));
|
||||
return withLogging("Page.selectOption",
|
||||
() -> mainFrame.selectOptionImpl(selector, values, convertType(options, Frame.SelectOptionOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1178,7 +1220,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
}
|
||||
params.add("mask", maskArray);
|
||||
}
|
||||
JsonObject json = sendMessage("screenshot", params, timeoutSettings.timeout(options.timeout)).getAsJsonObject();
|
||||
JsonObject json = sendMessage("screenshot", params).getAsJsonObject();
|
||||
|
||||
byte[] buffer = Base64.getDecoder().decode(json.get("binary").getAsString());
|
||||
if (options.path != null) {
|
||||
@@ -1189,46 +1231,62 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public List<String> selectOption(String selector, SelectOption[] values, SelectOptionOptions options) {
|
||||
return mainFrame.selectOptionImpl(selector, values, convertType(options, Frame.SelectOptionOptions.class));
|
||||
return withLogging("Page.selectOption",
|
||||
() -> mainFrame.selectOptionImpl(selector, values, convertType(options, Frame.SelectOptionOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> selectOption(String selector, ElementHandle[] values, SelectOptionOptions options) {
|
||||
return mainFrame.selectOptionImpl(selector, values, convertType(options, Frame.SelectOptionOptions.class));
|
||||
return withLogging("Page.selectOption",
|
||||
() -> mainFrame.selectOptionImpl(selector, values, convertType(options, Frame.SelectOptionOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setChecked(String selector, boolean checked, SetCheckedOptions options) {
|
||||
mainFrame.setCheckedImpl(selector, checked, convertType(options, Frame.SetCheckedOptions.class));
|
||||
withLogging("Page.setChecked",
|
||||
() -> mainFrame.setCheckedImpl(selector, checked, convertType(options, Frame.SetCheckedOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setContent(String html, SetContentOptions options) {
|
||||
mainFrame.setContent(html, convertType(options, Frame.SetContentOptions.class));
|
||||
withLogging("Page.setContent",
|
||||
() -> mainFrame.setContentImpl(html, convertType(options, Frame.SetContentOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultNavigationTimeout(double timeout) {
|
||||
timeoutSettings.setDefaultNavigationTimeout(timeout);
|
||||
withLogging("Page.setDefaultNavigationTimeout", () -> {
|
||||
timeoutSettings.setDefaultNavigationTimeout(timeout);
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("timeout", timeout);
|
||||
sendMessage("setDefaultNavigationTimeoutNoReply", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setDefaultTimeout(double timeout) {
|
||||
timeoutSettings.setDefaultTimeout(timeout);
|
||||
withLogging("Page.setDefaultTimeout", () -> {
|
||||
timeoutSettings.setDefaultTimeout(timeout);
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("timeout", timeout);
|
||||
sendMessage("setDefaultTimeoutNoReply", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setExtraHTTPHeaders(Map<String, String> headers) {
|
||||
JsonObject params = new JsonObject();
|
||||
JsonArray jsonHeaders = new JsonArray();
|
||||
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||
JsonObject header = new JsonObject();
|
||||
header.addProperty("name", e.getKey());
|
||||
header.addProperty("value", e.getValue());
|
||||
jsonHeaders.add(header);
|
||||
}
|
||||
params.add("headers", jsonHeaders);
|
||||
sendMessage("setExtraHTTPHeaders", params, NO_TIMEOUT);
|
||||
withLogging("Page.setExtraHTTPHeaders", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
JsonArray jsonHeaders = new JsonArray();
|
||||
for (Map.Entry<String, String> e : headers.entrySet()) {
|
||||
JsonObject header = new JsonObject();
|
||||
header.addProperty("name", e.getKey());
|
||||
header.addProperty("value", e.getValue());
|
||||
jsonHeaders.add(header);
|
||||
}
|
||||
params.add("headers", jsonHeaders);
|
||||
sendMessage("setExtraHTTPHeaders", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1238,7 +1296,8 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void setInputFiles(String selector, Path[] files, SetInputFilesOptions options) {
|
||||
mainFrame.setInputFilesImpl(selector, files, convertType(options, Frame.SetInputFilesOptions.class));
|
||||
withLogging("Page.setInputFiles",
|
||||
() -> mainFrame.setInputFilesImpl(selector, files, convertType(options, Frame.SetInputFilesOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1248,30 +1307,35 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void setInputFiles(String selector, FilePayload[] files, SetInputFilesOptions options) {
|
||||
mainFrame.setInputFilesImpl(selector, files, convertType(options, Frame.SetInputFilesOptions.class));
|
||||
withLogging("Page.setInputFiles",
|
||||
() -> mainFrame.setInputFilesImpl(selector, files, convertType(options, Frame.SetInputFilesOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setViewportSize(int width, int height) {
|
||||
viewport = new ViewportSize(width, height);
|
||||
JsonObject params = new JsonObject();
|
||||
params.add("viewportSize", gson().toJsonTree(viewport));
|
||||
sendMessage("setViewportSize", params, NO_TIMEOUT);
|
||||
withLogging("Page.setViewportSize", () -> {
|
||||
viewport = new ViewportSize(width, height);
|
||||
JsonObject params = new JsonObject();
|
||||
params.add("viewportSize", gson().toJsonTree(viewport));
|
||||
sendMessage("setViewportSize", params);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void tap(String selector, TapOptions options) {
|
||||
mainFrame.tap(selector, convertType(options, Frame.TapOptions.class));
|
||||
withLogging("Page.tap",
|
||||
() -> mainFrame.tapImpl(selector, convertType(options, Frame.TapOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String textContent(String selector, TextContentOptions options) {
|
||||
return mainFrame.textContent(selector, convertType(options, Frame.TextContentOptions.class));
|
||||
return withLogging("Page.textContent",
|
||||
() -> mainFrame.textContentImpl(selector, convertType(options, Frame.TextContentOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String title() {
|
||||
return mainFrame.title();
|
||||
return withLogging("Page.title", () -> mainFrame.titleImpl());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1281,23 +1345,27 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void type(String selector, String text, TypeOptions options) {
|
||||
mainFrame.type(selector, text, convertType(options, Frame.TypeOptions.class));
|
||||
withLogging("Page.type",
|
||||
() -> mainFrame.typeImpl(selector, text, convertType(options, Frame.TypeOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void uncheck(String selector, UncheckOptions options) {
|
||||
mainFrame.uncheck(selector, convertType(options, Frame.UncheckOptions.class));
|
||||
withLogging("Page.uncheck",
|
||||
() -> mainFrame.uncheckImpl(selector, convertType(options, Frame.UncheckOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unrouteAll() {
|
||||
routes.removeAll();
|
||||
updateInterceptionPatterns();
|
||||
withLogging("Page.unrouteAll", () -> {
|
||||
routes.removeAll();
|
||||
updateInterceptionPatterns();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unroute(String url, Consumer<Route> handler) {
|
||||
unroute(UrlMatcher.forGlob(browserContext.baseUrl(), url, this.connection.localUtils, false), handler);
|
||||
unroute(UrlMatcher.forGlob(browserContext.baseUrl, url, this.connection.localUtils, false), handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1311,16 +1379,18 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
}
|
||||
|
||||
private void unroute(UrlMatcher matcher, Consumer<Route> handler) {
|
||||
routes.remove(matcher, handler);
|
||||
updateInterceptionPatterns();
|
||||
withLogging("Page.unroute", () -> {
|
||||
routes.remove(matcher, handler);
|
||||
updateInterceptionPatterns();
|
||||
});
|
||||
}
|
||||
|
||||
private void updateInterceptionPatterns() {
|
||||
sendMessage("setNetworkInterceptionPatterns", routes.interceptionPatterns(), NO_TIMEOUT);
|
||||
sendMessage("setNetworkInterceptionPatterns", routes.interceptionPatterns());
|
||||
}
|
||||
|
||||
private void updateWebSocketInterceptionPatterns() {
|
||||
sendMessage("setWebSocketInterceptionPatterns", webSocketRoutes.interceptionPatterns(), NO_TIMEOUT);
|
||||
sendMessage("setWebSocketInterceptionPatterns", webSocketRoutes.interceptionPatterns());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1341,7 +1411,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
// Note: we are creating Video object lazily, because we do not know
|
||||
// BrowserContextOptions when constructing the page - it is assigned
|
||||
// too late during launchPersistentContext.
|
||||
if (browserContext.videosDir() == null) {
|
||||
if (browserContext.videosDir == null) {
|
||||
return null;
|
||||
}
|
||||
return forceVideo();
|
||||
@@ -1362,7 +1432,8 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public JSHandle waitForFunction(String pageFunction, Object arg, WaitForFunctionOptions options) {
|
||||
return mainFrame.waitForFunction(pageFunction, arg, convertType(options, Frame.WaitForFunctionOptions.class));
|
||||
return withLogging("Page.waitForFunction",
|
||||
() -> mainFrame.waitForFunctionImpl(pageFunction, arg, convertType(options, Frame.WaitForFunctionOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1437,7 +1508,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Request waitForRequest(String urlGlob, WaitForRequestOptions options, Runnable code) {
|
||||
return waitForRequest(UrlMatcher.forGlob(browserContext.baseUrl(), urlGlob, this.connection.localUtils, false), null, options, code);
|
||||
return waitForRequest(UrlMatcher.forGlob(browserContext.baseUrl, urlGlob, this.connection.localUtils, false), null, options, code);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1482,7 +1553,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Response waitForResponse(String urlGlob, WaitForResponseOptions options, Runnable code) {
|
||||
return waitForResponse(UrlMatcher.forGlob(browserContext.baseUrl(), urlGlob, this.connection.localUtils, false), null, options, code);
|
||||
return waitForResponse(UrlMatcher.forGlob(browserContext.baseUrl, urlGlob, this.connection.localUtils, false), null, options, code);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1515,7 +1586,8 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public ElementHandle waitForSelector(String selector, WaitForSelectorOptions options) {
|
||||
return mainFrame.waitForSelector(selector, convertType(options, Frame.WaitForSelectorOptions.class));
|
||||
return withLogging("Page.waitForSelector",
|
||||
() -> mainFrame.waitForSelectorImpl(selector, convertType(options, Frame.WaitForSelectorOptions.class)));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -1529,12 +1601,12 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void waitForTimeout(double timeout) {
|
||||
mainFrame.waitForTimeout(timeout);
|
||||
withLogging("Page.waitForTimeout", () -> mainFrame.waitForTimeoutImpl(timeout));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void waitForURL(String url, WaitForURLOptions options) {
|
||||
waitForURL(UrlMatcher.forGlob(browserContext.baseUrl(), url, this.connection.localUtils, false), options);
|
||||
waitForURL(UrlMatcher.forGlob(browserContext.baseUrl, url, this.connection.localUtils, false), options);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -52,6 +52,7 @@ public class PlaywrightImpl extends ChannelOwner implements Playwright {
|
||||
Connection connection = new Connection(new PipeTransport(p.getInputStream(), p.getOutputStream()), env);
|
||||
PlaywrightImpl result = connection.initializePlaywright();
|
||||
result.driverProcess = p;
|
||||
result.initSharedSelectors(null);
|
||||
return result;
|
||||
} catch (IOException e) {
|
||||
throw new PlaywrightException("Failed to launch driver", e);
|
||||
@@ -61,8 +62,9 @@ public class PlaywrightImpl extends ChannelOwner implements Playwright {
|
||||
private final BrowserTypeImpl chromium;
|
||||
private final BrowserTypeImpl firefox;
|
||||
private final BrowserTypeImpl webkit;
|
||||
private final SelectorsImpl selectors;
|
||||
private final APIRequestImpl apiRequest;
|
||||
protected SelectorsImpl selectors;
|
||||
private SharedSelectors sharedSelectors;
|
||||
|
||||
PlaywrightImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
@@ -70,14 +72,24 @@ public class PlaywrightImpl extends ChannelOwner implements Playwright {
|
||||
firefox = parent.connection.getExistingObject(initializer.getAsJsonObject("firefox").get("guid").getAsString());
|
||||
webkit = parent.connection.getExistingObject(initializer.getAsJsonObject("webkit").get("guid").getAsString());
|
||||
|
||||
chromium.playwright = this;
|
||||
firefox.playwright = this;
|
||||
webkit.playwright = this;
|
||||
|
||||
selectors = new SelectorsImpl();
|
||||
selectors = connection.getExistingObject(initializer.getAsJsonObject("selectors").get("guid").getAsString());
|
||||
apiRequest = new APIRequestImpl(this);
|
||||
}
|
||||
|
||||
void initSharedSelectors(PlaywrightImpl parent) {
|
||||
assert sharedSelectors == null;
|
||||
if (parent == null) {
|
||||
sharedSelectors = new SharedSelectors();
|
||||
} else {
|
||||
sharedSelectors = parent.sharedSelectors;
|
||||
}
|
||||
sharedSelectors.addChannel(selectors);
|
||||
}
|
||||
|
||||
void unregisterSelectors() {
|
||||
sharedSelectors.removeChannel(selectors);
|
||||
}
|
||||
|
||||
public LocalUtils localUtils() {
|
||||
return connection.localUtils;
|
||||
}
|
||||
@@ -108,7 +120,7 @@ public class PlaywrightImpl extends ChannelOwner implements Playwright {
|
||||
|
||||
@Override
|
||||
public Selectors selectors() {
|
||||
return selectors;
|
||||
return sharedSelectors;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
// This file is generated by generate_java_rpc.js, do not edit manually.
|
||||
|
||||
package com.microsoft.playwright.impl;
|
||||
|
||||
import java.util.List;
|
||||
@@ -103,7 +105,6 @@ class ExpectedTextValue {
|
||||
class FrameExpectOptions {
|
||||
Object expressionArg;
|
||||
List<ExpectedTextValue> expectedText;
|
||||
String selector;
|
||||
Double expectedNumber;
|
||||
SerializedArgument expectedValue;
|
||||
Boolean useInnerText;
|
||||
|
||||
@@ -26,4 +26,8 @@ public class RemoteBrowser extends ChannelOwner {
|
||||
BrowserImpl browser() {
|
||||
return connection.getExistingObject(initializer.getAsJsonObject("browser").get("guid").getAsString());
|
||||
}
|
||||
|
||||
SelectorsImpl selectors() {
|
||||
return connection.getExistingObject(initializer.getAsJsonObject("selectors").get("guid").getAsString());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,6 +53,7 @@ public class RequestImpl extends ChannelOwner implements Request {
|
||||
|
||||
RequestImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
markAsInternalType();
|
||||
|
||||
if (initializer.has("redirectedFrom")) {
|
||||
redirectedFrom = connection.getExistingObject(initializer.getAsJsonObject("redirectedFrom").get("guid").getAsString());
|
||||
@@ -68,7 +69,7 @@ public class RequestImpl extends ChannelOwner implements Request {
|
||||
|
||||
@Override
|
||||
public Map<String, String> allHeaders() {
|
||||
return getRawHeaders().headers();
|
||||
return withLogging("Request.allHeaders", () -> getRawHeaders().headers());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,12 +98,12 @@ public class RequestImpl extends ChannelOwner implements Request {
|
||||
|
||||
@Override
|
||||
public List<HttpHeader> headersArray() {
|
||||
return getRawHeaders().headersArray();
|
||||
return withLogging("Request.headersArray", () -> getRawHeaders().headersArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String headerValue(String name) {
|
||||
return getRawHeaders().get(name);
|
||||
return withLogging("Request.headerValue", () -> getRawHeaders().get(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -152,21 +153,25 @@ public class RequestImpl extends ChannelOwner implements Request {
|
||||
|
||||
@Override
|
||||
public ResponseImpl response() {
|
||||
JsonObject result = sendMessage("response").getAsJsonObject();
|
||||
if (!result.has("response")) {
|
||||
return null;
|
||||
}
|
||||
return connection.getExistingObject(result.getAsJsonObject("response").get("guid").getAsString());
|
||||
return withLogging("Request.response", () -> {
|
||||
JsonObject result = sendMessage("response").getAsJsonObject();
|
||||
if (!result.has("response")) {
|
||||
return null;
|
||||
}
|
||||
return connection.getExistingObject(result.getAsJsonObject("response").get("guid").getAsString());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Sizes sizes() {
|
||||
ResponseImpl response = response();
|
||||
if (response == null) {
|
||||
throw new PlaywrightException("Unable to fetch sizes for failed request");
|
||||
}
|
||||
JsonObject json = response.sendMessage("sizes").getAsJsonObject();
|
||||
return gson().fromJson(json.getAsJsonObject("sizes"), Sizes.class);
|
||||
return withLogging("Request.sizes", () -> {
|
||||
ResponseImpl response = response();
|
||||
if (response == null) {
|
||||
throw new PlaywrightException("Unable to fetch sizes for failed request");
|
||||
}
|
||||
JsonObject json = response.sendMessage("sizes").getAsJsonObject();
|
||||
return gson().fromJson(json.getAsJsonObject("sizes"), Sizes.class);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -193,8 +198,10 @@ public class RequestImpl extends ChannelOwner implements Request {
|
||||
if (rawHeaders != null) {
|
||||
return rawHeaders;
|
||||
}
|
||||
JsonObject result = sendMessage("rawRequestHeaders").getAsJsonObject();
|
||||
JsonArray rawHeadersJson = result.getAsJsonArray("headers");
|
||||
JsonArray rawHeadersJson = withLogging("Request.allHeaders", () -> {
|
||||
JsonObject result = sendMessage("rawRequestHeaders").getAsJsonObject();
|
||||
return result.getAsJsonArray("headers");
|
||||
});
|
||||
|
||||
// The field may have been initialized in a nested call but it is ok.
|
||||
rawHeaders = new RawHeaders(asList(gson().fromJson(rawHeadersJson, HttpHeader[].class)));
|
||||
|
||||
@@ -40,6 +40,7 @@ public class ResponseImpl extends ChannelOwner implements Response {
|
||||
|
||||
ResponseImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
markAsInternalType();
|
||||
headers = new RawHeaders(asList(gson().fromJson(initializer.getAsJsonArray("headers"), HttpHeader[].class)));
|
||||
request = connection.getExistingObject(initializer.getAsJsonObject("request").get("guid").getAsString());
|
||||
request.timing = gson().fromJson(initializer.get("timing"), Timing.class);
|
||||
@@ -47,13 +48,15 @@ public class ResponseImpl extends ChannelOwner implements Response {
|
||||
|
||||
@Override
|
||||
public Map<String, String> allHeaders() {
|
||||
return getRawHeaders().headers();
|
||||
return withLogging("Response.allHeaders", () -> getRawHeaders().headers());
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] body() {
|
||||
JsonObject json = sendMessage("body").getAsJsonObject();
|
||||
return Base64.getDecoder().decode(json.get("binary").getAsString());
|
||||
return withLogging("Response.body", () -> {
|
||||
JsonObject json = sendMessage("body").getAsJsonObject();
|
||||
return Base64.getDecoder().decode(json.get("binary").getAsString());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -93,7 +96,7 @@ public class ResponseImpl extends ChannelOwner implements Response {
|
||||
|
||||
@Override
|
||||
public List<HttpHeader> headersArray() {
|
||||
return getRawHeaders().headersArray();
|
||||
return withLogging("Response.headersArray", () -> getRawHeaders().headersArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -118,20 +121,24 @@ public class ResponseImpl extends ChannelOwner implements Response {
|
||||
|
||||
@Override
|
||||
public SecurityDetails securityDetails() {
|
||||
JsonObject json = sendMessage("securityDetails").getAsJsonObject();
|
||||
if (json.has("value")) {
|
||||
return gson().fromJson(json.get("value"), SecurityDetails.class);
|
||||
}
|
||||
return null;
|
||||
return withLogging("Response.securityDetails", () -> {
|
||||
JsonObject json = sendMessage("securityDetails").getAsJsonObject();
|
||||
if (json.has("value")) {
|
||||
return gson().fromJson(json.get("value"), SecurityDetails.class);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServerAddr serverAddr() {
|
||||
JsonObject json = sendMessage("serverAddr").getAsJsonObject();
|
||||
if (json.has("value")) {
|
||||
return gson().fromJson(json.get("value"), ServerAddr.class);
|
||||
}
|
||||
return null;
|
||||
return withLogging("Response.serverAddr", () -> {
|
||||
JsonObject json = sendMessage("serverAddr").getAsJsonObject();
|
||||
if (json.has("value")) {
|
||||
return gson().fromJson(json.get("value"), ServerAddr.class);
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -38,15 +38,18 @@ public class RouteImpl extends ChannelOwner implements Route {
|
||||
|
||||
public RouteImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
markAsInternalType();
|
||||
request = connection.getExistingObject(initializer.getAsJsonObject("request").get("guid").getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void abort(String errorCode) {
|
||||
startHandling();
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("errorCode", errorCode);
|
||||
sendMessageAsync("abort", params);
|
||||
withLogging("Route.abort", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("errorCode", errorCode);
|
||||
sendMessageAsync("abort", params);
|
||||
});
|
||||
}
|
||||
|
||||
boolean isHandled() {
|
||||
@@ -61,7 +64,7 @@ public class RouteImpl extends ChannelOwner implements Route {
|
||||
void resume(ResumeOptions options, boolean isFallback) {
|
||||
startHandling();
|
||||
applyOverrides(convertType(options, FallbackOptions.class));
|
||||
resumeImpl(request().fallbackOverridesForResume(), isFallback);
|
||||
withLogging("Route.resume", () -> resumeImpl(request().fallbackOverridesForResume(), isFallback));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -149,7 +152,7 @@ public class RouteImpl extends ChannelOwner implements Route {
|
||||
@Override
|
||||
public void fulfill(FulfillOptions options) {
|
||||
startHandling();
|
||||
fulfillImpl(options);
|
||||
withLogging("Route.fulfill", () -> fulfillImpl(options));
|
||||
}
|
||||
|
||||
private void fulfillImpl(FulfillOptions options) {
|
||||
|
||||
@@ -17,72 +17,28 @@
|
||||
package com.microsoft.playwright.impl;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
import com.microsoft.playwright.PlaywrightException;
|
||||
import com.microsoft.playwright.Selectors;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import static com.microsoft.playwright.impl.Serialization.gson;
|
||||
|
||||
import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
public class SelectorsImpl extends LoggingSupport implements Selectors {
|
||||
protected final List<BrowserContextImpl> contextsForSelectors = new ArrayList<>();
|
||||
protected final List<JsonObject> selectorEngines = new ArrayList<>();
|
||||
|
||||
String testIdAttributeName = "data-testid";
|
||||
|
||||
@Override
|
||||
public void setTestIdAttribute(String attributeName) {
|
||||
if (attributeName == null) {
|
||||
throw new PlaywrightException("Test id attribute cannot be null");
|
||||
}
|
||||
testIdAttributeName = attributeName;
|
||||
for (BrowserContextImpl context : contextsForSelectors) {
|
||||
try {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("testIdAttributeName", attributeName);
|
||||
context.sendMessageAsync("setTestIdAttributeName", params);
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
}
|
||||
class SelectorsImpl extends ChannelOwner {
|
||||
SelectorsImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(String name, String script, RegisterOptions options) {
|
||||
registerImpl(name, script, options);
|
||||
void register(String name, String script, Selectors.RegisterOptions options) {
|
||||
if (options == null) {
|
||||
options = new Selectors.RegisterOptions();
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("name", name);
|
||||
params.addProperty("source", script);
|
||||
sendMessage("register", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(String name, Path path, RegisterOptions options) {
|
||||
byte[] buffer;
|
||||
try {
|
||||
buffer = Files.readAllBytes(path);
|
||||
} catch (IOException e) {
|
||||
throw new PlaywrightException("Failed to read selector from file: " + path, e);
|
||||
}
|
||||
registerImpl(name, new String(buffer, UTF_8), options);
|
||||
}
|
||||
|
||||
private void registerImpl(String name, String script, RegisterOptions options) {
|
||||
if (selectorEngines.stream().anyMatch(engine -> name.equals(engine.get("name").getAsString()))) {
|
||||
throw new PlaywrightException("selectors.register: \"" + name + "\" selector engine has been already registered");
|
||||
}
|
||||
|
||||
JsonObject engine = new JsonObject();
|
||||
engine.addProperty("name", name);
|
||||
engine.addProperty("source", script);
|
||||
if (options != null && options.contentScript != null) {
|
||||
engine.addProperty("contentScript", options.contentScript);
|
||||
}
|
||||
for (BrowserContextImpl context : contextsForSelectors) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.add("selectorEngine", engine);
|
||||
context.sendMessage("registerSelectorEngine", params, NO_TIMEOUT);
|
||||
}
|
||||
selectorEngines.add(engine);
|
||||
void setTestIdAttributeName(String name) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("testIdAttributeName", name);
|
||||
sendMessageAsync("setTestIdAttributeName", params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.impl;
|
||||
|
||||
import com.microsoft.playwright.PlaywrightException;
|
||||
import com.microsoft.playwright.Selectors;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
|
||||
public class SharedSelectors extends LoggingSupport implements Selectors {
|
||||
private final List<SelectorsImpl> channels = new ArrayList<>();
|
||||
private final List<Registration> registrations = new ArrayList<>();
|
||||
|
||||
String testIdAttributeName = "data-testid";
|
||||
|
||||
private static class Registration {
|
||||
final String name;
|
||||
final String script;
|
||||
final RegisterOptions options;
|
||||
|
||||
Registration(String name, String script, RegisterOptions options) {
|
||||
this.name = name;
|
||||
this.script = script;
|
||||
this.options = options;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(String name, String script, RegisterOptions options) {
|
||||
withLogging("Selectors.register", () -> registerImpl(name, script, options));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void register(String name, Path path, RegisterOptions options) {
|
||||
withLogging("Selectors.register", () -> {
|
||||
byte[] buffer;
|
||||
try {
|
||||
buffer = Files.readAllBytes(path);
|
||||
} catch (IOException e) {
|
||||
throw new PlaywrightException("Failed to read selector from file: " + path, e);
|
||||
}
|
||||
registerImpl(name, new String(buffer, UTF_8), options);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setTestIdAttribute(String attributeName) {
|
||||
if (attributeName == null) {
|
||||
throw new PlaywrightException("Test id attribute cannot be null");
|
||||
}
|
||||
testIdAttributeName = attributeName;
|
||||
channels.forEach(channel -> channel.setTestIdAttributeName(testIdAttributeName));
|
||||
}
|
||||
|
||||
void addChannel(SelectorsImpl channel) {
|
||||
registrations.forEach(r -> {
|
||||
try {
|
||||
channel.register(r.name, r.script, r.options);
|
||||
} catch (PlaywrightException e) {
|
||||
// This should not fail except for connection closure, but just in case we catch.
|
||||
}
|
||||
channel.setTestIdAttributeName(testIdAttributeName);
|
||||
});
|
||||
channels.add(channel);
|
||||
}
|
||||
|
||||
void removeChannel(SelectorsImpl channel) {
|
||||
channels.remove(channel);
|
||||
}
|
||||
|
||||
private void registerImpl(String name, String script, RegisterOptions options) {
|
||||
channels.forEach(impl -> impl.register(name, script, options));
|
||||
registrations.add(new Registration(name, script, options));
|
||||
}
|
||||
}
|
||||
@@ -50,7 +50,7 @@ public class Stream extends ChannelOwner {
|
||||
}
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("size", len);
|
||||
JsonObject json = sendMessage("read", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = sendMessage("read", params).getAsJsonObject();
|
||||
String encoded = json.get("binary").getAsString();
|
||||
if (encoded.isEmpty()) {
|
||||
return -1;
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.microsoft.playwright.impl;
|
||||
|
||||
class TimeoutSettings {
|
||||
private static final int DEFAULT_TIMEOUT_MS = 30_000;
|
||||
private static final int DEFAULT_LAUNCH_TIMEOUT_MS = 180_000;
|
||||
|
||||
private final TimeoutSettings parent;
|
||||
private Double defaultTimeout ;
|
||||
@@ -81,11 +80,4 @@ class TimeoutSettings {
|
||||
}
|
||||
return new WaitableTimeout<>(timeout(timeout));
|
||||
}
|
||||
|
||||
static double launchTimeout(Double timeout) {
|
||||
if (timeout != null) {
|
||||
return timeout;
|
||||
}
|
||||
return DEFAULT_LAUNCH_TIMEOUT_MS;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,6 @@ package com.microsoft.playwright.impl;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.microsoft.playwright.Touchscreen;
|
||||
|
||||
import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT;
|
||||
|
||||
class TouchscreenImpl implements Touchscreen {
|
||||
private final PageImpl page;
|
||||
|
||||
@@ -30,9 +28,11 @@ class TouchscreenImpl implements Touchscreen {
|
||||
|
||||
@Override
|
||||
public void tap(double x, double y) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("x", x);
|
||||
params.addProperty("y", y);
|
||||
page.sendMessage("touchscreenTap", params, NO_TIMEOUT);
|
||||
page.withLogging("Touchscreen.tap", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("x", x);
|
||||
params.addProperty("y", y);
|
||||
page.sendMessage("touchscreenTap", params);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ class TracingImpl extends ChannelOwner implements Tracing {
|
||||
|
||||
TracingImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
markAsInternalType();
|
||||
}
|
||||
|
||||
private void stopChunkImpl(Path path) {
|
||||
@@ -45,7 +46,7 @@ class TracingImpl extends ChannelOwner implements Tracing {
|
||||
// Not interested in artifacts.
|
||||
if (path == null) {
|
||||
params.addProperty("mode", "discard");
|
||||
sendMessage("tracingStopChunk", params, NO_TIMEOUT);
|
||||
sendMessage("tracingStopChunk", params);
|
||||
if (stacksId != null) {
|
||||
connection.localUtils().traceDiscarded(stacksId);
|
||||
}
|
||||
@@ -55,14 +56,14 @@ class TracingImpl extends ChannelOwner implements Tracing {
|
||||
boolean isLocal = !connection.isRemote;
|
||||
if (isLocal) {
|
||||
params.addProperty("mode", "entries");
|
||||
JsonObject json = sendMessage("tracingStopChunk", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = sendMessage("tracingStopChunk", params).getAsJsonObject();
|
||||
JsonArray entries = json.getAsJsonArray("entries");
|
||||
connection.localUtils.zip(path, entries, stacksId, false, includeSources);
|
||||
return;
|
||||
}
|
||||
|
||||
params.addProperty("mode", "archive");
|
||||
JsonObject json = sendMessage("tracingStopChunk", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject json = sendMessage("tracingStopChunk", params).getAsJsonObject();
|
||||
// The artifact may be missing if the browser closed while stopping tracing.
|
||||
if (!json.has("artifact")) {
|
||||
if (stacksId != null) {
|
||||
@@ -87,7 +88,7 @@ class TracingImpl extends ChannelOwner implements Tracing {
|
||||
|
||||
@Override
|
||||
public void group(String name, GroupOptions options) {
|
||||
groupImpl(name, options);
|
||||
withLogging("Tracing.group", () -> groupImpl(name, options));
|
||||
}
|
||||
|
||||
private void groupImpl(String name, GroupOptions options) {
|
||||
@@ -96,12 +97,12 @@ class TracingImpl extends ChannelOwner implements Tracing {
|
||||
}
|
||||
JsonObject params = gson().toJsonTree(options).getAsJsonObject();
|
||||
params.addProperty("name", name);
|
||||
sendMessage("tracingGroup", params, NO_TIMEOUT);
|
||||
sendMessage("tracingGroup", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void groupEnd() {
|
||||
sendMessage("tracingGroupEnd");
|
||||
withLogging("Tracing.groupEnd", () -> sendMessage("tracingGroupEnd"));
|
||||
}
|
||||
|
||||
private void tracingStartChunk(String name, String title) {
|
||||
@@ -112,7 +113,7 @@ class TracingImpl extends ChannelOwner implements Tracing {
|
||||
if (title != null) {
|
||||
params.addProperty("title", title);
|
||||
}
|
||||
JsonObject result = sendMessage("tracingStartChunk", params, NO_TIMEOUT).getAsJsonObject();
|
||||
JsonObject result = sendMessage("tracingStartChunk", params).getAsJsonObject();
|
||||
startCollectingStacks(result.get("traceName").getAsString());
|
||||
}
|
||||
|
||||
@@ -134,7 +135,7 @@ class TracingImpl extends ChannelOwner implements Tracing {
|
||||
if (includeSources) {
|
||||
params.addProperty("sources", true);
|
||||
}
|
||||
sendMessage("tracingStart", params, NO_TIMEOUT);
|
||||
sendMessage("tracingStart", params);
|
||||
tracingStartChunk(options.name, options.title);
|
||||
}
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static com.microsoft.playwright.impl.ChannelOwner.NO_TIMEOUT;
|
||||
import static com.microsoft.playwright.impl.Serialization.toJsonArray;
|
||||
import static java.nio.file.Files.readAllBytes;
|
||||
|
||||
@@ -201,7 +200,7 @@ public class Utils {
|
||||
items.add(item);
|
||||
}
|
||||
tempFilesParams.add("items", items);
|
||||
return context.sendMessage("createTempFiles", tempFilesParams, NO_TIMEOUT).getAsJsonObject();
|
||||
return context.sendMessage("createTempFiles", tempFilesParams).getAsJsonObject();
|
||||
}
|
||||
|
||||
static void checkFilePayloadSize(FilePayload[] files) {
|
||||
|
||||
@@ -30,6 +30,7 @@ class VideoImpl implements Video {
|
||||
|
||||
VideoImpl(PageImpl page) {
|
||||
this.page = page;
|
||||
BrowserImpl browser = page.context().browser();
|
||||
}
|
||||
|
||||
void setArtifact(ArtifactImpl artifact) {
|
||||
@@ -43,33 +44,39 @@ class VideoImpl implements Video {
|
||||
|
||||
@Override
|
||||
public void delete() {
|
||||
try {
|
||||
waitForArtifact().delete();
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
page.withLogging("Video.delete", () -> {
|
||||
try {
|
||||
waitForArtifact().delete();
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Path path() {
|
||||
if (page.connection.isRemote) {
|
||||
throw new PlaywrightException("Path is not available when using browserType.connect(). Use saveAs() to save a local copy.");
|
||||
}
|
||||
try {
|
||||
return Paths.get(waitForArtifact().initializer.get("absolutePath").getAsString());
|
||||
} catch (PlaywrightException e) {
|
||||
throw new PlaywrightException("Page did not produce any video frames", e);
|
||||
}
|
||||
return page.withLogging("Video.path", () -> {
|
||||
if (page.connection.isRemote) {
|
||||
throw new PlaywrightException("Path is not available when using browserType.connect(). Use saveAs() to save a local copy.");
|
||||
}
|
||||
try {
|
||||
return Paths.get(waitForArtifact().initializer.get("absolutePath").getAsString());
|
||||
} catch (PlaywrightException e) {
|
||||
throw new PlaywrightException("Page did not produce any video frames", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveAs(Path path) {
|
||||
if (!page.isClosed()) {
|
||||
throw new PlaywrightException("Page is not yet closed. Close the page prior to calling saveAs");
|
||||
}
|
||||
try {
|
||||
waitForArtifact().saveAs(path);
|
||||
} catch (PlaywrightException e) {
|
||||
throw new PlaywrightException("Page did not produce any video frames", e);
|
||||
}
|
||||
page.withLogging("Video.saveAs", () -> {
|
||||
if (!page.isClosed()) {
|
||||
throw new PlaywrightException("Page is not yet closed. Close the page prior to calling saveAs");
|
||||
}
|
||||
try {
|
||||
waitForArtifact().saveAs(path);
|
||||
} catch (PlaywrightException e) {
|
||||
throw new PlaywrightException("Page did not produce any video frames", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,21 +38,23 @@ public class WaitForEventLogger<T> implements Supplier<T>, Logger {
|
||||
|
||||
@Override
|
||||
public T get() {
|
||||
{
|
||||
return channel.withLogging(apiName, () -> {
|
||||
{
|
||||
JsonObject info = new JsonObject();
|
||||
info.addProperty("phase", "before");
|
||||
sendWaitForEventInfo(info);
|
||||
}
|
||||
JsonObject info = new JsonObject();
|
||||
info.addProperty("phase", "before");
|
||||
sendWaitForEventInfo(info);
|
||||
}
|
||||
JsonObject info = new JsonObject();
|
||||
info.addProperty("phase", "after");
|
||||
try {
|
||||
return supplier.apply(this);
|
||||
} catch (RuntimeException e) {
|
||||
info.addProperty("error", e.getMessage());
|
||||
throw e;
|
||||
} finally {
|
||||
sendWaitForEventInfo(info);
|
||||
}
|
||||
info.addProperty("phase", "after");
|
||||
try {
|
||||
return supplier.apply(this);
|
||||
} catch (RuntimeException e) {
|
||||
info.addProperty("error", e.getMessage());
|
||||
throw e;
|
||||
} finally {
|
||||
sendWaitForEventInfo(info);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -69,6 +69,7 @@ class WebSocketRouteImpl extends ChannelOwner implements WebSocketRoute {
|
||||
|
||||
WebSocketRouteImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
markAsInternalType();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -128,11 +129,7 @@ class WebSocketRouteImpl extends ChannelOwner implements WebSocketRoute {
|
||||
return;
|
||||
}
|
||||
// Ensure that websocket is "open" and can send messages without an actual server connection.
|
||||
try {
|
||||
sendMessageAsync("ensureOpened");
|
||||
} catch (PlaywrightException e) {
|
||||
// If this happens after the page has been closed, ignore the error.
|
||||
}
|
||||
sendMessageAsync("ensureOpened");
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -71,21 +71,25 @@ class WorkerImpl extends ChannelOwner implements Worker {
|
||||
|
||||
@Override
|
||||
public Object evaluate(String pageFunction, Object arg) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evaluateExpression", params, NO_TIMEOUT);
|
||||
SerializedValue value = gson().fromJson(json.getAsJsonObject().get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
return withLogging("Worker.evaluate", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evaluateExpression", params);
|
||||
SerializedValue value = gson().fromJson(json.getAsJsonObject().get("value"), SerializedValue.class);
|
||||
return deserialize(value);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public JSHandle evaluateHandle(String pageFunction, Object arg) {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evaluateExpressionHandle", params, NO_TIMEOUT);
|
||||
return connection.getExistingObject(json.getAsJsonObject().getAsJsonObject("handle").get("guid").getAsString());
|
||||
return withLogging("Worker.evaluateHandle", () -> {
|
||||
JsonObject params = new JsonObject();
|
||||
params.addProperty("expression", pageFunction);
|
||||
params.add("arg", gson().toJsonTree(serializeArgument(arg)));
|
||||
JsonElement json = sendMessage("evaluateExpressionHandle", params);
|
||||
return connection.getExistingObject(json.getAsJsonObject().getAsJsonObject("handle").get("guid").getAsString());
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -42,7 +42,7 @@ class WritableStream extends ChannelOwner {
|
||||
ByteBuffer buffer = ByteBuffer.wrap(b, off, len);
|
||||
ByteBuffer encoded = Base64.getEncoder().encode(buffer);
|
||||
params.addProperty("binary", new String(encoded.array(), StandardCharsets.UTF_8));
|
||||
sendMessage("write", params, NO_TIMEOUT);
|
||||
sendMessage("write", params);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -48,12 +48,6 @@ public class Cookie {
|
||||
* Optional.
|
||||
*/
|
||||
public SameSiteAttribute sameSite;
|
||||
/**
|
||||
* For partitioned third-party cookies (aka <a
|
||||
* href="https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies">CHIPS</a>), the
|
||||
* partition key. Optional.
|
||||
*/
|
||||
public String partitionKey;
|
||||
|
||||
public Cookie(String name, String value) {
|
||||
this.name = name;
|
||||
@@ -109,13 +103,4 @@ public class Cookie {
|
||||
this.sameSite = sameSite;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* For partitioned third-party cookies (aka <a
|
||||
* href="https://developer.mozilla.org/en-US/docs/Web/Privacy/Guides/Privacy_sandbox/Partitioned_cookies">CHIPS</a>), the
|
||||
* partition key. Optional.
|
||||
*/
|
||||
public Cookie setPartitionKey(String partitionKey) {
|
||||
this.partitionKey = partitionKey;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -436,7 +436,7 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
context.request().get(server.PREFIX + "/slow", RequestOptions.create().setTimeout(100));
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout 100ms exceeded"), e.getMessage());
|
||||
assertTrue(e.getMessage().contains("Request timed out after 100ms"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -468,7 +468,7 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
|
||||
context.setDefaultTimeout(100);
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.request().get(server.PREFIX + "/redirect"));
|
||||
assertTrue(e.getMessage().contains("Timeout 100ms exceeded"), e.getMessage());
|
||||
assertTrue(e.getMessage().contains("Request timed out after 100ms"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.microsoft.playwright;
|
||||
|
||||
import com.microsoft.playwright.options.HarContentPolicy;
|
||||
import com.microsoft.playwright.options.HarMode;
|
||||
import com.microsoft.playwright.options.HarNotFound;
|
||||
import com.microsoft.playwright.options.RouteFromHarUpdateContentPolicy;
|
||||
@@ -39,6 +40,7 @@ import static com.microsoft.playwright.Utils.copy;
|
||||
import static com.microsoft.playwright.Utils.extractZip;
|
||||
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
|
||||
import static com.microsoft.playwright.options.HarContentPolicy.ATTACH;
|
||||
import static com.microsoft.playwright.options.HarContentPolicy.EMBED;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestBrowserContextHar extends TestBase {
|
||||
|
||||
@@ -174,19 +174,10 @@ public class TestBrowserContextStorageState extends TestBase {
|
||||
@Test
|
||||
void shouldSupportIndexedDB() {
|
||||
page.navigate(server.PREFIX + "/to-do-notifications/index.html");
|
||||
|
||||
assertThat(page.locator("#notifications")).matchesAriaSnapshot(
|
||||
" - list:\n" +
|
||||
" - listitem: Database initialised."
|
||||
);
|
||||
page.locator("label:has-text('Task title')").fill("Pet the cat");
|
||||
page.locator("label:has-text('Hours')").fill("1");
|
||||
page.locator("label:has-text('Mins')").fill("1");
|
||||
page.locator("text=Add Task").click();
|
||||
assertThat(page.locator("#notifications")).matchesAriaSnapshot(
|
||||
" - list:\n" +
|
||||
" - listitem: \"Transaction completed: database modification finished.\""
|
||||
);
|
||||
|
||||
String storageState = page.context().storageState(new BrowserContext.StorageStateOptions().setIndexedDB(true));
|
||||
assertJsonEquals("{\"cookies\":[],\"origins\":[\n" +
|
||||
|
||||
@@ -57,35 +57,18 @@ public class TestChromiumTracing extends TestBase {
|
||||
}
|
||||
}
|
||||
|
||||
private static void rafraf(Page page) {
|
||||
int count = 2;
|
||||
for (int i = 0; i < count; i++) {
|
||||
page.evaluate("() => new Promise(f => requestAnimationFrame(() => requestAnimationFrame(f)))");
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRunWithCustomCategoriesIfProvided(@TempDir Path tempDir) throws IOException {
|
||||
try (Page page = browser.newPage()) {
|
||||
Path outputTraceFile = tempDir.resolve("trace.json");
|
||||
browser.startTracing(page, new Browser.StartTracingOptions()
|
||||
.setPath(outputTraceFile)
|
||||
.setCategories(asList("disabled-by-default-cc.debug")));
|
||||
rafraf(page);
|
||||
.setCategories(asList("disabled-by-default-v8.cpu_profiler.hires")));
|
||||
browser.stopTracing();
|
||||
try (FileReader fileReader = new FileReader(outputTraceFile.toFile())) {
|
||||
JsonObject traceJson = new Gson().fromJson(fileReader, JsonObject.class);
|
||||
// NOTE: trace-config is deprecated as per http://crrev.com/c/6628182
|
||||
boolean hasTraceConfig =
|
||||
traceJson.getAsJsonObject("metadata").get("trace-config") != null
|
||||
&& traceJson.getAsJsonObject("metadata").get("trace-config").getAsString().contains("disabled-by-default-cc.debug");
|
||||
boolean hasTraceEvents = traceJson.getAsJsonArray("traceEvents").asList().stream()
|
||||
.anyMatch(event -> {
|
||||
JsonObject eventObj = (JsonObject) event;
|
||||
return eventObj.has("cat") &&
|
||||
eventObj.get("cat").getAsString().equals("disabled-by-default-cc.debug");
|
||||
});
|
||||
assertTrue(hasTraceConfig || hasTraceEvents);
|
||||
assertTrue(traceJson.getAsJsonObject("metadata").get("trace-config")
|
||||
.getAsString().contains("disabled-by-default-v8.cpu_profiler.hires"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -125,8 +125,8 @@ public class TestClientCertificates extends TestBase {
|
||||
.setIgnoreHTTPSErrors(true) // TODO: remove once we can pass a custom CA.
|
||||
.setClientCertificates(asList(
|
||||
new ClientCertificate(customServer.origin)
|
||||
.setPfxPath(asset("client-certificates/client/trusted/keystore.p12"))
|
||||
.setPassphrase("")));
|
||||
.setPfxPath(asset("client-certificates/client/trusted/client_keystore.p12"))
|
||||
.setPassphrase("passphrase")));
|
||||
|
||||
APIRequestContext request = playwright.request().newContext(requestOptions);
|
||||
APIResponse response = request.get(customServer.url);
|
||||
|
||||
@@ -307,19 +307,4 @@ public class TestDefaultBrowserContext2 extends TestBase {
|
||||
assertTrue(Files.list(userDataDir).count() > 0);
|
||||
context.close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldExposeBrowser() {
|
||||
Page page = launchPersistent();
|
||||
BrowserContext context = page.context();
|
||||
Browser browser = context.browser();
|
||||
assertFalse(browser.version().isEmpty());
|
||||
Page page2 = browser.newPage();
|
||||
page2.navigate("data:text/html,<html><title>Title</title></html>");
|
||||
assertEquals("Title", page2.title());
|
||||
browser.close();
|
||||
assertEquals(0, context.pages().size());
|
||||
// Next line should not throw.
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +189,7 @@ public class TestGlobalFetch extends TestBase {
|
||||
APIRequestContext request = playwright.request().newContext(new APIRequest.NewContextOptions().setTimeout(100));
|
||||
server.setRoute("/empty.html", exchange -> {});
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> request.get(server.EMPTY_PAGE));
|
||||
assertTrue(e.getMessage().contains("Timeout 100ms exceeded"), e.getMessage());
|
||||
assertTrue(e.getMessage().contains("Request timed out after 100ms"), e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1070,7 +1070,7 @@ public class TestLocatorAssertions extends TestBase {
|
||||
Locator locator = page.locator("div");
|
||||
PlaywrightAssertions.setDefaultAssertionTimeout(1000);
|
||||
AssertionFailedError exception = assertThrows(AssertionFailedError.class, () -> assertThat(locator).hasText("foo"));
|
||||
assertTrue(exception.getMessage().contains("Assert \"hasText\" with timeout 1000ms"), exception.getMessage());
|
||||
assertTrue(exception.getMessage().contains("Locator.expect with timeout 1000ms"), exception.getMessage());
|
||||
// Restore default.
|
||||
PlaywrightAssertions.setDefaultAssertionTimeout(5_000);
|
||||
}
|
||||
@@ -1119,7 +1119,7 @@ public class TestLocatorAssertions extends TestBase {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(page.locator("div")).containsClass("does-not-exist", new ContainsClassOptions().setTimeout(1000));
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Assert \"containsClass\" with timeout 1000ms"), e.getMessage());
|
||||
assertTrue(e.getMessage().contains("Locator.expect with timeout 1000ms"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1137,6 +1137,6 @@ public class TestLocatorAssertions extends TestBase {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(page.locator("div")).containsClass(asList("foo", "bar", "baz"), new ContainsClassOptions().setTimeout(1000));
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Assert \"containsClass\" with timeout 1000ms"), e.getMessage());
|
||||
assertTrue(e.getMessage().contains("Locator.expect with timeout 1000ms"), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,6 +218,6 @@ public class TestLocatorAssertions2 extends TestBase {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () ->
|
||||
assertThat(locator).isChecked(new LocatorAssertions.IsCheckedOptions().setIndeterminate(true).setTimeout(1000)));
|
||||
// TODO: should be "assertThat().isChecked() with timeout 1000ms"
|
||||
assertTrue(e.getMessage().contains("Assert \"isChecked\" with timeout 1000ms"), e.getMessage());
|
||||
assertTrue(e.getMessage().contains("Locator.expect with timeout 1000ms"), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,7 +271,7 @@ public class TestPageAddLocatorHandler extends TestBase {
|
||||
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.locator("#target").click(new Locator.ClickOptions().setTimeout(3_000)));
|
||||
assertEquals(0, (int) page.evaluate("window.clicked"));
|
||||
assertTrue(page.locator("#interstitial").isVisible());
|
||||
assertThat(page.locator("#interstitial")).isVisible();
|
||||
assertEquals(1, called[0]);
|
||||
assertTrue(e.getMessage().contains("locator handler has finished, waiting for getByRole(AriaRole.BUTTON, new Page.GetByRoleOptions().setName(\"close\")) to be hidden"), e.getMessage());
|
||||
}
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
package com.microsoft.playwright;
|
||||
|
||||
import com.microsoft.playwright.Locator.AriaSnapshotOptions;
|
||||
import com.microsoft.playwright.junit.FixtureTest;
|
||||
import com.microsoft.playwright.junit.UsePlaywright;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.opentest4j.AssertionFailedError;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -14,6 +14,7 @@ import java.util.stream.Collectors;
|
||||
import static com.microsoft.playwright.assertions.PlaywrightAssertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
@FixtureTest
|
||||
@UsePlaywright
|
||||
@@ -72,6 +73,12 @@ public class TestPageAriaSnapshot {
|
||||
checkAndMatchSnapshot(page.locator("body"), "- list:\n - listitem:\n - link \"link\":\n - /url: about:blank");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSnapshotRef(Page page) {
|
||||
page.setContent("<ul><li>foo</li></ul>");
|
||||
assertEquals(unshift("- list [ref=s1e3]:\n - listitem [ref=s1e4]: foo"), page.locator("body").ariaSnapshot(new AriaSnapshotOptions().setRef(true)));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAllowTextNodes(Page page) {
|
||||
page.setContent("<h1>Microsoft</h1><div>Open source projects and samples from Microsoft</div>");
|
||||
@@ -104,27 +111,4 @@ public class TestPageAriaSnapshot {
|
||||
"- link:\n" +
|
||||
" - /url: /.*example.com/");
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldHandleTopLevelDeepEqual(Page page) {
|
||||
// https://github.com/microsoft/playwright/issues/36456
|
||||
page.setContent("" +
|
||||
"<ul>\n" +
|
||||
" <li>\n" +
|
||||
" <ul>\n" +
|
||||
" <li>1.1</li>\n" +
|
||||
" <li>1.2</li>\n" +
|
||||
" </ul>\n" +
|
||||
" </li>\n" +
|
||||
"</ul>");
|
||||
|
||||
assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(page.locator("body")).matchesAriaSnapshot("" +
|
||||
"- /children: deep-equal\n" +
|
||||
"- list:\n" +
|
||||
" - listitem:\n" +
|
||||
" - listitem: \"1.1\"\n" +
|
||||
" - listitem: \"1.2\"");
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ import static com.microsoft.playwright.options.ColorScheme.LIGHT;
|
||||
import static com.microsoft.playwright.options.Media.PRINT;
|
||||
import static com.microsoft.playwright.Utils.attachFrame;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
|
||||
public class TestPageEmulateMedia extends TestBase {
|
||||
@Test
|
||||
|
||||
@@ -99,7 +99,7 @@ public class TestPageInterception extends TestBase {
|
||||
page.route("**/*", route -> {
|
||||
PlaywrightException error = assertThrows(PlaywrightException.class,
|
||||
() -> route.fetch(new Route.FetchOptions().setTimeout(1000)));
|
||||
assertTrue(error.getMessage().contains("Timeout 1000ms exceeded"), error.getMessage());
|
||||
assertTrue(error.getMessage().contains("Request timed out after 1000ms"), error.getMessage());
|
||||
});
|
||||
PlaywrightException error = assertThrows(PlaywrightException.class,
|
||||
() -> page.navigate(server.PREFIX + "/slow", new Page.NavigateOptions().setTimeout(2000)));
|
||||
@@ -198,15 +198,6 @@ public class TestPageInterception extends TestBase {
|
||||
assertTrue(urlMatches("http://playwright.dev/foo", "http://playwright.dev/foo?bar", "\\\\?bar"));
|
||||
assertTrue(urlMatches("http://first.host/", "http://second.host/foo", "**/foo"));
|
||||
assertTrue(urlMatches("http://playwright.dev/", "http://localhost/", "*//localhost/"));
|
||||
|
||||
String[] customPrefixes = {"about", "data", "chrome", "edge", "file"};
|
||||
for (String prefix : customPrefixes) {
|
||||
assertTrue(urlMatches("http://playwright.dev/", prefix + ":blank", prefix + ":blank"));
|
||||
assertFalse(urlMatches("http://playwright.dev/", prefix + ":blank", "http://playwright.dev/"));
|
||||
assertTrue(urlMatches(null, prefix + ":blank", prefix + ":blank"));
|
||||
assertTrue(urlMatches(null, prefix + ":blank", prefix + ":*"));
|
||||
assertFalse(urlMatches(null, "not" + prefix + ":blank", prefix + ":*"));
|
||||
}
|
||||
}
|
||||
|
||||
Pattern globToRegex(String glob) {
|
||||
|
||||
@@ -60,6 +60,13 @@ public class TestPdf extends TestBase {
|
||||
assertTrue(outlineSize > noOutlineSize, "Unexpected sizes: " + outlineSize + " noOutline: " + noOutlineSize);
|
||||
}
|
||||
|
||||
@Test
|
||||
@DisabledIf(value="com.microsoft.playwright.TestBase#isChromium", disabledReason="skip")
|
||||
void shouldThrowInNonChromium() {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.pdf());
|
||||
assertTrue(e.getMessage().contains("PDF generation is only supported for Headless Chromium"), e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
@DisabledIf(value="com.microsoft.playwright.TestBase#isChromium", disabledReason="skip")
|
||||
|
||||
@@ -17,10 +17,12 @@
|
||||
package com.microsoft.playwright;
|
||||
|
||||
import com.microsoft.playwright.impl.PlaywrightImpl;
|
||||
import com.microsoft.playwright.impl.driver.Driver;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.nio.file.DirectoryStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
|
||||
@@ -23,26 +23,25 @@ import java.nio.file.Paths;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestSelectorsRegister extends TestBase {
|
||||
private static final String TAG_SELECTOR_SCRIPT = "{\n" +
|
||||
" create(root, target) {\n" +
|
||||
" return target.nodeName;\n" +
|
||||
" },\n" +
|
||||
" query(root, selector) {\n" +
|
||||
" return root.querySelector(selector);\n" +
|
||||
" },\n" +
|
||||
" queryAll(root, selector) {\n" +
|
||||
" return Array.from(root.querySelectorAll(selector));\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
|
||||
@Test
|
||||
void shouldWork() {
|
||||
String selectorScript = "{\n" +
|
||||
" create(root, target) {\n" +
|
||||
" return target.nodeName;\n" +
|
||||
" },\n" +
|
||||
" query(root, selector) {\n" +
|
||||
" return root.querySelector(selector);\n" +
|
||||
" },\n" +
|
||||
" queryAll(root, selector) {\n" +
|
||||
" return Array.from(root.querySelectorAll(selector));\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
// Register one engine before creating context.
|
||||
playwright.selectors().register("tag", TAG_SELECTOR_SCRIPT);
|
||||
playwright.selectors().register("tag", selectorScript);
|
||||
|
||||
BrowserContext context = browser.newContext();
|
||||
// Register another engine after creating context.
|
||||
playwright.selectors().register("tag2", TAG_SELECTOR_SCRIPT);
|
||||
playwright.selectors().register("tag2", selectorScript);
|
||||
|
||||
Page page = context.newPage();
|
||||
page.setContent("<div><span></span></div><div></div>");
|
||||
@@ -135,21 +134,4 @@ public class TestSelectorsRegister extends TestBase {
|
||||
});
|
||||
assertTrue(e.getMessage().contains("\"css\" is a predefined selector engine"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowAlreadyRegisteredErrorWhenRegistering() {
|
||||
// https://github.com/microsoft/playwright/issues/36467
|
||||
|
||||
// this test is about the exception *before* there's a context created
|
||||
context.close();
|
||||
|
||||
// Register the selector engine first
|
||||
playwright.selectors().register("alreadyRegistered", TAG_SELECTOR_SCRIPT);
|
||||
|
||||
// Attempt to register the same selector engine again should throw an error
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
playwright.selectors().register("alreadyRegistered", TAG_SELECTOR_SCRIPT);
|
||||
});
|
||||
assertTrue(e.getMessage().contains("\"alreadyRegistered\" selector engine has been already registered"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
package com.microsoft.playwright;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import com.google.gson.JsonObject;
|
||||
import com.microsoft.playwright.options.AriaRole;
|
||||
import com.microsoft.playwright.options.Location;
|
||||
import com.microsoft.playwright.options.MouseButton;
|
||||
@@ -182,7 +182,7 @@ public class TestTracing extends TestBase {
|
||||
List<TraceEvent> events = parseTraceEvents(traceFile1);
|
||||
List<TraceEvent> groups = events.stream().filter(e -> "tracingGroup".equals(e.method)).collect(Collectors.toList());
|
||||
assertEquals(1, groups.size());
|
||||
assertEquals("actual", groups.get(0).title);
|
||||
assertEquals("actual", groups.get(0).apiName);
|
||||
|
||||
}
|
||||
|
||||
@@ -203,8 +203,8 @@ public class TestTracing extends TestBase {
|
||||
context.tracing().stop(new Tracing.StopOptions().setPath(traceFile1));
|
||||
|
||||
List<TraceEvent> events = parseTraceEvents(traceFile1);
|
||||
List<String> calls = events.stream().filter(e -> e.renderedTitle() != null).map(e -> e.renderedTitle()).collect(Collectors.toList());
|
||||
assertEquals(asList("outer group", "Frame.goto", "inner group 1", "Frame.click", "inner group 2", "Frame.isVisible"), calls);
|
||||
List<String> calls = events.stream().filter(e -> e.apiName != null).map(e -> e.apiName).collect(Collectors.toList());
|
||||
assertEquals(asList("outer group", "Page.navigate", "inner group 1", "Frame.click", "inner group 2", "Page.isVisible"), calls);
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -241,30 +241,30 @@ public class TestTracing extends TestBase {
|
||||
context.tracing().stop(new Tracing.StopOptions().setPath(traceFile1));
|
||||
|
||||
List<TraceEvent> events = parseTraceEvents(traceFile1);
|
||||
List<String> calls = events.stream().filter(e -> e.renderedTitle() != null).map(e -> e.renderedTitle())
|
||||
List<String> calls = events.stream().filter(e -> e.apiName != null).map(e -> e.apiName)
|
||||
.collect(Collectors.toList());
|
||||
assertEquals(asList(
|
||||
"BrowserContext.clockInstall",
|
||||
"Frame.setContent",
|
||||
"Clock.install",
|
||||
"Page.setContent",
|
||||
"Frame.click",
|
||||
"Frame.click",
|
||||
"Page.keyboardType",
|
||||
"Page.keyboardPress",
|
||||
"Page.keyboardDown",
|
||||
"Page.keyboardInsertText",
|
||||
"Page.keyboardUp",
|
||||
"Page.mouseMove",
|
||||
"Page.mouseDown",
|
||||
"Page.mouseMove",
|
||||
"Page.mouseWheel",
|
||||
"Page.mouseUp",
|
||||
"BrowserContext.clockFastForward",
|
||||
"BrowserContext.clockFastForward",
|
||||
"BrowserContext.clockPauseAt",
|
||||
"BrowserContext.clockRunFor",
|
||||
"BrowserContext.clockSetFixedTime",
|
||||
"BrowserContext.clockSetSystemTime",
|
||||
"BrowserContext.clockResume",
|
||||
"Keyboard.type",
|
||||
"Keyboard.press",
|
||||
"Keyboard.down",
|
||||
"Keyboard.insertText",
|
||||
"Keyboard.up",
|
||||
"Mouse.move",
|
||||
"Mouse.down",
|
||||
"Mouse.move",
|
||||
"Mouse.wheel",
|
||||
"Mouse.up",
|
||||
"Clock.fastForward",
|
||||
"Clock.fastForward",
|
||||
"Clock.pauseAt",
|
||||
"Clock.runFor",
|
||||
"Clock.setFixedTime",
|
||||
"Clock.setSystemTime",
|
||||
"Clock.resume",
|
||||
"Frame.click"),
|
||||
calls);
|
||||
}
|
||||
@@ -285,31 +285,19 @@ public class TestTracing extends TestBase {
|
||||
context.tracing().stop(new Tracing.StopOptions().setPath(traceFile1));
|
||||
|
||||
List<TraceEvent> events = parseTraceEvents(traceFile1);
|
||||
List<String> calls = events.stream().filter(e -> e.renderedTitle() != null).map(e -> e.renderedTitle())
|
||||
List<String> calls = events.stream().filter(e -> e.apiName != null).map(e -> e.apiName)
|
||||
.collect(Collectors.toList());
|
||||
assertEquals(asList("Frame.goto"), calls);
|
||||
assertEquals(asList("Page.navigate"), calls);
|
||||
}
|
||||
|
||||
private static class TraceEvent {
|
||||
String type;
|
||||
String name;
|
||||
String title;
|
||||
@SerializedName("class")
|
||||
String clazz;
|
||||
String apiName;
|
||||
String method;
|
||||
Double startTime;
|
||||
Double endTime;
|
||||
String callId;
|
||||
|
||||
String renderedTitle() {
|
||||
if (title != null) {
|
||||
return title;
|
||||
}
|
||||
if (clazz != null && method != null) {
|
||||
return clazz + "." + method;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<TraceEvent> parseTraceEvents(Path traceFile) throws IOException {
|
||||
|
||||
@@ -1,16 +1,66 @@
|
||||
# Client Certificate test-certificates
|
||||
|
||||
Regenerate all certificates by running:
|
||||
## Server
|
||||
|
||||
```bash
|
||||
openssl req \
|
||||
-x509 \
|
||||
-newkey rsa:4096 \
|
||||
-keyout server/server_key.pem \
|
||||
-out server/server_cert.pem \
|
||||
-nodes \
|
||||
-days 365 \
|
||||
-subj "/CN=localhost/O=Client\ Certificate\ Demo" \
|
||||
-addext "subjectAltName=DNS:localhost,DNS:local.playwright"
|
||||
```
|
||||
|
||||
## Trusted client-certificate (server signed/valid)
|
||||
|
||||
```
|
||||
bash generate.sh
|
||||
mkdir -p client/trusted
|
||||
# generate server-signed (valid) certifcate
|
||||
openssl req \
|
||||
-newkey rsa:4096 \
|
||||
-keyout client/trusted/key.pem \
|
||||
-out client/trusted/csr.pem \
|
||||
-nodes \
|
||||
-days 365 \
|
||||
-subj "/CN=Alice"
|
||||
|
||||
# sign with server_cert.pem
|
||||
openssl x509 \
|
||||
-req \
|
||||
-in client/trusted/csr.pem \
|
||||
-CA server/server_cert.pem \
|
||||
-CAkey server/server_key.pem \
|
||||
-out client/trusted/cert.pem \
|
||||
-set_serial 01 \
|
||||
-days 365
|
||||
```
|
||||
|
||||
## Self-signed certificate (invalid)
|
||||
|
||||
```
|
||||
mkdir -p client/self-signed
|
||||
openssl req \
|
||||
-newkey rsa:4096 \
|
||||
-keyout client/self-signed/key.pem \
|
||||
-out client/self-signed/csr.pem \
|
||||
-nodes \
|
||||
-days 365 \
|
||||
-subj "/CN=Bob"
|
||||
|
||||
# sign with self-signed/key.pem
|
||||
openssl x509 \
|
||||
-req \
|
||||
-in client/self-signed/csr.pem \
|
||||
-signkey client/self-signed/key.pem \
|
||||
-out client/self-signed/cert.pem \
|
||||
-days 365
|
||||
```
|
||||
|
||||
## Java: Convert PEM Files to PKCS12
|
||||
|
||||
|
||||
Java server understands only PKCS12 keys, after copying the certificates from Node.js Playwright we need to convert them.
|
||||
|
||||
```
|
||||
bash generate_java.sh
|
||||
openssl pkcs12 -export -in server_cert.pem -inkey server_key.pem -out server_keystore.p12 -name myalias
|
||||
```
|
||||
|
||||
@@ -1,28 +1,28 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIIEUzCCAjsCAQAwDjEMMAoGA1UEAwwDQm9iMIICIjANBgkqhkiG9w0BAQEFAAOC
|
||||
Ag8AMIICCgKCAgEAzQMXYOZz3ILrbF9qpDng2pw2wJf1UFopehwaYyu7riWJ9+AD
|
||||
rhSnCSFBM3ScMBc/8dIR6etWwci8QwJ/MtvIU0yx4llq+53G+19Bc1teC6q/b4QC
|
||||
RDIcTGxOZoR+jfYZVjPODEyJ5y5MZIo34ZP4bu+JnpT4W7+uojm3jOoyNPqXMcc7
|
||||
0uAhfSKG+JfrwZKteA4T5VKFytVcWgh4v03z8zTYeW3kD4lCsongBz6yu2dn3D6X
|
||||
MROnxiPwi+IRQqX1pwnJ0UA3CTeOHEw1jA3koxWIIg44PWaPaCj9Udrhf4ew00XL
|
||||
PWVZP8T5rVf8yUfecWQCR7FueJFqoLhPMMFi17rYmGZUvw3/YkXBjay4Q9e+G2WS
|
||||
3Xk8u+I1sCuVBJNBRv9DqtMC9D/N9NI8GkLrXwZmk82SXG+cQ0TSkNUHYI/03YKo
|
||||
qsn5H8PsG7Tc+Y2Ca6TaCWims7lvOg7U0E6lu2h5NGcdWHFPJ9qfe+xho/yfYYwG
|
||||
qEKanGAu1kd5SbIaX6/YiM5/Pp/96MeRNrB9kLzDnZTNuGtdCawVFgbkWmfX2Z6/
|
||||
a0d6SvZGDzBxxTVZRB0my01E1FP53MS8YRH98HUjGEwNRVq2e1W+aXldKppgZ85G
|
||||
ZD3l2YTeuI0iPJCDUzQiaWzFtWc8s13YQ1HLCOyOXF7QqMyNCiLGb4xQ56kCAwEA
|
||||
AaAAMA0GCSqGSIb3DQEBCwUAA4ICAQAn/ZI7IkBUEfhZHefwtF+QHCyxSEKvqwHq
|
||||
fSqKVdarBPz8Ik8m3icj8R/DcS3y5jgzx3x8bXQoDpgsAQgeb825NRv2wAQAGoH1
|
||||
8vh204lTyjqzrgtK7eQeQDc7fjeigIkxQsAK9zk4BaFUWp0wEC0RLVAgvlQTl7vu
|
||||
n1jSSrhK8tvGy62/cIxZfwD0bAMHlW4m1A4fUuSGWQX2KldgA8tnmT6wx0If/nKb
|
||||
VB68AMbyMHUeb32v9wEvx2nHlwMjqNFeg7vYyJXOfBdDILUl+OTBoQY1X+jSx5iM
|
||||
txTzmA8Hcgx0Fq+BnbQuZCLqFpNWEfenAtQtaAFuJwMiKCf6kgbqkDVShJkmt+vC
|
||||
j3dcsVMZDsdMk4qRpiJhaTQOYmsMGCj4uoDpFGjwPoUwlDkjYgHAAsm9uCkshc+m
|
||||
WZO7I6Z3Tbi3XskJvAMc3dTWjtc6nApEtr/mn8LcETfOp7RRSfjllj6ijWUrVwUy
|
||||
BpzU9C/zLTkhFX0DVDCIV+jEefF8JPfzSKLgXyRbInTz1/6/sKXtswXW0NjzqLMI
|
||||
C9ggMBhOiDv9KJn3G/mY4CqIfo9KMzF+++4t+wdXTir8DWNlMUAn1vlBwxZAgKCM
|
||||
GonVExBU0VIGCpyTRLkesEHnPMgybP6gLzP3++54x288OS5JwuPPtkDcsBHUjTq8
|
||||
HxTJvUul/Q==
|
||||
Ag8AMIICCgKCAgEA179eTsqcc1c3AOQHzCZEyYLPta2CCAscUFqcEZ9vWvjW0uzO
|
||||
v9TDlB33Unovjch4CElZOBhzTadVsbmnYKpxwyVU89WCuQKvedz4k1vu7S1YryfN
|
||||
bmS8PWbnQ4ds9NB7SgJNHZILvx9DXuWeFEyzRIo1984z4HheBzrkf791LqpYKaKz
|
||||
iANUo8h8t0dmTX/boOz8cEnQNwtTC0ZX3aD0obG/UAhr/22ZGPo/E659fh4ptyYX
|
||||
2LrIUHGy+EuxnJ9Y4cTqa88Ee6K6AkDiT/AoNQNxE4X++jqLuie8j/ZYpI1Oll38
|
||||
GwKVOyy1msRLtoGmISNwkMIQDGABrJlxgpP4QQAQ+08v9srzXOlkdxdr7OCP81r+
|
||||
ccBXiSQEe7BAkdJ8l98l5dprJ++GJ+SZcV4+/iGR0dKU2IdAG5HiKZIFn6ch9Ux+
|
||||
UMqeGaYCpkHrTiietHwcXgtVBlE0jFmB/HspmI/O0abK+grMmueaH7XtTI8YHnw0
|
||||
mUpL8+yp7mfA7zFusgFgyiBPXeD/NQgg8vja67k++d1VGoXm2xr+5WPQCSbgQoMk
|
||||
kOBMLHWJTefd6F4Z5M+oI0VwYbf6eQW246wJgpCHSPR0Vdijd6MAGRWKUuLfDsA9
|
||||
+12iGbKvwJ2enJlStft2V2LZcjBfdIMbigW1aSVNN5w6m6YVrQPry3WPkWcCAwEA
|
||||
AaAAMA0GCSqGSIb3DQEBCwUAA4ICAQCb07d2IjUy1PeHCj/2k/z9FrZSo6K3c8y6
|
||||
b/u/MZ0AXPKLPDSo7UYpOJ8Z2cBiJ8jQapjTSEL8POUYqcvCmP55R6u68KmvINHo
|
||||
+Ly7pP+xPrbA4Q0WmPnz37hQn+I1he0GuEQyjZZqUln9zwp67TsWNKxKtCH+1j8M
|
||||
Ltzx6kuHCdPtDUtv291yhVRqvbjiDs+gzdQYNJtAkUbHwHFxu8oZhg8QZGyXYMN8
|
||||
TGoQ1LTezFZXJtX69K7WnrDGrjsgB6EMvwkqAFSYNH0LFvI0xo13OOgXr9mrwohA
|
||||
76uZtjXL9B15EqrMce6mdUZi46QJuQ2avTi57Lz+fqvsBYdQO89VcFSmqu2nfspN
|
||||
QZDrooyjHrlls8MpoBd8fde9oT4uA4/d9SJtuHUnjgGN7Qr7eTruWXL8wVMwFnvL
|
||||
igWE4detO9y2gpRLq6uEqzWYMGtN9PXJCGU8C8m9E2EBUKMrT/bpNbboatLcgRrW
|
||||
acj0BRVqoVzk1sRq7Sa6ejywqgARvIhTehg6DqdMdcENCPQ7rxDRu5PSDM8/mwIj
|
||||
0KYl8d2PlECB4ofRyLcy17BZzjP6hSnkGzcFk0/bChZOSIRnwvKbvfXnB45hhPk8
|
||||
XwT/6UNSwC2STP3gtOmLqrWj+OE0gy0AkDMvP3UnQVGMUvgfYg+N4ROCVtlqzxe9
|
||||
W65c05Mm1g==
|
||||
-----END CERTIFICATE REQUEST-----
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
v3/WVVAXEcIowL3T4jzJ0RLdf1qE8Bc=
|
||||
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
|
||||
dg6m3MAyZ1IXjHlogOdmGvnq07/w
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
Binary file not shown.
@@ -1,26 +1,26 @@
|
||||
-----BEGIN CERTIFICATE REQUEST-----
|
||||
MIIEVTCCAj0CAQAwEDEOMAwGA1UEAwwFQWxpY2UwggIiMA0GCSqGSIb3DQEBAQUA
|
||||
A4ICDwAwggIKAoICAQC4ggn74iAHLgOWOiOvB2CPe+Hr7W6STYJLZOoqPdh7mv7Q
|
||||
Gm8cYxfD+26p13aEaW4/qn45losWdEPPy2ZiVIF+kcOP0R4AqsB0w9UHT4WSzCWt
|
||||
Dqs8ywDMJ6tHge0++8S1bTpdutn/m8DPnKtkD9RQUzLFmGDO+mB08Xu+egTzJvUR
|
||||
bHXRJ27E+CXUXLEHbAJd8EKjJiQYXhcj4lzUXOUg+xkpPAGe1dgQ6BDkv3xq/81S
|
||||
9NTIT5YriHEm6egi9AFJLZbbZtCpRQm1MDMq7zfD7oL6ECLGrJ/aaxLEM49gMdw2
|
||||
SscYHotVxX2OMAKgN/ytB18L/mIQ4pOWp3HJQ+nks9Zu1V8cg7Pz5pWwjqoncbyU
|
||||
aBi3vGsitAot3cyLXbN9hH8zQB8QqGyNLvqQnCJOBlYxOPA8M8NQGDThWKspcix0
|
||||
LhkmnYsWWt3+KEGEpFRcJCEthm/DAd1GImP7/dg1/btT/zOsIIkIoCyBwznuR4M4
|
||||
XoNTbIBsiTnO/6PjOdTrjLVX7vMueTjdbCgK3VeOuwetbZ7aZ/hvMJCjJ4wuM3l2
|
||||
ZyfEQlP4gJLJS3Fw2PRsySZJl9JyEzwTqYVosDF5SF8uw0HIcFaliZCqBbgYfOiQ
|
||||
zjIX/GiHZdor1ZrhAbO/MpSxuxGzxF7Em4n+4p816NnC9S2JbHRetkM9P1adHwID
|
||||
AQABoAAwDQYJKoZIhvcNAQELBQADggIBACpScaAoLAs9DuTcI5Y4dbHf7LwF4Zxx
|
||||
UgPNzE1HB1Pr6NaHRiOWrlCtDEB5UwHrr0oZuRTqSEGg3Pe5Z2QtPG/sdFgfm4BP
|
||||
29o6qo0CXiEVBwU7/K0/lL2/0a7uSbD0Tkw9d6Bgik7/Z5rzXZIi2vtUcrOtHskP
|
||||
C+Z9w3vH9a+RnUeo52mCnRi4SaiSEnD5jvhmgaI9iF+k5pYBiMrKRj5W/F1QCkf4
|
||||
7OuSK97xN0eG/I4Oxgzi/qt51ySCYZbqoh7dIpwi/a4UsK8kdzDDI1M3J7bU07cO
|
||||
CJRfr0EETqCQw/gAKoag3tRFNvWQB6Z9G3Ev5jeaCLpcc32NlpN5xH3VW8A0Zb81
|
||||
dn5BXkPSxjwJaD0a3cLFkfgrasoe7ZMmHrVpQDw+9USuGCYXMPzNZLEeTFbrRkUn
|
||||
sqi30e28E1H69zVWj+OKzCWEH/azVlfaoVbwM+njUJDe5V09KvFtI7aZYmvLxbUX
|
||||
4ifoRUVoKedyKnueVmoIG57lF2VzeEhX5YjCngxIg+YuE99HkMQAZSlS6uJcVM92
|
||||
tsC/+pYECBk8ukenbxmKXROl3u4p2M1iCSL/8EOVROuyjnuzCXJZOpNptdpX4ZgL
|
||||
kHP1erq7/U8ZU8HviUsfMoisagx8dA8uj/4fk0jfNxOJqlZL9eJhpgBfYHqmAz3h
|
||||
m+PQVw96eeoK
|
||||
A4ICDwAwggIKAoICAQCac3+4rNmH4/N1s4HqR2X168tgS/aA6sHW5at8mWRnq54N
|
||||
m11RvnK55jHQYVAdBgJy5M07w0wakp8inxzlY95wqxBimYG63Un/1p7mX9FkB4LN
|
||||
ISCc6j/s/Ufv85MXPbn0S5rm9UcQO9cINJb1RP1YgDDLN5cxMz6X4nyofN8H6Lhv
|
||||
h4JDdBw4DfDEFERkVfF+bkZ7YW4XHEChgzm3RxCF0eeGzIXGrkkK9AsSdJAhOvTl
|
||||
HPFCQKXTYZhsL5+3Ma4RnWnDWvLTHx6KzoU+twTM2mYhhQuQgQpnmDHxGge8kGeH
|
||||
GtfdgAjtVJTE57xF/shP0JU+tuIV8NNhQ/vEmhL0Wa093/EvpTVp0EUEuDh9ORRH
|
||||
5K5M4bKJyU4XX5noiht6yOn00uaoJcWduUAWsU+cDSvDTMw81opWWm0QIAV3G2yu
|
||||
RSkumHAKqvQLeyeyiKz+OEhyEiZ7EZNExPD0TSpApSTU6aCTUAvPYGQ59VjsMHTu
|
||||
J9r4wKIYaDvfL+t72vg2vTQma5cTOBJfIdxH9blFTjEnToH3LX8t0XndQ2RkiRnI
|
||||
ze2p2jUShxo/lWCjCw+2Iaw0A0fNUK1BbOrFRPq1u7AnEuMJt7HF50MloItM97R9
|
||||
vofDwgDIzlX/PzlVRcn1WCo8Fr/0EXxPPreX0YDIp1ANQ8fSv7bKb2vQIxWuCQID
|
||||
AQABoAAwDQYJKoZIhvcNAQELBQADggIBAGgf3EC8WL3RGmuGA+d/4wd1jNfrfU6n
|
||||
xjnDwdEEX0TQZGGPjh5xvoCK76yZPkO6+z0IYSepEmWBS27HJKl7nuoOvS7MjQyJ
|
||||
C+3Bdk3ToCeQjmNBlRBKsUw5ftTU902oMl5BptHGj1KGjYBLAkPdXb44wXSVKJ8q
|
||||
ihFhWlovsva6GDoUorksU3vOwijdlGzTANQHJGFncgrRud9ATavpGS3KVxR73R3A
|
||||
aBbu3Qw+QIfu8Qx5eBJp8CbMrpAmjfuq17STvqr5bC10Fnn4NegrnHOQG9JcK02+
|
||||
5Bn3+9X/n1mue7aohIdErLEiDMSqMOwFfrJeaH6YM1G4QkWyqGugtmHsWOUf0nlU
|
||||
nkH1krvfw9rb6b+03c4A6GSeHnbX5ufFDSf5gaR6Wy7c0jBnoxVbtBLH2zXlrd0k
|
||||
iRQG7C6XZzGMS7hb7GL7+bkRy9kWjmDL7z7Fp+EgzKhNmzuWII3E9X9va33HoQ/Q
|
||||
UdK3JVToxRQg6XRKOxL9+U/+8i6U8lxObLWkWh2cypZqbz5qJxa+2u5JYO/KEoHZ
|
||||
G963UX7XWezR98vZuTc1XHGZtBDMrjjDd7Kmb4/i/xBPeWwseeGtzFy9z2pnEnkL
|
||||
uKE4C8wUNpzUUlsn4LneZXObIoErE7FqAAlVFujVe7iaJBmXoUXZR36drbfiaODK
|
||||
vwAGyrYHaOlR
|
||||
-----END CERTIFICATE REQUEST-----
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
21eLmxOuln98Q3na7ftpAWQdyjcE6Q==
|
||||
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
|
||||
Y+eu85cike5J4vnz8uG04yt7rXjIrUav
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
Binary file not shown.
@@ -1,86 +0,0 @@
|
||||
# Client Certificate test-certificates
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
|
||||
## Server
|
||||
|
||||
openssl req \
|
||||
-x509 \
|
||||
-newkey rsa:4096 \
|
||||
-keyout server/server_key.pem \
|
||||
-out server/server_cert.pem \
|
||||
-nodes \
|
||||
-days 3650 \
|
||||
-subj "/CN=localhost/O=Client\ Certificate\ Demo" \
|
||||
-addext "subjectAltName=DNS:localhost,DNS:local.playwright"
|
||||
|
||||
## Trusted client-certificate (server signed/valid)
|
||||
|
||||
mkdir -p client/trusted
|
||||
# generate server-signed (valid) certificate
|
||||
openssl req \
|
||||
-newkey rsa:4096 \
|
||||
-keyout client/trusted/key.pem \
|
||||
-out client/trusted/csr.pem \
|
||||
-nodes \
|
||||
-days 3650 \
|
||||
-subj "/CN=Alice"
|
||||
|
||||
# sign with server_cert.pem
|
||||
openssl x509 \
|
||||
-req \
|
||||
-in client/trusted/csr.pem \
|
||||
-CA server/server_cert.pem \
|
||||
-CAkey server/server_key.pem \
|
||||
-out client/trusted/cert.pem \
|
||||
-set_serial 01 \
|
||||
-days 3650
|
||||
# create pfx
|
||||
openssl pkcs12 -export -out client/trusted/cert.pfx -inkey client/trusted/key.pem -in client/trusted/cert.pem -passout pass:secure
|
||||
|
||||
## Trusted certificate for localhost (server signed/valid)
|
||||
|
||||
mkdir -p client/localhost
|
||||
|
||||
# generate server-signed (valid) certificate
|
||||
openssl req \
|
||||
-newkey rsa:4096 \
|
||||
-keyout client/localhost/localhost.key \
|
||||
-out client/localhost/localhost.csr \
|
||||
-nodes \
|
||||
-days 3650 \
|
||||
-subj "/CN=localhost" \
|
||||
-addext "subjectAltName=DNS:localhost,DNS:127.0.0.1"
|
||||
|
||||
# put extensions
|
||||
echo "subjectAltName=DNS:localhost,DNS:127.0.0.1" > client/localhost/localhost.ext
|
||||
|
||||
# sign with server_cert.pem
|
||||
openssl x509 \
|
||||
-req \
|
||||
-in client/localhost/localhost.csr \
|
||||
-CA server/server_cert.pem \
|
||||
-CAkey server/server_key.pem \
|
||||
-set_serial 01 \
|
||||
-out client/localhost/localhost.pem \
|
||||
-days 3650 \
|
||||
-extfile client/localhost/localhost.ext
|
||||
|
||||
## Self-signed certificate (invalid)
|
||||
|
||||
mkdir -p client/self-signed
|
||||
openssl req \
|
||||
-newkey rsa:4096 \
|
||||
-keyout client/self-signed/key.pem \
|
||||
-out client/self-signed/csr.pem \
|
||||
-nodes \
|
||||
-days 3650 \
|
||||
-subj "/CN=Bob"
|
||||
|
||||
# sign with self-signed/key.pem
|
||||
openssl x509 \
|
||||
-req \
|
||||
-in client/self-signed/csr.pem \
|
||||
-signkey client/self-signed/key.pem \
|
||||
-out client/self-signed/cert.pem \
|
||||
-days 3650
|
||||
@@ -1,8 +0,0 @@
|
||||
cd "$(dirname "$0")"
|
||||
CWD=$(pwd)
|
||||
|
||||
cd server
|
||||
openssl pkcs12 -export -in server_cert.pem -inkey server_key.pem -out server_keystore.p12 -name myalias -passout pass:
|
||||
|
||||
cd "$CWD/client/trusted"
|
||||
openssl pkcs12 -export -in cert.pem -inkey key.pem -out keystore.p12 -name myalias -passout pass:
|
||||
@@ -1,32 +1,32 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
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
|
||||
t3jt9TP8623D
|
||||
cmlnaHQwDQYJKoZIhvcNAQELBQADggIBALP4kOAP21ZusbEH89VkZT3MkGlZuDQP
|
||||
LyTYdLzT3EzN//2+lBDmJfpIPLL/K3sNEVSzNppa6tcCXiVNes/xJM7tHRhTOJ31
|
||||
HinSsib2r6DZ6SitQJWmD5FoAdkp9qdG8mA/5vOiwiVKKFV2/Z3i+3iUI/ZnEhUq
|
||||
uUA1I3TI5LAQzgWLwYu1jSEM1EbH6uQiZ8AmXLVO4GQnVQdbyarWHxIy+zsg+MJN
|
||||
fxIG/phDpkt1mI3SkAdpWRWjCKESQhrIcRUtu5eVk0lho6ttHODXF8bM7iWLoRc7
|
||||
rpcllI4HXHoXQqQkZHRa7KwTf0YVwwQbXTecZONWXwE9Ej5R5IcZzja5FWCSstsb
|
||||
ULNW0JVxGBE7j5aOjxasYAbRexDmlfEdLvnp6bctZuvMvuBxrB+x5HSEZl6bVnbC
|
||||
nvtoslylQJM1bwlZdCqJm04JXe1787HDBef2gABv27BjvG/zn89L5ipogZCrGpl6
|
||||
P9qs0eSERHuSrm3eHUVgXSQ1nbvOpk7RPFbsbp/npc1NbEDBdAMoXhLP9A+ytxLq
|
||||
TF+w08nfCF6yJJ3jTkvABo10UH6zcPnfH3Ys7JYsHRbcloMfn+mc88KrTaCO+VZx
|
||||
qjhFcz+zDu/AbtJkDJtxX2X7jNL0pzWS+9H8jFTrd3ta8XrJiSFq2VMxEU6R0IHk
|
||||
2Ct10prMWB/3
|
||||
-----END CERTIFICATE-----
|
||||
|
||||
@@ -1,52 +1,52 @@
|
||||
-----BEGIN PRIVATE KEY-----
|
||||
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
|
||||
dvQgA6dBjtYg5cQMHNbnfT3j3WzyQg==
|
||||
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
|
||||
8ynLaTs3oV3BjQya9pAUyzIX5L67
|
||||
-----END PRIVATE KEY-----
|
||||
|
||||
Binary file not shown.
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>com.microsoft.playwright</groupId>
|
||||
<artifactId>parent-pom</artifactId>
|
||||
<version>1.54.0</version>
|
||||
<version>1.52.0</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Playwright Parent Project</name>
|
||||
<description>Java library to automate Chromium, Firefox and WebKit with a single API.
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.54.1
|
||||
1.52.0
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>com.microsoft.playwright</groupId>
|
||||
<artifactId>api-generator</artifactId>
|
||||
<version>1.54.0</version>
|
||||
<version>1.52.0</version>
|
||||
<name>Playwright - API Generator</name>
|
||||
<description>
|
||||
This is an internal module used to generate Java API from the upstream Playwright
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>com.microsoft.playwright</groupId>
|
||||
<artifactId>test-cli-fatjar</artifactId>
|
||||
<version>1.54.0</version>
|
||||
<version>1.52.0</version>
|
||||
<name>Test Playwright Command Line FatJar</name>
|
||||
<properties>
|
||||
<compiler.version>1.8</compiler.version>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user