mirror of
https://github.com/microsoft/playwright-java.git
synced 2025-09-08 21:01:00 +00:00
feat(driver): extract driver into temp folder when running playwright (#74)
This commit is contained in:
parent
eeb8bd16c9
commit
6676cdd5b2
20
.github/workflows/test.yml
vendored
20
.github/workflows/test.yml
vendored
@ -20,27 +20,9 @@ jobs:
|
|||||||
uses: actions/setup-java@v1
|
uses: actions/setup-java@v1
|
||||||
with:
|
with:
|
||||||
java-version: 1.8
|
java-version: 1.8
|
||||||
- run: mkdir -p driver
|
|
||||||
- name: Install driver
|
- name: Install driver
|
||||||
working-directory: driver
|
|
||||||
env:
|
|
||||||
OS: ${{ matrix.os }}
|
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: scripts/download_driver.sh
|
||||||
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
|
|
||||||
- name: Build with Maven
|
- name: Build with Maven
|
||||||
run: mvn -B package -D skipTests --no-transfer-progress
|
run: mvn -B package -D skipTests --no-transfer-progress
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
|
@ -11,17 +11,11 @@ git clone https://github.com/microsoft/playwright-java
|
|||||||
cd 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
|
```bash
|
||||||
mkdir driver
|
scripts/download_driver.sh
|
||||||
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
|
|
||||||
```
|
```
|
||||||
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
|
Names of published driver archives can be found at https://github.com/microsoft/playwright-cli/actions
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ import com.google.gson.JsonElement;
|
|||||||
import com.google.gson.JsonObject;
|
import com.google.gson.JsonObject;
|
||||||
import com.microsoft.playwright.PlaywrightException;
|
import com.microsoft.playwright.PlaywrightException;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.time.Duration;
|
import java.time.Duration;
|
||||||
@ -68,6 +69,10 @@ public class Connection {
|
|||||||
root = new Root(this);
|
root = new Root(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void close() throws IOException {
|
||||||
|
transport.close();
|
||||||
|
}
|
||||||
|
|
||||||
public JsonElement sendMessage(String guid, String method, JsonObject params) {
|
public JsonElement sendMessage(String guid, String method, JsonObject params) {
|
||||||
return (JsonElement) root.toDeferred(sendMessageAsync(guid, method, params)).get();
|
return (JsonElement) root.toDeferred(sendMessageAsync(guid, method, params)).get();
|
||||||
}
|
}
|
||||||
|
@ -17,34 +17,68 @@
|
|||||||
package com.microsoft.playwright.impl;
|
package com.microsoft.playwright.impl;
|
||||||
|
|
||||||
import com.google.gson.Gson;
|
import com.google.gson.Gson;
|
||||||
import com.google.gson.JsonArray;
|
|
||||||
import com.google.gson.JsonElement;
|
import com.google.gson.JsonElement;
|
||||||
import com.google.gson.JsonObject;
|
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.io.IOException;
|
||||||
import java.nio.file.FileSystems;
|
import java.net.URISyntaxException;
|
||||||
import java.util.HashMap;
|
import java.nio.file.Files;
|
||||||
import java.util.Map;
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
public class PlaywrightImpl extends ChannelOwner implements Playwright {
|
public class PlaywrightImpl extends ChannelOwner implements Playwright {
|
||||||
|
private static Path driverTempDir;
|
||||||
|
|
||||||
public static PlaywrightImpl create() {
|
public static PlaywrightImpl create() {
|
||||||
try {
|
try {
|
||||||
File cwd = FileSystems.getDefault().getPath(".").toFile();
|
Path driver = ensureDriverExtracted();
|
||||||
File driver = new File(cwd, "../driver/playwright-cli");
|
ProcessBuilder pb = new ProcessBuilder(driver.toString(), "run-driver");
|
||||||
ProcessBuilder pb = new ProcessBuilder(driver.getCanonicalPath(), "run-driver");
|
|
||||||
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
|
pb.redirectError(ProcessBuilder.Redirect.INHERIT);
|
||||||
// pb.environment().put("DEBUG", "pw:pro*");
|
// pb.environment().put("DEBUG", "pw:pro*");
|
||||||
Process p = pb.start();
|
Process p = pb.start();
|
||||||
Connection connection = new Connection(p.getInputStream(), p.getOutputStream());
|
Connection connection = new Connection(p.getInputStream(), p.getOutputStream());
|
||||||
PlaywrightImpl playwright = (PlaywrightImpl)connection.waitForObjectWithKnownName("Playwright");
|
return (PlaywrightImpl) connection.waitForObjectWithKnownName("Playwright");
|
||||||
return playwright;
|
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new PlaywrightException("Failed to launch driver", 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 chromium;
|
||||||
private final BrowserTypeImpl firefox;
|
private final BrowserTypeImpl firefox;
|
||||||
private final BrowserTypeImpl webkit;
|
private final BrowserTypeImpl webkit;
|
||||||
@ -91,4 +125,12 @@ public class PlaywrightImpl extends ChannelOwner implements Playwright {
|
|||||||
public Selectors selectors() {
|
public Selectors selectors() {
|
||||||
return selectors;
|
return selectors;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
try {
|
||||||
|
connection.close();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new PlaywrightException("Failed to close", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -31,17 +31,21 @@ public class Transport {
|
|||||||
private final ReaderThread readerThread;
|
private final ReaderThread readerThread;
|
||||||
private final WriterThread writerThread;
|
private final WriterThread writerThread;
|
||||||
|
|
||||||
|
private boolean isClosed;
|
||||||
|
|
||||||
Transport(InputStream input, OutputStream output) {
|
Transport(InputStream input, OutputStream output) {
|
||||||
DataInputStream in = new DataInputStream(new BufferedInputStream(input));
|
DataInputStream in = new DataInputStream(new BufferedInputStream(input));
|
||||||
readerThread = new ReaderThread(in, incoming);
|
readerThread = new ReaderThread(in, incoming);
|
||||||
readerThread.start();
|
readerThread.start();
|
||||||
// TODO: buffer?
|
|
||||||
DataOutputStream out = new DataOutputStream(output);
|
DataOutputStream out = new DataOutputStream(output);
|
||||||
writerThread = new WriterThread(out, outgoing);
|
writerThread = new WriterThread(out, outgoing);
|
||||||
writerThread.start();
|
writerThread.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void send(String message) {
|
public void send(String message) {
|
||||||
|
if (isClosed) {
|
||||||
|
throw new PlaywrightException("Playwright connection closed");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
outgoing.put(message);
|
outgoing.put(message);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@ -50,16 +54,30 @@ public class Transport {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String poll(Duration timeout) {
|
public String poll(Duration timeout) {
|
||||||
|
if (isClosed) {
|
||||||
|
throw new PlaywrightException("Playwright connection closed");
|
||||||
|
}
|
||||||
try {
|
try {
|
||||||
return incoming.poll(timeout.toMillis(), TimeUnit.MILLISECONDS);
|
return incoming.poll(timeout.toMillis(), TimeUnit.MILLISECONDS);
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
throw new PlaywrightException("Failed to read message", 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 {
|
class ReaderThread extends Thread {
|
||||||
private final DataInputStream in;
|
final DataInputStream in;
|
||||||
private final BlockingQueue<String> queue;
|
private final BlockingQueue<String> queue;
|
||||||
|
|
||||||
private static int readIntLE(DataInputStream in) throws IOException {
|
private static int readIntLE(DataInputStream in) throws IOException {
|
||||||
@ -85,6 +103,7 @@ class ReaderThread extends Thread {
|
|||||||
try {
|
try {
|
||||||
queue.put(readMessage());
|
queue.put(readMessage());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
if (!isInterrupted())
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
break;
|
break;
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
@ -102,7 +121,7 @@ class ReaderThread extends Thread {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class WriterThread extends Thread {
|
class WriterThread extends Thread {
|
||||||
private final DataOutputStream out;
|
final DataOutputStream out;
|
||||||
private final BlockingQueue<String> queue;
|
private final BlockingQueue<String> queue;
|
||||||
|
|
||||||
private static void writeIntLE(DataOutputStream out, int v) throws IOException {
|
private static void writeIntLE(DataOutputStream out, int v) throws IOException {
|
||||||
@ -125,6 +144,7 @@ class WriterThread extends Thread {
|
|||||||
out.flush();
|
out.flush();
|
||||||
sendMessage(queue.take());
|
sendMessage(queue.take());
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
if (!isInterrupted())
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
break;
|
break;
|
||||||
} catch (InterruptedException e) {
|
} catch (InterruptedException e) {
|
||||||
|
1
playwright/src/main/resources/.gitignore
vendored
Normal file
1
playwright/src/main/resources/.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
driver/
|
44
scripts/download_driver.sh
Executable file
44
scripts/download_driver.sh
Executable 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
|
Loading…
x
Reference in New Issue
Block a user