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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import java.net.URISyntaxException;
import java.nio.file.*;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class DriverJar extends Driver {
Expand All @@ -29,17 +30,22 @@ public class DriverJar extends Driver {
DriverJar() throws IOException, URISyntaxException, InterruptedException {
driverTempDir = Files.createTempDirectory("playwright-java-");
driverTempDir.toFile().deleteOnExit();
}

@Override
protected void initialize(Map<String, String> env) throws Exception {
extractDriverToTempDir();
installBrowsers();
installBrowsers(env);
}

private void installBrowsers() throws IOException, InterruptedException {
private void installBrowsers(Map<String, String> env) throws IOException, InterruptedException {
String cliFileName = super.cliFileName();
Path driver = driverTempDir.resolve(cliFileName);
if (!Files.exists(driver)) {
throw new RuntimeException("Failed to find " + cliFileName + " at " + driver);
}
ProcessBuilder pb = new ProcessBuilder(driver.toString(), "install");
pb.environment().putAll(env);
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
pb.redirectOutput(ProcessBuilder.Redirect.INHERIT);
Process p = pb.start();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

import static org.junit.jupiter.api.Assertions.assertNull;
Expand All @@ -31,7 +32,7 @@ public class TestInstall {
void playwrightCliInstalled() throws Exception {
// Clear system property to ensure that the driver is loaded from jar.
System.clearProperty("playwright.cli.dir");
Path cli = Driver.ensureDriverInstalled();
Path cli = Driver.ensureDriverInstalled(Collections.emptyMap());
assertTrue(Files.exists(cli));

ProcessBuilder pb = new ProcessBuilder(cli.toString(), "install");
Expand Down
12 changes: 11 additions & 1 deletion driver/src/main/java/com/microsoft/playwright/impl/Driver.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Map;

/**
* This class provides access to playwright-cli. It can be either preinstalled
Expand All @@ -32,16 +33,23 @@ private static class PreinstalledDriver extends Driver {
PreinstalledDriver(Path driverDir) {
this.driverDir = driverDir;
}

@Override
protected void initialize(Map<String, String> env) {
// no-op
}

@Override
Path driverDir() {
return driverDir;
}
}

public static synchronized Path ensureDriverInstalled() {
public static synchronized Path ensureDriverInstalled(Map<String, String> env) {
if (instance == null) {
try {
instance = createDriver();
instance.initialize(env);
} catch (Exception exception) {
throw new RuntimeException("Failed to create driver", exception);
}
Expand All @@ -50,6 +58,8 @@ public static synchronized Path ensureDriverInstalled() {
return instance.driverDir().resolve(name);
}

protected abstract void initialize(Map<String, String> env) throws Exception;

protected String cliFileName() {
return System.getProperty("os.name").toLowerCase().contains("windows") ?
"playwright.cmd" : "playwright.sh";
Expand Down
3 changes: 2 additions & 1 deletion playwright/src/main/java/com/microsoft/playwright/CLI.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import java.io.IOException;
import java.nio.file.Path;
import java.util.Collections;

import static java.util.Arrays.asList;

Expand All @@ -28,7 +29,7 @@
*/
public class CLI {
public static void main(String[] args) throws IOException, InterruptedException {
Path driver = Driver.ensureDriverInstalled();
Path driver = Driver.ensureDriverInstalled(Collections.emptyMap());
ProcessBuilder pb = new ProcessBuilder(driver.toString());
pb.command().addAll(asList(args));
if (!pb.environment().containsKey("PW_CLI_TARGET_LANG")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@
* }</pre>
*/
public interface Playwright extends AutoCloseable {
class CreateOptions {
/**
* Specify environment variables that will be passed to the driver process. By default driver process inherits environment
* variables of the Playwright process.
*/
public Map<String, String> env;

public CreateOptions setEnv(Map<String, String> env) {
this.env = env;
return this;
}
}
/**
* This object can be used to launch or connect to Chromium, returning instances of {@code Browser}.
*/
Expand Down Expand Up @@ -72,8 +84,12 @@ public interface Playwright extends AutoCloseable {
* playwright.close();
* }</pre>
*/
static Playwright create(CreateOptions options) {
return PlaywrightImpl.create(options);
}

static Playwright create() {
return PlaywrightImpl.create();
return create(null);
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,23 @@

import java.io.IOException;
import java.nio.file.Path;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.TimeUnit;

public class PlaywrightImpl extends ChannelOwner implements Playwright {
private Process driverProcess;

public static PlaywrightImpl create() {
public static PlaywrightImpl create(CreateOptions options) {
try {
Path driver = Driver.ensureDriverInstalled();
Map<String, String> env = Collections.emptyMap();
if (options != null && options.env != null) {
env = options.env;
}
Path driver = Driver.ensureDriverInstalled(env);
ProcessBuilder pb = new ProcessBuilder(driver.toString(), "run-driver");
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
// pb.environment().put("DEBUG", "pw:pro*");
pb.environment().putAll(env);
Process p = pb.start();
Connection connection = new Connection(new PipeTransport(p.getInputStream(), p.getOutputStream()));
PlaywrightImpl result = (PlaywrightImpl) connection.waitForObjectWithKnownName("Playwright");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@

package com.microsoft.playwright;

import com.microsoft.playwright.options.BrowserChannel;
import org.junit.jupiter.api.*;

import java.io.IOException;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,7 @@
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.*;

import static com.microsoft.playwright.Utils.mapOf;
import static org.junit.jupiter.api.Assertions.*;
Expand All @@ -60,7 +58,7 @@ void kill() throws InterruptedException {

private static BrowserServer launchBrowserServer(BrowserType browserType) {
try {
Path driver = Driver.ensureDriverInstalled();
Path driver = Driver.ensureDriverInstalled(Collections.emptyMap());
Path dir = driver.getParent();
String node = dir.resolve(isWindows ? "node.exe" : "node").toString();
String cliJs = dir.resolve("package/lib/cli/cli.js").toString();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/*
* Copyright (c) Microsoft Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.microsoft.playwright;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

import java.io.IOException;
import java.nio.file.DirectoryStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;

import static com.microsoft.playwright.Utils.getBrowserTypeFromEnv;
import static com.microsoft.playwright.Utils.mapOf;
import static org.junit.jupiter.api.Assertions.*;

public class TestPlaywrightCreate {
@Test
void shouldSupportEnvSkipBrowserDownload(@TempDir Path browsersDir) throws IOException {
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("executable doesn't exist"), e.getMessage());
assertTrue(e.getMessage().contains(browsersDir.toString()), e.getMessage());
}

try (DirectoryStream<Path> ds = Files.newDirectoryStream(browsersDir)) {
for (Path child : ds) {
fail("Unexpected file: " + child.toString());
}
}
}
}

// This test is too slow, so we don't run it.
void shouldSupportEnvBrowsersPath(@TempDir Path browsersDir) throws IOException {
Map<String, String> env = mapOf("PLAYWRIGHT_BROWSERS_PATH", browsersDir.toString());
Playwright.CreateOptions options = new Playwright.CreateOptions().setEnv(env);

try (Playwright playwright = Playwright.create(options)) {
try (Browser browser = playwright.chromium().launch()) {
assertNotNull(browser);
}

try (DirectoryStream<Path> ds = Files.newDirectoryStream(browsersDir)) {
for (Path child : ds) {
assertTrue(Files.isDirectory(child));
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -587,15 +587,6 @@ class Method extends Element {
final TypeRef returnType;
final List<Param> params = new ArrayList<>();

private static Map<String, String[]> customSignature = new HashMap<>();
static {
customSignature.put("Playwright.create", new String[]{
"static Playwright create() {",
" return PlaywrightImpl.create();",
"}"
});
}

Method(TypeDefinition parent, JsonObject jsonElement) {
super(parent, jsonElement);
returnType = new TypeRef(this, jsonElement.get("type"));
Expand All @@ -614,8 +605,12 @@ class Method extends Element {
void writeTo(List<String> output, String offset) {
if ("Playwright.create".equals(jsonPath)) {
writeJavadoc(params, output, offset);
output.add(offset + "static Playwright create(CreateOptions options) {");
output.add(offset + " return PlaywrightImpl.create(options);");
output.add(offset + "}");
output.add("");
output.add(offset + "static Playwright create() {");
output.add(offset + " return PlaywrightImpl.create();");
output.add(offset + " return create(null);");
output.add(offset + "}");
return;
}
Expand Down