diff --git a/MODULE.bazel b/MODULE.bazel index 3a2744b6ae952..d623308cfd181 100644 --- a/MODULE.bazel +++ b/MODULE.bazel @@ -228,6 +228,8 @@ maven.install( "org.slf4j:slf4j-jdk14:2.0.17", "org.tomlj:tomlj:1.1.1", "org.zeromq:jeromq:0.6.0", + "uk.org.webcompere:system-stubs-jupiter:2.1.8", + "uk.org.webcompere:system-stubs-core:2.1.8", ], boms = [ "io.opentelemetry:opentelemetry-bom:1.50.0", diff --git a/java/maven_install.json b/java/maven_install.json index 4637eabe2ad65..2339401e18213 100644 --- a/java/maven_install.json +++ b/java/maven_install.json @@ -1,7 +1,7 @@ { "__AUTOGENERATED_FILE_DO_NOT_MODIFY_THIS_FILE_MANUALLY": "THERE_IS_NO_DATA_ONLY_ZUUL", - "__INPUT_ARTIFACTS_HASH": -952221507, - "__RESOLVED_ARTIFACTS_HASH": -405645956, + "__INPUT_ARTIFACTS_HASH": -1882913193, + "__RESOLVED_ARTIFACTS_HASH": -76667375, "artifacts": { "com.beust:jcommander": { "shasums": { @@ -793,11 +793,26 @@ "sources": "f04df788868c471833d4aff0c9fdced4042069efe392c768f4373c04b559f5e3" }, "version": "0.1.1-beta2" + }, + "uk.org.webcompere:system-stubs-core": { + "shasums": { + "jar": "9c27322cfc7043c75384ad444007b0880ca18fe7231d69bfa69616bc773cafe1", + "sources": "6e6c4adf9094e0200400a5d9f8086c8a1c4a0940919fe0b30d30543b483d5687" + }, + "version": "2.1.8" + }, + "uk.org.webcompere:system-stubs-jupiter": { + "shasums": { + "jar": "9a24867a51f5d22db67d9052a06bc5dd2e9a3e273bc2ee9814620f2d9f25d0a8", + "sources": "208bfe2907ab022fe206402f2ef6b1ea445f8240f072a14a49e338c1448fb2b6" + }, + "version": "2.1.8" } }, "conflict_resolution": { "com.google.errorprone:error_prone_annotations:2.36.0": "com.google.errorprone:error_prone_annotations:2.38.0", "io.projectreactor:reactor-core:3.6.2": "io.projectreactor:reactor-core:3.6.6", + "net.bytebuddy:byte-buddy-agent:1.17.4": "net.bytebuddy:byte-buddy-agent:1.17.5", "org.apache.commons:commons-lang3:3.14.0": "org.apache.commons:commons-lang3:3.17.0", "org.objenesis:objenesis:3.4": "org.objenesis:objenesis:3.3", "org.reactivestreams:reactive-streams:1.0.4": "org.reactivestreams:reactive-streams:1.0.3" @@ -1133,6 +1148,13 @@ ], "redis.clients.authentication:redis-authx-core": [ "org.slf4j:slf4j-api" + ], + "uk.org.webcompere:system-stubs-core": [ + "net.bytebuddy:byte-buddy", + "net.bytebuddy:byte-buddy-agent" + ], + "uk.org.webcompere:system-stubs-jupiter": [ + "uk.org.webcompere:system-stubs-core" ] }, "packages": { @@ -2901,6 +2923,20 @@ ], "redis.clients.authentication:redis-authx-core": [ "redis.clients.authentication.core" + ], + "uk.org.webcompere:system-stubs-core": [ + "uk.org.webcompere.systemstubs", + "uk.org.webcompere.systemstubs.environment", + "uk.org.webcompere.systemstubs.exception", + "uk.org.webcompere.systemstubs.properties", + "uk.org.webcompere.systemstubs.resource", + "uk.org.webcompere.systemstubs.security", + "uk.org.webcompere.systemstubs.stream", + "uk.org.webcompere.systemstubs.stream.input", + "uk.org.webcompere.systemstubs.stream.output" + ], + "uk.org.webcompere:system-stubs-jupiter": [ + "uk.org.webcompere.systemstubs.jupiter" ] }, "repositories": { @@ -3130,7 +3166,11 @@ "org.zeromq:jeromq", "org.zeromq:jeromq:jar:sources", "redis.clients.authentication:redis-authx-core", - "redis.clients.authentication:redis-authx-core:jar:sources" + "redis.clients.authentication:redis-authx-core:jar:sources", + "uk.org.webcompere:system-stubs-core", + "uk.org.webcompere:system-stubs-core:jar:sources", + "uk.org.webcompere:system-stubs-jupiter", + "uk.org.webcompere:system-stubs-jupiter:jar:sources" ] }, "services": { diff --git a/java/src/org/openqa/selenium/chrome/ChromeDriverService.java b/java/src/org/openqa/selenium/chrome/ChromeDriverService.java index 3b1d61446df8f..700faaf90652c 100644 --- a/java/src/org/openqa/selenium/chrome/ChromeDriverService.java +++ b/java/src/org/openqa/selenium/chrome/ChromeDriverService.java @@ -48,6 +48,8 @@ public class ChromeDriverService extends DriverService { */ public static final String CHROME_DRIVER_EXE_PROPERTY = "webdriver.chrome.driver"; + public static final String CHROME_DRIVER_EXE_ENVIRONMENT_VARIABLE = "SE_CHROMEDRIVER"; + /** System property that toggles the formatting of the timestamps of the logs */ public static final String CHROME_DRIVER_READABLE_TIMESTAMP = "webdriver.chrome.readableTimestamp"; @@ -122,6 +124,10 @@ public String getDriverProperty() { return CHROME_DRIVER_EXE_PROPERTY; } + public String getDriverEnvironmentVariable() { + return CHROME_DRIVER_EXE_ENVIRONMENT_VARIABLE; + } + @Override public Capabilities getDefaultDriverOptions() { return new ChromeOptions(); diff --git a/java/src/org/openqa/selenium/edge/EdgeDriverService.java b/java/src/org/openqa/selenium/edge/EdgeDriverService.java index 799e3c3759d95..4564ec8846d1e 100644 --- a/java/src/org/openqa/selenium/edge/EdgeDriverService.java +++ b/java/src/org/openqa/selenium/edge/EdgeDriverService.java @@ -46,6 +46,8 @@ public class EdgeDriverService extends DriverService { */ public static final String EDGE_DRIVER_EXE_PROPERTY = "webdriver.edge.driver"; + public static final String EDGE_DRIVER_EXE_ENVIRONMENT_VARIABLE = "SE_EDGEDRIVER"; + /** System property that toggles the formatting of the timestamps of the logs */ public static final String EDGE_DRIVER_READABLE_TIMESTAMP = "webdriver.edge.readableTimestamp"; @@ -111,6 +113,10 @@ public String getDriverProperty() { return EDGE_DRIVER_EXE_PROPERTY; } + public String getDriverEnvironmentVariable() { + return EDGE_DRIVER_EXE_ENVIRONMENT_VARIABLE; + } + @Override public Capabilities getDefaultDriverOptions() { return new EdgeOptions(); diff --git a/java/src/org/openqa/selenium/firefox/GeckoDriverService.java b/java/src/org/openqa/selenium/firefox/GeckoDriverService.java index 7602085d506f6..c2085408b8162 100644 --- a/java/src/org/openqa/selenium/firefox/GeckoDriverService.java +++ b/java/src/org/openqa/selenium/firefox/GeckoDriverService.java @@ -48,6 +48,8 @@ public class GeckoDriverService extends FirefoxDriverService { */ public static final String GECKO_DRIVER_EXE_PROPERTY = "webdriver.gecko.driver"; + public static final String GECKO_DRIVER_EXE_ENVIRONMENT_VARIABLE = "SE_GECKODRIVER"; + /** * System property that defines the location of the file where GeckoDriver should write log * messages to. @@ -103,6 +105,10 @@ public String getDriverProperty() { return GECKO_DRIVER_EXE_PROPERTY; } + public String getDriverEnvironmentVariable() { + return GECKO_DRIVER_EXE_ENVIRONMENT_VARIABLE; + } + @Override public Capabilities getDefaultDriverOptions() { return new FirefoxOptions(); diff --git a/java/src/org/openqa/selenium/ie/InternetExplorerDriverService.java b/java/src/org/openqa/selenium/ie/InternetExplorerDriverService.java index e66f0eab35a81..5164702bbbaa9 100644 --- a/java/src/org/openqa/selenium/ie/InternetExplorerDriverService.java +++ b/java/src/org/openqa/selenium/ie/InternetExplorerDriverService.java @@ -46,6 +46,8 @@ public class InternetExplorerDriverService extends DriverService { */ public static final String IE_DRIVER_EXE_PROPERTY = "webdriver.ie.driver"; + public static final String IE_DRIVER_EXE_ENVIRONMENT_VARIABLE = "SE_IEDRIVER"; + /** * System property that defines the location of the file where IEDriverServer should write log * messages to. @@ -98,6 +100,10 @@ public String getDriverProperty() { return IE_DRIVER_EXE_PROPERTY; } + public String getDriverEnvironmentVariable() { + return IE_DRIVER_EXE_ENVIRONMENT_VARIABLE; + } + @Override public Capabilities getDefaultDriverOptions() { return new InternetExplorerOptions(); diff --git a/java/src/org/openqa/selenium/remote/service/DriverFinder.java b/java/src/org/openqa/selenium/remote/service/DriverFinder.java index 436878fbbb48f..6972b837c08f4 100644 --- a/java/src/org/openqa/selenium/remote/service/DriverFinder.java +++ b/java/src/org/openqa/selenium/remote/service/DriverFinder.java @@ -96,17 +96,20 @@ private Result getBinaryPaths() { String driverName = service.getDriverName(); result = new Result(service.getExecutable()); if (result.getDriverPath() == null) { - result = new Result(System.getProperty(service.getDriverProperty())); + result = new Result(System.getenv(service.getDriverEnvironmentVariable())); if (result.getDriverPath() == null) { - List arguments = toArguments(); - result = seleniumManager.getBinaryPaths(arguments); - Require.state(options.getBrowserName(), Path.of(result.getBrowserPath())) - .isExecutable(); - } else { - LOG.fine( - String.format( - "Skipping Selenium Manager, path to %s found in system property: %s", - driverName, result.getDriverPath())); + result = new Result(System.getProperty(service.getDriverProperty())); + if (result.getDriverPath() == null) { + List arguments = toArguments(); + result = seleniumManager.getBinaryPaths(arguments); + Require.state(options.getBrowserName(), Path.of(result.getBrowserPath())) + .isExecutable(); + } else { + LOG.fine( + String.format( + "Skipping Selenium Manager, path to %s found in system property: %s", + driverName, result.getDriverPath())); + } } } else { LOG.fine( diff --git a/java/src/org/openqa/selenium/remote/service/DriverService.java b/java/src/org/openqa/selenium/remote/service/DriverService.java index cc16bcb96acca..c62e9d08f998f 100644 --- a/java/src/org/openqa/selenium/remote/service/DriverService.java +++ b/java/src/org/openqa/selenium/remote/service/DriverService.java @@ -154,6 +154,10 @@ protected Capabilities getDefaultDriverOptions() { return null; } + public String getDriverEnvironmentVariable() { + return null; + } + protected @Nullable File getDriverExecutable() { return null; } diff --git a/java/src/org/openqa/selenium/safari/SafariDriverService.java b/java/src/org/openqa/selenium/safari/SafariDriverService.java index 7e49e5ed841a5..e2ee960ffecda 100644 --- a/java/src/org/openqa/selenium/safari/SafariDriverService.java +++ b/java/src/org/openqa/selenium/safari/SafariDriverService.java @@ -49,6 +49,8 @@ public class SafariDriverService extends DriverService { */ public static final String SAFARI_DRIVER_EXE_PROPERTY = "webdriver.safari.driver"; + public static final String SAFARI_DRIVER_EXE_ENVIRONMENT_VARIABLE = "SE_SAFARIDRIVER"; + public static final String SAFARI_DRIVER_LOGGING = "webdriver.safari.logging"; private static final File SAFARI_DRIVER_EXECUTABLE = new File("/usr/bin/safaridriver"); @@ -84,6 +86,10 @@ public String getDriverProperty() { return SAFARI_DRIVER_EXE_PROPERTY; } + public String getDriverEnvironmentVariable() { + return SAFARI_DRIVER_EXE_ENVIRONMENT_VARIABLE; + } + public File getDriverExecutable() { return SAFARI_DRIVER_EXECUTABLE; } diff --git a/java/test/org/openqa/selenium/remote/service/BUILD.bazel b/java/test/org/openqa/selenium/remote/service/BUILD.bazel index 876a43067a485..14e881761b48b 100644 --- a/java/test/org/openqa/selenium/remote/service/BUILD.bazel +++ b/java/test/org/openqa/selenium/remote/service/BUILD.bazel @@ -12,5 +12,7 @@ java_test_suite( artifact("org.junit.jupiter:junit-jupiter-api"), artifact("org.assertj:assertj-core"), artifact("org.mockito:mockito-core"), + artifact("uk.org.webcompere:system-stubs-jupiter"), + artifact("uk.org.webcompere:system-stubs-core"), ] + JUNIT5_DEPS, ) diff --git a/java/test/org/openqa/selenium/remote/service/DriverFinderTest.java b/java/test/org/openqa/selenium/remote/service/DriverFinderTest.java index 53644da24c115..d1a6c8b572be1 100644 --- a/java/test/org/openqa/selenium/remote/service/DriverFinderTest.java +++ b/java/test/org/openqa/selenium/remote/service/DriverFinderTest.java @@ -35,19 +35,26 @@ import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Tag; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.openqa.selenium.Capabilities; import org.openqa.selenium.ImmutableCapabilities; import org.openqa.selenium.Proxy; import org.openqa.selenium.manager.SeleniumManager; import org.openqa.selenium.manager.SeleniumManagerOutput.Result; +import uk.org.webcompere.systemstubs.environment.EnvironmentVariables; +import uk.org.webcompere.systemstubs.jupiter.SystemStub; +import uk.org.webcompere.systemstubs.jupiter.SystemStubsExtension; @Tag("UnitTests") +@ExtendWith(SystemStubsExtension.class) class DriverFinderTest { private final DriverService service = mock(DriverService.class); private final SeleniumManager seleniumManager = mock(SeleniumManager.class); Path driverFile; Path browserFile; + @SystemStub private EnvironmentVariables environment; + @BeforeEach void createMocks() { driverFile = createExecutableFile("testDriver"); @@ -73,6 +80,63 @@ void serviceValueIgnoresSeleniumManager() { void systemPropertyIgnoresSeleniumManager() throws IOException { when(service.getExecutable()).thenReturn(null); when(service.getDriverProperty()).thenReturn("property.ignores.selenium.manager"); + when(service.getDriverEnvironmentVariable()) + .thenReturn("ENVIRONMENT_VARIABLE_IGNORES_SELENIUM_MANAGER"); + System.setProperty("property.ignores.selenium.manager", driverFile.toString()); + + Capabilities capabilities = new ImmutableCapabilities("browserName", "chrome"); + DriverFinder finder = new DriverFinder(service, capabilities); + + assertThat(finder.getDriverPath()).isEqualTo(driverFile.toString()); + assertThat(finder.getBrowserPath()).isNull(); + verify(service, times(1)).getExecutable(); + verify(service, times(1)).getDriverName(); + verify(service, times(1)).getDriverProperty(); + } + + @Test + void environmentVariableIgnoresSeleniumManager() throws IOException { + environment.set("ENVIRONMENT_VARIABLE_DRIVER_PATH", driverFile.toString()); + when(service.getExecutable()).thenReturn(null); + when(service.getDriverProperty()).thenReturn("property.ignores.selenium.manager"); + when(service.getDriverEnvironmentVariable()).thenReturn("ENVIRONMENT_VARIABLE_DRIVER_PATH"); + + Capabilities capabilities = new ImmutableCapabilities("browserName", "chrome"); + DriverFinder finder = new DriverFinder(service, capabilities); + + assertThat(finder.getDriverPath()).isEqualTo(driverFile.toString()); + assertThat(finder.getBrowserPath()).isNull(); + verify(service, times(1)).getExecutable(); + verify(service, times(1)).getDriverName(); + verify(service, times(1)).getDriverEnvironmentVariable(); + } + + @Test + void environmentVariableTakePriorityOverSystemProperty() throws IOException { + environment.set("ENVIRONMENT_VARIABLE_DRIVER_PATH", driverFile.toString()); + when(service.getExecutable()).thenReturn(null); + when(service.getDriverProperty()).thenReturn("property.ignores.selenium.manager"); + when(service.getDriverEnvironmentVariable()).thenReturn("ENVIRONMENT_VARIABLE_DRIVER_PATH"); + + System.setProperty("property.ignores.selenium.manager", "path"); + + Capabilities capabilities = new ImmutableCapabilities("browserName", "chrome"); + DriverFinder finder = new DriverFinder(service, capabilities); + + assertThat(finder.getDriverPath()).isEqualTo(driverFile.toString()); + assertThat(finder.getBrowserPath()).isNull(); + verify(service, times(1)).getExecutable(); + verify(service, times(1)).getDriverName(); + verify(service, times(1)).getDriverEnvironmentVariable(); + } + + @Test + void systemPropertyIsUsedIfEnvironmentVariableIsNotSet() throws IOException { + when(service.getExecutable()).thenReturn(null); + when(service.getDriverProperty()).thenReturn("property.ignores.selenium.manager"); + when(service.getDriverEnvironmentVariable()) + .thenReturn("ENVIRONMENT_VARIABLE_IGNORES_SELENIUM_MANAGER"); + System.setProperty("property.ignores.selenium.manager", driverFile.toString()); Capabilities capabilities = new ImmutableCapabilities("browserName", "chrome"); @@ -82,6 +146,7 @@ void systemPropertyIgnoresSeleniumManager() throws IOException { assertThat(finder.getBrowserPath()).isNull(); verify(service, times(1)).getExecutable(); verify(service, times(1)).getDriverName(); + verify(service, times(1)).getDriverEnvironmentVariable(); verify(service, times(1)).getDriverProperty(); } @@ -89,6 +154,8 @@ void systemPropertyIgnoresSeleniumManager() throws IOException { void createsArgumentsForSeleniumManager() throws IOException { when(service.getExecutable()).thenReturn(null); when(service.getDriverProperty()).thenReturn("property.selenium.manager.empty"); + when(service.getDriverEnvironmentVariable()) + .thenReturn("ENVIRONMENT_VARIABLE_IGNORES_SELENIUM_MANAGER"); Proxy proxy = new Proxy().setHttpProxy("https://localhost:1234"); Capabilities capabilities = @@ -120,6 +187,7 @@ void createsArgumentsForSeleniumManager() throws IOException { verify(service, times(1)).getExecutable(); verify(service, times(1)).getDriverName(); verify(service, times(1)).getDriverProperty(); + verify(service, times(1)).getDriverEnvironmentVariable(); verifyNoMoreInteractions(service); verify(seleniumManager, times(1)).getBinaryPaths(arguments); verifyNoMoreInteractions(seleniumManager); diff --git a/rust/Cargo.Bazel.lock b/rust/Cargo.Bazel.lock index 98cc3ec434b57..230114aaf7d55 100644 --- a/rust/Cargo.Bazel.lock +++ b/rust/Cargo.Bazel.lock @@ -1,5 +1,5 @@ { - "checksum": "4328866a2bfa2153f8c6f066f65ab94f1b037dcd4f169a6f4c6b4e7d243bf750", + "checksum": "0c040d68206ee0e1cb8f4b9750fc838ec1c150da4a76a9c387387684712e8168", "crates": { "addr2line 0.21.0": { "name": "addr2line", @@ -2031,79 +2031,16 @@ "id": "jobserver 0.1.31", "target": "jobserver" }, + { + "id": "libc 0.2.168", + "target": "libc" + }, { "id": "shlex 1.3.0", "target": "shlex" } ], - "selects": { - "aarch64-apple-darwin": [ - { - "id": "libc 0.2.168", - "target": "libc" - } - ], - "aarch64-unknown-linux-gnu": [ - { - "id": "libc 0.2.168", - "target": "libc" - } - ], - "aarch64-unknown-nixos-gnu": [ - { - "id": "libc 0.2.168", - "target": "libc" - } - ], - "arm-unknown-linux-gnueabi": [ - { - "id": "libc 0.2.168", - "target": "libc" - } - ], - "i686-unknown-linux-gnu": [ - { - "id": "libc 0.2.168", - "target": "libc" - } - ], - "powerpc-unknown-linux-gnu": [ - { - "id": "libc 0.2.168", - "target": "libc" - } - ], - "s390x-unknown-linux-gnu": [ - { - "id": "libc 0.2.168", - "target": "libc" - } - ], - "x86_64-apple-darwin": [ - { - "id": "libc 0.2.168", - "target": "libc" - } - ], - "x86_64-unknown-freebsd": [ - { - "id": "libc 0.2.168", - "target": "libc" - } - ], - "x86_64-unknown-linux-gnu": [ - { - "id": "libc 0.2.168", - "target": "libc" - } - ], - "x86_64-unknown-nixos-gnu": [ - { - "id": "libc 0.2.168", - "target": "libc" - } - ] - } + "selects": {} }, "edition": "2018", "version": "1.1.30"