From 5049e23988b3c688aea138f86e630eb784f5a8b1 Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Sun, 21 Dec 2025 22:41:30 -0600 Subject: [PATCH 1/6] [dotnet] run selenium manager tests on CI --- .github/workflows/ci-dotnet.yml | 45 +++++++++-- dotnet/test/common/BUILD.bazel | 10 +-- dotnet/test/common/SeleniumManagerTest.cs | 97 +++++++++++++++++++++++ 3 files changed, 137 insertions(+), 15 deletions(-) create mode 100644 dotnet/test/common/SeleniumManagerTest.cs diff --git a/.github/workflows/ci-dotnet.yml b/.github/workflows/ci-dotnet.yml index 0c88afd629d4c..75943e33ab765 100644 --- a/.github/workflows/ci-dotnet.yml +++ b/.github/workflows/ci-dotnet.yml @@ -8,20 +8,51 @@ jobs: build: name: Build uses: ./.github/workflows/bazel.yml + strategy: + fail-fast: false + matrix: + os: ['windows', 'macos'] with: - name: Build - cache-key: false - os: windows + name: Build (${{ matrix.os }}) + cache-key: dotnet-${{ matrix.os }}-test + os: ${{ matrix.os }} run: bazel build //dotnet:all + manager-tests: + name: Selenium Manager Tests + needs: build + uses: ./.github/workflows/bazel.yml + strategy: + fail-fast: false + matrix: + os: ['windows', 'macos', 'ubuntu'] + with: + name: Manager Tests (${{ matrix.os }}) + cache-key: dotnet-${{ matrix.os }}-test + os: ${{ matrix.os }} + run: > + bazel test + --keep_going + --flaky_test_attempts 3 + --local_test_jobs 1 + --pin_browsers=false + --test_env=SE_FORCE_BROWSER_DOWNLOAD=true + --test_env=SE_SKIP_DRIVER_IN_PATH=true + //dotnet/test/common:SeleniumManagerTest-chrome + //dotnet/test/common:SeleniumManagerTest-firefox + //dotnet/test/common:SeleniumManagerTest-edge + integration-tests: name: Browser Tests uses: ./.github/workflows/bazel.yml with: name: Browser Tests - cache-key: false + cache-key: dotnet-windows-test java-version: 17 os: windows - run: | - fsutil 8dot3name set 0 - bazel test //dotnet/test/common:ElementFindingTest-firefox //dotnet/test/common:ElementFindingTest-chrome + run: > + bazel test + --keep_going + --local_test_jobs 1 + //dotnet/test/common:ElementFindingTest-firefox + //dotnet/test/common:ElementFindingTest-chrome diff --git a/dotnet/test/common/BUILD.bazel b/dotnet/test/common/BUILD.bazel index 2ec48afa81136..a337afc9e3816 100644 --- a/dotnet/test/common/BUILD.bazel +++ b/dotnet/test/common/BUILD.bazel @@ -57,15 +57,9 @@ csharp_library( ], ) -# copy_file( -# name = "manager-macos", -# src = "//common/manager:selenium-manager-macos", -# out = "manager/macos/selenium-manager", -# ) - dotnet_nunit_test_suite( name = "AllTests", - size = "small", + size = "large", srcs = glob([ "**/*Test.cs", "**/*Tests.cs", @@ -77,7 +71,7 @@ dotnet_nunit_test_suite( # The first browser in this list is assumed to be the one that should # be used by default. "firefox", - # "safari", # Skipping safari for now + "safari", # Skipping safari for now "ie", "edge", "chrome", diff --git a/dotnet/test/common/SeleniumManagerTest.cs b/dotnet/test/common/SeleniumManagerTest.cs new file mode 100644 index 0000000000000..be08cee3b8068 --- /dev/null +++ b/dotnet/test/common/SeleniumManagerTest.cs @@ -0,0 +1,97 @@ +// +// 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. +// + +using NUnit.Framework; +using OpenQA.Selenium.Chrome; +using OpenQA.Selenium.Edge; +using OpenQA.Selenium.Environment; +using OpenQA.Selenium.Firefox; +using OpenQA.Selenium.Safari; +using System; +using System.IO; + +namespace OpenQA.Selenium; + +[TestFixture] +[Category("SeleniumManager")] +[IgnoreBrowser(Browser.IE, "IE does not use Selenium Manager")] +[IgnoreBrowser(Browser.Safari, "Safari does not need Selenium Manager")] +[IgnoreBrowser(Browser.Remote, "Remote does not use Selenium Manager directly")] +public class SeleniumManagerTest +{ + private static readonly string CacheDirectory = System.Environment.GetEnvironmentVariable("SE_CACHE") ?? ".cache/selenium"; + + private DriverOptions CreateOptionsForCurrentBrowser() + { + return EnvironmentManager.Instance.Browser switch + { + Browser.Chrome => new ChromeOptions(), + Browser.Firefox => new FirefoxOptions(), + Browser.Edge => new EdgeOptions(), + _ => throw new NotSupportedException($"Browser {EnvironmentManager.Instance.Browser} is not supported for Selenium Manager tests") + }; + } + + private DriverService CreateServiceForCurrentBrowser(string driverPath) + { + return EnvironmentManager.Instance.Browser switch + { + Browser.Chrome => ChromeDriverService.CreateDefaultService(driverPath), + Browser.Firefox => FirefoxDriverService.CreateDefaultService(driverPath), + Browser.Edge => EdgeDriverService.CreateDefaultService(driverPath), + _ => throw new NotSupportedException($"Browser {EnvironmentManager.Instance.Browser} is not supported for Selenium Manager tests") + }; + } + + [Test] + public void ShouldGetDriverAndBrowserPaths() + { + var options = CreateOptionsForCurrentBrowser(); + var driverFinder = new DriverFinder(options); + + string driverPath = driverFinder.GetDriverPath(); + string browserPath = driverFinder.GetBrowserPath(); + + Assert.That(File.Exists(driverPath), Is.True, $"Driver path should exist: {driverPath}"); + Assert.That(File.Exists(browserPath), Is.True, $"Browser path should exist: {browserPath}"); + Assert.That(driverPath, Does.Contain(CacheDirectory), $"Driver path should contain cache directory: {driverPath}"); + Assert.That(browserPath, Does.Contain(CacheDirectory), $"Browser path should contain cache directory: {browserPath}"); + } + + [Test] + public void ShouldStartDriverService() + { + var options = CreateOptionsForCurrentBrowser(); + var driverFinder = new DriverFinder(options); + + string driverPath = driverFinder.GetDriverPath(); + var service = CreateServiceForCurrentBrowser(driverPath); + + try + { + service.Start(); + Assert.That(service.ServiceUrl, Is.Not.Null); + Assert.That(service.ServiceUrl.IsAbsoluteUri, Is.True); + } + finally + { + service.Dispose(); + } + } +} From 4f4e2964576cffc0c7222bbbb9ba60107b46c018 Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Sun, 21 Dec 2025 23:24:52 -0600 Subject: [PATCH 2/6] skip safari --- dotnet/test/common/BUILD.bazel | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/test/common/BUILD.bazel b/dotnet/test/common/BUILD.bazel index a337afc9e3816..a76aedd2328c7 100644 --- a/dotnet/test/common/BUILD.bazel +++ b/dotnet/test/common/BUILD.bazel @@ -71,7 +71,7 @@ dotnet_nunit_test_suite( # The first browser in this list is assumed to be the one that should # be used by default. "firefox", - "safari", # Skipping safari for now + # "safari", # Skipping safari for now "ie", "edge", "chrome", From 66a72a4ade1de1da2640aff86a34ea3f03458a4b Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Mon, 22 Dec 2025 07:15:18 -0600 Subject: [PATCH 3/6] use the right .NET code --- dotnet/test/common/SeleniumManagerTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/test/common/SeleniumManagerTest.cs b/dotnet/test/common/SeleniumManagerTest.cs index be08cee3b8068..9383af364958d 100644 --- a/dotnet/test/common/SeleniumManagerTest.cs +++ b/dotnet/test/common/SeleniumManagerTest.cs @@ -35,7 +35,7 @@ namespace OpenQA.Selenium; [IgnoreBrowser(Browser.Remote, "Remote does not use Selenium Manager directly")] public class SeleniumManagerTest { - private static readonly string CacheDirectory = System.Environment.GetEnvironmentVariable("SE_CACHE") ?? ".cache/selenium"; + private static readonly string CacheDirectory = System.Environment.GetEnvironmentVariable("SE_CACHE") ?? Path.Combine(".cache", "selenium"); private DriverOptions CreateOptionsForCurrentBrowser() { From 07e191dcfcac2b0bb56ec8feb0d18f4764ae7068 Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Mon, 22 Dec 2025 12:29:51 -0600 Subject: [PATCH 4/6] fix assertion Co-authored-by: Michael Render --- dotnet/test/common/SeleniumManagerTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/test/common/SeleniumManagerTest.cs b/dotnet/test/common/SeleniumManagerTest.cs index 9383af364958d..cba60c463f98a 100644 --- a/dotnet/test/common/SeleniumManagerTest.cs +++ b/dotnet/test/common/SeleniumManagerTest.cs @@ -70,7 +70,7 @@ public void ShouldGetDriverAndBrowserPaths() Assert.That(File.Exists(driverPath), Is.True, $"Driver path should exist: {driverPath}"); Assert.That(File.Exists(browserPath), Is.True, $"Browser path should exist: {browserPath}"); - Assert.That(driverPath, Does.Contain(CacheDirectory), $"Driver path should contain cache directory: {driverPath}"); + Assert.That(driverPath, Is.SubPathOf(CacheDirectory), $"Driver path should be nested under the cache directory: {driverPath}"); Assert.That(browserPath, Does.Contain(CacheDirectory), $"Browser path should contain cache directory: {browserPath}"); } From 3f09a1ab28c287ae7a798bce8689ff26dba004a6 Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Tue, 23 Dec 2025 15:55:15 -0600 Subject: [PATCH 5/6] always use Selenium Manager when pinned browsers are false --- dotnet/private/dotnet_nunit_test_suite.bzl | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/dotnet/private/dotnet_nunit_test_suite.bzl b/dotnet/private/dotnet_nunit_test_suite.bzl index 346174fda35fc..43fe499b3502f 100644 --- a/dotnet/private/dotnet_nunit_test_suite.bzl +++ b/dotnet/private/dotnet_nunit_test_suite.bzl @@ -20,10 +20,7 @@ _BROWSERS = { "--params=DriverServiceLocation=$(location @mac_chromedriver//:chromedriver)", "--params=BrowserLocation=$(location @mac_chrome//:Chrome.app)/Contents/MacOS/Chrome", ], - "@selenium//common:use_local_chromedriver": [], - "//conditions:default": [ - "--where=SkipTest==True", - ], + "//conditions:default": [], }), "data": chrome_data, "tags": [], @@ -40,10 +37,7 @@ _BROWSERS = { "--params=DriverServiceLocation=$(location @mac_edgedriver//:msedgedriver)", "\"--params=BrowserLocation=$(location @mac_edge//:Edge.app)/Contents/MacOS/Microsoft Edge\"", ], - "@selenium//common:use_local_msedgedriver": [], - "//conditions:default": [ - "--where=SkipTest==True", - ], + "//conditions:default": [], }), "data": edge_data, "tags": [], @@ -60,10 +54,7 @@ _BROWSERS = { "--params=DriverServiceLocation=$(location @mac_geckodriver//:geckodriver)", "--params=BrowserLocation=$(location @mac_firefox//:Firefox.app)/Contents/MacOS/firefox", ], - "@selenium//common:use_local_geckodriver": [], - "//conditions:default": [ - "--where=SkipTest==True", - ], + "//conditions:default": [], }), "data": firefox_data, "tags": [], From 8f05f81e7d3398e42493fd6dc5b6110c84834cf2 Mon Sep 17 00:00:00 2001 From: Titus Fortner Date: Wed, 24 Dec 2025 11:21:49 -0600 Subject: [PATCH 6/6] fix subdirectory resolution --- dotnet/test/common/SeleniumManagerTest.cs | 28 ++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/dotnet/test/common/SeleniumManagerTest.cs b/dotnet/test/common/SeleniumManagerTest.cs index cba60c463f98a..7bb70cedd7655 100644 --- a/dotnet/test/common/SeleniumManagerTest.cs +++ b/dotnet/test/common/SeleniumManagerTest.cs @@ -35,7 +35,25 @@ namespace OpenQA.Selenium; [IgnoreBrowser(Browser.Remote, "Remote does not use Selenium Manager directly")] public class SeleniumManagerTest { - private static readonly string CacheDirectory = System.Environment.GetEnvironmentVariable("SE_CACHE") ?? Path.Combine(".cache", "selenium"); + private static readonly string CacheDirectory = ResolveCacheDirectory(); + + private static string ResolveCacheDirectory() + { + string? cacheDirectory = System.Environment.GetEnvironmentVariable("SE_CACHE_PATH"); + + if (!string.IsNullOrWhiteSpace(cacheDirectory)) + { + return cacheDirectory; + } + + string homeDirectory = System.Environment.GetFolderPath(System.Environment.SpecialFolder.UserProfile); + if (!string.IsNullOrWhiteSpace(homeDirectory)) + { + return Path.Combine(homeDirectory, ".cache", "selenium"); + } + + return Path.Combine(".cache", "selenium"); + } private DriverOptions CreateOptionsForCurrentBrowser() { @@ -70,8 +88,12 @@ public void ShouldGetDriverAndBrowserPaths() Assert.That(File.Exists(driverPath), Is.True, $"Driver path should exist: {driverPath}"); Assert.That(File.Exists(browserPath), Is.True, $"Browser path should exist: {browserPath}"); - Assert.That(driverPath, Is.SubPathOf(CacheDirectory), $"Driver path should be nested under the cache directory: {driverPath}"); - Assert.That(browserPath, Does.Contain(CacheDirectory), $"Browser path should contain cache directory: {browserPath}"); + string fullCacheDirectory = Path.GetFullPath(CacheDirectory); + string fullDriverPath = Path.GetFullPath(driverPath); + string fullBrowserPath = Path.GetFullPath(browserPath); + + Assert.That(fullDriverPath, Is.SubPathOf(fullCacheDirectory), $"Driver path should be nested under the cache directory: {fullDriverPath}"); + Assert.That(fullBrowserPath, Does.Contain(fullCacheDirectory), $"Browser path should contain cache directory: {fullBrowserPath}"); } [Test]