diff --git a/.github/workflows/ci-java.yml b/.github/workflows/ci-java.yml index f04334fba068c..13712413be43d 100644 --- a/.github/workflows/ci-java.yml +++ b/.github/workflows/ci-java.yml @@ -5,71 +5,50 @@ on: workflow_dispatch: jobs: - browser-tests-windows: + browser-tests: name: Browser Tests uses: ./.github/workflows/bazel.yml strategy: fail-fast: false matrix: - include: - - os: windows + os: + - ubuntu + - windows + - macos with: - name: Browser Tests (chrome, ${{ matrix.os }}) + name: Browser Tests (${{ matrix.os }}) os: ${{ matrix.os }} - browser: chrome cache-key: java-${{ matrix.os }}-tests - # rules_jvm_external is not fully hermetic - # https://github.com/bazelbuild/rules_jvm_external/issues/1046 java-version: 17 - run: | - fsutil 8dot3name set 0 - bazel test --flaky_test_attempts 3 //java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest ` - //java/test/org/openqa/selenium/federatedcredentialmanagement:FederatedCredentialManagementTest ` - //java/test/org/openqa/selenium/firefox:FirefoxDriverBuilderTest ` - //java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest ` - //java/test/org/openqa/selenium/remote:RemoteWebDriverBuilderTest ` - //java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest ` - //java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest - - browser-tests-macos: - name: Browser Tests - uses: ./.github/workflows/bazel.yml - strategy: - fail-fast: false - matrix: - include: - - os: macos - with: - name: Browser Tests (chrome, ${{ matrix.os }}) - os: ${{ matrix.os }} - browser: chrome - cache-key: java-${{ matrix.os }}-tests - # rules_jvm_external is not fully hermetic - # https://github.com/bazelbuild/rules_jvm_external/issues/1046 - java-version: 17 - run: | - bazel test --flaky_test_attempts 3 //java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest-remote \ - //java/test/org/openqa/selenium/federatedcredentialmanagement:FederatedCredentialManagementTest \ - //java/test/org/openqa/selenium/firefox:FirefoxDriverBuilderTest \ - //java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest \ - //java/test/org/openqa/selenium/remote:RemoteWebDriverBuilderTest \ - //java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest - - remote-tests: - name: Remote Tests - uses: ./.github/workflows/bazel.yml - strategy: - fail-fast: false - matrix: - include: - - os: macos - with: - name: Remote Tests (chrome, ${{ matrix.os }}) - os: ${{ matrix.os }} - browser: chrome - cache-key: java-${{ matrix.os }}-remote-tests - # rules_jvm_external is not fully hermetic - # https://github.com/bazelbuild/rules_jvm_external/issues/1046 - java-version: 17 - run: | - bazel test --flaky_test_attempts 3 //java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest-remote + # Targets: + # 1. Browser functional tests (local & remote) + # 2. Selenium Manager tests + # 3. Tests skipped in .skipped-tests (cannot run on RBE) + run: > + bazel test + --flaky_test_attempts 3 + --pin_browsers=false + --test_env=SE_FORCE_BROWSER_DOWNLOAD=true + --test_env=SE_SKIP_DRIVER_IN_PATH=true + //java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest + //java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest-remote + //java/test/org/openqa/selenium/edge:EdgeDriverFunctionalTest + //java/test/org/openqa/selenium/edge:EdgeDriverFunctionalTest-remote + //java/test/org/openqa/selenium/firefox:FirefoxDriverBuilderTest + //java/test/org/openqa/selenium/firefox:RemoteFirefoxDriverTest + //java/test/org/openqa/selenium/manager:SeleniumManagerTest + //java/test/org/openqa/selenium/manager:SeleniumManagerTest-chrome + //java/test/org/openqa/selenium/manager:SeleniumManagerTest-edge + //java/test/org/openqa/selenium/manager:SeleniumManagerTest-safari + //java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest + //java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest-remote + //java/test/org/openqa/selenium/federatedcredentialmanagement:FederatedCredentialManagementTest + //java/test/org/openqa/selenium/grid/gridui:OverallGridTest + //java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest + //java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest-chrome + //java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest-chrome-remote + //java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest-edge + //java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest-edge-remote + //java/test/org/openqa/selenium/grid/router:RemoteWebDriverDownloadTest-remote + //java/test/org/openqa/selenium/remote:RemoteWebDriverBuilderTest + //java/test/org/openqa/selenium/remote:RemoteWebDriverScreenshotTest-remote diff --git a/.skipped-tests b/.skipped-tests index 41f225a3d45c6..e5140b9ed2290 100644 --- a/.skipped-tests +++ b/.skipped-tests @@ -4,7 +4,6 @@ -//java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest -//java/test/org/openqa/selenium/chrome:ChromeDriverFunctionalTest-remote -//java/test/org/openqa/selenium/edge:EdgeDriverFunctionalTest --//java/test/org/openqa/selenium/edge:EdgeDriverFunctionalTest-edge -//java/test/org/openqa/selenium/edge:EdgeDriverFunctionalTest-remote -//java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest -//java/test/org/openqa/selenium/devtools:NetworkInterceptorRestTest-remote diff --git a/java/src/org/openqa/selenium/manager/SeleniumManager.java b/java/src/org/openqa/selenium/manager/SeleniumManager.java index bed9e56e08dbe..ce3f88a2cd070 100644 --- a/java/src/org/openqa/selenium/manager/SeleniumManager.java +++ b/java/src/org/openqa/selenium/manager/SeleniumManager.java @@ -286,17 +286,19 @@ private Level getLogLevel() { return level; } - private Path getBinaryInCache(String binaryName) throws IOException { - + Path getCachePath() { // Look for cache path as system property or env String cachePath = System.getProperty(CACHE_PATH_ENV, ""); if (cachePath.isEmpty()) cachePath = System.getenv(CACHE_PATH_ENV); if (cachePath == null) cachePath = DEFAULT_CACHE_PATH; cachePath = cachePath.replace(HOME, System.getProperty("user.home")); + return Paths.get(cachePath); + } + private Path getBinaryInCache(String binaryName) throws IOException { // If cache path is not writable, SM will be extracted to a temporal folder - Path cacheParent = Paths.get(cachePath); + Path cacheParent = getCachePath(); if (!Files.isWritable(cacheParent)) { cacheParent = Files.createTempDirectory(SELENIUM_MANAGER); binaryInTemporalFolder = true; diff --git a/java/src/org/openqa/selenium/remote/service/DriverService.java b/java/src/org/openqa/selenium/remote/service/DriverService.java index 371a192fb9bdf..8b554c1b60d6b 100644 --- a/java/src/org/openqa/selenium/remote/service/DriverService.java +++ b/java/src/org/openqa/selenium/remote/service/DriverService.java @@ -142,7 +142,7 @@ protected URL getUrl(int port) throws IOException { return new URL(String.format(Locale.ROOT, "http://localhost:%d", port)); } - protected Capabilities getDefaultDriverOptions() { + public Capabilities getDefaultDriverOptions() { return new ImmutableCapabilities(); } diff --git a/java/src/org/openqa/selenium/safari/SafariDriverService.java b/java/src/org/openqa/selenium/safari/SafariDriverService.java index 4e0b4f2bdf674..f81297d4a4dd9 100644 --- a/java/src/org/openqa/selenium/safari/SafariDriverService.java +++ b/java/src/org/openqa/selenium/safari/SafariDriverService.java @@ -96,7 +96,7 @@ public File getDriverExecutable() { } @Override - protected Capabilities getDefaultDriverOptions() { + public Capabilities getDefaultDriverOptions() { return new SafariOptions(); } diff --git a/java/test/org/openqa/selenium/edge/EdgeDriverFunctionalTest.java b/java/test/org/openqa/selenium/edge/EdgeDriverFunctionalTest.java index df8c87af2e490..ee9cf0e0f1331 100644 --- a/java/test/org/openqa/selenium/edge/EdgeDriverFunctionalTest.java +++ b/java/test/org/openqa/selenium/edge/EdgeDriverFunctionalTest.java @@ -58,7 +58,7 @@ public void builderGeneratesDefaultEdgeOptions() { Capabilities capabilities = ((EdgeDriver) localDriver).getCapabilities(); assertThat(localDriver.manage().timeouts().getImplicitWaitTimeout()).isEqualTo(Duration.ZERO); - assertThat(capabilities.getCapability("browserName")).isEqualTo("msedge"); + assertThat(capabilities.getCapability("browserName")).isEqualTo("MicrosoftEdge"); } @Test diff --git a/java/test/org/openqa/selenium/grid/router/BUILD.bazel b/java/test/org/openqa/selenium/grid/router/BUILD.bazel index 9707792d9e267..91716fe47ac5c 100644 --- a/java/test/org/openqa/selenium/grid/router/BUILD.bazel +++ b/java/test/org/openqa/selenium/grid/router/BUILD.bazel @@ -11,11 +11,8 @@ LARGE_TESTS = [ "DistributedTest.java", "DistributedCdpTest.java", "NewSessionCreationTest.java", - "RemoteWebDriverDownloadTest.java", -] - -FIREFOX_CHROMIUM_ONLY_LARGE_TESTS = [ "RemoteWebDriverBiDiTest.java", + "RemoteWebDriverDownloadTest.java", ] java_library( @@ -91,6 +88,10 @@ java_selenium_test_suite( ], deps = [ ":support", + "//java/src/org/openqa/selenium/bidi", + "//java/src/org/openqa/selenium/bidi/browsingcontext", + "//java/src/org/openqa/selenium/bidi/log", + "//java/src/org/openqa/selenium/bidi/module", "//java/src/org/openqa/selenium/chrome", "//java/src/org/openqa/selenium/firefox", "//java/src/org/openqa/selenium/grid", @@ -111,38 +112,12 @@ java_selenium_test_suite( ] + CDP_DEPS + JUNIT5_DEPS, ) -java_selenium_test_suite( - name = "firefox-chromium-only-large-tests", - size = "large", - srcs = FIREFOX_CHROMIUM_ONLY_LARGE_TESTS, - browsers = [ - "firefox", - "chrome", - "edge", - ], - deps = [ - ":support", - "//java/src/org/openqa/selenium/bidi", - "//java/src/org/openqa/selenium/bidi/browsingcontext", - "//java/src/org/openqa/selenium/bidi/log", - "//java/src/org/openqa/selenium/bidi/module", - "//java/src/org/openqa/selenium/firefox", - "//java/src/org/openqa/selenium/grid/config", - "//java/src/org/openqa/selenium/remote", - "//java/test/org/openqa/selenium/environment", - "//java/test/org/openqa/selenium/testing:annotations", - "//java/test/org/openqa/selenium/testing:test-base", - artifact("org.junit.jupiter:junit-jupiter-api"), - artifact("org.assertj:assertj-core"), - ] + CDP_DEPS + JUNIT5_DEPS, -) - java_test_suite( name = "medium-tests", size = "medium", srcs = glob( ["*Test.java"], - exclude = LARGE_TESTS + FIREFOX_CHROMIUM_ONLY_LARGE_TESTS + STRESS_TESTS, + exclude = LARGE_TESTS + STRESS_TESTS, ), tags = [ "requires-network", diff --git a/java/test/org/openqa/selenium/manager/BUILD.bazel b/java/test/org/openqa/selenium/manager/BUILD.bazel new file mode 100644 index 0000000000000..e5b18edea3bbb --- /dev/null +++ b/java/test/org/openqa/selenium/manager/BUILD.bazel @@ -0,0 +1,36 @@ +load("@rules_jvm_external//:defs.bzl", "artifact") +load("//java:defs.bzl", "JUNIT5_DEPS", "java_selenium_test_suite") +load("//java:version.bzl", "TOOLS_JAVA_VERSION") + +java_selenium_test_suite( + name = "medium-tests", + size = "medium", + srcs = ["SeleniumManagerTest.java"], + browsers = [ + "chrome", + "edge", + "firefox", + "safari", + ], + env = { + "SE_FORCE_BROWSER_DOWNLOAD": "true", + }, + javacopts = [ + "--release", + TOOLS_JAVA_VERSION, + ], + tags = ["skip-rbe"], + deps = [ + "//java/src/org/openqa/selenium/chrome", + "//java/src/org/openqa/selenium/edge", + "//java/src/org/openqa/selenium/firefox", + "//java/src/org/openqa/selenium/manager", + "//java/src/org/openqa/selenium/remote", + "//java/src/org/openqa/selenium/safari", + "//java/test/org/openqa/selenium/testing:annotations", + "//java/test/org/openqa/selenium/testing:test-base", + "//java/test/org/openqa/selenium/testing/drivers", + artifact("org.junit.jupiter:junit-jupiter-api"), + artifact("org.assertj:assertj-core"), + ] + JUNIT5_DEPS, +) diff --git a/java/test/org/openqa/selenium/manager/SeleniumManagerTest.java b/java/test/org/openqa/selenium/manager/SeleniumManagerTest.java new file mode 100644 index 0000000000000..2dd446f8e02d3 --- /dev/null +++ b/java/test/org/openqa/selenium/manager/SeleniumManagerTest.java @@ -0,0 +1,123 @@ +// Licensed to the Software Freedom Conservancy (SFC) under one +// or more contributor license agreements. See the NOTICE file +// distributed with this work for additional information +// regarding copyright ownership. The SFC licenses this file +// to you 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 org.openqa.selenium.manager; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.openqa.selenium.chrome.ChromeDriverService; +import org.openqa.selenium.edge.EdgeDriverService; +import org.openqa.selenium.firefox.GeckoDriverService; +import org.openqa.selenium.io.FileHandler; +import org.openqa.selenium.remote.service.DriverFinder; +import org.openqa.selenium.remote.service.DriverService; +import org.openqa.selenium.safari.SafariDriverService; +import org.openqa.selenium.testing.JupiterTestBase; +import org.openqa.selenium.testing.NoDriverBeforeTest; +import org.openqa.selenium.testing.drivers.Browser; + +class SeleniumManagerTest extends JupiterTestBase { + + private DriverService service; + Path cachePath = SeleniumManager.getInstance().getCachePath(); + Browser browser = Browser.detect(); + + @BeforeEach + void removeCachedBinary() throws IOException { + Path cachedManager = cachePath.resolve("manager"); + if (Files.exists(cachedManager) && !FileHandler.delete(cachedManager.toFile())) { + throw new IOException("Unable to delete cached Selenium Manager directory: " + cachedManager); + } + } + + @AfterEach + void stopService() { + if (service != null) { + service.stop(); + } + } + + @Test + @NoDriverBeforeTest + void startsService() throws IOException { + String driverProperty = driverExecutableProperty(browser); + String previousPath = System.getProperty(driverProperty); + try { + System.clearProperty(driverProperty); + + service = buildService(browser); + Assertions.assertThat(service.getExecutable()).isNull(); + + DriverFinder finder = new DriverFinder(service, service.getDefaultDriverOptions()); + String driverPath = finder.getDriverPath(); + String browserPath = finder.getBrowserPath(); + + Assertions.assertThat(Files.isExecutable(Path.of(driverPath))).isTrue(); + Assertions.assertThat(Files.isExecutable(Path.of(browserPath))).isTrue(); + if (browser != Browser.SAFARI) { + Assertions.assertThat(driverPath).contains(cachePath.toString()); + Assertions.assertThat(browserPath).contains(cachePath.toString()); + } + + service.setExecutable(driverPath); + service.start(); + + Assertions.assertThat(service.isRunning()).isTrue(); + } finally { + if (previousPath == null) { + System.clearProperty(driverProperty); + } else { + System.setProperty(driverProperty, previousPath); + } + } + } + + private DriverService buildService(Browser browser) { + switch (browser) { + case CHROME: + return new ChromeDriverService.Builder().build(); + case EDGE: + return new EdgeDriverService.Builder().build(); + case FIREFOX: + return new GeckoDriverService.Builder().build(); + case SAFARI: + return new SafariDriverService.Builder().build(); + default: + throw new IllegalStateException("Unsupported browser: " + browser); + } + } + + private String driverExecutableProperty(Browser browser) { + switch (browser) { + case CHROME: + return ChromeDriverService.CHROME_DRIVER_EXE_PROPERTY; + case EDGE: + return EdgeDriverService.EDGE_DRIVER_EXE_PROPERTY; + case FIREFOX: + return GeckoDriverService.GECKO_DRIVER_EXE_PROPERTY; + case SAFARI: + return SafariDriverService.SAFARI_DRIVER_EXE_PROPERTY; + default: + throw new IllegalStateException("Unsupported browser: " + browser); + } + } +}