Compare commits
20 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c1c538c7dc | |||
| bfc7645d20 | |||
| c34a35d6a7 | |||
| 6ef0cc29dd | |||
| 8dfe959cce | |||
| 5979077403 | |||
| 020618d83d | |||
| 6bef6bb4a7 | |||
| 734d56f5d5 | |||
| 6e66861db3 | |||
| cf73a8d525 | |||
| 4a0ff6ef5c | |||
| 398c979378 | |||
| 39be690062 | |||
| b5b0a983bd | |||
| 6b842e0d50 | |||
| 321673407a | |||
| 4d278c391e | |||
| 5c47cfb1d5 | |||
| f036b3d38a |
@@ -11,9 +11,9 @@ Playwright is a Java library to automate [Chromium](https://www.chromium.org/Hom
|
||||
|
||||
| | Linux | macOS | Windows |
|
||||
| :--- | :---: | :---: | :---: |
|
||||
| Chromium <!-- GEN:chromium-version -->105.0.5195.19<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Chromium <!-- GEN:chromium-version -->106.0.5249.30<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| WebKit <!-- GEN:webkit-version -->16.0<!-- GEN:stop --> | ✅ | ✅ | ✅ |
|
||||
| Firefox <!-- GEN:firefox-version -->103.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
| Firefox <!-- GEN:firefox-version -->104.0<!-- GEN:stop --> | :white_check_mark: | :white_check_mark: | :white_check_mark: |
|
||||
|
||||
Headless execution is supported for all the browsers on all platforms. Check out [system requirements](https://playwright.dev/java/docs/next/intro/#system-requirements) for details.
|
||||
|
||||
@@ -47,6 +47,14 @@ To run Playwright simply add following dependency to your Maven project:
|
||||
</dependency>
|
||||
```
|
||||
|
||||
To run Playwright using Gradle add following dependency to your build.gradle file:
|
||||
|
||||
```json lines
|
||||
dependencies {
|
||||
implementation group: 'com.microsoft.playwright', name: 'playwright', version: '1.25.0'
|
||||
}
|
||||
```
|
||||
|
||||
#### Is Playwright thread-safe?
|
||||
|
||||
No, Playwright is not thread safe, i.e. all its methods as well as methods on all objects created by it (such as BrowserContext, Browser, Page etc.) are expected to be called on the same thread where Playwright object was created or proper synchronization should be implemented to ensure only one thread calls Playwright methods at any given time. Having said that it's okay to create multiple Playwright instances each on its own thread.
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.microsoft.playwright</groupId>
|
||||
<artifactId>parent-pom</artifactId>
|
||||
<version>1.25.0-SNAPSHOT</version>
|
||||
<version>1.26.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>driver-bundle</artifactId>
|
||||
|
||||
+30
-6
@@ -29,7 +29,9 @@ import java.util.concurrent.TimeUnit;
|
||||
public class DriverJar extends Driver {
|
||||
private static final String PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD = "PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD";
|
||||
private static final String SELENIUM_REMOTE_URL = "SELENIUM_REMOTE_URL";
|
||||
static final String PLAYWRIGHT_NODEJS_PATH = "PLAYWRIGHT_NODEJS_PATH";
|
||||
private final Path driverTempDir;
|
||||
private Path preinstalledNodePath;
|
||||
|
||||
public DriverJar() throws IOException {
|
||||
// Allow specifying custom path for the driver installation
|
||||
@@ -40,11 +42,27 @@ public class DriverJar extends Driver {
|
||||
? Files.createTempDirectory(prefix)
|
||||
: Files.createTempDirectory(Paths.get(alternativeTmpdir), prefix);
|
||||
driverTempDir.toFile().deleteOnExit();
|
||||
String nodePath = System.getProperty("playwright.nodejs.path");
|
||||
if (nodePath != null) {
|
||||
preinstalledNodePath = Paths.get(nodePath);
|
||||
if (!Files.exists(preinstalledNodePath)) {
|
||||
throw new RuntimeException("Invalid Node.js path specified: " + nodePath);
|
||||
}
|
||||
}
|
||||
logMessage("created DriverJar: " + driverTempDir);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize(Map<String, String> env, Boolean installBrowsers) throws Exception {
|
||||
protected void initialize(Boolean installBrowsers) throws Exception {
|
||||
if (preinstalledNodePath == null && env.containsKey(PLAYWRIGHT_NODEJS_PATH)) {
|
||||
preinstalledNodePath = Paths.get(env.get(PLAYWRIGHT_NODEJS_PATH));
|
||||
if (!Files.exists(preinstalledNodePath)) {
|
||||
throw new RuntimeException("Invalid Node.js path specified: " + preinstalledNodePath);
|
||||
}
|
||||
} else if (preinstalledNodePath != null) {
|
||||
// Pass the env variable to the driver process.
|
||||
env.put(PLAYWRIGHT_NODEJS_PATH, preinstalledNodePath.toString());
|
||||
}
|
||||
extractDriverToTempDir();
|
||||
logMessage("extracted driver from jar to " + driverPath());
|
||||
if (installBrowsers)
|
||||
@@ -68,9 +86,8 @@ public class DriverJar extends Driver {
|
||||
if (!Files.exists(driver)) {
|
||||
throw new RuntimeException("Failed to find driver: " + driver);
|
||||
}
|
||||
ProcessBuilder pb = new ProcessBuilder(driver.toString(), "install");
|
||||
pb.environment().putAll(env);
|
||||
setRequiredEnvironmentVariables(pb);
|
||||
ProcessBuilder pb = createProcessBuilder();
|
||||
pb.command().add("install");
|
||||
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
|
||||
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
|
||||
Process p = pb.start();
|
||||
@@ -89,9 +106,10 @@ public class DriverJar extends Driver {
|
||||
return name.endsWith(".sh") || name.endsWith(".exe") || !name.contains(".");
|
||||
}
|
||||
|
||||
private void extractDriverToTempDir() throws URISyntaxException, IOException {
|
||||
void extractDriverToTempDir() throws URISyntaxException, IOException {
|
||||
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
|
||||
URI originalUri = classloader.getResource("driver/" + platformDir()).toURI();
|
||||
URI originalUri = classloader.getResource(
|
||||
"driver/" + platformDir()).toURI();
|
||||
URI uri = maybeExtractNestedJar(originalUri);
|
||||
|
||||
// Create zip filesystem if loading from jar.
|
||||
@@ -103,6 +121,12 @@ public class DriverJar extends Driver {
|
||||
// See https://github.com/microsoft/playwright-java/issues/306
|
||||
Path srcRootDefaultFs = Paths.get(srcRoot.toString());
|
||||
Files.walk(srcRoot).forEach(fromPath -> {
|
||||
if (preinstalledNodePath != null) {
|
||||
String fileName = fromPath.getFileName().toString();
|
||||
if ("node.exe".equals(fileName) || "node".equals(fileName)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
Path relative = srcRootDefaultFs.relativize(Paths.get(fromPath.toString()));
|
||||
Path toPath = driverTempDir.resolve(relative.toString());
|
||||
try {
|
||||
|
||||
+61
-27
@@ -14,10 +14,10 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.microsoft.playwright;
|
||||
package com.microsoft.playwright.impl.driver.jar;
|
||||
|
||||
import com.microsoft.playwright.impl.driver.Driver;
|
||||
import com.microsoft.playwright.impl.driver.jar.DriverJar;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.io.TempDir;
|
||||
@@ -25,6 +25,8 @@ import org.junit.jupiter.api.io.TempDir;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.ServerSocket;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
@@ -32,6 +34,8 @@ import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import static com.microsoft.playwright.impl.driver.jar.DriverJar.PLAYWRIGHT_NODEJS_PATH;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestInstall {
|
||||
@@ -57,6 +61,7 @@ public class TestInstall {
|
||||
// Clear system property to ensure that the driver is loaded from jar.
|
||||
System.clearProperty("playwright.cli.dir");
|
||||
System.clearProperty("playwright.driver.tmpdir");
|
||||
System.clearProperty("playwright.nodejs.path");
|
||||
// Clear system property to ensure that the default driver is loaded.
|
||||
System.clearProperty("playwright.driver.impl");
|
||||
}
|
||||
@@ -72,27 +77,18 @@ public class TestInstall {
|
||||
env.put("PLAYWRIGHT_BROWSERS_PATH", tmpDir.toString());
|
||||
env.put("PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD", "false");
|
||||
|
||||
// Reset instance field value to null for the test.
|
||||
Field field = Driver.class.getDeclaredField("instance");
|
||||
field.setAccessible(true);
|
||||
Object value = field.get(Driver.class);
|
||||
field.set(Driver.class, null);
|
||||
|
||||
for (int i = 0; i < 2; i++){
|
||||
RuntimeException exception = assertThrows(RuntimeException.class, () -> Driver.ensureDriverInstalled(env, true));
|
||||
String message = exception.getMessage();
|
||||
assertTrue(message.contains("Failed to create driver"), message);
|
||||
}
|
||||
|
||||
field.set(Driver.class, value);
|
||||
RuntimeException exception = assertThrows(RuntimeException.class, () -> Driver.createAndInstall(env, true));
|
||||
String message = exception.getMessage();
|
||||
assertTrue(message.contains("Failed to create driver"), message);
|
||||
}
|
||||
|
||||
@Test
|
||||
void playwrightCliInstalled() throws Exception {
|
||||
Path cli = Driver.ensureDriverInstalled(Collections.emptyMap(), false);
|
||||
assertTrue(Files.exists(cli));
|
||||
Driver driver = Driver.createAndInstall(Collections.emptyMap(), false);
|
||||
assertTrue(Files.exists(driver.driverPath()));
|
||||
|
||||
ProcessBuilder pb = new ProcessBuilder(cli.toString(), "install");
|
||||
ProcessBuilder pb = driver.createProcessBuilder();
|
||||
pb.command().add("install");
|
||||
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
|
||||
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
|
||||
Process p = pb.start();
|
||||
@@ -109,24 +105,62 @@ public class TestInstall {
|
||||
|
||||
@Test
|
||||
void playwrightDriverDefaultImpl() {
|
||||
assertDoesNotThrow(() -> Driver.ensureDriverInstalled(Collections.emptyMap(), false));
|
||||
assertDoesNotThrow(() -> Driver.createAndInstall(Collections.emptyMap(), false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void playwrightDriverAlternativeImpl() throws NoSuchFieldException, IllegalAccessException {
|
||||
// Reset instance field value to null for the test.
|
||||
Field field = Driver.class.getDeclaredField("instance");
|
||||
field.setAccessible(true);
|
||||
Object value = field.get(Driver.class);
|
||||
field.set(Driver.class, null);
|
||||
|
||||
System.setProperty("playwright.driver.impl", "com.microsoft.playwright.impl.AlternativeDriver");
|
||||
RuntimeException thrown =
|
||||
assertThrows(
|
||||
RuntimeException.class,
|
||||
() -> Driver.ensureDriverInstalled(Collections.emptyMap(), false));
|
||||
() -> Driver.createAndInstall(Collections.emptyMap(), false));
|
||||
assertEquals("Failed to create driver", thrown.getMessage());
|
||||
}
|
||||
|
||||
field.set(Driver.class, value);
|
||||
@Test
|
||||
void canPassPreinstalledNodeJsAsSystemProperty(@TempDir Path tmpDir) throws IOException, URISyntaxException, InterruptedException {
|
||||
String nodePath = extractNodeJsToTemp();
|
||||
System.setProperty("playwright.nodejs.path", nodePath);
|
||||
Driver driver = Driver.createAndInstall(Collections.emptyMap(), false);
|
||||
canSpecifyPreinstalledNodeJsShared(driver, tmpDir);
|
||||
}
|
||||
|
||||
@Test
|
||||
void canSpecifyPreinstalledNodeJsAsEnv(@TempDir Path tmpDir) throws IOException, URISyntaxException, InterruptedException {
|
||||
String nodePath = extractNodeJsToTemp();
|
||||
Driver driver = Driver.createAndInstall(singletonMap(PLAYWRIGHT_NODEJS_PATH, nodePath), false);
|
||||
canSpecifyPreinstalledNodeJsShared(driver, tmpDir);
|
||||
}
|
||||
|
||||
|
||||
private static String extractNodeJsToTemp() throws URISyntaxException, IOException {
|
||||
DriverJar auxDriver = new DriverJar();
|
||||
auxDriver.extractDriverToTempDir();
|
||||
String nodePath = auxDriver.driverPath().getParent().resolve(isWindows() ? "node.exe" : "node").toString();
|
||||
return nodePath;
|
||||
}
|
||||
|
||||
private static boolean isWindows() {
|
||||
String name = System.getProperty("os.name").toLowerCase();
|
||||
return name.contains("win");
|
||||
}
|
||||
|
||||
private static void canSpecifyPreinstalledNodeJsShared(Driver driver, Path tmpDir) throws IOException, URISyntaxException, InterruptedException {
|
||||
Path builtinNode = driver.driverPath().getParent().resolve("node");
|
||||
assertFalse(Files.exists(builtinNode), builtinNode.toString());
|
||||
Path builtinNodeExe = driver.driverPath().getParent().resolve("node.exe");
|
||||
assertFalse(Files.exists(builtinNodeExe), builtinNodeExe.toString());
|
||||
|
||||
ProcessBuilder pb = driver.createProcessBuilder();
|
||||
pb.command().add("--version");
|
||||
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
|
||||
Path out = tmpDir.resolve("out.txt");
|
||||
pb.redirectOutput(out.toFile());
|
||||
Process p = pb.start();
|
||||
boolean result = p.waitFor(1, TimeUnit.MINUTES);
|
||||
assertTrue(result, "Timed out waiting for version to be printed");
|
||||
String stdout = new String(Files.readAllBytes(out), StandardCharsets.UTF_8);
|
||||
assertTrue(stdout.contains("Version "), stdout);
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
<parent>
|
||||
<groupId>com.microsoft.playwright</groupId>
|
||||
<artifactId>parent-pom</artifactId>
|
||||
<version>1.25.0-SNAPSHOT</version>
|
||||
<version>1.26.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>driver</artifactId>
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.microsoft.playwright.impl.driver;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.microsoft.playwright.impl.driver.DriverLogging.logWithTimestamp;
|
||||
@@ -28,6 +30,8 @@ import static com.microsoft.playwright.impl.driver.DriverLogging.logWithTimestam
|
||||
* loaded from the driver-bundle module if that module is in the classpath.
|
||||
*/
|
||||
public abstract class Driver {
|
||||
protected final Map<String, String> env = new LinkedHashMap<>();
|
||||
|
||||
private static Driver instance;
|
||||
|
||||
private static class PreinstalledDriver extends Driver {
|
||||
@@ -38,7 +42,7 @@ public abstract class Driver {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void initialize(Map<String, String> env, Boolean installBrowsers) {
|
||||
protected void initialize(Boolean installBrowsers) {
|
||||
// no-op
|
||||
}
|
||||
|
||||
@@ -48,22 +52,18 @@ public abstract class Driver {
|
||||
}
|
||||
}
|
||||
|
||||
public static synchronized Path ensureDriverInstalled(Map<String, String> env, Boolean installBrowsers) {
|
||||
public static synchronized Driver ensureDriverInstalled(Map<String, String> env, Boolean installBrowsers) {
|
||||
if (instance == null) {
|
||||
try {
|
||||
instance = createDriver();
|
||||
logMessage("initializing driver");
|
||||
instance.initialize(env, installBrowsers);
|
||||
logMessage("driver initialized.");
|
||||
} catch (Exception exception) {
|
||||
instance = null;
|
||||
throw new RuntimeException("Failed to create driver", exception);
|
||||
}
|
||||
instance = createAndInstall(env, installBrowsers);
|
||||
}
|
||||
return instance.driverPath();
|
||||
return instance;
|
||||
}
|
||||
|
||||
protected abstract void initialize(Map<String, String> env, Boolean installBrowsers) throws Exception;
|
||||
private void initialize(Map<String, String> env, Boolean installBrowsers) throws Exception {
|
||||
this.env.putAll(env);
|
||||
initialize(installBrowsers);
|
||||
}
|
||||
protected abstract void initialize(Boolean installBrowsers) throws Exception;
|
||||
|
||||
public Path driverPath() {
|
||||
String cliFileName = System.getProperty("os.name").toLowerCase().contains("windows") ?
|
||||
@@ -71,13 +71,16 @@ public abstract class Driver {
|
||||
return driverDir().resolve(cliFileName);
|
||||
}
|
||||
|
||||
public static void setRequiredEnvironmentVariables(ProcessBuilder pb) {
|
||||
public ProcessBuilder createProcessBuilder() {
|
||||
ProcessBuilder pb = new ProcessBuilder(driverPath().toString());
|
||||
pb.environment().putAll(env);
|
||||
pb.environment().put("PW_LANG_NAME", "java");
|
||||
pb.environment().put("PW_LANG_NAME_VERSION", getMajorJavaVersion());
|
||||
String version = Driver.class.getPackage().getImplementationVersion();
|
||||
if (version != null) {
|
||||
pb.environment().put("PW_CLI_DISPLAY_VERSION", version);
|
||||
}
|
||||
return pb;
|
||||
}
|
||||
|
||||
private static String getMajorJavaVersion() {
|
||||
@@ -91,8 +94,19 @@ public abstract class Driver {
|
||||
}
|
||||
return version;
|
||||
}
|
||||
public static Driver createAndInstall(Map<String, String> env, Boolean installBrowsers) {
|
||||
try {
|
||||
Driver instance = newInstance();
|
||||
logMessage("initializing driver");
|
||||
instance.initialize(env, installBrowsers);
|
||||
logMessage("driver initialized.");
|
||||
return instance;
|
||||
} catch (Exception exception) {
|
||||
throw new RuntimeException("Failed to create driver", exception);
|
||||
}
|
||||
}
|
||||
|
||||
private static Driver createDriver() throws Exception {
|
||||
private static Driver newInstance() throws Exception {
|
||||
String pathFromProperty = System.getProperty("playwright.cli.dir");
|
||||
if (pathFromProperty != null) {
|
||||
return new PreinstalledDriver(Paths.get(pathFromProperty));
|
||||
|
||||
+1
-1
@@ -6,7 +6,7 @@
|
||||
|
||||
<groupId>org.example</groupId>
|
||||
<artifactId>examples</artifactId>
|
||||
<version>1.25.0-SNAPSHOT</version>
|
||||
<version>1.26.1</version>
|
||||
<name>Playwright Client Examples</name>
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
|
||||
+1
-1
@@ -7,7 +7,7 @@
|
||||
<parent>
|
||||
<groupId>com.microsoft.playwright</groupId>
|
||||
<artifactId>parent-pom</artifactId>
|
||||
<version>1.25.0-SNAPSHOT</version>
|
||||
<version>1.26.1</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>playwright</artifactId>
|
||||
|
||||
@@ -95,9 +95,6 @@ public interface Browser extends AutoCloseable {
|
||||
/**
|
||||
* Emulates {@code "forced-colors"} media feature, supported values are {@code "active"}, {@code "none"}. See {@link Page#emulateMedia
|
||||
* Page.emulateMedia()} for more details. Defaults to {@code "none"}.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> It's not supported in WebKit, see <a href="https://bugs.webkit.org/show_bug.cgi?id=225281">here</a> in their issue
|
||||
* tracker.
|
||||
*/
|
||||
public ForcedColors forcedColors;
|
||||
public Geolocation geolocation;
|
||||
@@ -284,9 +281,6 @@ public interface Browser extends AutoCloseable {
|
||||
/**
|
||||
* Emulates {@code "forced-colors"} media feature, supported values are {@code "active"}, {@code "none"}. See {@link Page#emulateMedia
|
||||
* Page.emulateMedia()} for more details. Defaults to {@code "none"}.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> It's not supported in WebKit, see <a href="https://bugs.webkit.org/show_bug.cgi?id=225281">here</a> in their issue
|
||||
* tracker.
|
||||
*/
|
||||
public NewContextOptions setForcedColors(ForcedColors forcedColors) {
|
||||
this.forcedColors = forcedColors;
|
||||
@@ -581,9 +575,6 @@ public interface Browser extends AutoCloseable {
|
||||
/**
|
||||
* Emulates {@code "forced-colors"} media feature, supported values are {@code "active"}, {@code "none"}. See {@link Page#emulateMedia
|
||||
* Page.emulateMedia()} for more details. Defaults to {@code "none"}.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> It's not supported in WebKit, see <a href="https://bugs.webkit.org/show_bug.cgi?id=225281">here</a> in their issue
|
||||
* tracker.
|
||||
*/
|
||||
public ForcedColors forcedColors;
|
||||
public Geolocation geolocation;
|
||||
@@ -770,9 +761,6 @@ public interface Browser extends AutoCloseable {
|
||||
/**
|
||||
* Emulates {@code "forced-colors"} media feature, supported values are {@code "active"}, {@code "none"}. See {@link Page#emulateMedia
|
||||
* Page.emulateMedia()} for more details. Defaults to {@code "none"}.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> It's not supported in WebKit, see <a href="https://bugs.webkit.org/show_bug.cgi?id=225281">here</a> in their issue
|
||||
* tracker.
|
||||
*/
|
||||
public NewPageOptions setForcedColors(ForcedColors forcedColors) {
|
||||
this.forcedColors = forcedColors;
|
||||
|
||||
@@ -442,9 +442,6 @@ public interface BrowserType {
|
||||
/**
|
||||
* Emulates {@code "forced-colors"} media feature, supported values are {@code "active"}, {@code "none"}. See {@link Page#emulateMedia
|
||||
* Page.emulateMedia()} for more details. Defaults to {@code "none"}.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> It's not supported in WebKit, see <a href="https://bugs.webkit.org/show_bug.cgi?id=225281">here</a> in their issue
|
||||
* tracker.
|
||||
*/
|
||||
public ForcedColors forcedColors;
|
||||
public Geolocation geolocation;
|
||||
@@ -725,9 +722,6 @@ public interface BrowserType {
|
||||
/**
|
||||
* Emulates {@code "forced-colors"} media feature, supported values are {@code "active"}, {@code "none"}. See {@link Page#emulateMedia
|
||||
* Page.emulateMedia()} for more details. Defaults to {@code "none"}.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> It's not supported in WebKit, see <a href="https://bugs.webkit.org/show_bug.cgi?id=225281">here</a> in their issue
|
||||
* tracker.
|
||||
*/
|
||||
public LaunchPersistentContextOptions setForcedColors(ForcedColors forcedColors) {
|
||||
this.forcedColors = forcedColors;
|
||||
@@ -1051,6 +1045,11 @@ public interface BrowserType {
|
||||
* <p> The default browser context is accessible via {@link Browser#contexts Browser.contexts()}.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> Connecting over the Chrome DevTools Protocol is only supported for Chromium-based browsers.
|
||||
* <pre>{@code
|
||||
* Browser browser = playwright.chromium().connectOverCDP("http://localhost:9222");
|
||||
* BrowserContext defaultContext = browser.contexts().get(0);
|
||||
* Page page = defaultContext.pages().get(0);
|
||||
* }</pre>
|
||||
*
|
||||
* @param endpointURL A CDP websocket endpoint or http url to connect to. For example {@code http://localhost:9222/} or
|
||||
* {@code ws://127.0.0.1:9222/devtools/browser/387adf4c-243f-4051-a181-46798f4a46f4}.
|
||||
@@ -1064,6 +1063,11 @@ public interface BrowserType {
|
||||
* <p> The default browser context is accessible via {@link Browser#contexts Browser.contexts()}.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> Connecting over the Chrome DevTools Protocol is only supported for Chromium-based browsers.
|
||||
* <pre>{@code
|
||||
* Browser browser = playwright.chromium().connectOverCDP("http://localhost:9222");
|
||||
* BrowserContext defaultContext = browser.contexts().get(0);
|
||||
* Page page = defaultContext.pages().get(0);
|
||||
* }</pre>
|
||||
*
|
||||
* @param endpointURL A CDP websocket endpoint or http url to connect to. For example {@code http://localhost:9222/} or
|
||||
* {@code ws://127.0.0.1:9222/devtools/browser/387adf4c-243f-4051-a181-46798f4a46f4}.
|
||||
|
||||
@@ -29,10 +29,9 @@ import static java.util.Arrays.asList;
|
||||
*/
|
||||
public class CLI {
|
||||
public static void main(String[] args) throws IOException, InterruptedException {
|
||||
Path driver = Driver.ensureDriverInstalled(Collections.emptyMap(), false);
|
||||
ProcessBuilder pb = new ProcessBuilder(driver.toString());
|
||||
Driver driver = Driver.ensureDriverInstalled(Collections.emptyMap(), false);
|
||||
ProcessBuilder pb = driver.createProcessBuilder();
|
||||
pb.command().addAll(asList(args));
|
||||
Driver.setRequiredEnvironmentVariables(pb);
|
||||
String version = Playwright.class.getPackage().getImplementationVersion();
|
||||
if (version != null) {
|
||||
pb.environment().put("PW_CLI_DISPLAY_VERSION", version);
|
||||
|
||||
@@ -1166,7 +1166,7 @@ public interface ElementHandle extends JSHandle {
|
||||
*/
|
||||
public WaitForSelectorState state;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1193,7 +1193,7 @@ public interface ElementHandle extends JSHandle {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public WaitForSelectorOptions setStrict(boolean strict) {
|
||||
|
||||
@@ -167,7 +167,7 @@ public interface Frame {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -217,7 +217,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public CheckOptions setStrict(boolean strict) {
|
||||
@@ -278,7 +278,7 @@ public interface Frame {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -357,7 +357,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public ClickOptions setStrict(boolean strict) {
|
||||
@@ -414,7 +414,7 @@ public interface Frame {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -486,7 +486,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public DblclickOptions setStrict(boolean strict) {
|
||||
@@ -514,7 +514,7 @@ public interface Frame {
|
||||
}
|
||||
class DispatchEventOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -526,7 +526,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public DispatchEventOptions setStrict(boolean strict) {
|
||||
@@ -561,7 +561,7 @@ public interface Frame {
|
||||
*/
|
||||
public Position sourcePosition;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -616,7 +616,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public DragAndDropOptions setStrict(boolean strict) {
|
||||
@@ -659,13 +659,13 @@ public interface Frame {
|
||||
}
|
||||
class EvalOnSelectorOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public EvalOnSelectorOptions setStrict(boolean strict) {
|
||||
@@ -686,7 +686,7 @@ public interface Frame {
|
||||
*/
|
||||
public Boolean noWaitAfter;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -715,7 +715,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public FillOptions setStrict(boolean strict) {
|
||||
@@ -734,7 +734,7 @@ public interface Frame {
|
||||
}
|
||||
class FocusOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -746,7 +746,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public FocusOptions setStrict(boolean strict) {
|
||||
@@ -765,7 +765,7 @@ public interface Frame {
|
||||
}
|
||||
class GetAttributeOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -777,7 +777,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public GetAttributeOptions setStrict(boolean strict) {
|
||||
@@ -867,7 +867,7 @@ public interface Frame {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -916,7 +916,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public HoverOptions setStrict(boolean strict) {
|
||||
@@ -944,7 +944,7 @@ public interface Frame {
|
||||
}
|
||||
class InnerHTMLOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -956,7 +956,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public InnerHTMLOptions setStrict(boolean strict) {
|
||||
@@ -975,7 +975,7 @@ public interface Frame {
|
||||
}
|
||||
class InnerTextOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -987,7 +987,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public InnerTextOptions setStrict(boolean strict) {
|
||||
@@ -1006,7 +1006,7 @@ public interface Frame {
|
||||
}
|
||||
class InputValueOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1018,7 +1018,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public InputValueOptions setStrict(boolean strict) {
|
||||
@@ -1037,7 +1037,7 @@ public interface Frame {
|
||||
}
|
||||
class IsCheckedOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1049,7 +1049,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public IsCheckedOptions setStrict(boolean strict) {
|
||||
@@ -1068,7 +1068,7 @@ public interface Frame {
|
||||
}
|
||||
class IsDisabledOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1080,7 +1080,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public IsDisabledOptions setStrict(boolean strict) {
|
||||
@@ -1099,7 +1099,7 @@ public interface Frame {
|
||||
}
|
||||
class IsEditableOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1111,7 +1111,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public IsEditableOptions setStrict(boolean strict) {
|
||||
@@ -1130,7 +1130,7 @@ public interface Frame {
|
||||
}
|
||||
class IsEnabledOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1142,7 +1142,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public IsEnabledOptions setStrict(boolean strict) {
|
||||
@@ -1161,7 +1161,7 @@ public interface Frame {
|
||||
}
|
||||
class IsHiddenOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1172,7 +1172,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public IsHiddenOptions setStrict(boolean strict) {
|
||||
@@ -1190,7 +1190,7 @@ public interface Frame {
|
||||
}
|
||||
class IsVisibleOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1201,7 +1201,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public IsVisibleOptions setStrict(boolean strict) {
|
||||
@@ -1273,7 +1273,7 @@ public interface Frame {
|
||||
*/
|
||||
public Boolean noWaitAfter;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1301,7 +1301,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public PressOptions setStrict(boolean strict) {
|
||||
@@ -1320,13 +1320,13 @@ public interface Frame {
|
||||
}
|
||||
class QuerySelectorOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public QuerySelectorOptions setStrict(boolean strict) {
|
||||
@@ -1347,7 +1347,7 @@ public interface Frame {
|
||||
*/
|
||||
public Boolean noWaitAfter;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1376,7 +1376,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public SelectOptionOptions setStrict(boolean strict) {
|
||||
@@ -1411,7 +1411,7 @@ public interface Frame {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1461,7 +1461,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public SetCheckedOptions setStrict(boolean strict) {
|
||||
@@ -1538,7 +1538,7 @@ public interface Frame {
|
||||
*/
|
||||
public Boolean noWaitAfter;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1559,7 +1559,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public SetInputFilesOptions setStrict(boolean strict) {
|
||||
@@ -1599,7 +1599,7 @@ public interface Frame {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1657,7 +1657,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public TapOptions setStrict(boolean strict) {
|
||||
@@ -1685,7 +1685,7 @@ public interface Frame {
|
||||
}
|
||||
class TextContentOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1697,7 +1697,7 @@ public interface Frame {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public TextContentOptions setStrict(boolean strict) {
|
||||
@@ -1726,7 +1726,7 @@ public interface Frame {
|
||||
*/
|
||||
public Boolean noWaitAfter;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1754,7 +1754,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public TypeOptions setStrict(boolean strict) {
|
||||
@@ -1789,7 +1789,7 @@ public interface Frame {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1839,7 +1839,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public UncheckOptions setStrict(boolean strict) {
|
||||
@@ -2004,7 +2004,7 @@ public interface Frame {
|
||||
*/
|
||||
public WaitForSelectorState state;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -2031,7 +2031,7 @@ public interface Frame {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public WaitForSelectorOptions setStrict(boolean strict) {
|
||||
|
||||
@@ -30,7 +30,7 @@ import java.util.regex.Pattern;
|
||||
* <p> **Strictness**
|
||||
*
|
||||
* <p> Frame locators are strict. This means that all operations on frame locators will throw if more than one element matches
|
||||
* given selector.
|
||||
* a given selector.
|
||||
* <pre>{@code
|
||||
* // Throws if there are several frames in DOM:
|
||||
* page.frame_locator(".result-frame").locator("button").click();
|
||||
|
||||
@@ -428,7 +428,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -478,7 +478,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public CheckOptions setStrict(boolean strict) {
|
||||
@@ -539,7 +539,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -618,7 +618,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public ClickOptions setStrict(boolean strict) {
|
||||
@@ -691,7 +691,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -763,7 +763,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public DblclickOptions setStrict(boolean strict) {
|
||||
@@ -791,7 +791,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class DispatchEventOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -803,7 +803,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public DispatchEventOptions setStrict(boolean strict) {
|
||||
@@ -838,7 +838,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Position sourcePosition;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -893,7 +893,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public DragAndDropOptions setStrict(boolean strict) {
|
||||
@@ -943,9 +943,6 @@ public interface Page extends AutoCloseable {
|
||||
/**
|
||||
* Emulates {@code "forced-colors"} media feature, supported values are {@code "active"} and {@code "none"}. Passing {@code null} disables forced
|
||||
* colors emulation.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> It's not supported in WebKit, see <a href="https://bugs.webkit.org/show_bug.cgi?id=225281">here</a> in their issue
|
||||
* tracker.
|
||||
*/
|
||||
public Optional<ForcedColors> forcedColors;
|
||||
/**
|
||||
@@ -970,9 +967,6 @@ public interface Page extends AutoCloseable {
|
||||
/**
|
||||
* Emulates {@code "forced-colors"} media feature, supported values are {@code "active"} and {@code "none"}. Passing {@code null} disables forced
|
||||
* colors emulation.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> It's not supported in WebKit, see <a href="https://bugs.webkit.org/show_bug.cgi?id=225281">here</a> in their issue
|
||||
* tracker.
|
||||
*/
|
||||
public EmulateMediaOptions setForcedColors(ForcedColors forcedColors) {
|
||||
this.forcedColors = Optional.ofNullable(forcedColors);
|
||||
@@ -997,13 +991,13 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class EvalOnSelectorOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public EvalOnSelectorOptions setStrict(boolean strict) {
|
||||
@@ -1040,7 +1034,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Boolean noWaitAfter;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1069,7 +1063,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public FillOptions setStrict(boolean strict) {
|
||||
@@ -1088,7 +1082,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class FocusOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1100,7 +1094,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public FocusOptions setStrict(boolean strict) {
|
||||
@@ -1119,7 +1113,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class GetAttributeOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1131,7 +1125,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public GetAttributeOptions setStrict(boolean strict) {
|
||||
@@ -1307,7 +1301,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1356,7 +1350,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public HoverOptions setStrict(boolean strict) {
|
||||
@@ -1384,7 +1378,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class InnerHTMLOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1396,7 +1390,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public InnerHTMLOptions setStrict(boolean strict) {
|
||||
@@ -1415,7 +1409,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class InnerTextOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1427,7 +1421,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public InnerTextOptions setStrict(boolean strict) {
|
||||
@@ -1446,7 +1440,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class InputValueOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1458,7 +1452,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public InputValueOptions setStrict(boolean strict) {
|
||||
@@ -1477,7 +1471,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class IsCheckedOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1489,7 +1483,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public IsCheckedOptions setStrict(boolean strict) {
|
||||
@@ -1508,7 +1502,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class IsDisabledOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1520,7 +1514,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public IsDisabledOptions setStrict(boolean strict) {
|
||||
@@ -1539,7 +1533,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class IsEditableOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1551,7 +1545,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public IsEditableOptions setStrict(boolean strict) {
|
||||
@@ -1570,7 +1564,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class IsEnabledOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1582,7 +1576,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public IsEnabledOptions setStrict(boolean strict) {
|
||||
@@ -1601,7 +1595,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class IsHiddenOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1612,7 +1606,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public IsHiddenOptions setStrict(boolean strict) {
|
||||
@@ -1630,7 +1624,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class IsVisibleOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1641,7 +1635,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public IsVisibleOptions setStrict(boolean strict) {
|
||||
@@ -1879,7 +1873,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Boolean noWaitAfter;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -1907,7 +1901,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public PressOptions setStrict(boolean strict) {
|
||||
@@ -1926,13 +1920,13 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class QuerySelectorOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public QuerySelectorOptions setStrict(boolean strict) {
|
||||
@@ -2234,7 +2228,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Boolean noWaitAfter;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -2263,7 +2257,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public SelectOptionOptions setStrict(boolean strict) {
|
||||
@@ -2298,7 +2292,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -2348,7 +2342,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public SetCheckedOptions setStrict(boolean strict) {
|
||||
@@ -2425,7 +2419,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Boolean noWaitAfter;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -2446,7 +2440,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public SetInputFilesOptions setStrict(boolean strict) {
|
||||
@@ -2486,7 +2480,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -2544,7 +2538,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public TapOptions setStrict(boolean strict) {
|
||||
@@ -2572,7 +2566,7 @@ public interface Page extends AutoCloseable {
|
||||
}
|
||||
class TextContentOptions {
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -2584,7 +2578,7 @@ public interface Page extends AutoCloseable {
|
||||
public Double timeout;
|
||||
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public TextContentOptions setStrict(boolean strict) {
|
||||
@@ -2613,7 +2607,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Boolean noWaitAfter;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -2641,7 +2635,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public TypeOptions setStrict(boolean strict) {
|
||||
@@ -2676,7 +2670,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public Position position;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -2726,7 +2720,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public UncheckOptions setStrict(boolean strict) {
|
||||
@@ -3076,7 +3070,7 @@ public interface Page extends AutoCloseable {
|
||||
*/
|
||||
public WaitForSelectorState state;
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public Boolean strict;
|
||||
@@ -3103,7 +3097,7 @@ public interface Page extends AutoCloseable {
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more then one
|
||||
* When true, the call requires selector to resolve to a single element. If given selector resolves to more than one
|
||||
* element, the call throws an exception.
|
||||
*/
|
||||
public WaitForSelectorOptions setStrict(boolean strict) {
|
||||
@@ -6645,7 +6639,7 @@ public interface Page extends AutoCloseable {
|
||||
* {@code detached}.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> Playwright automatically waits for element to be ready before performing an action. Using {@code Locator} objects and
|
||||
* web-first assertions make the code wait-for-selector-free.
|
||||
* web-first assertions makes the code wait-for-selector-free.
|
||||
*
|
||||
* <p> Wait for the {@code selector} to satisfy {@code state} option (either appear/disappear from dom, or become visible/hidden). If at
|
||||
* the moment of calling the method {@code selector} already satisfies the condition, the method will return immediately. If the
|
||||
@@ -6683,7 +6677,7 @@ public interface Page extends AutoCloseable {
|
||||
* {@code detached}.
|
||||
*
|
||||
* <p> <strong>NOTE:</strong> Playwright automatically waits for element to be ready before performing an action. Using {@code Locator} objects and
|
||||
* web-first assertions make the code wait-for-selector-free.
|
||||
* web-first assertions makes the code wait-for-selector-free.
|
||||
*
|
||||
* <p> Wait for the {@code selector} to satisfy {@code state} option (either appear/disappear from dom, or become visible/hidden). If at
|
||||
* the moment of calling the method {@code selector} already satisfies the condition, the method will return immediately. If the
|
||||
|
||||
@@ -44,7 +44,7 @@ public interface Selectors {
|
||||
/**
|
||||
* An example of registering selector engine that queries elements based on a tag name:
|
||||
* <pre>{@code
|
||||
* // Script that evaluates to a selector engine instance.
|
||||
* // Script that evaluates to a selector engine instance. The script is evaluated in the page context.
|
||||
* String createTagNameEngine = "{\n" +
|
||||
* " // Returns the first element matching given selector in the root's subtree.\n" +
|
||||
* " query(root, selector) {\n" +
|
||||
@@ -71,7 +71,7 @@ public interface Selectors {
|
||||
*
|
||||
* @param name Name that is used in selectors as a prefix, e.g. {@code {name: 'foo'}} enables {@code foo=myselectorbody} selectors. May only
|
||||
* contain {@code [a-zA-Z0-9_]} characters.
|
||||
* @param script Script that evaluates to a selector engine instance.
|
||||
* @param script Script that evaluates to a selector engine instance. The script is evaluated in the page context.
|
||||
*/
|
||||
default void register(String name, String script) {
|
||||
register(name, script, null);
|
||||
@@ -79,7 +79,7 @@ public interface Selectors {
|
||||
/**
|
||||
* An example of registering selector engine that queries elements based on a tag name:
|
||||
* <pre>{@code
|
||||
* // Script that evaluates to a selector engine instance.
|
||||
* // Script that evaluates to a selector engine instance. The script is evaluated in the page context.
|
||||
* String createTagNameEngine = "{\n" +
|
||||
* " // Returns the first element matching given selector in the root's subtree.\n" +
|
||||
* " query(root, selector) {\n" +
|
||||
@@ -106,13 +106,13 @@ public interface Selectors {
|
||||
*
|
||||
* @param name Name that is used in selectors as a prefix, e.g. {@code {name: 'foo'}} enables {@code foo=myselectorbody} selectors. May only
|
||||
* contain {@code [a-zA-Z0-9_]} characters.
|
||||
* @param script Script that evaluates to a selector engine instance.
|
||||
* @param script Script that evaluates to a selector engine instance. The script is evaluated in the page context.
|
||||
*/
|
||||
void register(String name, String script, RegisterOptions options);
|
||||
/**
|
||||
* An example of registering selector engine that queries elements based on a tag name:
|
||||
* <pre>{@code
|
||||
* // Script that evaluates to a selector engine instance.
|
||||
* // Script that evaluates to a selector engine instance. The script is evaluated in the page context.
|
||||
* String createTagNameEngine = "{\n" +
|
||||
* " // Returns the first element matching given selector in the root's subtree.\n" +
|
||||
* " query(root, selector) {\n" +
|
||||
@@ -139,7 +139,7 @@ public interface Selectors {
|
||||
*
|
||||
* @param name Name that is used in selectors as a prefix, e.g. {@code {name: 'foo'}} enables {@code foo=myselectorbody} selectors. May only
|
||||
* contain {@code [a-zA-Z0-9_]} characters.
|
||||
* @param script Script that evaluates to a selector engine instance.
|
||||
* @param script Script that evaluates to a selector engine instance. The script is evaluated in the page context.
|
||||
*/
|
||||
default void register(String name, Path script) {
|
||||
register(name, script, null);
|
||||
@@ -147,7 +147,7 @@ public interface Selectors {
|
||||
/**
|
||||
* An example of registering selector engine that queries elements based on a tag name:
|
||||
* <pre>{@code
|
||||
* // Script that evaluates to a selector engine instance.
|
||||
* // Script that evaluates to a selector engine instance. The script is evaluated in the page context.
|
||||
* String createTagNameEngine = "{\n" +
|
||||
* " // Returns the first element matching given selector in the root's subtree.\n" +
|
||||
* " query(root, selector) {\n" +
|
||||
@@ -174,7 +174,7 @@ public interface Selectors {
|
||||
*
|
||||
* @param name Name that is used in selectors as a prefix, e.g. {@code {name: 'foo'}} enables {@code foo=myselectorbody} selectors. May only
|
||||
* contain {@code [a-zA-Z0-9_]} characters.
|
||||
* @param script Script that evaluates to a selector engine instance.
|
||||
* @param script Script that evaluates to a selector engine instance. The script is evaluated in the page context.
|
||||
*/
|
||||
void register(String name, Path script, RegisterOptions options);
|
||||
}
|
||||
|
||||
+1
-1
@@ -46,7 +46,7 @@ public interface APIResponseAssertions {
|
||||
*/
|
||||
APIResponseAssertions not();
|
||||
/**
|
||||
* Ensures the response status code is within [200..299] range.
|
||||
* Ensures the response status code is within {@code 200..299} range.
|
||||
* <pre>{@code
|
||||
* assertThat(response).isOK();
|
||||
* }</pre>
|
||||
|
||||
+25
-10
@@ -72,11 +72,16 @@ public interface LocatorAssertions {
|
||||
}
|
||||
}
|
||||
class IsEditableOptions {
|
||||
public Boolean editable;
|
||||
/**
|
||||
* Time to retry the assertion for.
|
||||
*/
|
||||
public Double timeout;
|
||||
|
||||
public IsEditableOptions setEditable(boolean editable) {
|
||||
this.editable = editable;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Time to retry the assertion for.
|
||||
*/
|
||||
@@ -100,11 +105,16 @@ public interface LocatorAssertions {
|
||||
}
|
||||
}
|
||||
class IsEnabledOptions {
|
||||
public Boolean enabled;
|
||||
/**
|
||||
* Time to retry the assertion for.
|
||||
*/
|
||||
public Double timeout;
|
||||
|
||||
public IsEnabledOptions setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
return this;
|
||||
}
|
||||
/**
|
||||
* Time to retry the assertion for.
|
||||
*/
|
||||
@@ -146,6 +156,7 @@ public interface LocatorAssertions {
|
||||
* Time to retry the assertion for.
|
||||
*/
|
||||
public Double timeout;
|
||||
public Boolean visible;
|
||||
|
||||
/**
|
||||
* Time to retry the assertion for.
|
||||
@@ -154,6 +165,10 @@ public interface LocatorAssertions {
|
||||
this.timeout = timeout;
|
||||
return this;
|
||||
}
|
||||
public IsVisibleOptions setVisible(boolean visible) {
|
||||
this.visible = visible;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
class ContainsTextOptions {
|
||||
/**
|
||||
@@ -456,8 +471,8 @@ public interface LocatorAssertions {
|
||||
*/
|
||||
void isFocused(IsFocusedOptions options);
|
||||
/**
|
||||
* Ensures the {@code Locator} points to a hidden DOM node, which is the opposite of <a
|
||||
* href="https://playwright.dev/java/docs/api/actionability#visible">visible</a>.
|
||||
* Ensures that {@code Locator} either does not resolve to any DOM node, or resolves to a <a
|
||||
* href="https://playwright.dev/java/docs/api/actionability#visible">non-visible</a> one.
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".my-element")).isHidden();
|
||||
* }</pre>
|
||||
@@ -466,16 +481,16 @@ public interface LocatorAssertions {
|
||||
isHidden(null);
|
||||
}
|
||||
/**
|
||||
* Ensures the {@code Locator} points to a hidden DOM node, which is the opposite of <a
|
||||
* href="https://playwright.dev/java/docs/api/actionability#visible">visible</a>.
|
||||
* Ensures that {@code Locator} either does not resolve to any DOM node, or resolves to a <a
|
||||
* href="https://playwright.dev/java/docs/api/actionability#visible">non-visible</a> one.
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".my-element")).isHidden();
|
||||
* }</pre>
|
||||
*/
|
||||
void isHidden(IsHiddenOptions options);
|
||||
/**
|
||||
* Ensures the {@code Locator} points to a <a href="https://playwright.dev/java/docs/api/actionability#visible">visible</a> DOM
|
||||
* node.
|
||||
* Ensures that {@code Locator} points to an <a href="https://playwright.dev/java/docs/api/actionability#visible">attached</a>
|
||||
* and <a href="https://playwright.dev/java/docs/api/actionability#visible">visible</a> DOM node.
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".my-element")).isVisible();
|
||||
* }</pre>
|
||||
@@ -484,8 +499,8 @@ public interface LocatorAssertions {
|
||||
isVisible(null);
|
||||
}
|
||||
/**
|
||||
* Ensures the {@code Locator} points to a <a href="https://playwright.dev/java/docs/api/actionability#visible">visible</a> DOM
|
||||
* node.
|
||||
* Ensures that {@code Locator} points to an <a href="https://playwright.dev/java/docs/api/actionability#visible">attached</a>
|
||||
* and <a href="https://playwright.dev/java/docs/api/actionability#visible">visible</a> DOM node.
|
||||
* <pre>{@code
|
||||
* assertThat(page.locator(".my-element")).isVisible();
|
||||
* }</pre>
|
||||
@@ -789,7 +804,7 @@ public interface LocatorAssertions {
|
||||
* @param value Expected attribute value.
|
||||
*/
|
||||
default void hasAttribute(String name, String value) {
|
||||
hasAttribute(name, value, null);
|
||||
hasAttribute(name, value, (HasAttributeOptions) null);
|
||||
}
|
||||
/**
|
||||
* Ensures the {@code Locator} points to an element with given attribute.
|
||||
@@ -811,7 +826,7 @@ public interface LocatorAssertions {
|
||||
* @param value Expected attribute value.
|
||||
*/
|
||||
default void hasAttribute(String name, Pattern value) {
|
||||
hasAttribute(name, value, null);
|
||||
hasAttribute(name, value, (HasAttributeOptions) null);
|
||||
}
|
||||
/**
|
||||
* Ensures the {@code Locator} points to an element with given attribute.
|
||||
|
||||
@@ -110,6 +110,12 @@ class APIRequestContextImpl extends ChannelOwner implements APIRequestContext {
|
||||
if (options.ignoreHTTPSErrors != null) {
|
||||
params.addProperty("ignoreHTTPSErrors", options.ignoreHTTPSErrors);
|
||||
}
|
||||
if (options.maxRedirects != null) {
|
||||
if (options.maxRedirects < 0) {
|
||||
throw new PlaywrightException("'maxRedirects' should be greater than or equal to '0'");
|
||||
}
|
||||
params.addProperty("maxRedirects", options.maxRedirects);
|
||||
}
|
||||
JsonObject json = sendMessage("fetch", params).getAsJsonObject();
|
||||
return new APIResponseImpl(this, json.getAsJsonObject("response"));
|
||||
}
|
||||
|
||||
@@ -170,7 +170,7 @@ class BrowserContextImpl extends ChannelOwner implements BrowserContext {
|
||||
|
||||
@Override
|
||||
public Page waitForPage(WaitForPageOptions options, Runnable code) {
|
||||
return withWaitLogging("BrowserContext.close", () -> waitForPageImpl(options, code));
|
||||
return withWaitLogging("BrowserContext.close", logger -> waitForPageImpl(options, code));
|
||||
}
|
||||
|
||||
private Page waitForPageImpl(WaitForPageOptions options, Runnable code) {
|
||||
|
||||
@@ -22,6 +22,8 @@ import com.google.gson.JsonObject;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.BinaryOperator;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
class ChannelOwner extends LoggingSupport {
|
||||
@@ -74,7 +76,7 @@ class ChannelOwner extends LoggingSupport {
|
||||
child.parent = this;
|
||||
}
|
||||
|
||||
<T> T withWaitLogging(String apiName, Supplier<T> code) {
|
||||
<T> T withWaitLogging(String apiName, Function<Logger, T> code) {
|
||||
return new WaitForEventLogger<>(this, apiName, code).get();
|
||||
}
|
||||
|
||||
|
||||
@@ -811,17 +811,17 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public void waitForLoadState(LoadState state, WaitForLoadStateOptions options) {
|
||||
withWaitLogging("Frame.waitForLoadState", () -> {
|
||||
waitForLoadStateImpl(state, options);
|
||||
withWaitLogging("Frame.waitForLoadState", logger -> {
|
||||
waitForLoadStateImpl(state, options, logger);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
void waitForLoadStateImpl(LoadState state, WaitForLoadStateOptions options) {
|
||||
waitForLoadStateImpl(convertType(state, WaitUntilState.class), options);
|
||||
void waitForLoadStateImpl(LoadState state, WaitForLoadStateOptions options, Logger logger) {
|
||||
waitForLoadStateImpl(convertType(state, WaitUntilState.class), options, logger);
|
||||
}
|
||||
|
||||
private void waitForLoadStateImpl(WaitUntilState state, WaitForLoadStateOptions options) {
|
||||
private void waitForLoadStateImpl(WaitUntilState state, WaitForLoadStateOptions options, Logger logger) {
|
||||
if (options == null) {
|
||||
options = new WaitForLoadStateOptions();
|
||||
}
|
||||
@@ -830,7 +830,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
|
||||
List<Waitable<Void>> waitables = new ArrayList<>();
|
||||
waitables.add(new WaitForLoadStateHelper(state));
|
||||
waitables.add(new WaitForLoadStateHelper(state, logger));
|
||||
waitables.add(page.createWaitForCloseHelper());
|
||||
waitables.add(page.createWaitableTimeout(options.timeout));
|
||||
runUntil(() -> {}, new WaitableRace<>(waitables));
|
||||
@@ -838,10 +838,12 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
private class WaitForLoadStateHelper implements Waitable<Void>, Consumer<WaitUntilState> {
|
||||
private final WaitUntilState expectedState;
|
||||
private final Logger logger;
|
||||
private boolean isDone;
|
||||
|
||||
WaitForLoadStateHelper(WaitUntilState state) {
|
||||
WaitForLoadStateHelper(WaitUntilState state, Logger logger) {
|
||||
expectedState = state;
|
||||
this.logger = logger;
|
||||
isDone = loadStates.contains(state);
|
||||
if (!isDone) {
|
||||
internalListeners.add(InternalEventType.LOADSTATE, this);
|
||||
@@ -850,6 +852,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public void accept(WaitUntilState state) {
|
||||
logger.log(" load state changed to " + state);
|
||||
if (expectedState.equals(state)) {
|
||||
isDone = true;
|
||||
dispose();
|
||||
@@ -873,20 +876,24 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
private class WaitForNavigationHelper implements Waitable<Response>, Consumer<JsonObject> {
|
||||
private final UrlMatcher matcher;
|
||||
private final WaitUntilState expectedLoadState;
|
||||
private final Logger logger;
|
||||
private WaitForLoadStateHelper loadStateHelper;
|
||||
|
||||
private RequestImpl request;
|
||||
private RuntimeException exception;
|
||||
|
||||
WaitForNavigationHelper(UrlMatcher matcher, WaitUntilState expectedLoadState) {
|
||||
WaitForNavigationHelper(UrlMatcher matcher, WaitUntilState expectedLoadState, Logger logger) {
|
||||
this.matcher = matcher;
|
||||
this.expectedLoadState = expectedLoadState;
|
||||
this.logger = logger;
|
||||
internalListeners.add(InternalEventType.NAVIGATED, this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(JsonObject params) {
|
||||
if (!matcher.test(params.get("url").getAsString())) {
|
||||
String url = params.get("url").getAsString();
|
||||
logger.log(" navigated to " + url);
|
||||
if (!matcher.test(url)) {
|
||||
return;
|
||||
}
|
||||
if (params.has("error")) {
|
||||
@@ -898,7 +905,7 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
request = connection.getExistingObject(jsonReq.get("guid").getAsString());
|
||||
}
|
||||
}
|
||||
loadStateHelper = new WaitForLoadStateHelper(expectedLoadState);
|
||||
loadStateHelper = new WaitForLoadStateHelper(expectedLoadState, logger);
|
||||
}
|
||||
internalListeners.remove(InternalEventType.NAVIGATED, this);
|
||||
}
|
||||
@@ -937,14 +944,14 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
|
||||
@Override
|
||||
public Response waitForNavigation(WaitForNavigationOptions options, Runnable code) {
|
||||
return withLogging("Frame.waitForNavigation", () -> waitForNavigationImpl(code, options, null));
|
||||
return withWaitLogging("Frame.waitForNavigation", logger -> waitForNavigationImpl(logger, code, options, null));
|
||||
}
|
||||
|
||||
Response waitForNavigationImpl(Runnable code, WaitForNavigationOptions options) {
|
||||
return waitForNavigationImpl(code, options, null);
|
||||
Response waitForNavigationImpl(Logger logger, Runnable code, WaitForNavigationOptions options) {
|
||||
return waitForNavigationImpl(logger, code, options, null);
|
||||
}
|
||||
|
||||
private Response waitForNavigationImpl(Runnable code, WaitForNavigationOptions options, UrlMatcher matcher) {
|
||||
private Response waitForNavigationImpl(Logger logger, Runnable code, WaitForNavigationOptions options, UrlMatcher matcher) {
|
||||
if (options == null) {
|
||||
options = new WaitForNavigationOptions();
|
||||
}
|
||||
@@ -956,7 +963,8 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
if (matcher == null) {
|
||||
matcher = UrlMatcher.forOneOf(page.context().baseUrl, options.url);
|
||||
}
|
||||
waitables.add(new WaitForNavigationHelper(matcher, options.waitUntil));
|
||||
logger.log("waiting for navigation " + matcher);
|
||||
waitables.add(new WaitForNavigationHelper(matcher, options.waitUntil, logger));
|
||||
waitables.add(page.createWaitForCloseHelper());
|
||||
waitables.add(page.createWaitableFrameDetach(this));
|
||||
waitables.add(page.createWaitableNavigationTimeout(options.timeout));
|
||||
@@ -1014,18 +1022,22 @@ public class FrameImpl extends ChannelOwner implements Frame {
|
||||
}
|
||||
|
||||
private void waitForURL(UrlMatcher matcher, WaitForURLOptions options) {
|
||||
withLogging("Frame.waitForURL", () -> waitForURLImpl(matcher, options));
|
||||
withWaitLogging("Frame.waitForURL", logger -> {
|
||||
waitForURLImpl(logger, matcher, options);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
void waitForURLImpl(UrlMatcher matcher, WaitForURLOptions options) {
|
||||
void waitForURLImpl(Logger logger, UrlMatcher matcher, WaitForURLOptions options) {
|
||||
logger.log("waiting for url " + matcher);
|
||||
if (options == null) {
|
||||
options = new WaitForURLOptions();
|
||||
}
|
||||
if (matcher.test(url())) {
|
||||
waitForLoadStateImpl(options.waitUntil, convertType(options, WaitForLoadStateOptions.class));
|
||||
waitForLoadStateImpl(options.waitUntil, convertType(options, WaitForLoadStateOptions.class), logger);
|
||||
return;
|
||||
}
|
||||
waitForNavigationImpl(() -> {}, convertType(options, WaitForNavigationOptions.class), matcher);
|
||||
waitForNavigationImpl(logger, () -> {}, convertType(options, WaitForNavigationOptions.class), matcher);
|
||||
}
|
||||
|
||||
int queryCount(String selector) {
|
||||
|
||||
@@ -26,8 +26,7 @@ import java.nio.file.Path;
|
||||
import java.util.Base64;
|
||||
import java.util.Map;
|
||||
|
||||
import static com.microsoft.playwright.impl.LoggingSupport.isApiLoggingEnabled;
|
||||
import static com.microsoft.playwright.impl.LoggingSupport.logApi;
|
||||
import static com.microsoft.playwright.impl.LoggingSupport.*;
|
||||
import static com.microsoft.playwright.impl.Serialization.fromNameValues;
|
||||
import static com.microsoft.playwright.impl.Serialization.gson;
|
||||
|
||||
@@ -67,9 +66,7 @@ public class HARRouter {
|
||||
String action = response.get("action").getAsString();
|
||||
if ("redirect".equals(action)) {
|
||||
String redirectURL = response.get("redirectURL").getAsString();
|
||||
if (isApiLoggingEnabled()) {
|
||||
logApi("HAR: " + route.request().url() + " redirected to " + redirectURL);
|
||||
}
|
||||
logApiIfEnabled("HAR: " + route.request().url() + " redirected to " + redirectURL);
|
||||
((RouteImpl) route).redirectNavigationRequest(redirectURL);
|
||||
return;
|
||||
}
|
||||
@@ -86,9 +83,7 @@ public class HARRouter {
|
||||
}
|
||||
|
||||
if ("error".equals(action)) {
|
||||
if (isApiLoggingEnabled()) {
|
||||
logApi("HAR: " + response.get("message").getAsString());
|
||||
}
|
||||
logApiIfEnabled("HAR: " + response.get("message").getAsString());
|
||||
// Report the error, but fall through to the default handler.
|
||||
}
|
||||
|
||||
|
||||
@@ -299,7 +299,9 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
|
||||
@Override
|
||||
public void isEditable(IsEditableOptions options) {
|
||||
expectTrue("to.be.editable", "Locator expected to be editable", convertType(options, FrameExpectOptions.class));
|
||||
FrameExpectOptions frameOptions = convertType(options, FrameExpectOptions.class);
|
||||
boolean editable = options == null || options.editable == null || options.editable == true;
|
||||
expectTrue(editable ? "to.be.editable" : "to.be.readonly", "Locator expected to be editable", frameOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -309,7 +311,9 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
|
||||
@Override
|
||||
public void isEnabled(IsEnabledOptions options) {
|
||||
expectTrue("to.be.enabled", "Locator expected to be enabled", convertType(options, FrameExpectOptions.class));
|
||||
FrameExpectOptions frameOptions = convertType(options, FrameExpectOptions.class);
|
||||
boolean enabled = options == null || options.enabled == null || options.enabled == true;
|
||||
expectTrue(enabled ? "to.be.enabled" : "to.be.disabled", "Locator expected to be enabled", frameOptions);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -324,7 +328,9 @@ public class LocatorAssertionsImpl extends AssertionsBase implements LocatorAsse
|
||||
|
||||
@Override
|
||||
public void isVisible(IsVisibleOptions options) {
|
||||
expectTrue("to.be.visible", "Locator expected to be visible", convertType(options, FrameExpectOptions.class));
|
||||
FrameExpectOptions frameOptions = convertType(options, FrameExpectOptions.class);
|
||||
boolean visible = options == null || options.visible == null || options.visible == true;
|
||||
expectTrue(visible ? "to.be.visible" : "to.be.hidden", "Locator expected to be visible", frameOptions);
|
||||
}
|
||||
|
||||
private void expectTrue(String expression, String message, FrameExpectOptions options) {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
interface Logger {
|
||||
void log(String message);
|
||||
}
|
||||
@@ -60,8 +60,10 @@ class LoggingSupport {
|
||||
System.err.println(timestamp + " " + message);
|
||||
}
|
||||
|
||||
static boolean isApiLoggingEnabled() {
|
||||
return isEnabled;
|
||||
static void logApiIfEnabled(String message) {
|
||||
if (isEnabled) {
|
||||
logApi(message);
|
||||
}
|
||||
}
|
||||
|
||||
static void logApi(String message) {
|
||||
|
||||
@@ -443,7 +443,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Page waitForClose(WaitForCloseOptions options, Runnable code) {
|
||||
return withWaitLogging("Page.waitForClose", () -> waitForCloseImpl(options, code));
|
||||
return withWaitLogging("Page.waitForClose", logger -> waitForCloseImpl(options, code));
|
||||
}
|
||||
|
||||
private Page waitForCloseImpl(WaitForCloseOptions options, Runnable code) {
|
||||
@@ -455,7 +455,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public ConsoleMessage waitForConsoleMessage(WaitForConsoleMessageOptions options, Runnable code) {
|
||||
return withWaitLogging("Page.waitForConsoleMessage", () -> waitForConsoleMessageImpl(options, code));
|
||||
return withWaitLogging("Page.waitForConsoleMessage", logger -> waitForConsoleMessageImpl(options, code));
|
||||
}
|
||||
|
||||
private ConsoleMessage waitForConsoleMessageImpl(WaitForConsoleMessageOptions options, Runnable code) {
|
||||
@@ -467,7 +467,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Download waitForDownload(WaitForDownloadOptions options, Runnable code) {
|
||||
return withWaitLogging("Page.waitForDownload", () -> waitForDownloadImpl(options, code));
|
||||
return withWaitLogging("Page.waitForDownload", logger -> waitForDownloadImpl(options, code));
|
||||
}
|
||||
|
||||
private Download waitForDownloadImpl(WaitForDownloadOptions options, Runnable code) {
|
||||
@@ -479,7 +479,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public FileChooser waitForFileChooser(WaitForFileChooserOptions options, Runnable code) {
|
||||
return withWaitLogging("Page.waitForFileChooser", () -> waitForFileChooserImpl(options, code));
|
||||
return withWaitLogging("Page.waitForFileChooser", logger -> waitForFileChooserImpl(options, code));
|
||||
}
|
||||
|
||||
private FileChooser waitForFileChooserImpl(WaitForFileChooserOptions options, Runnable code) {
|
||||
@@ -492,7 +492,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Page waitForPopup(WaitForPopupOptions options, Runnable code) {
|
||||
return withWaitLogging("Page.waitForPopup", () -> waitForPopupImpl(options, code));
|
||||
return withWaitLogging("Page.waitForPopup", logger -> waitForPopupImpl(options, code));
|
||||
}
|
||||
|
||||
private Page waitForPopupImpl(WaitForPopupOptions options, Runnable code) {
|
||||
@@ -504,7 +504,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public WebSocket waitForWebSocket(WaitForWebSocketOptions options, Runnable code) {
|
||||
return withWaitLogging("Page.waitForWebSocket", () -> waitForWebSocketImpl(options, code));
|
||||
return withWaitLogging("Page.waitForWebSocket", logger -> waitForWebSocketImpl(options, code));
|
||||
}
|
||||
|
||||
private WebSocket waitForWebSocketImpl(WaitForWebSocketOptions options, Runnable code) {
|
||||
@@ -516,7 +516,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Worker waitForWorker(WaitForWorkerOptions options, Runnable code) {
|
||||
return withWaitLogging("Page.waitForWorker", () -> waitForWorkerImpl(options, code));
|
||||
return withWaitLogging("Page.waitForWorker", logger -> waitForWorkerImpl(options, code));
|
||||
}
|
||||
|
||||
private Worker waitForWorkerImpl(WaitForWorkerOptions options, Runnable code) {
|
||||
@@ -1268,25 +1268,25 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public void waitForLoadState(LoadState state, WaitForLoadStateOptions options) {
|
||||
withWaitLogging("Page.waitForLoadState", () -> {
|
||||
mainFrame.waitForLoadStateImpl(state, convertType(options, Frame.WaitForLoadStateOptions.class));
|
||||
withWaitLogging("Page.waitForLoadState", logger -> {
|
||||
mainFrame.waitForLoadStateImpl(state, convertType(options, Frame.WaitForLoadStateOptions.class), logger);
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response waitForNavigation(WaitForNavigationOptions options, Runnable code) {
|
||||
return withLogging("Page.waitForNavigation", () -> waitForNavigationImpl(code, options));
|
||||
return withWaitLogging("Page.waitForNavigation", logger -> waitForNavigationImpl(logger, code, options));
|
||||
}
|
||||
|
||||
Response waitForNavigationImpl(Runnable code, WaitForNavigationOptions options) {
|
||||
private Response waitForNavigationImpl(Logger logger, Runnable code, WaitForNavigationOptions options) {
|
||||
Frame.WaitForNavigationOptions frameOptions = new Frame.WaitForNavigationOptions();
|
||||
if (options != null) {
|
||||
frameOptions.timeout = options.timeout;
|
||||
frameOptions.waitUntil = options.waitUntil;
|
||||
frameOptions.url = options.url;
|
||||
}
|
||||
return mainFrame.waitForNavigationImpl(code, frameOptions);
|
||||
return mainFrame.waitForNavigationImpl(logger, code, frameOptions);
|
||||
}
|
||||
|
||||
void frameNavigated(FrameImpl frame) {
|
||||
@@ -1338,21 +1338,28 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Request waitForRequest(String urlGlob, WaitForRequestOptions options, Runnable code) {
|
||||
return waitForRequest(toRequestPredicate(new UrlMatcher(browserContext.baseUrl, urlGlob)), options, code);
|
||||
return waitForRequest(new UrlMatcher(browserContext.baseUrl, urlGlob), null, options, code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request waitForRequest(Pattern urlPattern, WaitForRequestOptions options, Runnable code) {
|
||||
return waitForRequest(toRequestPredicate(new UrlMatcher(urlPattern)), options, code);
|
||||
return waitForRequest(new UrlMatcher(urlPattern), null, options, code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Request waitForRequest(Predicate<Request> predicate, WaitForRequestOptions options, Runnable code) {
|
||||
return withWaitLogging("Page.waitForRequest", () -> waitForRequestImpl(predicate, options, code));
|
||||
return waitForRequest(null, predicate, options, code);
|
||||
}
|
||||
|
||||
private static Predicate<Request> toRequestPredicate(UrlMatcher matcher) {
|
||||
return request -> matcher.test(request.url());
|
||||
private Request waitForRequest(UrlMatcher urlMatcher, Predicate<Request> predicate, WaitForRequestOptions options, Runnable code) {
|
||||
return withWaitLogging("Page.waitForRequest", logger -> {
|
||||
logger.log("waiting for request " + ((urlMatcher == null) ? "matching predicate" : urlMatcher.toString()));
|
||||
Predicate<Request> requestPredicate = predicate;
|
||||
if (requestPredicate == null) {
|
||||
requestPredicate = request -> urlMatcher.test(request.url());;
|
||||
}
|
||||
return waitForRequestImpl(requestPredicate, options, code);
|
||||
});
|
||||
}
|
||||
|
||||
private Request waitForRequestImpl(Predicate<Request> predicate, WaitForRequestOptions options, Runnable code) {
|
||||
@@ -1364,7 +1371,7 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Request waitForRequestFinished(WaitForRequestFinishedOptions options, Runnable code) {
|
||||
return withWaitLogging("Page.waitForRequestFinished", () -> waitForRequestFinishedImpl(options, code));
|
||||
return withWaitLogging("Page.waitForRequestFinished", logger -> waitForRequestFinishedImpl(options, code));
|
||||
}
|
||||
|
||||
private Request waitForRequestFinishedImpl(WaitForRequestFinishedOptions options, Runnable code) {
|
||||
@@ -1376,21 +1383,28 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
|
||||
@Override
|
||||
public Response waitForResponse(String urlGlob, WaitForResponseOptions options, Runnable code) {
|
||||
return waitForResponse(toResponsePredicate(new UrlMatcher(browserContext.baseUrl, urlGlob)), options, code);
|
||||
return waitForResponse(new UrlMatcher(browserContext.baseUrl, urlGlob), null, options, code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response waitForResponse(Pattern urlPattern, WaitForResponseOptions options, Runnable code) {
|
||||
return waitForResponse(toResponsePredicate(new UrlMatcher(urlPattern)), options, code);
|
||||
return waitForResponse(new UrlMatcher(urlPattern), null, options, code);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Response waitForResponse(Predicate<Response> predicate, WaitForResponseOptions options, Runnable code) {
|
||||
return withLogging("Page.waitForResponse", () -> waitForResponseImpl(predicate, options, code));
|
||||
return waitForResponse(null, predicate, options, code);
|
||||
}
|
||||
|
||||
private static Predicate<Response> toResponsePredicate(UrlMatcher matcher) {
|
||||
return response -> matcher.test(response.url());
|
||||
private Response waitForResponse(UrlMatcher urlMatcher, Predicate<Response> predicate, WaitForResponseOptions options, Runnable code) {
|
||||
return withWaitLogging("Page.waitForResponse", logger -> {
|
||||
logger.log("waiting for response " + ((urlMatcher == null) ? "matching predicate" : urlMatcher.toString()));
|
||||
Predicate<Response> responsePredicate = predicate;
|
||||
if (responsePredicate == null) {
|
||||
responsePredicate = response -> urlMatcher.test(response.url());;
|
||||
}
|
||||
return waitForResponseImpl(responsePredicate, options, code);
|
||||
});
|
||||
}
|
||||
|
||||
private Response waitForResponseImpl(Predicate<Response> predicate, WaitForResponseOptions options, Runnable code) {
|
||||
@@ -1427,7 +1441,10 @@ public class PageImpl extends ChannelOwner implements Page {
|
||||
}
|
||||
|
||||
private void waitForURL(UrlMatcher matcher, WaitForURLOptions options) {
|
||||
withLogging("Page.waitForURL", () -> mainFrame.waitForURLImpl(matcher, convertType(options, Frame.WaitForURLOptions.class)));
|
||||
withWaitLogging("Page.waitForURL", logger -> {
|
||||
mainFrame.waitForURLImpl(logger, matcher, convertType(options, Frame.WaitForURLOptions.class));
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.microsoft.playwright.Selectors;
|
||||
import com.microsoft.playwright.impl.driver.Driver;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Collections;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@@ -33,16 +32,21 @@ public class PlaywrightImpl extends ChannelOwner implements Playwright {
|
||||
private Process driverProcess;
|
||||
|
||||
public static PlaywrightImpl create(CreateOptions options) {
|
||||
return createImpl(options, false);
|
||||
}
|
||||
|
||||
public static PlaywrightImpl createImpl(CreateOptions options, boolean forceNewDriverInstanceForTests) {
|
||||
Map<String, String> env = Collections.emptyMap();
|
||||
if (options != null && options.env != null) {
|
||||
env = options.env;
|
||||
}
|
||||
Driver driver = forceNewDriverInstanceForTests ?
|
||||
Driver.createAndInstall(env, true) :
|
||||
Driver.ensureDriverInstalled(env, true);
|
||||
try {
|
||||
Map<String, String> env = Collections.emptyMap();
|
||||
if (options != null && options.env != null) {
|
||||
env = options.env;
|
||||
}
|
||||
Path driver = Driver.ensureDriverInstalled(env, true);
|
||||
ProcessBuilder pb = new ProcessBuilder(driver.toString(), "run-driver");
|
||||
ProcessBuilder pb = driver.createProcessBuilder();
|
||||
pb.command().add("run-driver");
|
||||
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
|
||||
pb.environment().putAll(env);
|
||||
Driver.setRequiredEnvironmentVariables(pb);
|
||||
Process p = pb.start();
|
||||
Connection connection = new Connection(new PipeTransport(p.getInputStream(), p.getOutputStream()), env);
|
||||
PlaywrightImpl result = connection.initializePlaywright();
|
||||
|
||||
@@ -32,6 +32,7 @@ public class RequestOptionsImpl implements RequestOptions {
|
||||
Boolean failOnStatusCode;
|
||||
Boolean ignoreHTTPSErrors;
|
||||
Double timeout;
|
||||
Integer maxRedirects;
|
||||
|
||||
@Override
|
||||
public RequestOptions setHeader(String name, String value) {
|
||||
@@ -118,4 +119,10 @@ public class RequestOptionsImpl implements RequestOptions {
|
||||
this.ignoreHTTPSErrors = ignoreHTTPSErrors;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RequestOptions setMaxRedirects(int maxRedirects) {
|
||||
this.maxRedirects = maxRedirects;
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,10 +31,12 @@ import java.util.Map;
|
||||
import static com.microsoft.playwright.impl.Utils.convertType;
|
||||
|
||||
public class RouteImpl extends ChannelOwner implements Route {
|
||||
private final RequestImpl request;
|
||||
private boolean handled;
|
||||
|
||||
public RouteImpl(ChannelOwner parent, String type, String guid, JsonObject initializer) {
|
||||
super(parent, type, guid, initializer);
|
||||
request = connection.getExistingObject(initializer.getAsJsonObject("request").get("guid").getAsString());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -196,7 +198,7 @@ public class RouteImpl extends ChannelOwner implements Route {
|
||||
|
||||
@Override
|
||||
public RequestImpl request() {
|
||||
return connection.getExistingObject(initializer.getAsJsonObject("request").get("guid").getAsString());
|
||||
return request;
|
||||
}
|
||||
|
||||
void redirectNavigationRequest(String redirectURL) {
|
||||
|
||||
@@ -38,19 +38,16 @@ class Router {
|
||||
this.times = times;
|
||||
}
|
||||
|
||||
boolean handle(RouteImpl route) {
|
||||
if (!matcher.test(route.request().url())) {
|
||||
return false;
|
||||
}
|
||||
if (times != null) {
|
||||
--times;
|
||||
}
|
||||
void handle(RouteImpl route) {
|
||||
handler.accept(route);
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean isDone() {
|
||||
return times != null && times <= 0;
|
||||
boolean decrementRemainingCallCount() {
|
||||
if (times == null) {
|
||||
return false;
|
||||
}
|
||||
--times;
|
||||
return times <= 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,14 +70,16 @@ class Router {
|
||||
HandleResult result = HandleResult.NoMatchingHandler;
|
||||
for (Iterator<RouteInfo> it = routes.iterator(); it.hasNext();) {
|
||||
RouteInfo info = it.next();
|
||||
if (info.handle(route)) {
|
||||
result = HandleResult.FoundMatchingHandler;
|
||||
if (info.isDone()) {
|
||||
it.remove();
|
||||
}
|
||||
if (route.isHandled()) {
|
||||
break;
|
||||
}
|
||||
if (!info.matcher.test(route.request().url())) {
|
||||
continue;
|
||||
}
|
||||
if (info.decrementRemainingCallCount()) {
|
||||
it.remove();
|
||||
}
|
||||
result = HandleResult.FoundMatchingHandler;
|
||||
info.handle(route);
|
||||
if (route.isHandled()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
|
||||
@@ -33,6 +33,8 @@ import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.ZoneId;
|
||||
import java.util.*;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -150,6 +152,8 @@ class Serialization {
|
||||
result.s = (String) value;
|
||||
} else if (value instanceof Date) {
|
||||
result.d = ((Date)value).toInstant().toString();
|
||||
} else if (value instanceof LocalDateTime) {
|
||||
result.d = ((LocalDateTime)value).atZone(ZoneId.systemDefault()).toInstant().toString();
|
||||
} else if (value instanceof URL) {
|
||||
result.u = ((URL)value).toString();
|
||||
} else if (value instanceof Pattern) {
|
||||
|
||||
@@ -97,4 +97,13 @@ class UrlMatcher {
|
||||
public int hashCode() {
|
||||
return Objects.hash(rawSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
if (rawSource == null)
|
||||
return "<any>";
|
||||
if (rawSource instanceof Predicate)
|
||||
return "matching predicate";
|
||||
return rawSource.toString();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,38 +18,52 @@ package com.microsoft.playwright.impl;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.microsoft.playwright.impl.Utils.createGuid;
|
||||
|
||||
public class WaitForEventLogger<T> implements Supplier<T> {
|
||||
private final Supplier<T> supplier;
|
||||
public class WaitForEventLogger<T> implements Supplier<T>, Logger {
|
||||
private final Function<Logger, T> supplier;
|
||||
private final ChannelOwner channel;
|
||||
private final String waitId;
|
||||
private final String apiName;
|
||||
|
||||
WaitForEventLogger(ChannelOwner channelOwner, String apiName, Supplier<T> supplier) {
|
||||
WaitForEventLogger(ChannelOwner channelOwner, String apiName, Function<Logger, T> supplier) {
|
||||
this.supplier = supplier;
|
||||
this.channel = channelOwner;
|
||||
this.apiName = apiName;
|
||||
this.waitId = createGuid();
|
||||
JsonObject info = new JsonObject();
|
||||
info.addProperty("phase", "before");
|
||||
sendWaitForEventInfo(info);
|
||||
}
|
||||
|
||||
@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", "after");
|
||||
try {
|
||||
return supplier.apply(this);
|
||||
} catch (RuntimeException e) {
|
||||
info.addProperty("error", e.getMessage());
|
||||
throw e;
|
||||
} finally {
|
||||
sendWaitForEventInfo(info);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(String message) {
|
||||
LoggingSupport.logApiIfEnabled(message);
|
||||
JsonObject info = new JsonObject();
|
||||
info.addProperty("phase", "after");
|
||||
try {
|
||||
return supplier.get();
|
||||
} catch (RuntimeException e) {
|
||||
info.addProperty("error", e.getMessage());
|
||||
throw e;
|
||||
} finally {
|
||||
sendWaitForEventInfo(info);
|
||||
}
|
||||
info.addProperty("phase", "log");
|
||||
info.addProperty("message", message);
|
||||
sendWaitForEventInfo(info);
|
||||
}
|
||||
|
||||
private void sendWaitForEventInfo(JsonObject info) {
|
||||
@@ -57,6 +71,6 @@ public class WaitForEventLogger<T> implements Supplier<T> {
|
||||
info.addProperty("waitId", waitId);
|
||||
JsonObject params = new JsonObject();
|
||||
params.add("info", info);
|
||||
channel.withLogging(apiName, () -> channel.sendMessageAsync("waitForEventInfo", params));
|
||||
channel.sendMessageAsync("waitForEventInfo", params);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ class WebSocketImpl extends ChannelOwner implements WebSocket {
|
||||
|
||||
@Override
|
||||
public WebSocketFrame waitForFrameReceived(WaitForFrameReceivedOptions options, Runnable code) {
|
||||
return withWaitLogging("WebSocket.waitForFrameReceived", () -> waitForFrameReceivedImpl(options, code));
|
||||
return withWaitLogging("WebSocket.waitForFrameReceived", logger -> waitForFrameReceivedImpl(options, code));
|
||||
}
|
||||
|
||||
private WebSocketFrame waitForFrameReceivedImpl(WaitForFrameReceivedOptions options, Runnable code) {
|
||||
@@ -99,7 +99,7 @@ class WebSocketImpl extends ChannelOwner implements WebSocket {
|
||||
|
||||
@Override
|
||||
public WebSocketFrame waitForFrameSent(WaitForFrameSentOptions options, Runnable code) {
|
||||
return withWaitLogging("WebSocket.waitForFrameSent", () -> waitForFrameSentImpl(options, code));
|
||||
return withWaitLogging("WebSocket.waitForFrameSent", logger -> waitForFrameSentImpl(options, code));
|
||||
}
|
||||
|
||||
private WebSocketFrame waitForFrameSentImpl(WaitForFrameSentOptions options, Runnable code) {
|
||||
|
||||
@@ -59,7 +59,7 @@ class WorkerImpl extends ChannelOwner implements Worker {
|
||||
|
||||
@Override
|
||||
public Worker waitForClose(WaitForCloseOptions options, Runnable code) {
|
||||
return withWaitLogging("Worker.waitForClose", () -> waitForCloseImpl(options, code));
|
||||
return withWaitLogging("Worker.waitForClose", logger -> waitForCloseImpl(options, code));
|
||||
}
|
||||
|
||||
private Worker waitForCloseImpl(WaitForCloseOptions options, Runnable code) {
|
||||
|
||||
@@ -115,6 +115,13 @@ public interface RequestOptions {
|
||||
* @param ignoreHTTPSErrors Whether to ignore HTTPS errors when sending network requests.
|
||||
*/
|
||||
RequestOptions setIgnoreHTTPSErrors(boolean ignoreHTTPSErrors);
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param maxRedirects Maximum number of request redirects that will be followed automatically. An error will be thrown if the number is
|
||||
* exceeded. Defaults to {@code 20}. Pass {@code 0} to not follow redirects.
|
||||
*/
|
||||
RequestOptions setMaxRedirects(int maxRedirects);
|
||||
/**
|
||||
* Changes the request method (e.g. <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/PUT">PUT</a> or <a
|
||||
* href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST">POST</a>).
|
||||
|
||||
@@ -18,6 +18,8 @@ package com.microsoft.playwright;
|
||||
|
||||
import org.junit.jupiter.api.*;
|
||||
|
||||
import com.microsoft.playwright.options.SameSiteAttribute;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import static com.microsoft.playwright.Utils.getBrowserNameFromEnv;
|
||||
@@ -35,9 +37,11 @@ public class TestBase {
|
||||
static final boolean isMac = Utils.getOS() == Utils.OS.MAC;
|
||||
static final boolean isWindows = Utils.getOS() == Utils.OS.WINDOWS;
|
||||
static final boolean headful;
|
||||
static final SameSiteAttribute defaultSameSiteCookieValue;
|
||||
static {
|
||||
String headfulEnv = System.getenv("HEADFUL");
|
||||
headful = headfulEnv != null && !"0".equals(headfulEnv) && !"false".equals(headfulEnv);
|
||||
defaultSameSiteCookieValue = initSameSiteAttribute();
|
||||
}
|
||||
|
||||
// Fields reset before each test.
|
||||
@@ -145,4 +149,11 @@ public class TestBase {
|
||||
page = null;
|
||||
}
|
||||
}
|
||||
|
||||
private static SameSiteAttribute initSameSiteAttribute() {
|
||||
if (isChromium()) return SameSiteAttribute.LAX;
|
||||
if (isWebKit()) return SameSiteAttribute.NONE;
|
||||
// for firefox version >= 103 'None' is used.
|
||||
return SameSiteAttribute.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,12 +48,8 @@ public class TestBrowser extends TestBase {
|
||||
@Test
|
||||
void shouldThrowUponSecondCreateNewPage() {
|
||||
Page page = browser.newPage();
|
||||
try {
|
||||
page.context().newPage();
|
||||
fail("newPage should throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Please use browser.newContext()"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.context().newPage());
|
||||
assertTrue(e.getMessage().contains("Please use browser.newContext()"));
|
||||
page.close();
|
||||
}
|
||||
|
||||
|
||||
+13
-27
@@ -16,7 +16,6 @@
|
||||
|
||||
package com.microsoft.playwright;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.microsoft.playwright.options.Cookie;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
@@ -27,7 +26,6 @@ import java.util.concurrent.Future;
|
||||
|
||||
import static com.microsoft.playwright.Utils.assertJsonEquals;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
@@ -51,15 +49,11 @@ public class TestBrowserContextAddCookies extends TestBase {
|
||||
"}");
|
||||
assertEquals("username=John Doe", documentCookie);
|
||||
List<Cookie> cookies = context.cookies();
|
||||
assertEquals(1, cookies.size());
|
||||
context.clearCookies();
|
||||
assertEquals(emptyList(), context.cookies());
|
||||
context.addCookies(asList(new Cookie(cookies.get(0).name, cookies.get(0).value)
|
||||
.setDomain(cookies.get(0).domain)
|
||||
.setPath(cookies.get(0).path)
|
||||
.setExpires(cookies.get(0).expires)
|
||||
.setSameSite(cookies.get(0).sameSite)
|
||||
));
|
||||
assertJsonEquals(new Gson().toJson(cookies), context.cookies());
|
||||
assertEquals(0, context.cookies().size());
|
||||
context.addCookies(cookies);
|
||||
assertJsonEquals(cookies, context.cookies());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -248,27 +242,19 @@ public class TestBrowserContextAddCookies extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldNotSetACookieWithBlankPageURL() {
|
||||
try {
|
||||
context.addCookies(asList(
|
||||
new Cookie("example-cookie", "best").setUrl(server.EMPTY_PAGE),
|
||||
new Cookie("example-cookie-blank", "best").setUrl("about:blank")
|
||||
));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Blank page can not have cookie \"example-cookie-blank\""));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.addCookies(asList(
|
||||
new Cookie("example-cookie", "best").setUrl(server.EMPTY_PAGE),
|
||||
new Cookie("example-cookie-blank", "best").setUrl("about:blank")
|
||||
)));
|
||||
assertTrue(e.getMessage().contains("Blank page can not have cookie \"example-cookie-blank\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotSetACookieOnADataURLPage() {
|
||||
try {
|
||||
context.addCookies(asList(
|
||||
new Cookie("example-cookie", "best").setUrl("data:,Hello%2C%20World!")
|
||||
));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Data URL page can not have cookie \"example-cookie\""));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.addCookies(asList(
|
||||
new Cookie("example-cookie", "best").setUrl("data:,Hello%2C%20World!")
|
||||
)));
|
||||
assertTrue(e.getMessage().contains("Data URL page can not have cookie \"example-cookie\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -116,22 +116,18 @@ public class TestBrowserContextBasic extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldNotAllowDeviceScaleFactorWithNullViewport() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
browser.newContext(new Browser.NewContextOptions().setDeviceScaleFactor(1.0).setViewportSize(null));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("\"deviceScaleFactor\" option is not supported with null \"viewport\""));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("\"deviceScaleFactor\" option is not supported with null \"viewport\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotAllowIsMobileWithNullViewport() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
browser.newContext(new Browser.NewContextOptions().setIsMobile(true).setViewportSize(null));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("\"isMobile\" option is not supported with null \"viewport\""));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("\"isMobile\" option is not supported with null \"viewport\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -143,12 +139,10 @@ public class TestBrowserContextBasic extends TestBase {
|
||||
@Test
|
||||
void closeShouldAbortFutureEvent() {
|
||||
BrowserContext context = browser.newContext();
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
context.waitForPage(() -> context.close());
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Context closed"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Context closed"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -211,15 +205,11 @@ public class TestBrowserContextBasic extends TestBase {
|
||||
BrowserContext context = browser.newContext(new Browser.NewContextOptions().setJavaScriptEnabled(false));
|
||||
Page page = context.newPage();
|
||||
page.navigate("data:text/html, <script>var something = 'forbidden'</script>");
|
||||
try {
|
||||
page.evaluate("something");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
if (isWebKit())
|
||||
assertTrue(e.getMessage().contains("Can\'t find variable: something"));
|
||||
else
|
||||
assertTrue(e.getMessage().contains("something is not defined"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.evaluate("something"));
|
||||
if (isWebKit())
|
||||
assertTrue(e.getMessage().contains("Can\'t find variable: something"));
|
||||
else
|
||||
assertTrue(e.getMessage().contains("something is not defined"));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@@ -244,11 +234,7 @@ public class TestBrowserContextBasic extends TestBase {
|
||||
void shouldWorkWithOfflineOption() {
|
||||
BrowserContext context = browser.newContext(new Browser.NewContextOptions().setOffline(true));
|
||||
Page page = context.newPage();
|
||||
try {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE));
|
||||
|
||||
context.setOffline(false);
|
||||
Response response = page.navigate(server.EMPTY_PAGE);
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.microsoft.playwright.options.Cookie;
|
||||
import com.microsoft.playwright.options.SameSiteAttribute;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.DisabledIf;
|
||||
import org.junit.jupiter.api.condition.EnabledIf;
|
||||
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
@@ -29,8 +28,7 @@ import java.util.stream.Collectors;
|
||||
import static com.microsoft.playwright.Utils.assertJsonEquals;
|
||||
import static com.microsoft.playwright.Utils.getOS;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestBrowserContextCookies extends TestBase {
|
||||
@Test
|
||||
@@ -60,31 +58,28 @@ public class TestBrowserContextCookies extends TestBase {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
// @see https://en.wikipedia.org/wiki/Year_2038_problem
|
||||
Object documentCookie = page.evaluate("() => {\n" +
|
||||
" const date= new Date('1/1/2038');\n" +
|
||||
" document.cookie = `username=John Doe;expires=${date.toUTCString()}`;\n" +
|
||||
" return document.cookie;\n" +
|
||||
" }");
|
||||
" const date = new Date('1/1/2038');\n" +
|
||||
" document.cookie = `username=John Doe;expires=${date.toUTCString()}`;\n" +
|
||||
" return document.cookie;\n" +
|
||||
"}");
|
||||
assertEquals("username=John Doe", documentCookie);
|
||||
Cookie cookie = context.cookies().get(0);
|
||||
assertEquals("username", cookie.name);
|
||||
assertEquals("John Doe", cookie.value);
|
||||
assertEquals("localhost", cookie.domain);
|
||||
assertEquals("/", cookie.path);
|
||||
List<Cookie> cookies = context.cookies();
|
||||
assertEquals(1, cookies.size());
|
||||
assertEquals("username", cookies.get(0).name);
|
||||
assertEquals("John Doe", cookies.get(0).value);
|
||||
assertEquals("localhost", cookies.get(0).domain);
|
||||
assertEquals("/", cookies.get(0).path);
|
||||
assertFalse(cookies.get(0).httpOnly);
|
||||
assertFalse(cookies.get(0).secure);
|
||||
assertEquals(defaultSameSiteCookieValue, cookies.get(0).sameSite);
|
||||
|
||||
// Browsers start to cap cookies with 400 days max expires value.
|
||||
// See https://github.com/httpwg/http-extensions/pull/1732
|
||||
// Chromium patch: https://chromium.googlesource.com/chromium/src/+/aaa5d2b55478eac2ee642653dcd77a50ac3faff6
|
||||
// We want to make sure that expires date is at least 400 days in future.
|
||||
Double timestamp = (Double) page.evaluate("const FOUR_HUNDRED_DAYS = 1000 * 60 * 60 * 24 * 400;\n" +
|
||||
" const FIVE_MINUTES = 1000 * 60 * 5; // relax condition a bit to make sure test is not flaky.\n" +
|
||||
" (Date.now() + FOUR_HUNDRED_DAYS - FIVE_MINUTES) / 1000;");
|
||||
assertTrue(cookie.expires > timestamp, cookie.expires + " > " + timestamp + " failed.");
|
||||
assertEquals(false, cookie.httpOnly);
|
||||
assertEquals(false, cookie.secure);
|
||||
if (isChromium()) {
|
||||
assertEquals(SameSiteAttribute.LAX, cookie.sameSite);
|
||||
} else {
|
||||
assertEquals(SameSiteAttribute.NONE, cookie.sameSite);
|
||||
}
|
||||
int FOUR_HUNDRED_DAYS = 1000 * 60 * 60 * 24 * 400;
|
||||
int FIVE_MINUTES = 1000 * 60 * 5; // relax condition a bit to make sure test is not flaky.
|
||||
assertTrue(cookies.get(0).expires > ((System.currentTimeMillis() + FOUR_HUNDRED_DAYS - FIVE_MINUTES) / 1000));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+6
-18
@@ -58,28 +58,16 @@ public class TestBrowserContextExposeFunction extends TestBase {
|
||||
void shouldThrowForDuplicateRegistrations() {
|
||||
context.exposeFunction("foo", args -> null);
|
||||
context.exposeFunction("bar", args -> null);
|
||||
try {
|
||||
context.exposeFunction("foo", args -> null);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Function \"foo\" has been already registered"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.exposeFunction("foo", args -> null));
|
||||
assertTrue(e.getMessage().contains("Function \"foo\" has been already registered"));
|
||||
|
||||
Page page = context.newPage();
|
||||
try {
|
||||
page.exposeFunction("foo", args -> null);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Function \"foo\" has been already registered in the browser context"));
|
||||
}
|
||||
e = assertThrows(PlaywrightException.class, () -> page.exposeFunction("foo", args -> null));
|
||||
assertTrue(e.getMessage().contains("Function \"foo\" has been already registered in the browser context"));
|
||||
|
||||
page.exposeFunction("baz", args -> null);
|
||||
try {
|
||||
context.exposeFunction("baz", args -> null);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Function \"baz\" has been already registered in one of the pages"));
|
||||
}
|
||||
e = assertThrows(PlaywrightException.class, () -> context.exposeFunction("baz", args -> null));
|
||||
assertTrue(e.getMessage().contains("Function \"baz\" has been already registered in one of the pages"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -51,24 +51,16 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
@Test
|
||||
void shouldThrowOnNetworkError() {
|
||||
server.setRoute("/test", exchange -> exchange.getResponseBody().close());
|
||||
try {
|
||||
context.request().get(server.PREFIX + "/test");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("socket hang up"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.request().get(server.PREFIX + "/test"));
|
||||
assertTrue(e.getMessage().contains("socket hang up"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowOnNetworkErrorAfterRedirect() {
|
||||
server.setRedirect("/redirect", "/test");
|
||||
server.setRoute("/test", exchange -> exchange.getResponseBody().close());
|
||||
try {
|
||||
context.request().get(server.PREFIX + "/redirect");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("socket hang up"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.request().get(server.PREFIX + "/redirect"));
|
||||
assertTrue(e.getMessage().contains("socket hang up"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -80,12 +72,8 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
writer.write("<title>A");
|
||||
}
|
||||
});
|
||||
try {
|
||||
context.request().get(server.PREFIX + "/test");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("aborted"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.request().get(server.PREFIX + "/test"));
|
||||
assertTrue(e.getMessage().contains("aborted"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -98,12 +86,8 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
writer.write("<title>A");
|
||||
}
|
||||
});
|
||||
try {
|
||||
context.request().get(server.PREFIX + "/redirect");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("aborted"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.request().get(server.PREFIX + "/redirect"));
|
||||
assertTrue(e.getMessage().contains("aborted"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -134,12 +118,10 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
|
||||
@Test
|
||||
void getShouldSupportFailOnStatusCode() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
context.request().get(server.PREFIX + "/does-not-exist.html", RequestOptions.create().setFailOnStatusCode(true));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("404 Not Found"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("404 Not Found"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -385,29 +367,20 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldThrowOnInvalidHeaderValue() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
context.request().get(server.EMPTY_PAGE, RequestOptions.create()
|
||||
.setHeader("foo", "недопустимое значение"));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Invalid character in header content"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Invalid character in header content"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowOnNonHttpSProtocol() {
|
||||
try {
|
||||
context.request().get("data:text/plain,test");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Protocol \"data:\" not supported"), e.getMessage());
|
||||
}
|
||||
try {
|
||||
context.request().get("file:///tmp/foo");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Protocol \"file:\" not supported"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.request().get("data:text/plain,test"));
|
||||
assertTrue(e.getMessage().contains("Protocol \"data:\" not supported"), e.getMessage());
|
||||
|
||||
e = assertThrows(PlaywrightException.class, () -> context.request().get("file:///tmp/foo"));
|
||||
assertTrue(e.getMessage().contains("Protocol \"file:\" not supported"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -417,12 +390,10 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
exchange.sendResponseHeaders(200, 4096);
|
||||
});
|
||||
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
context.request().get(server.PREFIX + "/slow", RequestOptions.create().setTimeout(100));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Request timed out after 100ms"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Request timed out after 100ms"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -453,12 +424,8 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
});
|
||||
|
||||
context.setDefaultTimeout(100);
|
||||
try {
|
||||
context.request().get(server.PREFIX + "/redirect");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Request timed out after 100ms"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.request().get(server.PREFIX + "/redirect"));
|
||||
assertTrue(e.getMessage().contains("Request timed out after 100ms"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -466,12 +433,8 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
APIResponse response = context.request().get(server.PREFIX + "/simple.json");
|
||||
assertEquals("{\"foo\": \"bar\"}\n", response.text());
|
||||
response.dispose();
|
||||
try {
|
||||
response.body();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Response has been disposed"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> response.body());
|
||||
assertTrue(e.getMessage().contains("Response has been disposed"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -479,13 +442,9 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
APIResponse response = context.request().get(server.PREFIX + "/simple.json");
|
||||
assertEquals("{\"foo\": \"bar\"}\n", response.text());
|
||||
context.close();
|
||||
try {
|
||||
response.body();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Response has been disposed") ||
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> response.body());
|
||||
assertTrue(e.getMessage().contains("Response has been disposed") ||
|
||||
e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage());
|
||||
}
|
||||
}
|
||||
@Test
|
||||
void shouldOverrideRequestParameters() throws ExecutionException, InterruptedException {
|
||||
@@ -614,17 +573,11 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowWhenDataPassedForUnsupportedRequest() {
|
||||
try {
|
||||
context.request().fetch(server.EMPTY_PAGE, RequestOptions.create()
|
||||
.setMethod("GET").setData("bar"));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Method GET does not accept post data"), e.getMessage());
|
||||
}
|
||||
void shouldNotThrowWhenDataPassedForUnsupportedRequest() {
|
||||
context.request().fetch(server.EMPTY_PAGE, RequestOptions.create()
|
||||
.setMethod("GET").setData("bar"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void contextRequestShouldExportSameStorageStateAsContext() {
|
||||
server.setRoute("/setcookie.html", exchange -> {
|
||||
@@ -666,18 +619,10 @@ public class TestBrowserContextFetch extends TestBase {
|
||||
return null;
|
||||
});
|
||||
page.evaluate("() => setTimeout(closeContext, 1000);");
|
||||
try {
|
||||
context.request().get(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Request context disposed"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> context.request().get(server.EMPTY_PAGE));
|
||||
assertTrue(e.getMessage().contains("Request context disposed"), e.getMessage());
|
||||
|
||||
try {
|
||||
context.request().post(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage());
|
||||
}
|
||||
e = assertThrows(PlaywrightException.class, () -> context.request().post(server.EMPTY_PAGE));
|
||||
assertTrue(e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,11 +79,7 @@ public class TestBrowserContextHar extends TestBase {
|
||||
Path path = Paths.get("src/test/resources/har-fulfill.har");
|
||||
context.routeFromHAR(path);
|
||||
Page page = context.newPage();
|
||||
try {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -350,11 +346,7 @@ public class TestBrowserContextHar extends TestBase {
|
||||
assertEquals("2", page2.evaluate(fetchFunction, "2"));
|
||||
assertEquals("3", page2.evaluate(fetchFunction, "3"));
|
||||
assertEquals("3", page2.evaluate(fetchFunction, "3"));
|
||||
try {
|
||||
page2.evaluate(fetchFunction, "4");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
assertThrows(PlaywrightException.class, () -> page2.evaluate(fetchFunction, "4"));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -47,9 +47,9 @@ public class TestBrowserContextProxy extends TestBase {
|
||||
@EnabledIf(value="isChromiumWindows", disabledReason="Platform-specific")
|
||||
void shouldThrowForMissingGlobalProxyOnChromiumWindows() {
|
||||
try (Browser browser = browserType.launch(createLaunchOptions())) {
|
||||
browser.newContext(new Browser.NewContextOptions().setProxy("localhost:" + server.PORT));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
browser.newContext(new Browser.NewContextOptions().setProxy("localhost:" + server.PORT));
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Browser needs to be launched with the global proxy"));
|
||||
}
|
||||
}
|
||||
@@ -179,23 +179,9 @@ public class TestBrowserContextProxy extends TestBase {
|
||||
page.navigate("http://0.non.existent.domain.for.the.test/target.html");
|
||||
assertEquals("Served by the proxy", page.title());
|
||||
|
||||
try {
|
||||
page.navigate("http://1.non.existent.domain.for.the.test/target.html");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException exception) {
|
||||
}
|
||||
|
||||
try {
|
||||
page.navigate("http://2.non.existent.domain.for.the.test/target.html");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
|
||||
try {
|
||||
page.navigate("http://foo.is.the.another.test/target.html");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
assertThrows(PlaywrightException.class, () -> page.navigate("http://1.non.existent.domain.for.the.test/target.html"));
|
||||
assertThrows(PlaywrightException.class, () -> page.navigate("http://2.non.existent.domain.for.the.test/target.html"));
|
||||
assertThrows(PlaywrightException.class, () -> page.navigate("http://foo.is.the.another.test/target.html"));
|
||||
|
||||
page.navigate("http://3.non.existent.domain.for.the.test/target.html");
|
||||
assertEquals("Served by the proxy", page.title());
|
||||
|
||||
@@ -169,12 +169,8 @@ public class TestBrowserContextRoute extends TestBase {
|
||||
throw new RuntimeException("My Exception");
|
||||
});
|
||||
|
||||
try {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (RuntimeException e) {
|
||||
assertTrue(e.getMessage().contains("My Exception"), e.getMessage());
|
||||
}
|
||||
RuntimeException e = assertThrows(RuntimeException.class, () -> page.navigate(server.EMPTY_PAGE));
|
||||
assertTrue(e.getMessage().contains("My Exception"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -187,12 +183,8 @@ public class TestBrowserContextRoute extends TestBase {
|
||||
// Fulfilling with dsiposed response will lead to a server-side exception.
|
||||
route.fulfill(new Route.FulfillOptions().setResponse(response));
|
||||
});
|
||||
try {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (RuntimeException e) {
|
||||
assertTrue(e.getMessage().contains("Fetch response has been disposed"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE));
|
||||
assertTrue(e.getMessage().contains("Fetch response has been disposed"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -201,12 +193,8 @@ public class TestBrowserContextRoute extends TestBase {
|
||||
page.route("**/*", route -> {
|
||||
route.resume(new Route.ResumeOptions().setUrl("file:///tmp"));
|
||||
});
|
||||
try {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (RuntimeException e) {
|
||||
assertTrue(e.getMessage().contains("New URL must have same protocol as overridden URL"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE));
|
||||
assertTrue(e.getMessage().contains("New URL must have same protocol as overridden URL"), e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@@ -260,12 +248,7 @@ public class TestBrowserContextRoute extends TestBase {
|
||||
route.fallback();
|
||||
});
|
||||
|
||||
try {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertNotNull(e);
|
||||
}
|
||||
assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE));
|
||||
assertFalse(failed[0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -38,12 +38,8 @@ public class TestBrowserContextStrict extends TestBase {
|
||||
@Test
|
||||
void shouldFailPageTextContentInStrictMode() {
|
||||
page.setContent("<span>span1</span><div><span>target</span></div>");
|
||||
try {
|
||||
page.textContent("span");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.textContent("span"));
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -43,11 +43,7 @@ public class TestBrowserTypeBasic extends TestBase {
|
||||
@Test
|
||||
@DisabledIf(value="com.microsoft.playwright.TestBase#isChromium", disabledReason="Non-chromium behavior")
|
||||
void shouldThrowWhenTryingToConnectWithNotChromium() {
|
||||
try {
|
||||
browserType.connectOverCDP("foo");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Connecting over CDP is only supported in Chromium."));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> browserType.connectOverCDP("foo"));
|
||||
assertTrue(e.getMessage().contains("Connecting over CDP is only supported in Chromium."));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,8 +60,8 @@ public class TestBrowserTypeConnect extends TestBase {
|
||||
|
||||
private static BrowserServer launchBrowserServer(BrowserType browserType) {
|
||||
try {
|
||||
Path driver = Driver.ensureDriverInstalled(Collections.emptyMap(), false);
|
||||
Path dir = driver.getParent();
|
||||
Driver driver = Driver.ensureDriverInstalled(Collections.emptyMap(), false);
|
||||
Path dir = driver.driverPath().getParent();
|
||||
String node = dir.resolve(isWindows ? "node.exe" : "node").toString();
|
||||
String cliJs = dir.resolve("package/lib/cli/cli.js").toString();
|
||||
// We launch node process directly instead of using playwright.sh script as killing the script
|
||||
@@ -192,12 +192,8 @@ public class TestBrowserTypeConnect extends TestBase {
|
||||
|
||||
remote.kill();
|
||||
assertEquals(1, disconnected1[0]);
|
||||
try {
|
||||
// Tickle connection so that it gets a chance to dispatch disconnect event.
|
||||
page2.title();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
// Tickle connection so that it gets a chance to dispatch disconnect event.
|
||||
assertThrows(PlaywrightException.class, () -> page2.title());
|
||||
assertEquals(1, disconnected2[0]);
|
||||
}
|
||||
|
||||
@@ -238,11 +234,8 @@ public class TestBrowserTypeConnect extends TestBase {
|
||||
}
|
||||
}
|
||||
assertFalse(remote.isConnected());
|
||||
try {
|
||||
page.evaluate("1 + 1");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Browser has been closed"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.evaluate("1 + 1"));
|
||||
assertTrue(e.getMessage().contains("Browser has been closed"), e.getMessage());
|
||||
assertFalse(remote.isConnected());
|
||||
}
|
||||
|
||||
@@ -262,12 +255,8 @@ public class TestBrowserTypeConnect extends TestBase {
|
||||
}
|
||||
}
|
||||
assertFalse(browser.isConnected());
|
||||
try {
|
||||
page.waitForNavigation(() -> {});
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Page closed") || e.getMessage().contains("Browser has been closed"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.waitForNavigation(() -> {}));
|
||||
assertTrue(e.getMessage().contains("Page closed") || e.getMessage().contains("Browser has been closed"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -277,12 +266,10 @@ public class TestBrowserTypeConnect extends TestBase {
|
||||
|
||||
server.setRoute("/one-style.css", r -> {});
|
||||
page.onRequest(r -> remote.close());
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.navigate(server.PREFIX + "/one-style.html", new Page.NavigateOptions().setTimeout(60000));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Browser has been closed"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Browser has been closed"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -408,12 +395,8 @@ public class TestBrowserTypeConnect extends TestBase {
|
||||
Path savedAsPath = tempDir.resolve("my-video.webm");
|
||||
page.video().saveAs(savedAsPath);
|
||||
assertTrue(Files.exists(savedAsPath));
|
||||
try {
|
||||
page.video().path();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Path is not available when using browserType.connect(). Use saveAs() to save a local copy."));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.video().path());
|
||||
assertTrue(e.getMessage().contains("Path is not available when using browserType.connect(). Use saveAs() to save a local copy."));
|
||||
}
|
||||
|
||||
|
||||
@@ -435,12 +418,8 @@ public class TestBrowserTypeConnect extends TestBase {
|
||||
download.saveAs(nestedPath);
|
||||
assertTrue(Files.exists(nestedPath));
|
||||
assertEquals("Hello world", new String(Files.readAllBytes(nestedPath), StandardCharsets.UTF_8));
|
||||
try {
|
||||
download.path();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Path is not available when using browserType.connect(). Use download.saveAs() to save a local copy."));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> download.path());
|
||||
assertTrue(e.getMessage().contains("Path is not available when using browserType.connect(). Use download.saveAs() to save a local copy."));
|
||||
page.close();
|
||||
}
|
||||
|
||||
@@ -459,12 +438,8 @@ public class TestBrowserTypeConnect extends TestBase {
|
||||
Download download = page.waitForDownload(() -> page.click("a"));
|
||||
Path userPath = tempDir.resolve("download.txt");
|
||||
download.delete();
|
||||
try {
|
||||
download.saveAs(userPath);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Target page, context or browser has been closed"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> download.saveAs(userPath));
|
||||
assertTrue(e.getMessage().contains("Target page, context or browser has been closed"));
|
||||
page.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -80,12 +80,10 @@ public class TestChromiumTracing extends TestBase {
|
||||
browser.startTracing(page, new Browser.StartTracingOptions()
|
||||
.setPath(outputTraceFile));
|
||||
Page newPage = browser.newPage();
|
||||
try {
|
||||
assertThrows(PlaywrightException.class, () -> {
|
||||
browser.startTracing(newPage, new Browser.StartTracingOptions()
|
||||
.setPath(outputTraceFile));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
});
|
||||
newPage.close();
|
||||
browser.stopTracing();
|
||||
}
|
||||
|
||||
@@ -172,14 +172,10 @@ public class TestClick extends TestBase {
|
||||
void shouldNotWaitWithForce() {
|
||||
page.navigate(server.PREFIX + "/input/button.html");
|
||||
page.evalOnSelector("button", "b => b.style.display = 'none'");
|
||||
Exception exception = null;
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.click("button", new Page.ClickOptions().setForce(true));
|
||||
} catch (PlaywrightException e) {
|
||||
exception = e;
|
||||
}
|
||||
assertNotNull(exception);
|
||||
assertTrue(exception.getMessage().contains("Element is not visible"));
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Element is not visible"));
|
||||
assertEquals("Was not clicked", page.evaluate("result"));
|
||||
}
|
||||
|
||||
@@ -428,8 +424,8 @@ public class TestClick extends TestBase {
|
||||
int expectedY = 18;
|
||||
if (isWebKit()) {
|
||||
// WebKit rounds up during css -> dip -> css conversion.
|
||||
expectedX = 29;
|
||||
expectedY = 19;
|
||||
expectedX = 26;
|
||||
expectedY = 17;
|
||||
} else if (isChromium() && !headful) {
|
||||
// Headless Chromium rounds down during css -> dip -> css conversion.
|
||||
expectedX = 27;
|
||||
@@ -564,12 +560,10 @@ public class TestClick extends TestBase {
|
||||
page.evaluate("addButton()");
|
||||
ElementHandle handle = page.querySelector("button");
|
||||
page.evaluate("stopButton(true)");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
handle.click(new ElementHandle.ClickOptions().setForce(true));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Element is not attached to the DOM"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Element is not attached to the DOM"));
|
||||
assertEquals(null, page.evaluate("window.clicked"));
|
||||
}
|
||||
|
||||
|
||||
@@ -192,12 +192,10 @@ public class TestDefaultBrowserContext2 extends TestBase {
|
||||
BrowserType.LaunchPersistentContextOptions options = new BrowserType.LaunchPersistentContextOptions()
|
||||
.setArgs(asList(server.EMPTY_PAGE));
|
||||
Path userDataDir = Files.createTempDirectory("user-data-dir-");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
browserType.launchPersistentContext(userDataDir, options);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("can not specify page"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("can not specify page"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -102,9 +102,8 @@ public class TestDownload extends TestBase {
|
||||
assertTrue(error[0].getMessage().contains("Download is starting"));
|
||||
assertEquals("about:blank", page.url());
|
||||
} else {
|
||||
assertNotNull(response[0]);
|
||||
assertEquals(200, response[0].status());
|
||||
assertEquals(server.PREFIX + "/download", page.url());
|
||||
assertNotNull(error[0]);
|
||||
assertTrue(error[0].getMessage().contains("Download is starting"));
|
||||
}
|
||||
page.close();
|
||||
}
|
||||
@@ -116,13 +115,9 @@ public class TestDownload extends TestBase {
|
||||
Download download = page.waitForDownload(() -> page.click("a"));
|
||||
assertEquals(server.PREFIX + "/downloadWithFilename", download.url());
|
||||
assertEquals("file.txt", download.suggestedFilename());
|
||||
try {
|
||||
download.path();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(download.failure().contains("acceptDownloads"));
|
||||
assertTrue(e.getMessage().contains("acceptDownloads: true"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> download.path());
|
||||
assertTrue(download.failure().contains("acceptDownloads"));
|
||||
assertTrue(e.getMessage().contains("acceptDownloads: true"));
|
||||
}
|
||||
}
|
||||
@Test
|
||||
@@ -243,12 +238,8 @@ public class TestDownload extends TestBase {
|
||||
Download download = page.waitForDownload(() -> page.click("a"));
|
||||
|
||||
Path userPath = Files.createTempFile("download-", ".txt");
|
||||
try {
|
||||
download.saveAs(userPath);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Pass { acceptDownloads: true } when you are creating your browser context"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> download.saveAs(userPath));
|
||||
assertTrue(e.getMessage().contains("Pass { acceptDownloads: true } when you are creating your browser context"));
|
||||
page.close();
|
||||
}
|
||||
|
||||
@@ -260,12 +251,8 @@ public class TestDownload extends TestBase {
|
||||
|
||||
Path userPath = Files.createTempFile("download-", ".txt");
|
||||
download.delete();
|
||||
try {
|
||||
download.saveAs(userPath);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> download.saveAs(userPath));
|
||||
assertTrue(e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage());
|
||||
page.close();
|
||||
}
|
||||
|
||||
|
||||
@@ -60,12 +60,8 @@ public class TestElementHandleClick extends TestBase {
|
||||
page.navigate(server.PREFIX + "/input/button.html");
|
||||
ElementHandle button = page.querySelector("button");
|
||||
page.evaluate("button => button.remove()", button);
|
||||
try {
|
||||
button.click();
|
||||
fail("click should throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Element is not attached to the DOM"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> button.click());
|
||||
assertTrue(e.getMessage().contains("Element is not attached to the DOM"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -73,12 +69,10 @@ public class TestElementHandleClick extends TestBase {
|
||||
page.navigate(server.PREFIX + "/input/button.html");
|
||||
ElementHandle button = page.querySelector("button");
|
||||
page.evaluate("button => button.style.display = 'none'", button);
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
button.click(new ElementHandle.ClickOptions().setForce(true));
|
||||
fail("click should throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Element is not visible"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Element is not visible"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -86,24 +80,20 @@ public class TestElementHandleClick extends TestBase {
|
||||
page.navigate(server.PREFIX + "/input/button.html");
|
||||
ElementHandle button = page.querySelector("button");
|
||||
page.evaluate("button => button.parentElement.style.display = 'none'", button);
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
button.click(new ElementHandle.ClickOptions().setForce(true));
|
||||
fail("click should throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Element is not visible"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Element is not visible"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowForBrElementsWithForce() {
|
||||
page.setContent("hello<br>goodbye");
|
||||
ElementHandle br = page.querySelector("br");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
br.click(new ElementHandle.ClickOptions().setForce(true));
|
||||
fail("click should throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Element is outside of the viewport"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Element is outside of the viewport"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
+11
-30
@@ -57,19 +57,12 @@ public class TestElementHandleConvenience extends TestBase {
|
||||
ElementHandle handle = page.querySelector("#input");
|
||||
assertEquals("input value", handle.inputValue());
|
||||
|
||||
try {
|
||||
page.inputValue("#inner");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Node is not an <input>, <textarea> or <select> element"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.inputValue("#inner"));
|
||||
assertTrue(e.getMessage().contains("Node is not an <input>, <textarea> or <select> element"), e.getMessage());
|
||||
|
||||
ElementHandle handle2 = page.querySelector("#inner");
|
||||
try {
|
||||
handle2.inputValue();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Node is not an <input>, <textarea> or <select> element"), e.getMessage());
|
||||
}
|
||||
e = assertThrows(PlaywrightException.class, () -> handle2.inputValue());
|
||||
assertTrue(e.getMessage().contains("Node is not an <input>, <textarea> or <select> element"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -91,19 +84,11 @@ public class TestElementHandleConvenience extends TestBase {
|
||||
@Test
|
||||
void innerTextShouldThrow() {
|
||||
page.setContent("<svg>text</svg>");
|
||||
try {
|
||||
page.innerText("svg");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Node is not an HTMLElement"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.innerText("svg"));
|
||||
assertTrue(e.getMessage().contains("Node is not an HTMLElement"), e.getMessage());
|
||||
ElementHandle handle = page.querySelector("svg");
|
||||
try {
|
||||
handle.innerText();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Node is not an HTMLElement"), e.getMessage());
|
||||
}
|
||||
e = assertThrows(PlaywrightException.class, () -> handle.innerText());
|
||||
assertTrue(e.getMessage().contains("Node is not an HTMLElement"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -267,11 +252,7 @@ public class TestElementHandleConvenience extends TestBase {
|
||||
handle.evaluate("input => input.checked = false");
|
||||
assertFalse(handle.isChecked());
|
||||
assertFalse(page.isChecked("input"));
|
||||
try {
|
||||
page.isChecked("div");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Not a checkbox or radio button"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.isChecked("div"));
|
||||
assertTrue(e.getMessage().contains("Not a checkbox or radio button"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,12 +47,10 @@ public class TestElementHandleSelectText extends TestBase {
|
||||
page.navigate(server.PREFIX + "/input/textarea.html");
|
||||
ElementHandle textarea = page.querySelector("textarea");
|
||||
textarea.evaluate("e => e.style.display = 'none'");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
textarea.selectText(new ElementHandle.SelectTextOptions().setTimeout(3000));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("element is not visible"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("element is not visible"));
|
||||
}
|
||||
|
||||
// @Test
|
||||
|
||||
+8
-19
@@ -20,8 +20,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.DisabledIf;
|
||||
|
||||
import static com.microsoft.playwright.options.ElementState.*;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestElementHandleWaitForElementState extends TestBase {
|
||||
|
||||
@@ -51,12 +50,10 @@ public class TestElementHandleWaitForElementState extends TestBase {
|
||||
void shouldTimeoutWaitingForVisible() {
|
||||
page.setContent("<div style='display:none'>content</div>");
|
||||
ElementHandle div = page.querySelector("div");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
div.waitForElementState(VISIBLE, new ElementHandle.WaitForElementStateOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (TimeoutError e) {
|
||||
assertTrue(e.getMessage().contains("Timeout 1000ms exceeded"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout 1000ms exceeded"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -64,12 +61,8 @@ public class TestElementHandleWaitForElementState extends TestBase {
|
||||
page.setContent("<div style='display:none'>content</div>");
|
||||
ElementHandle div = page.querySelector("div");
|
||||
div.evaluate("div => div.remove()");
|
||||
try {
|
||||
div.waitForElementState(VISIBLE);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Element is not attached to the DOM"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> div.waitForElementState(VISIBLE));
|
||||
assertTrue(e.getMessage().contains("Element is not attached to the DOM"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -111,12 +104,8 @@ public class TestElementHandleWaitForElementState extends TestBase {
|
||||
page.setContent("<button disabled>Target</button>");
|
||||
ElementHandle button = page.querySelector("button");
|
||||
button.evaluate("button => button.remove()");
|
||||
try {
|
||||
button.waitForElementState(ENABLED);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Element is not attached to the DOM"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> button.waitForElementState(ENABLED));
|
||||
assertTrue(e.getMessage().contains("Element is not attached to the DOM"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -119,12 +119,10 @@ public class TestEvalOnSelector extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldThrowErrorIfNoElementIsFound() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.evalOnSelector("section", "e => e.id");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("failed to find element matching selector \"section\""));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("failed to find element matching selector \"section\""));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -166,23 +164,20 @@ public class TestEvalOnSelector extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldThrowOnMultipleCaptures() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.evalOnSelector("*css=div >> *css=span", "e => e.outerHTML");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Only one of the selectors can capture using * modifier"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Only one of the selectors can capture using * modifier"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowOnMalformedCapture() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.evalOnSelector("*=div", "e => e.outerHTML");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Unknown engine \"\" while parsing selector *=div"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Unknown engine \"\" while parsing selector *=div"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldWorkWithSpacesInCssAttributes() {
|
||||
page.setContent("<div><input placeholder='Select date'></div>");
|
||||
|
||||
@@ -21,8 +21,7 @@ import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.EnabledIf;
|
||||
|
||||
import static com.microsoft.playwright.Utils.mapOf;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestFirefoxLauncher extends TestBase {
|
||||
|
||||
@@ -47,11 +46,7 @@ public class TestFirefoxLauncher extends TestBase {
|
||||
"network.proxy.http_port", 3333));
|
||||
launchBrowser(options);
|
||||
Page page = browser.newPage();
|
||||
try {
|
||||
page.navigate("http://example.com");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("NS_ERROR_PROXY_CONNECTION_REFUSED"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.navigate("http://example.com"));
|
||||
assertTrue(e.getMessage().contains("NS_ERROR_PROXY_CONNECTION_REFUSED"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,8 +19,7 @@ package com.microsoft.playwright;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static com.microsoft.playwright.options.WaitUntilState.NETWORKIDLE;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestFrameNavigate extends TestBase {
|
||||
|
||||
@@ -43,12 +42,11 @@ public class TestFrameNavigate extends TestBase {
|
||||
void shouldContinueAfterClientRedirect() {
|
||||
server.setRoute("/frames/script.js", (httpExchange) -> {});
|
||||
String url = server.PREFIX + "/frames/child-redirect.html";
|
||||
try {
|
||||
TimeoutError e = assertThrows(TimeoutError.class, () -> {
|
||||
page.navigate(url, new Page.NavigateOptions().setTimeout(5000).setWaitUntil(NETWORKIDLE));
|
||||
} catch (TimeoutError e) {
|
||||
assertTrue(e.getMessage().contains("Timeout 5000ms exceeded."));
|
||||
assertTrue(e.getMessage().contains("navigating to \"" + url +"\", waiting until \"networkidle\""));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout 5000ms exceeded."));
|
||||
assertTrue(e.getMessage().contains("navigating to \"" + url +"\", waiting until \"networkidle\""));
|
||||
}
|
||||
|
||||
// TODO: not supported in sync api
|
||||
|
||||
@@ -24,8 +24,7 @@ import java.util.List;
|
||||
|
||||
import static com.microsoft.playwright.Utils.mapOf;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestGeolocation extends TestBase {
|
||||
@Test
|
||||
@@ -41,11 +40,10 @@ public class TestGeolocation extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldThrowWhenInvalidLongitude() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
context.setGeolocation(new Geolocation(10, 200));
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("geolocation.longitude: precondition -180 <= LONGITUDE <= 180 failed."));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("geolocation.longitude: precondition -180 <= LONGITUDE <= 180 failed."));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.microsoft.playwright.options.RequestOptions;
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
@@ -146,12 +148,8 @@ public class TestGlobalFetch extends TestBase {
|
||||
APIResponse response = request.get(server.PREFIX + "/simple.json");
|
||||
assertEquals("{\"foo\": \"bar\"}\n", response.text());
|
||||
request.dispose();
|
||||
try {
|
||||
response.body();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Response has been disposed"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> response.body());
|
||||
assertTrue(e.getMessage().contains("Response has been disposed"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -168,12 +166,8 @@ public class TestGlobalFetch extends TestBase {
|
||||
void shouldSupportGlobalTimeoutOption() {
|
||||
APIRequestContext request = playwright.request().newContext(new APIRequest.NewContextOptions().setTimeout(1));
|
||||
server.setRoute("/empty.html", exchange -> {});
|
||||
try {
|
||||
request.get(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Request timed out after 1ms"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> request.get(server.EMPTY_PAGE));
|
||||
assertTrue(e.getMessage().contains("Request timed out after 1ms"), e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@@ -265,12 +259,8 @@ public class TestGlobalFetch extends TestBase {
|
||||
assertEquals(0, body.length);
|
||||
assertEquals("", response.text());
|
||||
request.dispose();
|
||||
try {
|
||||
response.body();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Response has been disposed"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> response.body());
|
||||
assertTrue(e.getMessage().contains("Response has been disposed"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -321,4 +311,73 @@ public class TestGlobalFetch extends TestBase {
|
||||
}
|
||||
request.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnBodyForFailingRequests() {
|
||||
APIRequestContext request = playwright.request().newContext();
|
||||
for (String method : new String[] {"head", "put", "trace"}) {
|
||||
server.setRoute("/empty.html", exchange -> {
|
||||
exchange.getResponseHeaders().set("Content-type", "text/plain");
|
||||
exchange.sendResponseHeaders(404, 10);
|
||||
try (Writer writer = new OutputStreamWriter(exchange.getResponseBody())) {
|
||||
writer.write("Not found.");
|
||||
}
|
||||
});
|
||||
APIResponse response = request.fetch(server.EMPTY_PAGE, RequestOptions.create().setMethod(method));
|
||||
assertEquals(404, response.status());
|
||||
// HEAD response returns empty body in node http module.
|
||||
assertEquals("head".equals(method) ? "" : "Not found.", response.text());
|
||||
}
|
||||
request.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowAnErrorWhenMaxRedirectsIsExceeded() {
|
||||
server.setRedirect("/a/redirect1", "/b/c/redirect2");
|
||||
server.setRedirect("/b/c/redirect2", "/b/c/redirect3");
|
||||
server.setRedirect("/b/c/redirect3", "/b/c/redirect4");
|
||||
server.setRedirect("/b/c/redirect4", "/simple.json");
|
||||
|
||||
APIRequestContext request = playwright.request().newContext();
|
||||
for (String method : new String[] {"GET", "PUT", "POST", "OPTIONS", "HEAD", "PATCH"}) {
|
||||
for (int maxRedirects = 1; maxRedirects < 4; maxRedirects++) {
|
||||
int currMaxRedirects = maxRedirects;
|
||||
PlaywrightException exception = assertThrows(PlaywrightException.class,
|
||||
() -> request.fetch(server.PREFIX + "/a/redirect1",
|
||||
RequestOptions.create().setMethod(method).setMaxRedirects(currMaxRedirects)));
|
||||
assertTrue(exception.getMessage().contains("Max redirect count exceeded"), exception.getMessage());
|
||||
}
|
||||
}
|
||||
request.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldNotFollowRedirectsWhenMaxRedirectsIsSetTo0() {
|
||||
server.setRedirect("/a/redirect1", "/b/c/redirect2");
|
||||
server.setRedirect("/b/c/redirect2", "/simple.json");
|
||||
|
||||
APIRequestContext request = playwright.request().newContext();
|
||||
for (String method : new String[] {"GET", "PUT", "POST", "OPTIONS", "HEAD", "PATCH"}) {
|
||||
APIResponse response = request.fetch(server.PREFIX + "/a/redirect1",
|
||||
RequestOptions.create().setMethod(method).setMaxRedirects(0));
|
||||
assertEquals("/b/c/redirect2", response.headers().get("location"));
|
||||
assertEquals(302, response.status());
|
||||
}
|
||||
request.dispose();
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowAnErrorWhenMaxRedirectsIsLessThan0() {
|
||||
server.setRedirect("/a/redirect1", "/b/c/redirect2");
|
||||
server.setRedirect("/b/c/redirect2", "/simple.json");
|
||||
|
||||
APIRequestContext request = playwright.request().newContext();
|
||||
for (String method : new String[] {"GET", "PUT", "POST", "OPTIONS", "HEAD", "PATCH"}) {
|
||||
PlaywrightException exception = assertThrows(PlaywrightException.class,
|
||||
() -> request.fetch(server.PREFIX + "/a/redirect1",
|
||||
RequestOptions.create().setMethod(method).setMaxRedirects(-1)));
|
||||
assertTrue(exception.getMessage().contains("'maxRedirects' should be greater than or equal to '0'"), exception.getMessage());
|
||||
}
|
||||
request.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,14 +63,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void containsTextWRegexFail() {
|
||||
page.setContent("<div id=node>Text content</div>");
|
||||
Locator locator = page.locator("#node");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).containsText(Pattern.compile("ex2"), new LocatorAssertions.ContainsTextOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("ex2", e.getExpected().getStringRepresentation());
|
||||
assertEquals("Text content", e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Locator expected to contain regex"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("ex2", e.getExpected().getStringRepresentation());
|
||||
assertEquals("Text content", e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Locator expected to contain regex"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -112,14 +110,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void hasTextWRegexFail() {
|
||||
page.setContent("<div id=node>Text content</div>");
|
||||
Locator locator = page.locator("#node");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasText(Pattern.compile("Text 2"), new LocatorAssertions.HasTextOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("Text 2", e.getExpected().getStringRepresentation());
|
||||
assertEquals("Text content", e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have text matching regex"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("Text 2", e.getExpected().getStringRepresentation());
|
||||
assertEquals("Text content", e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have text matching regex"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -139,14 +135,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
page.setContent("<div id=node>Text content</div>");
|
||||
Locator locator = page.locator("#node");
|
||||
// Should normalize whitespace.
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasText("Text", new LocatorAssertions.HasTextOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("Text", e.getExpected().getStringRepresentation());
|
||||
assertEquals("Text content", e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have text"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("Text", e.getExpected().getStringRepresentation());
|
||||
assertEquals("Text content", e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have text"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -195,14 +189,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
page.setContent("<div></div>");
|
||||
Locator locator = page.locator("p");
|
||||
// Should normalize whitespace.
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).not().hasText(new String[] {}, new LocatorAssertions.HasTextOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("[]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("null", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to have text"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("[]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("null", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to have text"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -223,16 +215,14 @@ public class TestLocatorAssertions extends TestBase {
|
||||
page.evaluate("setTimeout(() => {\n" +
|
||||
" div.innerHTML = \"<p>Text 1</p><p>Text 2</p>\";\n" +
|
||||
"}, 100);");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
// Should normalize whitespace.
|
||||
assertThat(locator).hasText(new String[] {"Text 1", "Text 3", "Extra"}, new LocatorAssertions.HasTextOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("[Text 1, Text 3, Extra]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("[Text 1, Text 3]", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have text: [Text 1, Text 3, Extra]"), e.getMessage());
|
||||
assertTrue(e.getMessage().contains("Received: [Text 1, Text 3]"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("[Text 1, Text 3, Extra]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("[Text 1, Text 3]", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have text: [Text 1, Text 3, Extra]"), e.getMessage());
|
||||
assertTrue(e.getMessage().contains("Received: [Text 1, Text 3]"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -247,15 +237,13 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void hasTextWRegExArrayFail() {
|
||||
page.setContent("<div>Text 1</div><div>Text 3</div>");
|
||||
Locator locator = page.locator("div");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
// Should normalize whitespace.
|
||||
assertThat(locator).hasText(new Pattern[] {Pattern.compile( "Text 1"), Pattern.compile("Text \\d"), Pattern.compile("Extra")}, new LocatorAssertions.HasTextOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("[Text 1, Text \\d, Extra]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("[Text 1, Text 3]", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have text"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("[Text 1, Text \\d, Extra]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("[Text 1, Text 3]", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have text"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -269,14 +257,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void hasAttributeTextFail() {
|
||||
page.setContent("<div id=node>Text content</div>");
|
||||
Locator locator = page.locator("#node");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasAttribute("id", "foo", new LocatorAssertions.HasAttributeOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("foo", e.getExpected().getStringRepresentation());
|
||||
assertEquals("node", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have attribute 'id': foo\nReceived: node"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("foo", e.getExpected().getStringRepresentation());
|
||||
assertEquals("node", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have attribute 'id': foo\nReceived: node"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -290,14 +276,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void hasAttributeRegExpFail() {
|
||||
page.setContent("<div id=node>Text content</div>");
|
||||
Locator locator = page.locator("#node");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasAttribute("id", Pattern.compile(".Nod.."), new LocatorAssertions.HasAttributeOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals(".Nod..", e.getExpected().getStringRepresentation());
|
||||
assertEquals("node", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have attribute 'id' matching regex: .Nod..\nReceived: node"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals(".Nod..", e.getExpected().getStringRepresentation());
|
||||
assertEquals("node", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have attribute 'id' matching regex: .Nod..\nReceived: node"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -311,14 +295,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void hasClassTextFail() {
|
||||
page.setContent("<div class=\"bar baz\"></div>");
|
||||
Locator locator = page.locator("div");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasClass("foo bar baz", new LocatorAssertions.HasClassOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("foo bar baz", e.getExpected().getStringRepresentation());
|
||||
assertEquals("bar baz", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have class"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("foo bar baz", e.getExpected().getStringRepresentation());
|
||||
assertEquals("bar baz", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have class"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -332,14 +314,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void hasClassRegExpFail() {
|
||||
page.setContent("<div class=\"bar baz\"></div>");
|
||||
Locator locator = page.locator("div");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasClass(Pattern.compile("foo Z.*"), new LocatorAssertions.HasClassOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("foo Z.*", e.getExpected().getStringRepresentation());
|
||||
assertEquals("bar baz", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have class matching regex"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("foo Z.*", e.getExpected().getStringRepresentation());
|
||||
assertEquals("bar baz", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have class matching regex"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -353,14 +333,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void hasClassTextArrayFail() {
|
||||
page.setContent("<div class=\"foo\"></div><div class=\"bar\"></div><div class=\"baz\"></div>");
|
||||
Locator locator = page.locator("div");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasClass(new String[] {"foo", "bar", "missing"}, new LocatorAssertions.HasClassOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("[foo, bar, missing]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("[foo, bar, baz]", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have class"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("[foo, bar, missing]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("[foo, bar, baz]", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have class"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -374,14 +352,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void hasClassRegExpArrayFail() {
|
||||
page.setContent("<div class=\"foo\"></div><div class=\"bar\"></div><div class=\"baz\"></div>");
|
||||
Locator locator = page.locator("div");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasClass(new Pattern[] {Pattern.compile("fo.*"), Pattern.compile(".ar"), Pattern.compile("baz"), Pattern.compile("extra")}, new LocatorAssertions.HasClassOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("[fo.*, .ar, baz, extra]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("[foo, bar, baz]", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have class matching regex"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("[fo.*, .ar, baz, extra]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("[foo, bar, baz]", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have class matching regex"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -395,14 +371,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void hasCountFail() {
|
||||
page.setContent("<select><option>One</option><option>Two</option></select>");
|
||||
Locator locator = page.locator("option");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasCount(1, new LocatorAssertions.HasCountOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("1", e.getExpected().getStringRepresentation());
|
||||
assertEquals("2", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have count"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("1", e.getExpected().getStringRepresentation());
|
||||
assertEquals("2", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have count"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -424,14 +398,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void hasCSSFail() {
|
||||
page.setContent("<div id=node style='color: rgb(255, 0, 0)'>Text content</div>");
|
||||
Locator locator = page.locator("#node");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasCSS("color", "red", new LocatorAssertions.HasCSSOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("red", e.getExpected().getStringRepresentation());
|
||||
assertEquals("rgb(255, 0, 0)", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have CSS property 'color'"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("red", e.getExpected().getStringRepresentation());
|
||||
assertEquals("rgb(255, 0, 0)", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have CSS property 'color'"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -445,14 +417,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void hasCSSRegExFail() {
|
||||
page.setContent("<div id=node style='color: rgb(255, 0, 0)'>Text content</div>");
|
||||
Locator locator = page.locator("#node");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasCSS("color", Pattern.compile("red"), new LocatorAssertions.HasCSSOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("red", e.getExpected().getStringRepresentation());
|
||||
assertEquals("rgb(255, 0, 0)", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have CSS property 'color' matching regex"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("red", e.getExpected().getStringRepresentation());
|
||||
assertEquals("rgb(255, 0, 0)", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have CSS property 'color' matching regex"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -466,14 +436,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void hasIdFail() {
|
||||
page.setContent("<div id=node>Text content</div>");
|
||||
Locator locator = page.locator("#node");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasId("foo", new LocatorAssertions.HasIdOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("foo", e.getExpected().getStringRepresentation());
|
||||
assertEquals("node", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have ID"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("foo", e.getExpected().getStringRepresentation());
|
||||
assertEquals("node", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have ID"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -489,14 +457,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
page.setContent("<div id=node>Text content</div>");
|
||||
Locator locator = page.locator("#node");
|
||||
page.evalOnSelector("div", "e => e.foo = 2021");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasJSProperty("foo", 1, new LocatorAssertions.HasJSPropertyOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("1", e.getExpected().getStringRepresentation());
|
||||
assertEquals("2021", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have JavaScript property 'foo'"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("1", e.getExpected().getStringRepresentation());
|
||||
assertEquals("2021", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have JavaScript property 'foo'"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -504,28 +470,24 @@ public class TestLocatorAssertions extends TestBase {
|
||||
page.setContent("<div id=node>Text content</div>");
|
||||
Locator locator = page.locator("#node");
|
||||
page.evalOnSelector("div", "e => e.foo = { a: 1, b: 'string' }");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasJSProperty("foo", mapOf("a", 2), new LocatorAssertions.HasJSPropertyOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("{a=2}", e.getExpected().getStringRepresentation());
|
||||
assertEquals("{a=1, b=string}", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have JavaScript property 'foo'"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("{a=2}", e.getExpected().getStringRepresentation());
|
||||
assertEquals("{a=1, b=string}", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have JavaScript property 'foo'"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasJSPropertyStringFail() {
|
||||
page.setContent("<div id=node>Text content</div>");
|
||||
Locator locator = page.locator("#node");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasJSProperty("id", "foo", new LocatorAssertions.HasJSPropertyOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("foo", e.getExpected().getStringRepresentation());
|
||||
assertEquals("node", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have JavaScript property 'id'"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("foo", e.getExpected().getStringRepresentation());
|
||||
assertEquals("node", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have JavaScript property 'id'"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -541,14 +503,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
page.setContent("<input id=node></input>");
|
||||
Locator locator = page.locator("#node");
|
||||
locator.fill("Text content");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasValue("Text2", new LocatorAssertions.HasValueOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("Text2", e.getExpected().getStringRepresentation());
|
||||
assertEquals("Text content", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have value"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("Text2", e.getExpected().getStringRepresentation());
|
||||
assertEquals("Text content", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have value"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -572,14 +532,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
page.setContent("<input id=node></input>");
|
||||
Locator locator = page.locator("#node");
|
||||
locator.fill("Text content");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasValue(Pattern.compile("Text2"), new LocatorAssertions.HasValueOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("Text2", e.getExpected().getStringRepresentation());
|
||||
assertEquals("Text content", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have value matching regex"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("Text2", e.getExpected().getStringRepresentation());
|
||||
assertEquals("Text content", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have value matching regex"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -615,14 +573,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
" </select>");
|
||||
Locator locator = page.locator("select");
|
||||
locator.selectOption(new String[] {"RR", "GG"});
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasValues(new String[]{"R", "G"}, new LocatorAssertions.HasValuesOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("[R, G]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("[RR, GG]", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have values"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("[R, G]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("[RR, GG]", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have values"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -646,14 +602,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
" </select>");
|
||||
Locator locator = page.locator("select");
|
||||
locator.selectOption(new String[] {"B"}, new Locator.SelectOptionOptions().setTimeout(1000));
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).hasValues(new Pattern[]{ Pattern.compile("R"), Pattern.compile("G")});
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("[R, G]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("[B]", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have values matching regex"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("[R, G]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("[B]", e.getActual().getStringRepresentation());
|
||||
assertTrue(e.getMessage().contains("Locator expected to have values matching regex"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -665,24 +619,20 @@ public class TestLocatorAssertions extends TestBase {
|
||||
" </select>");
|
||||
Locator locator = page.locator("select");
|
||||
locator.selectOption(new String[] {"B"});
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
assertThat(locator).hasValues(new Pattern[]{ Pattern.compile("R"), Pattern.compile("G")});
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Not a select element with a multiple attribute"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Not a select element with a multiple attribute"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void hasValuesFailsWhenNotASelectElement() {
|
||||
page.setContent("<input value=\"foo\" />");
|
||||
Locator locator = page.locator("input");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
assertThat(locator).hasValues(new Pattern[]{ Pattern.compile("R"), Pattern.compile("G")}, new LocatorAssertions.HasValuesOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Not a select element with a multiple attribute"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Not a select element with a multiple attribute"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -696,28 +646,24 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void isCheckedFail() {
|
||||
page.setContent("<input type=checkbox></input>");
|
||||
Locator locator = page.locator("input");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).isChecked(new LocatorAssertions.IsCheckedOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be checked"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be checked"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void notIsCheckedFail() {
|
||||
page.setContent("<input type=checkbox checked></input>");
|
||||
Locator locator = page.locator("input");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).not().isChecked(new LocatorAssertions.IsCheckedOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be checked"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be checked"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -738,28 +684,24 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void isDisabledFail() {
|
||||
page.setContent("<button>Text</button>");
|
||||
Locator locator = page.locator("button");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).isDisabled(new LocatorAssertions.IsDisabledOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be disabled"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be disabled"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void notIsDisabledFail() {
|
||||
page.setContent("<button disabled>Text</button>");
|
||||
Locator locator = page.locator("button");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).not().isDisabled(new LocatorAssertions.IsDisabledOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be disabled"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be disabled"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -773,30 +715,53 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void isEditableFail() {
|
||||
page.setContent("<input disabled></input>");
|
||||
Locator locator = page.locator("input");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).isEditable(new LocatorAssertions.IsEditableOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be editable"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be editable"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void notIsEditableFail() {
|
||||
page.setContent("<input></input>");
|
||||
Locator locator = page.locator("input");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).not().isEditable(new LocatorAssertions.IsEditableOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be editable"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be editable"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEditableWithNot() {
|
||||
page.setContent("<input readonly></input>");
|
||||
Locator locator = page.locator("input");
|
||||
assertThat(locator).not().isEditable();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEditableWithEditableTrue() {
|
||||
page.setContent("<input></input>");
|
||||
Locator locator = page.locator("input");
|
||||
assertThat(locator).isEditable(new LocatorAssertions.IsEditableOptions().setEditable(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEditableWithEditableFalse() {
|
||||
page.setContent("<input readonly></input>");
|
||||
Locator locator = page.locator("input");
|
||||
assertThat(locator).isEditable(new LocatorAssertions.IsEditableOptions().setEditable(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEditableWithNotAndEditableFalse() {
|
||||
page.setContent("<input></input>");
|
||||
Locator locator = page.locator("input");
|
||||
assertThat(locator).not().isEditable(new LocatorAssertions.IsEditableOptions().setEditable(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEmptyPass() {
|
||||
@@ -809,28 +774,24 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void isEmptyFail() {
|
||||
page.setContent("<input value=text></input>");
|
||||
Locator locator = page.locator("input");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).isEmpty(new LocatorAssertions.IsEmptyOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be empty"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be empty"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void notIsEmptyFail() {
|
||||
page.setContent("<input></input>");
|
||||
Locator locator = page.locator("input");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).not().isEmpty(new LocatorAssertions.IsEmptyOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be empty"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be empty"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -844,28 +805,65 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void isEnabledFail() {
|
||||
page.setContent("<button disabled>Text</button>");
|
||||
Locator locator = page.locator("button");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).isEnabled(new LocatorAssertions.IsEnabledOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be enabled"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be enabled"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void notIsEnabledFail() {
|
||||
page.setContent("<button>Text</button>");
|
||||
Locator locator = page.locator("button");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).not().isEnabled(new LocatorAssertions.IsEnabledOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be enabled"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be enabled"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEnabledTrue() {
|
||||
page.setContent("<button>Text</button>");
|
||||
Locator locator = page.locator("button");
|
||||
assertThat(locator).isEnabled(new LocatorAssertions.IsEnabledOptions().setEnabled(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEnabledFalse() {
|
||||
page.setContent("<button disabled>Text</button>");
|
||||
Locator locator = page.locator("button");
|
||||
assertThat(locator).isEnabled(new LocatorAssertions.IsEnabledOptions().setEnabled(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEnabledEventually() {
|
||||
page.setContent("<button disabled>Text</button>");
|
||||
Locator locator = page.locator("button");
|
||||
locator.evaluate("e => setTimeout(() => {\n" +
|
||||
" e.removeAttribute('disabled');\n" +
|
||||
"}, 500);\n");
|
||||
assertThat(locator).isEnabled();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEnabledEventuallyWithNot() {
|
||||
page.setContent("<button>Text</button>");
|
||||
Locator locator = page.locator("button");
|
||||
locator.evaluate("e => setTimeout(() => {\n" +
|
||||
" e.setAttribute('disabled', '');\n" +
|
||||
"}, 500);\n");
|
||||
assertThat(locator).not().isEnabled();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isEnabledWithNotAndEnabledFalse() {
|
||||
page.setContent("<button>Text</button>");
|
||||
Locator locator = page.locator("button");
|
||||
assertThat(locator).not().isEnabled(new LocatorAssertions.IsEnabledOptions().setEnabled(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -880,14 +878,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void isFocusedFail() {
|
||||
page.setContent("<input></input>");
|
||||
Locator locator = page.locator("input");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).isFocused(new LocatorAssertions.IsFocusedOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be focused"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be focused"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -895,14 +891,12 @@ public class TestLocatorAssertions extends TestBase {
|
||||
page.setContent("<input></input>");
|
||||
Locator locator = page.locator("input");
|
||||
locator.focus();
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).not().isFocused(new LocatorAssertions.IsFocusedOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be focused"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be focused"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -916,28 +910,24 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void isHiddenFail() {
|
||||
page.setContent("<button></button>");
|
||||
Locator locator = page.locator("button");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).isHidden(new LocatorAssertions.IsHiddenOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be hidden"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be hidden"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void notIsHiddenFail() {
|
||||
page.setContent("<button style='display: none'></button>");
|
||||
Locator locator = page.locator("button");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).not().isHidden(new LocatorAssertions.IsHiddenOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be hidden"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be hidden"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -951,28 +941,65 @@ public class TestLocatorAssertions extends TestBase {
|
||||
void isVisibleFail() {
|
||||
page.setContent("<input style='display: none'></input>");
|
||||
Locator locator = page.locator("input");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).isVisible(new LocatorAssertions.IsVisibleOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be visible"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected to be visible"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void notIsVisibleFail() {
|
||||
page.setContent("<input></input>");
|
||||
Locator locator = page.locator("input");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(locator).not().isVisible(new LocatorAssertions.IsVisibleOptions().setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be visible"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertNull(e.getExpected());
|
||||
assertNull(e.getActual());
|
||||
assertTrue(e.getMessage().contains("Locator expected not to be visible"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void isVisibleWithTrue() {
|
||||
page.setContent("<button>hello</button>");
|
||||
Locator locator = page.locator("button");
|
||||
assertThat(locator).isVisible(new LocatorAssertions.IsVisibleOptions().setVisible(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isVisibleWithFalse() {
|
||||
page.setContent("<button hidden>hello</button>");
|
||||
Locator locator = page.locator("button");
|
||||
assertThat(locator).isVisible(new LocatorAssertions.IsVisibleOptions().setVisible(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isVisibleWithNotAndFalse() {
|
||||
page.setContent("<button>hello</button>");
|
||||
Locator locator = page.locator("button");
|
||||
assertThat(locator).not().isVisible(new LocatorAssertions.IsVisibleOptions().setVisible(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
void isVisibleEventually() {
|
||||
page.setContent("<div></div>");
|
||||
Locator locator = page.locator("span");
|
||||
page.evalOnSelector("div", "div => setTimeout(() => {\n" +
|
||||
" div.innerHTML = '<span>Hello</span>';\n" +
|
||||
" }, 10);");
|
||||
assertThat(locator).isVisible();
|
||||
}
|
||||
|
||||
@Test
|
||||
void isVisibleEventuallyWithNot() {
|
||||
page.setContent("<div><span>Hello</span></div>");
|
||||
Locator locator = page.locator("span");
|
||||
page.evalOnSelector("span", "span => setTimeout(() => {\n" +
|
||||
" span.textContent = '';\n" +
|
||||
" }, 10);");
|
||||
assertThat(locator).not().isVisible();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -61,19 +61,13 @@ public class TestLocatorConvenience extends TestBase {
|
||||
Locator locator = page.locator("#input");
|
||||
assertEquals("input value", locator.inputValue());
|
||||
|
||||
try {
|
||||
page.inputValue("#inner");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Node is not an <input>, <textarea> or <select> element"), e.getMessage());
|
||||
}
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.inputValue("#inner"));
|
||||
assertTrue(e.getMessage().contains("Node is not an <input>, <textarea> or <select> element"), e.getMessage());
|
||||
e = assertThrows(PlaywrightException.class, () -> {
|
||||
Locator locator2 = page.locator("#inner");
|
||||
locator2.inputValue();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Node is not an <input>, <textarea> or <select> element"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Node is not an <input>, <textarea> or <select> element"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -95,19 +89,12 @@ public class TestLocatorConvenience extends TestBase {
|
||||
@Test
|
||||
void innerTextShouldThrow() {
|
||||
page.setContent("<svg>text</svg>");
|
||||
try {
|
||||
page.innerText("svg");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Node is not an HTMLElement"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.innerText("svg"));
|
||||
assertTrue(e.getMessage().contains("Node is not an HTMLElement"), e.getMessage());
|
||||
|
||||
Locator locator = page.locator("svg");
|
||||
try {
|
||||
locator.innerText();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Node is not an HTMLElement"), e.getMessage());
|
||||
}
|
||||
e = assertThrows(PlaywrightException.class, () -> locator.innerText());
|
||||
assertTrue(e.getMessage().contains("Node is not an HTMLElement"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -184,12 +171,8 @@ public class TestLocatorConvenience extends TestBase {
|
||||
element.evaluate("input => input.checked = false");
|
||||
assertFalse(element.isChecked());
|
||||
assertFalse(page.isChecked("input"));
|
||||
try {
|
||||
page.isChecked("div");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Not a checkbox or radio button"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.isChecked("div"));
|
||||
assertTrue(e.getMessage().contains("Not a checkbox or radio button"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -99,12 +99,10 @@ public class TestLocatorFrame extends TestBase {
|
||||
@Test
|
||||
void shouldWaitForFrame() {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.frameLocator("iframe").locator("span").click(new Locator.ClickOptions().setTimeout(300));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("waiting for frame \"iframe\""), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("waiting for frame \"iframe\""), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -206,13 +204,9 @@ public class TestLocatorFrame extends TestBase {
|
||||
routeIframe(page);
|
||||
page.setContent("<div></div>");
|
||||
Locator button = page.frameLocator("div").locator("button");
|
||||
try {
|
||||
button.waitFor();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("<div></div>"), e.getMessage());
|
||||
assertTrue(e.getMessage().contains("<iframe> was expected"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> button.waitFor());
|
||||
assertTrue(e.getMessage().contains("<div></div>"), e.getMessage());
|
||||
assertTrue(e.getMessage().contains("<iframe> was expected"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -231,12 +225,8 @@ public class TestLocatorFrame extends TestBase {
|
||||
routeAmbiguous(page);
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
Locator button = page.locator("body").frameLocator("iframe").locator("button");
|
||||
try {
|
||||
button.waitFor();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Error: strict mode violation: \"body >> iframe\" resolved to 3 elements"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> button.waitFor());
|
||||
assertTrue(e.getMessage().contains("Error: strict mode violation: \"body >> iframe\" resolved to 3 elements"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -60,12 +60,10 @@ public class TestLocatorMisc extends TestBase{
|
||||
page.locator("button", new Page.LocatorOptions().setHas(page.locator("text=Драматург")))
|
||||
};
|
||||
for (Locator locator: locators) {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
locator.click(new Locator.ClickOptions().setTimeout(100));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Драматург"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Драматург"), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,12 +67,8 @@ public class TestNetworkResponse extends TestBase {
|
||||
assertNotNull(redirectedFrom);
|
||||
Response redirected = redirectedFrom.response();
|
||||
assertEquals(302, redirected.status());
|
||||
try {
|
||||
redirected.text();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Response body is unavailable for redirect responses"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> redirected.text());
|
||||
assertTrue(e.getMessage().contains("Response body is unavailable for redirect responses"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -35,14 +35,12 @@ public class TestPageAssertions extends TestBase {
|
||||
@Test
|
||||
void hasURLTextFail() {
|
||||
page.navigate("data:text/html,<div>B</div>");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(page).hasURL("foo", new PageAssertions.HasURLOptions().setTimeout(1_000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("foo", e.getExpected().getValue());
|
||||
assertEquals("data:text/html,<div>B</div>", e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Page URL expected to be"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("foo", e.getExpected().getValue());
|
||||
assertEquals("data:text/html,<div>B</div>", e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Page URL expected to be"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -69,14 +67,12 @@ public class TestPageAssertions extends TestBase {
|
||||
@Test
|
||||
void hasURLRegexFail() {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(page).hasURL(Pattern.compile(".*foo.*"), new PageAssertions.HasURLOptions().setTimeout(1_000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals(".*foo.*", e.getExpected().getStringRepresentation());
|
||||
assertEquals(server.EMPTY_PAGE, e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Page URL expected to match regex"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals(".*foo.*", e.getExpected().getStringRepresentation());
|
||||
assertEquals(server.EMPTY_PAGE, e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Page URL expected to match regex"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -100,14 +96,12 @@ public class TestPageAssertions extends TestBase {
|
||||
@Test
|
||||
void hasTitleTextFail() {
|
||||
page.navigate(server.PREFIX + "/title.html");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(page).hasTitle("foo", new PageAssertions.HasTitleOptions().setTimeout(1_000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("foo", e.getExpected().getValue());
|
||||
assertEquals("Woof-Woof", e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Page title expected to be: foo\nReceived: Woof-Woof"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("foo", e.getExpected().getValue());
|
||||
assertEquals("Woof-Woof", e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Page title expected to be: foo\nReceived: Woof-Woof"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -119,14 +113,12 @@ public class TestPageAssertions extends TestBase {
|
||||
@Test
|
||||
void hasTitleRegexFail() {
|
||||
page.navigate(server.PREFIX + "/title.html");
|
||||
try {
|
||||
AssertionFailedError e = assertThrows(AssertionFailedError.class, () -> {
|
||||
assertThat(page).hasTitle(Pattern.compile("^foo[AB]"), new PageAssertions.HasTitleOptions().setTimeout(1_000));
|
||||
fail("did not throw");
|
||||
} catch (AssertionFailedError e) {
|
||||
assertEquals("^foo[AB]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("Woof-Woof", e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Page title expected to match regex: ^foo[AB]\nReceived: Woof-Woof"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertEquals("^foo[AB]", e.getExpected().getStringRepresentation());
|
||||
assertEquals("Woof-Woof", e.getActual().getValue());
|
||||
assertTrue(e.getMessage().contains("Page title expected to match regex: ^foo[AB]\nReceived: Woof-Woof"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -35,12 +35,10 @@ public class TestPageBasic extends TestBase {
|
||||
void shouldRejectAllPromisesWhenPageIsClosed() {
|
||||
Page newPage = context.newPage();
|
||||
newPage.close();
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
newPage.evaluate("() => new Promise(r => {})");
|
||||
fail("evaluate should throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Target page, context or browser has been closed"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -108,21 +106,17 @@ public class TestPageBasic extends TestBase {
|
||||
@Test
|
||||
void shouldTerminateNetworkWaiters() {
|
||||
Page newPage = context.newPage();
|
||||
try {
|
||||
PlaywrightException e1 = assertThrows(PlaywrightException.class, () -> {
|
||||
newPage.waitForResponse("**", () -> {
|
||||
try {
|
||||
PlaywrightException e2 = assertThrows(PlaywrightException.class, () -> {
|
||||
newPage.waitForRequest(server.EMPTY_PAGE, () -> newPage.close());
|
||||
fail("waitForRequest() should throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Page closed"));
|
||||
assertFalse(e.getMessage().contains("Timeout"));
|
||||
}
|
||||
});
|
||||
assertTrue(e2.getMessage().contains("Page closed"));
|
||||
assertFalse(e2.getMessage().contains("Timeout"));
|
||||
});
|
||||
fail("waitForResponse() should throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Page closed"));
|
||||
assertFalse(e.getMessage().contains("Timeout"));
|
||||
}
|
||||
});
|
||||
assertTrue(e1.getMessage().contains("Page closed"));
|
||||
assertFalse(e1.getMessage().contains("Timeout"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -19,12 +19,12 @@ package com.microsoft.playwright;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.condition.DisabledIf;
|
||||
|
||||
import java.time.*;
|
||||
import java.util.Map;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.Date;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.time.ZonedDateTime;
|
||||
|
||||
import static com.microsoft.playwright.Utils.mapOf;
|
||||
import static java.util.Arrays.asList;
|
||||
@@ -157,15 +157,13 @@ public class TestPageEvaluate extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldThrowWhenEvaluationTriggersReload() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.evaluate("() => {\n" +
|
||||
" location.reload();\n" +
|
||||
" return new Promise(() => { });\n" +
|
||||
"}");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("navigation"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("navigation"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -208,32 +206,20 @@ public class TestPageEvaluate extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldRejectPromiseWithException() {
|
||||
try {
|
||||
page.evaluate("() => not_existing_object.property");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("not_existing_object"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.evaluate("() => not_existing_object.property"));
|
||||
assertTrue(e.getMessage().contains("not_existing_object"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSupportThrownStringsAsErrorMessages() {
|
||||
try {
|
||||
page.evaluate("() => { throw 'qwerty'; }");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("qwerty"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.evaluate("() => { throw 'qwerty'; }"));
|
||||
assertTrue(e.getMessage().contains("qwerty"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldSupportThrownNumbersAsErrorMessages() {
|
||||
try {
|
||||
page.evaluate("() => { throw 100500; }");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("100500"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.evaluate("() => { throw 100500; }"));
|
||||
assertTrue(e.getMessage().contains("100500"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -357,14 +343,12 @@ public class TestPageEvaluate extends TestBase {
|
||||
@Test
|
||||
void shouldBeAbleToThrowATrickyError() {
|
||||
String errorText = "My error";
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.evaluate("errorText => {\n" +
|
||||
" throw new Error(errorText);\n" +
|
||||
"}", errorText);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains(errorText));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains(errorText));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -399,12 +383,8 @@ public class TestPageEvaluate extends TestBase {
|
||||
ElementHandle element = page.querySelector("section");
|
||||
assertNotNull(element);
|
||||
element.dispose();
|
||||
try {
|
||||
page.evaluate("e => e.textContent", element);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("JSHandle is disposed"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.evaluate("e => e.textContent", element));
|
||||
assertTrue(e.getMessage().contains("JSHandle is disposed"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -418,7 +398,7 @@ public class TestPageEvaluate extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldThrowANiceErrorAfterANavigation() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForNavigation(() -> {
|
||||
page.evaluate("() => {\n" +
|
||||
" const promise = new Promise(f => window['__resolve'] = f);\n" +
|
||||
@@ -427,9 +407,8 @@ public class TestPageEvaluate extends TestBase {
|
||||
" return promise;\n" +
|
||||
"}");
|
||||
});
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("navigation"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("navigation"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -478,14 +457,12 @@ public class TestPageEvaluate extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldThrowErrorWithDetailedInformationOnExceptionInsidePromise() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.evaluate("() => new Promise(() => {\n" +
|
||||
" throw new Error('Error in promise');\n" +
|
||||
"})");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Error in promise"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Error in promise"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -523,7 +500,7 @@ public class TestPageEvaluate extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldRespectUseStrictExpression() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.evaluate("() => {\n" +
|
||||
" 'use strict';\n" +
|
||||
" // @ts-ignore\n" +
|
||||
@@ -531,10 +508,8 @@ public class TestPageEvaluate extends TestBase {
|
||||
" // @ts-ignore\n" +
|
||||
" return variableY;\n" +
|
||||
"}");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("variableY"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("variableY"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -544,12 +519,8 @@ public class TestPageEvaluate extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldNotLeakHandles() {
|
||||
try {
|
||||
page.evaluate("handles.length");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains(" handles"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.evaluate("handles.length"));
|
||||
assertTrue(e.getMessage().contains(" handles"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -561,16 +532,13 @@ public class TestPageEvaluate extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldEvaluateException() {
|
||||
try {
|
||||
page.evaluate("() => {\n" +
|
||||
" return (function functionOnStack() {\n" +
|
||||
" return new Error('error message');\n" +
|
||||
" })();\n" +
|
||||
"}");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Error: error message"));
|
||||
assertTrue(e.getMessage().contains("functionOnStack"));
|
||||
}
|
||||
String result = (String) page.evaluate("() => {\n" +
|
||||
" return (function functionOnStack() {\n" +
|
||||
" return new Error('error message');\n" +
|
||||
" })();\n" +
|
||||
"}");
|
||||
assertTrue(result.contains("Error: error message"));
|
||||
assertTrue(result.contains("functionOnStack"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -661,4 +629,13 @@ public class TestPageEvaluate extends TestBase {
|
||||
assertEquals(1, map.size());
|
||||
assertTrue(map == map.get("b"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldAcceptParameter() {
|
||||
Instant instant = Instant.now();
|
||||
LocalDateTime localDateTime = instant.atZone(ZoneId.systemDefault()).toLocalDateTime();
|
||||
Object object = page.evaluate("p => p", localDateTime);
|
||||
assertTrue(object instanceof Date);
|
||||
assertEquals(Date.from(instant), object);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,12 +196,10 @@ public class TestPageExposeFunction extends TestBase {
|
||||
@Test
|
||||
void shouldThrowForDuplicateRegistrations() {
|
||||
page.exposeFunction("foo", args -> null);
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.exposeFunction("foo", args -> null);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Function \"foo\" has been already registered"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Function \"foo\" has been already registered"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -218,14 +216,12 @@ public class TestPageExposeFunction extends TestBase {
|
||||
assertEquals(17, page.evaluate("async function() {\n" +
|
||||
" return window['logme'](undefined, undefined, undefined);\n" +
|
||||
"}"));
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.evaluate("async function() {\n" +
|
||||
" return window['logme'](1, 2);\n" +
|
||||
"}");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("exposeBindingHandle supports a single argument, 2 received"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("exposeBindingHandle supports a single argument, 2 received"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -43,12 +43,8 @@ public class TestPageFill extends TestBase {
|
||||
page.navigate(server.PREFIX + "/input/textarea.html");
|
||||
for (String type : new String[]{"button", "checkbox", "file", "image", "radio", "reset", "submit"}) {
|
||||
page.evalOnSelector("input", "(input, type) => input.setAttribute('type', type)", type);
|
||||
try {
|
||||
page.fill("input", "");
|
||||
fail("fill should throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("input of type \"" + type + "\" cannot be filled"), "type = " + type + e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.fill("input", ""));
|
||||
assertTrue(e.getMessage().contains("input of type \"" + type + "\" cannot be filled"), "type = " + type + e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,24 +58,14 @@ public class TestPageFill extends TestBase {
|
||||
@Test
|
||||
void shouldThrowOnIncorrectRangeValue() {
|
||||
page.setContent("<input type=range min=0 max=100 value=50>");
|
||||
try {
|
||||
page.fill("input", "foo");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Malformed value"), e.getMessage());
|
||||
}
|
||||
try {
|
||||
page.fill("input", "200");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Malformed value"), e.getMessage());
|
||||
}
|
||||
try {
|
||||
page.fill("input", "15.43");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Malformed value"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.fill("input", "foo"));
|
||||
assertTrue(e.getMessage().contains("Malformed value"), e.getMessage());
|
||||
|
||||
e = assertThrows(PlaywrightException.class, () -> page.fill("input", "200"));
|
||||
assertTrue(e.getMessage().contains("Malformed value"), e.getMessage());
|
||||
|
||||
e = assertThrows(PlaywrightException.class, () -> page.fill("input", "15.43"));
|
||||
assertTrue(e.getMessage().contains("Malformed value"), e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
@@ -105,12 +91,8 @@ public class TestPageFill extends TestBase {
|
||||
@DisabledIf(value="com.microsoft.playwright.TestBase#isWebKit", disabledReason="skip")
|
||||
void shouldThrowOnIncorrectDate() {
|
||||
page.setContent("<input type=date>");
|
||||
try {
|
||||
page.fill("input", "2020-13-05");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Malformed value"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.fill("input", "2020-13-05"));
|
||||
assertTrue(e.getMessage().contains("Malformed value"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -124,12 +106,8 @@ public class TestPageFill extends TestBase {
|
||||
@DisabledIf(value="com.microsoft.playwright.TestBase#isWebKit", disabledReason="skip")
|
||||
void shouldThrowOnIncorrectTime() {
|
||||
page.setContent("<input type=time>");
|
||||
try {
|
||||
page.fill("input", "25:05");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Malformed value"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.fill("input", "25:05"));
|
||||
assertTrue(e.getMessage().contains("Malformed value"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -143,12 +121,8 @@ public class TestPageFill extends TestBase {
|
||||
@EnabledIf(value="com.microsoft.playwright.TestBase#isChromium", disabledReason="skip")
|
||||
void shouldThrowOnIncorrectDatetimeLocal() {
|
||||
page.setContent("<input type=datetime-local>");
|
||||
try {
|
||||
page.fill("input", "abc");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Malformed value"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.fill("input", "abc"));
|
||||
assertTrue(e.getMessage().contains("Malformed value"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -188,12 +162,8 @@ public class TestPageFill extends TestBase {
|
||||
@Test
|
||||
void shouldThrowWhenElementIsNotAnInputTextareaOrContenteditable() {
|
||||
page.navigate(server.PREFIX + "/input/textarea.html");
|
||||
try {
|
||||
page.fill("body", "");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Element is not an <input>"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.fill("body", ""));
|
||||
assertTrue(e.getMessage().contains("Element is not an <input>"));
|
||||
}
|
||||
|
||||
void shouldThrowIfPassedANonStringValue() {
|
||||
@@ -252,12 +222,8 @@ public class TestPageFill extends TestBase {
|
||||
@Test
|
||||
void shouldNotBeAbleToFillTextIntoTheInputTypeNumber() {
|
||||
page.setContent("<input id='input' type='number'></input>");
|
||||
try {
|
||||
page.fill("input", "abc");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Cannot type text into input[type=number]"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.fill("input", "abc"));
|
||||
assertTrue(e.getMessage().contains("Cannot type text into input[type=number]"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -295,24 +295,14 @@ public class TestPageKeyboard extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldThrowOnUnknownKeys() {
|
||||
try {
|
||||
page.keyboard().press("NotARealKey");
|
||||
fail("did not throw");
|
||||
} catch (Exception e) {
|
||||
assertTrue(e.getMessage().contains("Unknown key: \"NotARealKey\""), "Expecting Exception: " + e.getMessage() + " contain: Unknown key: \"NotARealKey\"");
|
||||
}
|
||||
try {
|
||||
page.keyboard().press("ё");
|
||||
fail("did not throw");
|
||||
} catch (Exception e) {
|
||||
assertTrue(e.getMessage().contains("Unknown key: \"ё\""), "Expecting Exception: " + e.getMessage() + " contain: Unknown key: \"ё\"");
|
||||
}
|
||||
try {
|
||||
page.keyboard().press("😊");
|
||||
fail("did not throw");
|
||||
} catch (Exception e) {
|
||||
assertTrue(e.getMessage().contains("Unknown key: \"😊\""), "Expecting Exception: " + e.getMessage() + " contain: Unknown key: \"😊\"");
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.keyboard().press("NotARealKey"));
|
||||
assertTrue(e.getMessage().contains("Unknown key: \"NotARealKey\""), "Expecting Exception: " + e.getMessage() + " contain: Unknown key: \"NotARealKey\"");
|
||||
|
||||
e = assertThrows(PlaywrightException.class, () -> page.keyboard().press("ё"));
|
||||
assertTrue(e.getMessage().contains("Unknown key: \"ё\""), "Expecting Exception: " + e.getMessage() + " contain: Unknown key: \"ё\"");
|
||||
|
||||
e = assertThrows(PlaywrightException.class, () -> page.keyboard().press("😊"));
|
||||
assertTrue(e.getMessage().contains("Unknown key: \"😊\""), "Expecting Exception: " + e.getMessage() + " contain: Unknown key: \"😊\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -52,34 +52,28 @@ public class TestPageLocatorQuery extends TestBase {
|
||||
@Test
|
||||
void shouldThrowOnCaptureWNth() {
|
||||
page.setContent("<section><div><p>A</p></div></section>");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.locator("*css=div >> p").nth(1).click();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Can't query n-th element"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Can't query n-th element"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowOnDueToStrictness() {
|
||||
page.setContent("<div>A</div><div>B</div>");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.locator("div").isVisible();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("strict mode violation"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("strict mode violation"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowOnDueToStrictness2() {
|
||||
page.setContent("<select><option>One</option><option>Two</option></select>");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.locator("option").evaluate("e => {}");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("strict mode violation"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("strict mode violation"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -132,17 +132,13 @@ public class TestPageNavigate extends TestBase {
|
||||
exchange.sendResponseHeaders(204, -1);
|
||||
exchange.getResponseBody().close();
|
||||
});
|
||||
try {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
if (isChromium())
|
||||
assertTrue(e.getMessage().contains("net::ERR_ABORTED"));
|
||||
else if (isWebKit())
|
||||
assertTrue(e.getMessage().contains("Aborted: 204 No Content"));
|
||||
else
|
||||
assertTrue(e.getMessage().contains("NS_BINDING_ABORTED"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE));
|
||||
if (isChromium())
|
||||
assertTrue(e.getMessage().contains("net::ERR_ABORTED"));
|
||||
else if (isWebKit())
|
||||
assertTrue(e.getMessage().contains("Aborted: 204 No Content"));
|
||||
else
|
||||
assertTrue(e.getMessage().contains("NS_BINDING_ABORTED"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -72,13 +72,9 @@ public class TestPageRequestContinue extends TestBase {
|
||||
route.resume();
|
||||
done[0] = true;
|
||||
});
|
||||
try {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Navigation failed because page was closed") ||
|
||||
e.getMessage().contains("frame was detached"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE));
|
||||
assertTrue(e.getMessage().contains("Navigation failed because page was closed") ||
|
||||
e.getMessage().contains("frame was detached"), e.getMessage());
|
||||
assertTrue(done[0]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.microsoft.playwright;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -106,12 +107,7 @@ public class TestPageRequestFallback extends TestBase {
|
||||
page.route("**/empty.html", route -> {
|
||||
route.fallback();
|
||||
});
|
||||
try {
|
||||
Response response = page.navigate(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
assertEquals("fulfilled", response.text());
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE));
|
||||
assertFalse(failed[0]);
|
||||
}
|
||||
|
||||
@@ -132,13 +128,16 @@ public class TestPageRequestFallback extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldChainOnce() {
|
||||
page.route("**/empty.html", route -> {
|
||||
boolean didFulfill[] = {false};
|
||||
page.route("**/title.html", route -> {
|
||||
route.fulfill(new Route.FulfillOptions().setStatus(200).setBody("fulfilled one"));
|
||||
didFulfill[0] = true;
|
||||
}, new Page.RouteOptions().setTimes(1));
|
||||
page.route("**/empty.html", route -> {
|
||||
page.route("**/title.html", route -> {
|
||||
route.fallback();
|
||||
}, new Page.RouteOptions().setTimes(1));
|
||||
Response response = page.navigate(server.EMPTY_PAGE);
|
||||
Response response = page.navigate(server.PREFIX + "/title.html");
|
||||
assertTrue(didFulfill[0]);
|
||||
assertEquals("fulfilled one", response.text());
|
||||
}
|
||||
|
||||
@@ -229,7 +228,8 @@ public class TestPageRequestFallback extends TestBase {
|
||||
page.route("**/foo", route -> route.fallback(new Route.FallbackOptions().setUrl(server.PREFIX + "/global-var.html")));
|
||||
Response response = page.waitForResponse("**/*", () -> page.navigate(server.PREFIX + "/foo"));
|
||||
assertEquals(server.PREFIX + "/global-var.html", url[0]);
|
||||
assertEquals(server.PREFIX + "/foo", response.url());
|
||||
assertEquals(server.PREFIX + "/global-var.html", response.url());
|
||||
assertEquals(server.PREFIX + "/global-var.html", response.request().url());
|
||||
assertEquals(123, page.evaluate("() => window['globalVar']"));
|
||||
assertEquals("GET", request.get().method);
|
||||
}
|
||||
|
||||
@@ -251,10 +251,7 @@ public class TestPageRoute extends TestBase {
|
||||
page.route("**/*", route -> route.abort("internetdisconnected"));
|
||||
Request[] failedRequest = {null};
|
||||
page.onRequestFailed(r -> failedRequest[0] = r);
|
||||
try {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE));
|
||||
assertNotNull(failedRequest[0]);
|
||||
if (isWebKit()) {
|
||||
assertEquals("Blocked by Web Inspector", failedRequest[0].failure());
|
||||
@@ -277,17 +274,13 @@ public class TestPageRoute extends TestBase {
|
||||
@Test
|
||||
void shouldFailNavigationWhenAbortingMainResource() {
|
||||
page.route("**/*", route -> route.abort());
|
||||
try {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
if (isWebKit())
|
||||
assertTrue(e.getMessage().contains("Blocked by Web Inspector"), e.getMessage());
|
||||
else if (isFirefox())
|
||||
assertTrue(e.getMessage().contains("NS_ERROR_FAILURE"));
|
||||
else
|
||||
assertTrue(e.getMessage().contains("net::ERR_FAILED"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.navigate(server.EMPTY_PAGE));
|
||||
if (isWebKit())
|
||||
assertTrue(e.getMessage().contains("Blocked by Web Inspector"), e.getMessage());
|
||||
else if (isFirefox())
|
||||
assertTrue(e.getMessage().contains("NS_ERROR_FAILURE"));
|
||||
else
|
||||
assertTrue(e.getMessage().contains("net::ERR_FAILED"));
|
||||
}
|
||||
|
||||
|
||||
@@ -484,12 +477,8 @@ public class TestPageRoute extends TestBase {
|
||||
page.waitForRequest("**", () -> page.evalOnSelector("iframe", "(frame, url) => frame.src = url", server.EMPTY_PAGE));
|
||||
// Delete frame to cause request to be canceled.
|
||||
page.evalOnSelector("iframe", "frame => frame.remove()");
|
||||
try {
|
||||
route[0].resume();
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Route is already handled!"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> route[0].resume());
|
||||
assertTrue(e.getMessage().contains("Route is already handled!"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -555,20 +544,18 @@ public class TestPageRoute extends TestBase {
|
||||
}
|
||||
{
|
||||
// Should be rejected
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.evaluate("async () => {\n" +
|
||||
" const response = await fetch('https://example.com/cars?reject', { mode: 'cors' });\n" +
|
||||
" return response.json();\n" +
|
||||
"}");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
if (isChromium()) {
|
||||
assertTrue(e.getMessage().contains("Failed"), e.getMessage());
|
||||
} else if (isWebKit()) {
|
||||
assertTrue(e.getMessage().contains("TypeError"), e.getMessage());
|
||||
} else if (isFirefox()) {
|
||||
assertTrue(e.getMessage().contains("NetworkError"), e.getMessage());
|
||||
}
|
||||
});
|
||||
if (isChromium()) {
|
||||
assertTrue(e.getMessage().contains("Failed"), e.getMessage());
|
||||
} else if (isWebKit()) {
|
||||
assertTrue(e.getMessage().contains("TypeError"), e.getMessage());
|
||||
} else if (isFirefox()) {
|
||||
assertTrue(e.getMessage().contains("NetworkError"), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -633,7 +620,7 @@ public class TestPageRoute extends TestBase {
|
||||
.setHeaders(mapOf("Access-Control-Allow-Origin", server.PREFIX))
|
||||
.setBody("[\"electric\",\"gas\"]"));
|
||||
});
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.evaluate("async () => {\n" +
|
||||
" const response = await fetch('https://example.com/cars', {\n" +
|
||||
" method: 'POST',\n" +
|
||||
@@ -644,9 +631,7 @@ public class TestPageRoute extends TestBase {
|
||||
" });\n" +
|
||||
" return response.json();\n" +
|
||||
"}");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -111,12 +111,7 @@ public class TestPageScreenshot extends TestBase {
|
||||
byte[] buffer1 = page.screenshot();
|
||||
rafraf(page);
|
||||
byte[] buffer2 = page.screenshot();
|
||||
try {
|
||||
assertArrayEquals(buffer1, buffer2);
|
||||
} catch (AssertionFailedError e) {
|
||||
return;
|
||||
}
|
||||
fail("Screenshots are equal");
|
||||
assertThrows(AssertionFailedError.class, () -> assertArrayEquals(buffer1, buffer2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -133,12 +128,7 @@ public class TestPageScreenshot extends TestBase {
|
||||
byte[] buffer1 = page.screenshot();
|
||||
rafraf(page);
|
||||
byte[] buffer2 = page.screenshot();
|
||||
try {
|
||||
assertArrayEquals(buffer1, buffer2);
|
||||
} catch (AssertionFailedError e) {
|
||||
return;
|
||||
}
|
||||
fail("Screenshots are equal");
|
||||
assertThrows(AssertionFailedError.class, () -> assertArrayEquals(buffer1, buffer2));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -149,12 +139,7 @@ public class TestPageScreenshot extends TestBase {
|
||||
.setMask(asList(page.locator("div").nth(5))));
|
||||
// TODO: toMatchSnapshot is not present in java, so we only checks that masked screenshot is different.
|
||||
byte[] originalScreenshot = page.screenshot();
|
||||
try {
|
||||
assertArrayEquals(screenshot, originalScreenshot);
|
||||
} catch (AssertionFailedError e) {
|
||||
return;
|
||||
}
|
||||
fail("Screenshots are equal");
|
||||
assertThrows(AssertionFailedError.class, () -> assertArrayEquals(screenshot, originalScreenshot));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -79,12 +79,11 @@ public class TestPageSelectOption extends TestBase {
|
||||
void shouldNotSelectSingleOptionWhenSomeAttributesDoNotMatch() {
|
||||
page.navigate(server.PREFIX + "/input/select.html");
|
||||
page.evalOnSelector("select", "s => s.value = undefined");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.selectOption("select", new SelectOption()
|
||||
.setValue("green").setLabel("Brown"), new Page.SelectOptionOptions().setTimeout(300));
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Timeout"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout"));
|
||||
assertEquals("", page.evaluate("() => document.querySelector('select').value"));
|
||||
}
|
||||
|
||||
@@ -137,12 +136,8 @@ public class TestPageSelectOption extends TestBase {
|
||||
@Test
|
||||
void shouldThrowWhenElementIsNotASelect() {
|
||||
page.navigate(server.PREFIX + "/input/select.html");
|
||||
try {
|
||||
page.selectOption("body", "");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Element is not a <select> element"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.selectOption("body", ""));
|
||||
assertTrue(e.getMessage().contains("Element is not a <select> element"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -181,12 +176,10 @@ public class TestPageSelectOption extends TestBase {
|
||||
void shouldNotAllowNullItems() {
|
||||
page.navigate(server.PREFIX + "/input/select.html");
|
||||
page.evaluate("() => window['makeMultiple']()");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.selectOption("select", new String[]{"blue", null, "black","magenta"});
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("options.get(1): expected object, got null"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("options.get(1): expected object, got null"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -70,11 +70,9 @@ public class TestPageSetContent extends TestBase {
|
||||
String imgPath = "/img.png";
|
||||
// stall for image
|
||||
server.setRoute(imgPath, exchange -> {});
|
||||
try {
|
||||
assertThrows(PlaywrightException.class, () -> {
|
||||
page.setContent("<img src='" + server.PREFIX + imgPath + "'></img>", new Page.SetContentOptions().setTimeout(100));
|
||||
fail("did not throw");
|
||||
} catch (TimeoutError e) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -83,12 +81,10 @@ public class TestPageSetContent extends TestBase {
|
||||
String imgPath = "/img.png";
|
||||
// stall for image
|
||||
server.setRoute(imgPath, exchange -> {});
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.setContent("<img src='" + server.PREFIX + imgPath + "'></img>");
|
||||
fail("did not throw");
|
||||
} catch (TimeoutError e) {
|
||||
assertTrue(e.getMessage().contains("Timeout 100ms exceeded."), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout 100ms exceeded."), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -70,11 +70,9 @@ public class TestPageSetExtraHttpHeaders extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldThrowForNonStringHeaderValues() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
browser.newContext(new Browser.NewContextOptions().setExtraHTTPHeaders(mapOf("foo", null)));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("expected string, got undefined"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("expected string, got undefined"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,34 +217,28 @@ public class TestPageSetInputFiles extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldRespectTimeout() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForFileChooser(new Page.WaitForFileChooserOptions().setTimeout(1), () -> {});
|
||||
fail("did not throw");
|
||||
} catch (TimeoutError e) {
|
||||
assertTrue(e.getMessage().contains("Timeout 1ms exceeded"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout 1ms exceeded"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRespectDefaultTimeoutWhenThereIsNoCustomTimeout() {
|
||||
page.setDefaultTimeout(1);
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForFileChooser(() -> {});
|
||||
fail("did not throw");
|
||||
} catch (TimeoutError e) {
|
||||
assertTrue(e.getMessage().contains("Timeout 1ms exceeded"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout 1ms exceeded"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldPrioritizeExactTimeoutOverDefaultTimeout() {
|
||||
page.setDefaultTimeout(0);
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForFileChooser(new Page.WaitForFileChooserOptions().setTimeout(1), () -> {});
|
||||
fail("did not throw");
|
||||
} catch (TimeoutError e) {
|
||||
assertTrue(e.getMessage().contains("Timeout 1ms exceeded"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout 1ms exceeded"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -340,13 +334,12 @@ public class TestPageSetInputFiles extends TestBase {
|
||||
void shouldNotAcceptMultipleFilesForSingleFileInput() {
|
||||
page.setContent("<input type=file>");
|
||||
FileChooser fileChooser = page.waitForFileChooser(() -> page.click("input"));
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
fileChooser.setFiles(new Path[]{FILE_TO_UPLOAD, Paths.get("src/test/resources/pptr.png")});
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Non-multiple file input can only accept single file"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Non-multiple file input can only accept single file"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldEmitInputAndChangeEvents() {
|
||||
List<Object> events = new ArrayList<>();
|
||||
|
||||
@@ -4,74 +4,61 @@ import org.junit.jupiter.api.Test;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.junit.jupiter.api.Assertions.fail;
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestPageStrict extends TestBase {
|
||||
@Test
|
||||
void shouldFailPageTextContentInStrictMode() {
|
||||
page.setContent("<span>span1</span><div><span>target</span></div>");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.textContent("span", new Page.TextContentOptions().setStrict(true));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailPageGetAttributeInStrictMode() {
|
||||
page.setContent("<span>span1</span><div><span>target</span></div>");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.getAttribute("span", "id", new Page.GetAttributeOptions().setStrict(true));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailPageFillInStrictMode() {
|
||||
page.setContent("<input></input><div><input></input></div>");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.fill("input", "text", new Page.FillOptions().setStrict(true));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void shouldFailPageInStrictMode() {
|
||||
page.setContent("<span>span1</span><div><span>target</span></div>");
|
||||
try {
|
||||
ElementHandle error = page.querySelector("span", new Page.QuerySelectorOptions().setStrict(true));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.querySelector("span", new Page.QuerySelectorOptions().setStrict(true));
|
||||
});
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailPageWaitForSelectorInStrictMode() {
|
||||
page.setContent("<span>span1</span><div><span>target</span></div>");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForSelector("span", new Page.WaitForSelectorOptions().setStrict(true));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailPageDispatchEventInStrictMode() {
|
||||
page.setContent("<span></span><div><span></span></div>");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.dispatchEvent("span", "click", new HashMap<>(), new Page.DispatchEventOptions().setStrict(true));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("strict mode violation"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,14 +44,12 @@ public class TestPageWaitForNavigation extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldRespectTimeout() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForNavigation(
|
||||
new Page.WaitForNavigationOptions().setUrl("**/frame.html").setTimeout(5000),
|
||||
() -> page.navigate(server.EMPTY_PAGE));
|
||||
fail("did not throw");
|
||||
} catch (TimeoutError e) {
|
||||
assertTrue(e.getMessage().contains("Timeout 5000ms exceeded"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout 5000ms exceeded"));
|
||||
}
|
||||
|
||||
// Skipped in sync API.
|
||||
@@ -92,14 +90,12 @@ public class TestPageWaitForNavigation extends TestBase {
|
||||
void shouldWorkWithClickingOnLinksWhichDoNotCommitNavigation() throws InterruptedException {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
page.setContent("<a href='" + httpsServer.EMPTY_PAGE + "'>foobar</a>");
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForNavigation(() -> page.click("a"));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
// TODO: figure out why it is inconsistent on Linux WebKit.
|
||||
List<String> possibleErrorMessages = expectedSSLError(browserType.name());
|
||||
assertTrue(checkSSLErrorMessage(e.getMessage(), possibleErrorMessages), "Unexpected exception: '" + e.getMessage() + "' check message(s): " + String.join(",", possibleErrorMessages));
|
||||
}
|
||||
});
|
||||
// TODO: figure out why it is inconsistent on Linux WebKit.
|
||||
List<String> possibleErrorMessages = expectedSSLError(browserType.name());
|
||||
assertTrue(checkSSLErrorMessage(e.getMessage(), possibleErrorMessages), "Unexpected exception: '" + e.getMessage() + "' check message(s): " + String.join(",", possibleErrorMessages));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -161,7 +157,11 @@ public class TestPageWaitForNavigation extends TestBase {
|
||||
}
|
||||
});
|
||||
});
|
||||
page.navigate(server.PREFIX + "/frames/one-frame.html");
|
||||
try {
|
||||
page.navigate(server.PREFIX + "/frames/one-frame.html", new Page.NavigateOptions().setTimeout(2000));
|
||||
} catch (TimeoutError e) {
|
||||
assertTrue(isWebKit()); // Chromium and Firefox issue load event in this case.
|
||||
}
|
||||
assertTrue(frameWindowStopCalled[0]);
|
||||
}
|
||||
|
||||
@@ -239,7 +239,7 @@ public class TestPageWaitForNavigation extends TestBase {
|
||||
page.navigate(server.PREFIX + "/frames/one-frame.html");
|
||||
Frame frame = page.frames().get(1);
|
||||
server.setRoute("/empty.html", exchange -> {});
|
||||
try {
|
||||
PlaywrightException ex = assertThrows(PlaywrightException.class, () -> {
|
||||
frame.waitForNavigation(() -> {
|
||||
Future<Server.Request> req = server.futureRequest("/empty.html");
|
||||
page.evalOnSelector("iframe", "frame => { frame.contentWindow.location.href = '/empty.html'; }");
|
||||
@@ -250,35 +250,29 @@ public class TestPageWaitForNavigation extends TestBase {
|
||||
}
|
||||
page.evaluate("setTimeout(() => document.querySelector('iframe').remove());");
|
||||
});
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("frame was detached"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(ex.getMessage().contains("frame was detached"), ex.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowOnInvalidUrlMatcherTypeInPage() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
Page.WaitForNavigationOptions options = new Page.WaitForNavigationOptions();
|
||||
options.url = new Object();
|
||||
page.waitForNavigation(options, () -> {});
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Url must be String, Pattern or Predicate<String>"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Url must be String, Pattern or Predicate<String>"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldThrowOnInvalidUrlMatcherTypeInFrame() {
|
||||
page.navigate(server.PREFIX + "/frames/one-frame.html");
|
||||
Frame frame = page.frames().get(1);
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
Frame.WaitForNavigationOptions options = new Frame.WaitForNavigationOptions();
|
||||
options.url = new Object();
|
||||
frame.waitForNavigation(options, () -> {});
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Url must be String, Pattern or Predicate<String>"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Url must be String, Pattern or Predicate<String>"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,23 +52,19 @@ public class TestPageWaitForRequest extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldRespectTimeout() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForRequest(url -> false, new Page.WaitForRequestOptions().setTimeout(1), () -> {});
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRespectDefaultTimeout() {
|
||||
page.setDefaultTimeout(1);
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForRequest(request -> false, () -> {});
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -63,12 +63,10 @@ public class TestPageWaitForResponse extends TestBase {
|
||||
@Test
|
||||
void shouldRespectDefaultTimeout() {
|
||||
page.setDefaultTimeout(1);
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForResponse(response -> false, () -> {});
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -37,12 +37,10 @@ public class TestPageWaitForUrl extends TestBase {
|
||||
@Test
|
||||
void shouldRespectTimeout() {
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
try {
|
||||
TimeoutError e = assertThrows(TimeoutError.class, () -> {
|
||||
page.waitForURL("**/frame.html", new Page.WaitForURLOptions().setTimeout(2500));
|
||||
fail("did not throw");
|
||||
} catch (TimeoutError e) {
|
||||
assertTrue(e.getMessage().contains("Timeout 2500ms exceeded"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout 2500ms exceeded"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -50,16 +50,8 @@ public class TestPdf extends TestBase {
|
||||
|
||||
@Test
|
||||
@DisabledIf(value="com.microsoft.playwright.TestBase#isChromium", disabledReason="skip")
|
||||
void shouldOnlyHavePdfInChromium() {
|
||||
try {
|
||||
page.pdf();
|
||||
if (isChromium()) {
|
||||
return;
|
||||
}
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertFalse(e.getMessage().contains("did not throw"));
|
||||
}
|
||||
void shouldThrowInNonChromium() {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.pdf());
|
||||
assertTrue(e.getMessage().contains("Page.pdf only supported in headless Chromium"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -16,10 +16,13 @@
|
||||
|
||||
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;
|
||||
@@ -31,19 +34,16 @@ import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
public class TestPlaywrightCreate {
|
||||
@Test
|
||||
void shouldSupportEnvSkipBrowserDownload(@TempDir Path browsersDir) throws IOException {
|
||||
void shouldSupportEnvSkipBrowserDownload(@TempDir Path browsersDir) throws IOException, NoSuchFieldException, IllegalAccessException {
|
||||
System.err.println("shouldSupportEnvSkipBrowserDownload PLAYWRIGHT_BROWSERS_PATH = " + browsersDir);
|
||||
Map<String, String> env = mapOf("PLAYWRIGHT_BROWSERS_PATH", browsersDir.toString(),
|
||||
"PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD", "1");
|
||||
Playwright.CreateOptions options = new Playwright.CreateOptions().setEnv(env);
|
||||
|
||||
try (Playwright playwright = Playwright.create(options)) {
|
||||
try {
|
||||
getBrowserTypeFromEnv(playwright).launch();
|
||||
fail("Did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Looks like Playwright Test or Playwright was just installed or updated") ||
|
||||
e.getMessage().contains("Looks like Playwright was just installed or updated."), e.getMessage());
|
||||
}
|
||||
try (Playwright playwright = PlaywrightImpl.createImpl(options, true)) {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> getBrowserTypeFromEnv(playwright).launch());
|
||||
assertTrue(e.getMessage().contains("Looks like Playwright Test or Playwright was just installed or updated") ||
|
||||
e.getMessage().contains("Looks like Playwright was just installed or updated."), e.getMessage());
|
||||
|
||||
try (DirectoryStream<Path> ds = Files.newDirectoryStream(browsersDir)) {
|
||||
for (Path child : ds) {
|
||||
|
||||
@@ -29,12 +29,8 @@ public class TestQuerySelector extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldThrowForNonStringSelector() {
|
||||
try {
|
||||
page.querySelector(null);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("selector: expected string, got undefined"));
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.querySelector(null));
|
||||
assertTrue(e.getMessage().contains("selector: expected string, got undefined"));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -67,7 +67,8 @@ public class TestRequestContinue extends TestBase {
|
||||
route.resume(new Route.ResumeOptions().setUrl(server.PREFIX + "/global-var.html"));
|
||||
});
|
||||
Response response = page.navigate(server.PREFIX + "/foo");
|
||||
assertEquals(server.PREFIX + "/foo", response.url());
|
||||
assertEquals(server.PREFIX + "/global-var.html", response.url());
|
||||
assertEquals(server.PREFIX + "/global-var.html", response.request().url());
|
||||
assertEquals(123, page.evaluate("window['globalVar']"));
|
||||
assertEquals("GET", serverRequest.get().method);
|
||||
}
|
||||
@@ -75,18 +76,14 @@ public class TestRequestContinue extends TestBase {
|
||||
@Test
|
||||
@Disabled("resume() method is now asynchronous")
|
||||
void shouldNotAllowChangingProtocolWhenOverridingUrl() {
|
||||
PlaywrightException[] error = {null};
|
||||
page.route("**/*", route -> {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
route.resume(new Route.ResumeOptions().setUrl("file:///tmp/foo"));
|
||||
} catch (PlaywrightException e) {
|
||||
error[0] = e;
|
||||
route.resume();
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("New URL must have same protocol as overridden URL"), e.getMessage());
|
||||
route.resume();
|
||||
});
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
assertNotNull(error[0]);
|
||||
assertTrue(error[0].getMessage().contains("New URL must have same protocol as overridden URL"), error[0].getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -106,43 +106,37 @@ public class TestRequestFulfill extends TestBase {
|
||||
|
||||
@Test
|
||||
void fulfillShouldThrowIfHandledTwice() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.route("**/*", route -> {
|
||||
route.fulfill();
|
||||
route.fulfill();
|
||||
});
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("didn't throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Route is already handled!"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Route is already handled!"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void abortShouldThrowIfHandledTwice() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.route("**/*", route -> {
|
||||
route.abort();
|
||||
route.abort();
|
||||
});
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("didn't throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Route is already handled!"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Route is already handled!"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
void resumeShouldThrowIfHandledTwice() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.route("**/*", route -> {
|
||||
route.resume();
|
||||
route.resume();
|
||||
});
|
||||
page.navigate(server.EMPTY_PAGE);
|
||||
fail("didn't throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Route is already handled!"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Route is already handled!"), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -76,15 +76,16 @@ public class TestScreencast extends TestBase {
|
||||
page.close();
|
||||
|
||||
Path saveAsPath = videosDir.resolve("my-video.webm");
|
||||
try {
|
||||
if (!popup.isClosed()) {
|
||||
popup.waitForClose(() -> {});
|
||||
}
|
||||
// WebKit pauses renderer before win.close() and actually writes something.
|
||||
if (isWebKit()) {
|
||||
popup.video().saveAs(saveAsPath);
|
||||
} catch (PlaywrightException e) {
|
||||
// WebKit pauses renderer before win.close() and actually writes something.
|
||||
if (isWebKit()) {
|
||||
assertTrue(Files.exists(saveAsPath));
|
||||
} else {
|
||||
assertTrue(e.getMessage().contains("Page did not produce any video frames"), e.getMessage());
|
||||
}
|
||||
assertTrue(Files.exists(saveAsPath));
|
||||
} else {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> popup.video().saveAs(saveAsPath));
|
||||
assertTrue(e.getMessage().contains("Page did not produce any video frames"), e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,46 +176,22 @@ public class TestSelectorsMisc extends TestBase {
|
||||
|
||||
assertEquals("id5,id6,id3", page.evalOnSelectorAll("div:right-of(#id0) + div:above(#id8)", "els => els.map(e => e.id).join(',')"));
|
||||
|
||||
try {
|
||||
ElementHandle error = page.querySelector(":near(50)");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("\"near\" engine expects a selector list and optional maximum distance in pixels"), e.getMessage());
|
||||
}
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> page.querySelector(":near(50)"));
|
||||
assertTrue(e.getMessage().contains("\"near\" engine expects a selector list and optional maximum distance in pixels"), e.getMessage());
|
||||
|
||||
try {
|
||||
ElementHandle error1 = page.querySelector("div >> left-of=abc");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Malformed selector: left-of=abc"));
|
||||
}
|
||||
e = assertThrows(PlaywrightException.class, () -> page.querySelector("div >> left-of=abc"));
|
||||
assertTrue(e.getMessage().contains("Malformed selector: left-of=abc"));
|
||||
|
||||
try {
|
||||
ElementHandle error2 = page.querySelector("left-of=\"div\"");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("\"left-of\" selector cannot be first"), e.getMessage());
|
||||
}
|
||||
e = assertThrows(PlaywrightException.class, () -> page.querySelector("left-of=\"div\""));
|
||||
assertTrue(e.getMessage().contains("\"left-of\" selector cannot be first"), e.getMessage());
|
||||
|
||||
try {
|
||||
ElementHandle error3 = page.querySelector("div >> left-of=33");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Malformed selector: left-of=33"));
|
||||
}
|
||||
e = assertThrows(PlaywrightException.class, () -> page.querySelector("div >> left-of=33"));
|
||||
assertTrue(e.getMessage().contains("Malformed selector: left-of=33"));
|
||||
|
||||
try {
|
||||
ElementHandle error4 = page.querySelector("div >> left-of='span','foo'");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Malformed selector: left-of='span','foo'"));
|
||||
}
|
||||
e = assertThrows(PlaywrightException.class, () -> page.querySelector("div >> left-of='span','foo'"));
|
||||
assertTrue(e.getMessage().contains("Malformed selector: left-of='span','foo'"));
|
||||
|
||||
try {
|
||||
ElementHandle error5 = page.querySelector("div >> left-of='span',3,4");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Malformed selector: left-of='span',3,4"));
|
||||
}
|
||||
e = assertThrows(PlaywrightException.class, () -> page.querySelector("div >> left-of='span',3,4"));
|
||||
assertTrue(e.getMessage().contains("Malformed selector: left-of='span',3,4"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -53,13 +53,11 @@ public class TestSelectorsRegister extends TestBase {
|
||||
assertEquals("DIV", page.evalOnSelector("tag2=DIV", "e => e.nodeName"));
|
||||
assertEquals("SPAN", page.evalOnSelector("tag2=SPAN", "e => e.nodeName"));
|
||||
assertEquals(2, page.evalOnSelectorAll("tag2=DIV", "es => es.length"));
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
// Selector names are case-sensitive.
|
||||
page.querySelector("tAG=DIV");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Unknown engine \"tAG\" while parsing selector tAG=DIV"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Unknown engine \"tAG\" while parsing selector tAG=DIV"));
|
||||
context.close();
|
||||
}
|
||||
|
||||
@@ -105,12 +103,10 @@ public class TestSelectorsRegister extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldHandleErrors() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.querySelector("neverregister=ignored");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Unknown engine \"neverregister\" while parsing selector neverregister=ignored"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Unknown engine \"neverregister\" while parsing selector neverregister=ignored"));
|
||||
String createDummySelector = "{\n" +
|
||||
" create(root, target) {\n" +
|
||||
" return target.nodeName;\n" +
|
||||
@@ -122,26 +118,20 @@ public class TestSelectorsRegister extends TestBase {
|
||||
" return Array.from(root.querySelectorAll(\"dummy\"));\n" +
|
||||
" }\n" +
|
||||
"}";
|
||||
try {
|
||||
e = assertThrows(PlaywrightException.class, () -> {
|
||||
playwright.selectors().register("$", createDummySelector);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Selector engine name may only contain [a-zA-Z0-9_] characters"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Selector engine name may only contain [a-zA-Z0-9_] characters"));
|
||||
// Selector names are case-sensitive.
|
||||
playwright.selectors().register("dummy", createDummySelector);
|
||||
playwright.selectors().register("duMMy", createDummySelector);
|
||||
try {
|
||||
e = assertThrows(PlaywrightException.class, () -> {
|
||||
playwright.selectors().register("dummy", createDummySelector);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("\"dummy\" selector engine has been already registered"));
|
||||
}
|
||||
try {
|
||||
});
|
||||
assertTrue(e.getMessage().contains("\"dummy\" selector engine has been already registered"));
|
||||
e = assertThrows(PlaywrightException.class, () -> {
|
||||
playwright.selectors().register("css", createDummySelector);
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("\"css\" is a predefined selector engine"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("\"css\" is a predefined selector engine"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import java.util.concurrent.Semaphore;
|
||||
import static com.microsoft.playwright.options.KeyboardModifier.ALT;
|
||||
import static com.microsoft.playwright.Utils.mapOf;
|
||||
import static java.util.Arrays.asList;
|
||||
import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
public class TestTap extends TestBase {
|
||||
@@ -103,11 +104,7 @@ public class TestTap extends TestBase {
|
||||
List<String> events = Collections.synchronizedList(new ArrayList<>());
|
||||
server.setRoute("/intercept-this.html", exchange -> {
|
||||
// make sure the tap doesnt resolve too early
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {
|
||||
events.add("interrupted");
|
||||
}
|
||||
assertDoesNotThrow(() -> Thread.sleep(100));
|
||||
exchange.getResponseHeaders().add("Content-Type", "application/octet-stream");
|
||||
exchange.sendResponseHeaders(200, 0);
|
||||
try (OutputStreamWriter writer = new OutputStreamWriter(exchange.getResponseBody())) {
|
||||
|
||||
@@ -74,15 +74,13 @@ public class TestWaitForFunction extends TestBase {
|
||||
int[] counter = { 0 };
|
||||
page.onConsoleMessage(message -> ++counter[0]);
|
||||
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
JSHandle result = page.waitForFunction("() => {\n" +
|
||||
" window['counter'] = (window['counter'] || 0) + 1;\n" +
|
||||
" console.log(window['counter']);\n" +
|
||||
"}", null, new Page.WaitForFunctionOptions().setPollingInterval(1).setTimeout(1000));
|
||||
fail("did not throw");
|
||||
} catch (TimeoutError e) {
|
||||
assertTrue(e.getMessage().contains("Timeout 1000ms exceeded"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout 1000ms exceeded"));
|
||||
|
||||
int savedCounter = counter[0];
|
||||
page.waitForTimeout(2000); // Give it some time to produce more logs.
|
||||
@@ -101,37 +99,31 @@ public class TestWaitForFunction extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldFailWithPredicateThrowingOnFirstCall() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForFunction("() => { throw new Error('oh my'); }");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("oh my"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("oh my"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailWithPredicateThrowingSometimes() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForFunction("() => {\n" +
|
||||
" window['counter'] = (window['counter'] || 0) + 1;\n" +
|
||||
" if (window['counter'] === 3)\n" +
|
||||
" throw new Error('Bad counter!');\n" +
|
||||
" return window['counter'] === 5 ? 'result' : false;\n" +
|
||||
"}");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Bad counter!"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Bad counter!"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFailWithReferenceErrorOnWrongPage() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForFunction("() => globalVar === 123");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("globalVar"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("globalVar"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -149,12 +141,10 @@ public class TestWaitForFunction extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldThrowNegativePollingInterval() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForFunction("() => !!document.body", null, new Page.WaitForFunctionOptions().setPollingInterval(-10));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Cannot poll with non-positive interval"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Cannot poll with non-positive interval"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -177,23 +167,19 @@ public class TestWaitForFunction extends TestBase {
|
||||
|
||||
@Test
|
||||
void shouldRespectTimeout() {
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForFunction("false", null, new Page.WaitForFunctionOptions().setTimeout(10));
|
||||
fail("did not throw");
|
||||
} catch (TimeoutError e) {
|
||||
assertTrue(e.getMessage().contains("Timeout 10ms exceeded"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout 10ms exceeded"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldRespectDefaultTimeout() {
|
||||
page.setDefaultTimeout(1);
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForFunction("false");
|
||||
fail("did not throw");
|
||||
} catch (TimeoutError e) {
|
||||
assertTrue(e.getMessage().contains("Timeout 1ms exceeded"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout 1ms exceeded"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -269,33 +255,29 @@ public class TestWaitForFunction extends TestBase {
|
||||
messages.add(msg.text());
|
||||
}
|
||||
});
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForFunction("() => {\n" +
|
||||
" console.log('waitForFunction1');\n" +
|
||||
" throw new Error('waitForFunction1');\n" +
|
||||
"}");
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("waitForFunction1"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("waitForFunction1"));
|
||||
page.reload();
|
||||
try {
|
||||
e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForFunction("() => {\n" +
|
||||
" console.log('waitForFunction2');\n" +
|
||||
" throw new Error('waitForFunction2');\n" +
|
||||
"}");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("waitForFunction2"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("waitForFunction2"));
|
||||
page.reload();
|
||||
try {
|
||||
e = assertThrows(PlaywrightException.class, () -> {
|
||||
page.waitForFunction("() => {\n" +
|
||||
" console.log('waitForFunction3');\n" +
|
||||
" throw new Error('waitForFunction3');\n" +
|
||||
"}");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("waitForFunction3"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("waitForFunction3"));
|
||||
assertEquals(asList("waitForFunction1", "waitForFunction2", "waitForFunction3"), messages);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -182,12 +182,10 @@ public class TestWebSocket extends TestBase {
|
||||
"}", webSocketServer.getPort());
|
||||
});
|
||||
ws.waitForFrameReceived(() -> {});
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
ws.waitForFrameSent(() -> page.evaluate("window.ws.close()"));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException exception) {
|
||||
assertTrue(exception.getMessage().contains("Socket closed"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Socket closed"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -198,12 +196,10 @@ public class TestWebSocket extends TestBase {
|
||||
"}", webSocketServer.getPort());
|
||||
});
|
||||
ws.waitForFrameReceived(() -> {});
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
ws.waitForFrameSent(() -> page.close());
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException exception) {
|
||||
assertTrue(exception.getMessage().contains("Page closed"));
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Page closed"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -258,13 +254,11 @@ public class TestWebSocket extends TestBase {
|
||||
"}", webSocketServer.getPort());
|
||||
});
|
||||
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
ws.waitForFrameReceived(new WebSocket.WaitForFrameReceivedOptions()
|
||||
.setPredicate(webSocketFrame -> false).setTimeout(1), () -> {});
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -276,12 +270,10 @@ public class TestWebSocket extends TestBase {
|
||||
"}", webSocketServer.getPort());
|
||||
});
|
||||
|
||||
try {
|
||||
PlaywrightException e = assertThrows(PlaywrightException.class, () -> {
|
||||
ws.waitForFrameSent(new WebSocket.WaitForFrameSentOptions()
|
||||
.setPredicate(webSocketFrame -> false).setTimeout(1), () -> page.evaluate("ws.send('outgoing');"));
|
||||
fail("did not throw");
|
||||
} catch (PlaywrightException e) {
|
||||
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
|
||||
}
|
||||
});
|
||||
assertTrue(e.getMessage().contains("Timeout"), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user