Skip to content

Commit 22d946a

Browse files
committed
[java] Create new io maven artifact and make SeleniumManager use that for executing command lines
1 parent 8d8f2ff commit 22d946a

File tree

13 files changed

+161
-85
lines changed

13 files changed

+161
-85
lines changed

Rakefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ JAVA_RELEASE_TARGETS = %w[
113113
//java/src/org/openqa/selenium/json:json.publish
114114
//java/src/org/openqa/selenium/lift:lift.publish
115115
//java/src/org/openqa/selenium/manager:manager.publish
116+
//java/src/org/openqa/selenium/os:os.publish
116117
//java/src/org/openqa/selenium/remote/http/jdk:jdk.publish
117118
//java/src/org/openqa/selenium/remote/http:http.publish
118119
//java/src/org/openqa/selenium/remote:remote.publish

java/private/selenium_test.bzl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,12 +114,12 @@ def selenium_test(name, test_class, size = "medium", browsers = DEFAULT_BROWSERS
114114
size = size,
115115
jvm_flags = BROWSERS[browser]["jvm_flags"] + jvm_flags + [
116116
"-Dselenium.browser.remote=true",
117-
"-Dselenium.browser.remote.path=$(location @selenium//java/src/org/openqa/selenium/grid:selenium_server_deploy.jar)",
117+
"-Dselenium.browser.remote.path=$(location @selenium//java/src/org/openqa/selenium/grid:selenium_server)",
118118
],
119119
# No need to lint remote tests as the code for non-remote is the same and they get linted
120-
tags = BROWSERS[browser]["tags"] + tags + ["remote", "no-lint"],
120+
tags = BROWSERS[browser]["tags"] + tags + ["remote-browser", "no-lint"],
121121
data = BROWSERS[browser]["data"] + data + [
122-
"@selenium//java/src/org/openqa/selenium/grid:selenium_server_deploy.jar",
122+
"@selenium//java/src/org/openqa/selenium/grid:selenium_server",
123123
],
124124
**stripped_args
125125
)

java/src/dev/selenium/tools/javadoc/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ java_binary(
1313
"//visibility:public",
1414
],
1515
deps = [
16-
"//java/src/org/openqa/selenium/io",
16+
"//java/src/org/openqa/selenium/os",
1717
"@rules_jvm_external//private/tools/java/com/github/bazelbuild/rules_jvm_external/zip",
1818
],
1919
)

java/src/org/openqa/selenium/BUILD.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
load("//java:version.bzl", "SE_VERSION")
21
load("//java:defs.bzl", "java_dist_zip", "java_export", "java_import", "javadoc")
2+
load("//java:version.bzl", "SE_VERSION")
33
load("//java/src/org/openqa/selenium/devtools:versions.bzl", "CDP_DEPS")
44

