feat(driver): extract driver into temp folder when running playwright (#74)

This commit is contained in:
Yury Semikhatsky 2020-11-16 22:58:59 -08:00 committed by GitHub
parent eeb8bd16c9
commit 6676cdd5b2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 131 additions and 43 deletions

View File

@ -20,27 +20,9 @@ jobs:
uses: actions/setup-java@v1
with:
java-version: 1.8
- run: mkdir -p driver
- name: Install driver
working-directory: driver
env:
OS: ${{ matrix.os }}
shell: bash
run: |
FILE_NAME="unkwnown"
if [[ $OS == *"ubuntu"* ]]; then
FILE_NAME=playwright-cli-0.160.0-next.1604357190081-linux.zip
fi
if [[ $OS == *"macos"* ]]; then
FILE_NAME=playwright-cli-0.160.0-next.1604357190081-mac.zip
fi
if [[ $OS == *"windows"* ]]; then
FILE_NAME=playwright-cli-0.160.0-next.1604357190081-win32_x64.zip
fi
echo "Downloading from $FILE_NAME"
curl -O https://playwright.azureedge.net/builds/cli/next/$FILE_NAME
unzip $FILE_NAME -d .
./playwright-cli install
run: scripts/download_driver.sh
- name: Build with Maven
run: mvn -B package -D skipTests --no-transfer-progress
- name: Run tests

View File

@ -11,17 +11,11 @@ git clone https://github.com/microsoft/playwright-java
cd playwright-java
```
2. Download playwright-cli binary package into `driver/` directory and run `install` command. It will install Playwright and download browser binaries for Chromium, Firefox and WebKit.
2. Run the following script to download playwright-cli binary for your platform into `playwright/src/main/resources/driver/` directory. It will also install Playwright and download browser binaries for Chromium, Firefox and WebKit.
```bash
mkdir driver
cd driver
FILENAME=playwright-cli-0.160.0-next.1604373941495-linux.zip
curl -O https://playwright.azureedge.net/builds/cli/next/${FILENAME}
unzip ${FILENAME} -d .
./playwright-cli install
scripts/download_driver.sh
```
Replace `-linux.zip` in the file name with `-win32_x64.zip` or `-mac.zip` for other platforms.
Names of published driver archives can be found at https://github.com/microsoft/playwright-cli/actions

View File

@ -20,6 +20,7 @@ import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.microsoft.playwright.PlaywrightException;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.time.Duration;
@ -68,6 +69,10 @@ public class Connection {
root = new Root(this);
}
void close() throws IOException {
transport.close();
}
public JsonElement sendMessage(String guid, String method, JsonObject params) {
return (JsonElement) root.toDeferred(sendMessageAsync(guid, method, params)).get();
}

View File

@ -17,34 +17,68 @@
package com.microsoft.playwright.impl;
import com.google.gson.Gson;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.microsoft.playwright.*;
import com.microsoft.playwright.DeviceDescriptor;
import com.microsoft.playwright.Playwright;
import com.microsoft.playwright.PlaywrightException;
import com.microsoft.playwright.Selectors;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.util.HashMap;
import java.util.Map;
import java.net.URISyntaxException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
public class PlaywrightImpl extends ChannelOwner implements Playwright {
private static Path driverTempDir;
public static PlaywrightImpl create() {
try {
File cwd = FileSystems.getDefault().getPath(".").toFile();
File driver = new File(cwd, "../driver/playwright-cli");
ProcessBuilder pb = new ProcessBuilder(driver.getCanonicalPath(), "run-driver");
Path driver = ensureDriverExtracted();
ProcessBuilder pb = new ProcessBuilder(driver.toString(), "run-driver");
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
// pb.environment().put("DEBUG", "pw:pro*");
Process p = pb.start();
Connection connection = new Connection(p.getInputStream(), p.getOutputStream());
PlaywrightImpl playwright = (PlaywrightImpl)connection.waitForObjectWithKnownName("Playwright");
return playwright;
return (PlaywrightImpl) connection.waitForObjectWithKnownName("Playwright");
} catch (IOException e) {
throw new PlaywrightException("Failed to launch driver", e);
}
}
private static Path ensureDriverExtracted() {
if (driverTempDir == null) {
try {
driverTempDir = Files.createTempDirectory("playwright-java-");
driverTempDir.toFile().deleteOnExit();
ClassLoader classloader = Thread.currentThread().getContextClassLoader();
Path path = Paths.get(classloader.getResource("driver").toURI());
Files.list(path).forEach(filePath -> {
try {
extractResource(filePath, driverTempDir);
} catch (IOException e) {
throw new RuntimeException("Failed to extract driver from " + path, e);
}
});
} catch (IOException | URISyntaxException e) {
throw new PlaywrightException("Failed to launch driver", e);
}
}
// TODO: remove dir on exit
return driverTempDir.resolve("playwright-cli");
}
private static Path extractResource(Path from, Path toDir) throws IOException {
Path path = toDir.resolve(from.getFileName());
Files.copy(from, path);
path.toFile().setExecutable(true);
path.toFile().deleteOnExit();
System.out.println("extracting: " + from.toString() + " to " + path.toString());
return path;
}
private final BrowserTypeImpl chromium;
private final BrowserTypeImpl firefox;
private final BrowserTypeImpl webkit;
@ -91,4 +125,12 @@ public class PlaywrightImpl extends ChannelOwner implements Playwright {
public Selectors selectors() {
return selectors;
}
public void close() {
try {
connection.close();
} catch (IOException e) {
throw new PlaywrightException("Failed to close", e);
}
}
}

View File

@ -31,17 +31,21 @@ public class Transport {
private final ReaderThread readerThread;
private final WriterThread writerThread;
private boolean isClosed;
Transport(InputStream input, OutputStream output) {
DataInputStream in = new DataInputStream(new BufferedInputStream(input));
readerThread = new ReaderThread(in, incoming);
readerThread.start();
// TODO: buffer?
DataOutputStream out = new DataOutputStream(output);
writerThread = new WriterThread(out, outgoing);
writerThread.start();
}
public void send(String message) {
if (isClosed) {
throw new PlaywrightException("Playwright connection closed");
}
try {
outgoing.put(message);
} catch (InterruptedException e) {
@ -50,16 +54,30 @@ public class Transport {
}
public String poll(Duration timeout) {
if (isClosed) {
throw new PlaywrightException("Playwright connection closed");
}
try {
return incoming.poll(timeout.toMillis(), TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {
throw new PlaywrightException("Failed to read message", e);
}
}
void close() throws IOException {
if (isClosed) {
return;
}
isClosed = true;
readerThread.interrupt();
readerThread.in.close();
writerThread.interrupt();
writerThread.out.close();
}
}
class ReaderThread extends Thread {
private final DataInputStream in;
final DataInputStream in;
private final BlockingQueue<String> queue;
private static int readIntLE(DataInputStream in) throws IOException {
@ -85,6 +103,7 @@ class ReaderThread extends Thread {
try {
queue.put(readMessage());
} catch (IOException e) {
if (!isInterrupted())
e.printStackTrace();
break;
} catch (InterruptedException e) {
@ -102,7 +121,7 @@ class ReaderThread extends Thread {
}
class WriterThread extends Thread {
private final DataOutputStream out;
final DataOutputStream out;
private final BlockingQueue<String> queue;
private static void writeIntLE(DataOutputStream out, int v) throws IOException {
@ -125,6 +144,7 @@ class WriterThread extends Thread {
out.flush();
sendMessage(queue.take());
} catch (IOException e) {
if (!isInterrupted())
e.printStackTrace();
break;
} catch (InterruptedException e) {

View File

@ -0,0 +1 @@
driver/

44
scripts/download_driver.sh Executable file
View File

@ -0,0 +1,44 @@
#!/bin/bash
set -e
set +x
FILE_PREFIX=playwright-cli-0.160.0-next.1604373941495
trap "cd $(pwd -P)" EXIT
cd "$(dirname $0)"
cd ../playwright/src/main/resources
if [[ -d driver ]]; then
echo "$(pwd)/driver already exists, delete it first"
exit 1;
fi
mkdir driver
cd driver
echo "Created directory: $(pwd)"
FILE_NAME="unknown"
case $(uname) in
Darwin)
FILE_NAME=${FILE_PREFIX}-mac.zip
echo "Downloading driver for macOS"
;;
Linux)
FILE_NAME=${FILE_PREFIX}-linux.zip
echo "Downloading driver for Linux"
;;
MINGW*)
FILE_NAME=${FILE_PREFIX}-win32_x64.zip
echo "Downloading driver for Windows"
;;
*)
echo "Unknown platform '$(uname)'"
exit 1;
;;
esac
curl -O https://playwright.azureedge.net/builds/cli/next/${FILE_NAME}
unzip ${FILE_NAME} -d .
rm $FILE_NAME
./playwright-cli install