Skip to content

Improve stability of Selenium tests #5367

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 8, 2025
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,44 +22,81 @@ public static class SeleniumExtensions
private static readonly TimeSpan ExplicitTimespan = TimeSpan.FromSeconds(20);
private static readonly TimeSpan ShortExplicitTimespan = TimeSpan.FromSeconds(5);

public static IWebDriver CreateDefaultWebDriver()
public static IWebDriver CreateDefaultWebDriver(int maxRetries = 3, int timeoutSeconds = 30)
{
// ---------- Chrome launch flags ----------
var options = new ChromeOptions();
options.AddArguments(
"--headless=new", // modern headless mode (remove this for debugging)
"--disable-gpu",
"--window-size=1920,1080",
"--remote-allow-origins=*",
"--disable-dev-shm-usage"); // avoids crashes in low-memory containers

// ---------- Pick a driver binary ----------
// 1) Prefer explicit env-var so devs can override locally
var driverDir = Environment.GetEnvironmentVariable("CHROMEWEBDRIVER");

// 2) Otherwise use the folder where CI drops a matching chromedriver
if (string.IsNullOrEmpty(driverDir))

for (int attempt = 1; attempt <= maxRetries; attempt++)
{
driverDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "drivers");
}
try
{
Trace.WriteLine($"[Selenium] Creating Chrome WebDriver (attempt {attempt}/{maxRetries})");

// ---------- Chrome launch flags ----------
var options = new ChromeOptions();
options.AddArguments(
"--headless=new", // modern headless mode (remove this for debugging)
"--disable-gpu",
"--window-size=1920,1080",
"--remote-allow-origins=*",
"--disable-dev-shm-usage"); // avoids crashes in low-memory containers

// Additional options to improve stability
options.PageLoadStrategy = PageLoadStrategy.Eager;

// ---------- Pick a driver binary ----------
// 1) Prefer explicit env-var so devs can override locally
var driverDir = Environment.GetEnvironmentVariable("CHROMEWEBDRIVER");

// 2) Otherwise use the folder where CI drops a matching chromedriver
if (string.IsNullOrEmpty(driverDir))
{
driverDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "drivers");
}

// 3) Fallback: let Selenium look on PATH
ChromeDriverService service = string.IsNullOrEmpty(driverDir)
? ChromeDriverService.CreateDefaultService()
: ChromeDriverService.CreateDefaultService(driverDir);
// 3) Fallback: let Selenium look on PATH
ChromeDriverService service = string.IsNullOrEmpty(driverDir)
? ChromeDriverService.CreateDefaultService()
: ChromeDriverService.CreateDefaultService(driverDir);

service.HideCommandPromptWindow = true;
service.EnableVerboseLogging = true;
service.HideCommandPromptWindow = true;
service.EnableVerboseLogging = true;

var driver = new ChromeDriver(
service,
options,
TimeSpan.FromSeconds(timeoutSeconds));

driver.Manage().Timeouts().ImplicitWait = ImplicitTimespan;

try
{
driver.Navigate().GoToUrl("about:blank");
// If this succeeds, the browser is responding
}
catch (Exception)
{
driver.Dispose();
throw;
}

var driver = new ChromeDriver(
service,
options,
TimeSpan.FromSeconds(120)); // generous startup timeout
TryMaximize(driver);
Trace.WriteLine($"[Selenium] Chrome WebDriver created successfully");
return driver;
}
catch (Exception ex)
{
if (attempt == maxRetries)
{
Trace.WriteLine($"[Selenium] Failed to create Chrome WebDriver after {maxRetries} attempts. Last error: {ex.Message}");
throw;
}

driver.Manage().Timeouts().ImplicitWait = ImplicitTimespan;
Thread.Sleep(1000);
}
}

TryMaximize(driver);
return driver;
// This should never be reached due to the throw in the catch block on the last attempt
throw new InvalidOperationException("Failed to create Chrome WebDriver");
}

private static void TryMaximize(IWebDriver driver)
Expand Down Expand Up @@ -311,7 +348,7 @@ private static void EnterUsername(IWebDriver driver, LabUser user, bool withLogi
{
Trace.WriteLine("No, workaround failed");
}
}
}
}
}

Expand Down