55
filegroup(

java/src/org/openqa/selenium/io/BUILD.bazel

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,8 @@ java_library(
44
name = "io",
55
srcs = glob(["*.java"]),
66
visibility = [
7-
"//java/src/dev/selenium/tools/jar:__pkg__",
8-
"//java/src/dev/selenium/tools/javadoc:__pkg__",
97
"//java/src/dev/selenium/tools/modules:__pkg__",
108
"//java/src/org/openqa/selenium/os:__pkg__",
11-
"//java/src/org/openqa/selenium/remote:__pkg__",
129
"//java/test/org/openqa/selenium/io:__pkg__",
1310
],
1411
)

java/src/org/openqa/selenium/manager/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ java_export(
1919
deps = [
2020
"//java/src/org/openqa/selenium:core",
2121
"//java/src/org/openqa/selenium/json",
22+
"//java/src/org/openqa/selenium/os",
2223
artifact("com.google.guava:guava"),
2324
],
2425
)

java/src/org/openqa/selenium/manager/SeleniumManager.java

Lines changed: 84 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -16,32 +16,33 @@
1616
// under the License.
1717
package org.openqa.selenium.manager;
1818

19-
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
20-
import static org.openqa.selenium.Platform.MAC;
21-
import static org.openqa.selenium.Platform.WINDOWS;
19+
import org.openqa.selenium.Beta;
20+
import org.openqa.selenium.Capabilities;
21+
import org.openqa.selenium.Platform;
22+
import org.openqa.selenium.Proxy;
23+
import org.openqa.selenium.WebDriverException;
24+
import org.openqa.selenium.json.Json;
25+
import org.openqa.selenium.json.JsonException;
26+
import org.openqa.selenium.manager.SeleniumManagerOutput.Result;
27+
import org.openqa.selenium.os.CommandLine;
2228

23-
import com.google.common.io.CharStreams;
24-
import java.io.File;
2529
import java.io.IOException;
2630
import java.io.InputStream;
27-
import java.io.InputStreamReader;
28-
import java.nio.charset.StandardCharsets;
31+
import java.nio.file.FileVisitResult;
2932
import java.nio.file.Files;
3033
import java.nio.file.Path;
34+
import java.nio.file.SimpleFileVisitor;
35+
import java.nio.file.attribute.BasicFileAttributes;
3136
import java.util.ArrayList;
3237
import java.util.Arrays;
3338
import java.util.List;
3439
import java.util.Map;
3540
import java.util.logging.Level;
3641
import java.util.logging.Logger;
37-
import org.openqa.selenium.Beta;
38-
import org.openqa.selenium.Capabilities;
39-
import org.openqa.selenium.Platform;
40-
import org.openqa.selenium.Proxy;
41-
import org.openqa.selenium.WebDriverException;
42-
import org.openqa.selenium.json.Json;
43-
import org.openqa.selenium.json.JsonException;
44-
import org.openqa.selenium.manager.SeleniumManagerOutput.Result;
42+
43+
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
44+
import static org.openqa.selenium.Platform.MAC;
45+
import static org.openqa.selenium.Platform.WINDOWS;
4546

4647
/**
4748
* This implementation is still in beta, and may change.
@@ -67,17 +68,17 @@ public class SeleniumManager {
6768

6869
private static volatile SeleniumManager manager;
6970

70-
private File binary;
71+
private Path binary;
7172

7273
/** Wrapper for the Selenium Manager binary. */
7374
private SeleniumManager() {
7475
Runtime.getRuntime()
7576
.addShutdownHook(
7677
new Thread(
7778
() -> {
78-
if (binary != null && binary.exists()) {
79+
if (binary != null && Files.exists(binary)) {
7980
try {
80-
Files.delete(binary.toPath());
81+
Files.delete(binary);
8182
} catch (IOException e) {
8283
LOG.warning(
8384
String.format(
@@ -102,26 +103,26 @@ public static SeleniumManager getInstance() {
102103
/**
103104
* Executes a process with the given arguments.
104105
*
105-
* @param command the file and arguments to execute.
106+
* @param arguments the file and arguments to execute.
106107
* @return the standard output of the execution.
107108
*/
108-
private static Result runCommand(String... command) {
109-
LOG.fine(String.format("Executing Process: %s", Arrays.toString(command)));
109+
private static Result runCommand(Path binary, List<String> arguments) {
110+
LOG.fine(String.format("Executing Process: %s", arguments));
111+
110112
String output;
111113
int code;
112114
try {
113-
Process process = new ProcessBuilder(command).redirectErrorStream(true).start();
114-
process.waitFor();
115-
code = process.exitValue();
116-
output =
117-
CharStreams.toString(
118-
new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8));
119-
} catch (InterruptedException e) {
120-
Thread.currentThread().interrupt();
121-
throw new WebDriverException(
122-
"Interrupted while running command: " + Arrays.toString(command), e);
115+
CommandLine command = new CommandLine(binary.toAbsolutePath().toString(), arguments.toArray(new String[0]));
116+
command.copyOutputTo(System.err);
117+
command.executeAsync();
118+
command.waitFor(10000); // A generous timeout
119+
if (command.isRunning()) {
120+
LOG.warning("Selenium Manager did not exit");
121+
}
122+
code = command.getExitCode();
123+
output = command.getStdOut();
123124
} catch (Exception e) {
124-
throw new WebDriverException("Failed to run command: " + Arrays.toString(command), e);
125+
throw new WebDriverException("Failed to run command: " + arguments, e);
125126
}
126127
SeleniumManagerOutput jsonOutput = null;
127128
JsonException failedToParse = null;
@@ -148,13 +149,13 @@ private static Result runCommand(String... command) {
148149
"Command failed with code: "
149150
+ code
150151
+ ", executed: "
151-
+ Arrays.toString(command)
152+
+ arguments
152153
+ "\n"
153154
+ dump,
154155
failedToParse);
155156
} else if (failedToParse != null || jsonOutput == null) {
156157
throw new WebDriverException(
157-
"Failed to parse json output, executed: " + Arrays.toString(command) + "\n" + dump,
158+
"Failed to parse json output, executed: " + arguments + "\n" + dump,
158159
failedToParse);
159160
}
160161
return jsonOutput.result;
@@ -165,7 +166,7 @@ private static Result runCommand(String... command) {
165166
*
166167
* @return the path to the Selenium Manager binary.
167168
*/
168-
private synchronized File getBinary() {
169+
private synchronized Path getBinary() {
169170
if (binary == null) {
170171
try {
171172
Platform current = Platform.getCurrent();
@@ -180,12 +181,13 @@ private synchronized File getBinary() {
180181
String binaryPath = String.format("%s/%s%s", folder, SELENIUM_MANAGER, extension);
181182
try (InputStream inputStream = this.getClass().getResourceAsStream(binaryPath)) {
182183
Path tmpPath = Files.createTempDirectory(SELENIUM_MANAGER + System.nanoTime());
183-
File tmpFolder = tmpPath.toFile();
184-
tmpFolder.deleteOnExit();
185-
binary = new File(tmpFolder, SELENIUM_MANAGER + extension);
186-
Files.copy(inputStream, binary.toPath(), REPLACE_EXISTING);
184+
185+
deleteOnExit(tmpPath);
186+
187+
binary = tmpPath.resolve(SELENIUM_MANAGER + extension);
188+
Files.copy(inputStream, binary, REPLACE_EXISTING);
187189
}
188-
binary.setExecutable(true);
190+
binary.toFile().setExecutable(true);
189191
} catch (Exception e) {
190192
throw new WebDriverException("Unable to obtain Selenium Manager Binary", e);
191193
}
@@ -195,6 +197,30 @@ private synchronized File getBinary() {
195197
return binary;
196198
}
197199

200+
private void deleteOnExit(Path tmpPath) {
201+
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
202+
try {
203+
Files.walkFileTree(
204+
tmpPath,
205+
new SimpleFileVisitor<Path>() {
206+
@Override
207+
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
208+
Files.delete(dir);
209+
return FileVisitResult.CONTINUE;
210+
}
211+
212+
@Override
213+
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
214+
Files.delete(file);
215+
return FileVisitResult.CONTINUE;
216+
}
217+
});
218+
} catch (IOException e) {
219+
// Do nothing. We're just tidying up.
220+
}
221+
}));
222+
}
223+
198224
/**
199225
* Returns the browser binary path when present in the vendor options
200226
*
@@ -229,48 +255,48 @@ private String getBrowserBinary(Capabilities options) {
229255
* @return the location of the driver.
230256
*/
231257
public Result getDriverPath(Capabilities options, boolean offline) {
232-
File binaryFile = getBinary();
258+
Path binaryFile = getBinary();
233259
if (binaryFile == null) {
234260
return null;
235261
}
236-
List<String> commandList = new ArrayList<>();
237-
commandList.add(binaryFile.getAbsolutePath());
238-
commandList.add("--browser");
239-
commandList.add(options.getBrowserName());
240-
commandList.add("--output");
241-
commandList.add("json");
262+
263+
List<String> arguments = new ArrayList<>();
264+
arguments.add("--browser");
265+
arguments.add(options.getBrowserName());
266+
arguments.add("--output");
267+
arguments.add("json");
242268

243269
if (!options.getBrowserVersion().isEmpty()) {
244-
commandList.add("--browser-version");
245-
commandList.add(options.getBrowserVersion());
270+
arguments.add("--browser-version");
271+
arguments.add(options.getBrowserVersion());
246272
}
247273

248274
String browserBinary = getBrowserBinary(options);
249275
if (browserBinary != null && !browserBinary.isEmpty()) {
250-
commandList.add("--browser-path");
251-
commandList.add(browserBinary);
276+
arguments.add("--browser-path");
277+
arguments.add(browserBinary);
252278
}
253279

254280
if (getLogLevel().intValue() <= Level.FINE.intValue()) {
255-
commandList.add("--debug");
281+
arguments.add("--debug");
256282
}
257283

258284
if (offline) {
259-
commandList.add("--offline");
285+
arguments.add("--offline");
260286
}
261287

262288
Proxy proxy = (Proxy) options.getCapability("proxy");
263289
if (proxy != null) {
264290
if (proxy.getSslProxy() != null) {
265-
commandList.add("--proxy");
266-
commandList.add(proxy.getSslProxy());
291+
arguments.add("--proxy");
292+
arguments.add(proxy.getSslProxy());
267293
} else if (proxy.getHttpProxy() != null) {
268-
commandList.add("--proxy");
269-
commandList.add(proxy.getHttpProxy());
294+
arguments.add("--proxy");
295+
arguments.add(proxy.getHttpProxy());
270296
}
271297
}
272298

273-
Result result = runCommand(commandList.toArray(new String[0]));
299+
Result result = runCommand(binaryFile, arguments);
274300
LOG.fine(
275301
String.format(
276302
"Using driver at location: %s, browser at location %s",

java/src/org/openqa/selenium/manager/SeleniumManagerOutput.java

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
package org.openqa.selenium.manager;
1818

1919
import java.util.List;
20+
import java.util.Objects;
21+
2022
import org.openqa.selenium.json.JsonInput;
2123

2224
public class SeleniumManagerOutput {
@@ -119,6 +121,30 @@ public void setBrowserPath(String browserPath) {
119121
this.browserPath = browserPath;
120122
}
121123

124+
@Override
125+
public String toString() {
126+
return "Result{" +
127+
"code=" + code +
128+
", message='" + message + '\'' +
129+
", driverPath='" + driverPath + '\'' +
130+
", browserPath='" + browserPath + '\'' +
131+
'}';
132+
}
133+
134+
@Override
135+
public boolean equals(Object o) {
136+
if (!(o instanceof Result)) {
137+
return false;
138+
}
139+
Result that = (Result) o;
140+
return code == that.code && Objects.equals(message, that.message) && Objects.equals(driverPath, that.driverPath) && Objects.equals(browserPath, that.browserPath);
141+
}
142+
143+
@Override
144+
public int hashCode() {
145+
return Objects.hash(code, message, driverPath, browserPath);
146+
}
147+
122148
public static Result fromJson(JsonInput input) {
123149
int code = 0;
124150
String message = null;

java/src/org/openqa/selenium/os/BUILD.bazel

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,13 @@
11
load("@rules_jvm_external//:defs.bzl", "artifact")
2-
load("//java:defs.bzl", "java_library")
2+
load("//java:defs.bzl", "java_export")
3+
load("//java:version.bzl", "SE_VERSION")
34

4-
java_library(
5+
java_export(
56
name = "os",
67
srcs = glob(["*.java"]),
7-
visibility = [
8-
"//java/src/org/openqa/selenium:__pkg__",
9-
"//java/src/org/openqa/selenium/remote:__pkg__",
10-
"//java/test/org/openqa/selenium:__subpackages__",
11-
"//java/test/org/openqa/selenium/build:__pkg__",
12-
"//java/test/org/openqa/selenium/testing/drivers:__pkg__",
13-
],
8+
maven_coordinates = "org.seleniumhq.selenium:selenium-os:%s" % SE_VERSION,
9+
pom_template = "//java/src/org/openqa/selenium:template-pom",
10+
visibility = ["//visibility:public"],
1411
deps = [
1512
"//java/src/org/openqa/selenium:core",
1613
"//java/src/org/openqa/selenium/io",

java/src/org/openqa/selenium/remote/BUILD.bazel

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ java_export(
2626
"//java/src/org/openqa/selenium/bidi:augmenter",
2727
"//java/src/org/openqa/selenium/devtools",
2828
"//java/src/org/openqa/selenium/devtools:augmenter",
29-
"//java/src/org/openqa/selenium/io",
3029
"//java/src/org/openqa/selenium/os",
3130
"//java/src/org/openqa/selenium/remote/http",
3231
"//java/src/org/openqa/selenium/remote/locators",
@@ -53,7 +52,6 @@ java_library(
5352
"//java/src/org/openqa/selenium/bidi",
5453
"//java/src/org/openqa/selenium/concurrent",
5554
"//java/src/org/openqa/selenium/devtools",
56-
"//java/src/org/openqa/selenium/io",
5755
"//java/src/org/openqa/selenium/json",
5856
"//java/src/org/openqa/selenium/manager",
5957
"//java/src/org/openqa/selenium/os",

0 commit comments

Comments
 (0)