Skip to content

Commit 39c0eb0

Browse files
authored
Improve stability of Selenium tests (#5367)
Improve behavior of selenium webdriver creation
1 parent 961c9ee commit 39c0eb0

File tree

1 file changed

+69
-32
lines changed

1 file changed

+69
-32
lines changed

tests/Microsoft.Identity.Test.Integration.netcore/Infrastructure/SeleniumExtensions.cs

Lines changed: 69 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -22,44 +22,81 @@ public static class SeleniumExtensions
2222
private static readonly TimeSpan ExplicitTimespan = TimeSpan.FromSeconds(20);
2323
private static readonly TimeSpan ShortExplicitTimespan = TimeSpan.FromSeconds(5);
2424

25-
public static IWebDriver CreateDefaultWebDriver()
25+
public static IWebDriver CreateDefaultWebDriver(int maxRetries = 3, int timeoutSeconds = 30)
2626
{
27-
// ---------- Chrome launch flags ----------
28-
var options = new ChromeOptions();
29-
options.AddArguments(
30-
"--headless=new", // modern headless mode (remove this for debugging)
31-
"--disable-gpu",
32-
"--window-size=1920,1080",
33-
"--remote-allow-origins=*",
34-
"--disable-dev-shm-usage"); // avoids crashes in low-memory containers
35-
36-
// ---------- Pick a driver binary ----------
37-
// 1) Prefer explicit env-var so devs can override locally
38-
var driverDir = Environment.GetEnvironmentVariable("CHROMEWEBDRIVER");
39-
40-
// 2) Otherwise use the folder where CI drops a matching chromedriver
41-
if (string.IsNullOrEmpty(driverDir))
27+
28+
for (int attempt = 1; attempt <= maxRetries; attempt++)
4229
{
43-
driverDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "drivers");
44-
}
30+
try
31+
{
32+
Trace.WriteLine($"[Selenium] Creating Chrome WebDriver (attempt {attempt}/{maxRetries})");
33+
34+
// ---------- Chrome launch flags ----------
35+
var options = new ChromeOptions();
36+
options.AddArguments(
37+
"--headless=new", // modern headless mode (remove this for debugging)
38+
"--disable-gpu",
39+
"--window-size=1920,1080",
40+
"--remote-allow-origins=*",
41+
"--disable-dev-shm-usage"); // avoids crashes in low-memory containers
42+
43+
// Additional options to improve stability
44+
options.PageLoadStrategy = PageLoadStrategy.Eager;
45+
46+
// ---------- Pick a driver binary ----------
47+
// 1) Prefer explicit env-var so devs can override locally
48+
var driverDir = Environment.GetEnvironmentVariable("CHROMEWEBDRIVER");
49+
50+
// 2) Otherwise use the folder where CI drops a matching chromedriver
51+
if (string.IsNullOrEmpty(driverDir))
52+
{
53+
driverDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "drivers");
54+
}
4555

46-
// 3) Fallback: let Selenium look on PATH
47-
ChromeDriverService service = string.IsNullOrEmpty(driverDir)
48-
? ChromeDriverService.CreateDefaultService()
49-
: ChromeDriverService.CreateDefaultService(driverDir);
56+
// 3) Fallback: let Selenium look on PATH
57+
ChromeDriverService service = string.IsNullOrEmpty(driverDir)
58+
? ChromeDriverService.CreateDefaultService()
59+
: ChromeDriverService.CreateDefaultService(driverDir);
5060

51-
service.HideCommandPromptWindow = true;
52-
service.EnableVerboseLogging = true;
61+
service.HideCommandPromptWindow = true;
62+
service.EnableVerboseLogging = true;
63+
64+
var driver = new ChromeDriver(
65+
service,
66+
options,
67+
TimeSpan.FromSeconds(timeoutSeconds));
68+
69+
driver.Manage().Timeouts().ImplicitWait = ImplicitTimespan;
70+
71+
try
72+
{
73+
driver.Navigate().GoToUrl("about:blank");
74+
// If this succeeds, the browser is responding
75+
}
76+
catch (Exception)
77+
{
78+
driver.Dispose();
79+
throw;
80+
}
5381

54-
var driver = new ChromeDriver(
55-
service,
56-
options,
57-
TimeSpan.FromSeconds(120)); // generous startup timeout
82+
TryMaximize(driver);
83+
Trace.WriteLine($"[Selenium] Chrome WebDriver created successfully");
84+
return driver;
85+
}
86+
catch (Exception ex)
87+
{
88+
if (attempt == maxRetries)
89+
{
90+
Trace.WriteLine($"[Selenium] Failed to create Chrome WebDriver after {maxRetries} attempts. Last error: {ex.Message}");
91+
throw;
92+
}
5893

59-
driver.Manage().Timeouts().ImplicitWait = ImplicitTimespan;
94+
Thread.Sleep(1000);
95+
}
96+
}
6097

61-
TryMaximize(driver);
62-
return driver;
98+
// This should never be reached due to the throw in the catch block on the last attempt
99+
throw new InvalidOperationException("Failed to create Chrome WebDriver");
63100
}
64101

65102
private static void TryMaximize(IWebDriver driver)
@@ -311,7 +348,7 @@ private static void EnterUsername(IWebDriver driver, LabUser user, bool withLogi
311348
{
312349
Trace.WriteLine("No, workaround failed");
313350
}
314-
}
351+
}
315352
}
316353
}
317354

0 commit comments

Comments
 (0)