From 2fb02287a83d680d1f4fa25922008a0501b881ec Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Fri, 17 Jul 2026 13:09:36 +0200 Subject: [PATCH 1/9] Add C# example for unhandledPromptBehavior option Adds the missing SetUnhandledPromptBehavior test to OptionsTest.cs and wires the CSharp tab in the docs to it, replacing the placeholder badge. Based on #2611 and #2612 by kimtg. Co-authored-by: KIM Taegyoon Co-Authored-By: Claude Sonnet 5 --- .../dotnet/SeleniumDocs/Drivers/OptionsTest.cs | 17 ++++++++++++++++- .../webdriver/drivers/options.en.md | 2 +- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs b/examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs index 618e5361ecce..4d07da3a3b33 100644 --- a/examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs +++ b/examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs @@ -53,5 +53,20 @@ public void SetPageLoadStrategyNone() driver.Quit(); } } + [TestMethod] + public void SetUnhandledPromptBehavior() + { + var chromeOptions = new ChromeOptions(); + chromeOptions.UnhandledPromptBehavior = UnhandledPromptBehavior.DismissAndNotify; + IWebDriver driver = new ChromeDriver(chromeOptions); + try + { + driver.Navigate().GoToUrl("https://selenium.dev"); + } + finally + { + driver.Quit(); + } + } } -} \ No newline at end of file +} diff --git a/website_and_docs/content/documentation/webdriver/drivers/options.en.md b/website_and_docs/content/documentation/webdriver/drivers/options.en.md index 48f82e72d06e..6e7355d60471 100644 --- a/website_and_docs/content/documentation/webdriver/drivers/options.en.md +++ b/website_and_docs/content/documentation/webdriver/drivers/options.en.md @@ -412,7 +412,7 @@ user prompt encounters at the remote-end. This is defined by {{< gh-codeblock path="/examples/python/tests/drivers/test_options.py#L51-53">}} {{% /tab %}} {{< tab header="CSharp" >}} -{{< badge-code >}} +{{< gh-codeblock path="/examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L59-L60">}} {{< /tab >}} {{< tab header="Ruby" >}} {{< gh-codeblock path="/examples/ruby/spec/drivers/options_spec.rb#L60-L61" >}} From 1623d5c546bedfd048b429f3509eab04c6170e53 Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Sat, 18 Jul 2026 18:44:48 +0200 Subject: [PATCH 2/9] fix: avoid Windows file-lock races in EdgeTest log tests On Windows, msedgedriver can still hold its log file open for a moment after driver.Quit(), so reading the log right after Quit() intermittently threw IOException in LogsToFile, LogsLevel, ConfigureDriverLogs, and DisableBuildCheck. Mirrors the Python and Ruby examples, which read the log while the service is still running instead of after quitting (see 4decac33fa7 for the equivalent Python fix). Also guards the log file deletion in Cleanup() against the same race, tolerating IOException like Python's contextlib.suppress(OSError) and Ruby's FileUtils.rm_f. Co-Authored-By: Claude Sonnet 5 --- .../dotnet/SeleniumDocs/Browsers/EdgeTest.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs index a5782535a05c..74d37fcecfb3 100644 --- a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs +++ b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs @@ -18,11 +18,20 @@ public class EdgeTest [TestCleanup] public void Cleanup() { + driver.Quit(); + if (_logLocation != null && File.Exists(_logLocation)) { - File.Delete(_logLocation); + try + { + File.Delete(_logLocation); + } + catch (IOException) + { + // On Windows, the driver service can still hold the log file open for a + // moment after driver.Quit(), so tolerate the race instead of failing cleanup. + } } - driver.Quit(); } [TestMethod] @@ -94,7 +103,6 @@ public void LogsToFile() service.LogPath = GetLogLocation(); driver = new EdgeDriver(service, options); - driver.Quit(); // Close the Service log file before reading var lines = File.ReadLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver"))); } @@ -111,7 +119,6 @@ public void LogsLevel() driver = new EdgeDriver(service, options); - driver.Quit(); // Close the Service log file before reading var lines = File.ReadLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:"))); } @@ -130,7 +137,6 @@ public void ConfigureDriverLogs() driver = new EdgeDriver(service, options); - driver.Quit(); // Close the Service log file before reading var lines = File.ReadLines(GetLogLocation()); var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]"); Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0)); @@ -148,7 +154,6 @@ public void DisableBuildCheck() service.DisableBuildCheck = true; driver = new EdgeDriver(service, options); - driver.Quit(); // Close the Service log file before reading var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"; var lines = File.ReadLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected))); From 897e5374575325b36822bc1f558833966ce026f8 Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Sat, 18 Jul 2026 19:27:00 +0200 Subject: [PATCH 3/9] fix: retry reading Edge log file to survive Windows lock window CI showed the log file is locked for the entire life of the Edge driver service on Windows, not just briefly after Quit() -- moving the read before Quit() (previous commit) failed immediately since the driver process was still running. Reading after Quit() is correct, but the OS still needs a moment to release the handle once the process exits, so wrap the read in a short bounded retry instead. Co-Authored-By: Claude Sonnet 5 --- .../dotnet/SeleniumDocs/Browsers/EdgeTest.cs | 33 ++++++++++++++++--- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs index 74d37fcecfb3..e5987e222954 100644 --- a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs +++ b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using System.Text.RegularExpressions; +using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; using OpenQA.Selenium; using OpenQA.Selenium.Chromium; @@ -103,7 +104,8 @@ public void LogsToFile() service.LogPath = GetLogLocation(); driver = new EdgeDriver(service, options); - var lines = File.ReadLines(GetLogLocation()); + driver.Quit(); // Close the Service log file before reading + var lines = ReadLogLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver"))); } @@ -119,7 +121,8 @@ public void LogsLevel() driver = new EdgeDriver(service, options); - var lines = File.ReadLines(GetLogLocation()); + driver.Quit(); // Close the Service log file before reading + var lines = ReadLogLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:"))); } @@ -137,7 +140,8 @@ public void ConfigureDriverLogs() driver = new EdgeDriver(service, options); - var lines = File.ReadLines(GetLogLocation()); + driver.Quit(); // Close the Service log file before reading + var lines = ReadLogLines(GetLogLocation()); var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]"); Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0)); } @@ -154,11 +158,32 @@ public void DisableBuildCheck() service.DisableBuildCheck = true; driver = new EdgeDriver(service, options); + driver.Quit(); // Close the Service log file before reading var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"; - var lines = File.ReadLines(GetLogLocation()); + var lines = ReadLogLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected))); } + private static string[] ReadLogLines(string path) + { + const int maxAttempts = 10; + for (var attempt = 1; attempt <= maxAttempts; attempt++) + { + try + { + return File.ReadAllLines(path); + } + catch (IOException) when (attempt < maxAttempts) + { + // On Windows, the driver service can still hold the log file open for a + // moment after driver.Quit(), so retry until the handle is released. + Thread.Sleep(200); + } + } + + return File.ReadAllLines(path); + } + private string GetLogLocation() { if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation)) From 7831356c4a42bc7ae1a12c892c19d6876de0b880 Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Sat, 18 Jul 2026 19:38:04 +0200 Subject: [PATCH 4/9] fix: null-safe driver.Quit() in EdgeTest cleanup If driver creation throws before the field is assigned, Cleanup()'s unconditional driver.Quit() throws NullReferenceException and masks the real test failure. ChromeTest.cs already uses this driver?.Quit() pattern in its own cleanup; apply it here too. Co-Authored-By: Claude Sonnet 5 --- examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs index e5987e222954..c425c04216c7 100644 --- a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs +++ b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs @@ -19,7 +19,7 @@ public class EdgeTest [TestCleanup] public void Cleanup() { - driver.Quit(); + driver?.Quit(); if (_logLocation != null && File.Exists(_logLocation)) { From d49f495decc1fb15aa6f25ee7e7cc96e40314208 Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Sat, 18 Jul 2026 21:16:28 +0200 Subject: [PATCH 5/9] fix: widen retry budget for Edge log file read on Windows The previous 2s retry budget (10 x 200ms) wasn't enough -- CI still failed with the same IOException after exhausting all attempts. EdgeDriverService.LogPath is fed by DriverService's async OutputDataReceived event handler (per the Selenium.WebDriver XML docs), so the log FileStream can stay open for several seconds after Quit() returns while the last buffered output drains. Widen the budget to ~9.5s (20 x 500ms) to reliably outlast that tail. Co-Authored-By: Claude Sonnet 5 --- examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs index c425c04216c7..ce12bb35f6f3 100644 --- a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs +++ b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs @@ -166,7 +166,7 @@ public void DisableBuildCheck() private static string[] ReadLogLines(string path) { - const int maxAttempts = 10; + const int maxAttempts = 20; for (var attempt = 1; attempt <= maxAttempts; attempt++) { try @@ -175,9 +175,9 @@ private static string[] ReadLogLines(string path) } catch (IOException) when (attempt < maxAttempts) { - // On Windows, the driver service can still hold the log file open for a - // moment after driver.Quit(), so retry until the handle is released. - Thread.Sleep(200); + // On Windows, the driver service can still hold the log file open for + // several seconds after driver.Quit(), so retry until the handle is released. + Thread.Sleep(500); } } From 0ff56138a7373a2eea4875a4c96940cdab1a9057 Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Sat, 18 Jul 2026 21:43:53 +0200 Subject: [PATCH 6/9] fix: narrow EdgeTest log retry to sharing/lock violations only ReadLogLines was retrying on any IOException, so a genuine failure (missing file, bad path, permissions) would silently eat up to ~10s of sleeping before surfacing, slowing down and obscuring real failures. Restrict the retry to the specific Win32 sharing/lock violation HRESULTs the Windows file-lock race actually produces; everything else propagates immediately. Co-Authored-By: Claude Sonnet 5 --- examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs index ce12bb35f6f3..b1ca9489e690 100644 --- a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs +++ b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs @@ -164,6 +164,11 @@ public void DisableBuildCheck() Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected))); } + // HRESULTs for the Win32 sharing/lock violations raised when a file is still open + // in another process; see https://learn.microsoft.com/windows/win32/debug/system-error-codes--0-499- + private const int ErrorSharingViolation = unchecked((int)0x80070020); + private const int ErrorLockViolation = unchecked((int)0x80070021); + private static string[] ReadLogLines(string path) { const int maxAttempts = 20; @@ -173,10 +178,13 @@ private static string[] ReadLogLines(string path) { return File.ReadAllLines(path); } - catch (IOException) when (attempt < maxAttempts) + catch (IOException ex) when (attempt < maxAttempts && + (ex.HResult == ErrorSharingViolation || ex.HResult == ErrorLockViolation)) { // On Windows, the driver service can still hold the log file open for // several seconds after driver.Quit(), so retry until the handle is released. + // Any other IOException (missing file, permissions, etc.) is a real failure + // and should surface immediately instead of being retried. Thread.Sleep(500); } } From 28cb0c2e2c52478edab666c0798876552d6fd02b Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Sat, 18 Jul 2026 21:48:19 +0200 Subject: [PATCH 7/9] try: replace log-read retry with explicit service.Dispose() Drop the retry loop and try forcing a real synchronous teardown instead: EdgeDriverService.LogPath is fed by DriverService's async OutputDataReceived handler, so driver.Quit() alone may return before that stream is fully flushed and closed. Holding the service reference and calling service.Dispose() explicitly should block until the log file is actually released, letting us read it with a plain File.ReadAllLines and no polling. Co-Authored-By: Claude Sonnet 5 --- .../dotnet/SeleniumDocs/Browsers/EdgeTest.cs | 49 +++++-------------- 1 file changed, 12 insertions(+), 37 deletions(-) diff --git a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs index b1ca9489e690..eb89cb724134 100644 --- a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs +++ b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs @@ -2,7 +2,6 @@ using System.IO; using System.Linq; using System.Text.RegularExpressions; -using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; using OpenQA.Selenium; using OpenQA.Selenium.Chromium; @@ -104,8 +103,9 @@ public void LogsToFile() service.LogPath = GetLogLocation(); driver = new EdgeDriver(service, options); - driver.Quit(); // Close the Service log file before reading - var lines = ReadLogLines(GetLogLocation()); + driver.Quit(); + service.Dispose(); // Force the service log file to fully close before reading + var lines = File.ReadAllLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver"))); } @@ -121,8 +121,9 @@ public void LogsLevel() driver = new EdgeDriver(service, options); - driver.Quit(); // Close the Service log file before reading - var lines = ReadLogLines(GetLogLocation()); + driver.Quit(); + service.Dispose(); // Force the service log file to fully close before reading + var lines = File.ReadAllLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:"))); } @@ -140,8 +141,9 @@ public void ConfigureDriverLogs() driver = new EdgeDriver(service, options); - driver.Quit(); // Close the Service log file before reading - var lines = ReadLogLines(GetLogLocation()); + driver.Quit(); + service.Dispose(); // Force the service log file to fully close before reading + var lines = File.ReadAllLines(GetLogLocation()); var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]"); Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0)); } @@ -158,40 +160,13 @@ public void DisableBuildCheck() service.DisableBuildCheck = true; driver = new EdgeDriver(service, options); - driver.Quit(); // Close the Service log file before reading + driver.Quit(); + service.Dispose(); // Force the service log file to fully close before reading var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"; - var lines = ReadLogLines(GetLogLocation()); + var lines = File.ReadAllLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected))); } - // HRESULTs for the Win32 sharing/lock violations raised when a file is still open - // in another process; see https://learn.microsoft.com/windows/win32/debug/system-error-codes--0-499- - private const int ErrorSharingViolation = unchecked((int)0x80070020); - private const int ErrorLockViolation = unchecked((int)0x80070021); - - private static string[] ReadLogLines(string path) - { - const int maxAttempts = 20; - for (var attempt = 1; attempt <= maxAttempts; attempt++) - { - try - { - return File.ReadAllLines(path); - } - catch (IOException ex) when (attempt < maxAttempts && - (ex.HResult == ErrorSharingViolation || ex.HResult == ErrorLockViolation)) - { - // On Windows, the driver service can still hold the log file open for - // several seconds after driver.Quit(), so retry until the handle is released. - // Any other IOException (missing file, permissions, etc.) is a real failure - // and should surface immediately instead of being retried. - Thread.Sleep(500); - } - } - - return File.ReadAllLines(path); - } - private string GetLogLocation() { if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation)) From 50f46787f64646c12b510c3c049d3fc364417b03 Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Sat, 18 Jul 2026 22:10:37 +0200 Subject: [PATCH 8/9] revert: bring back narrowed retry, keep explicit service.Dispose() The explicit-Dispose-only approach didn't work: CI showed the same IOException immediately after driver.Quit() + service.Dispose(), so DriverService's async OutputDataReceived teardown isn't fully synchronous even through an explicit Dispose() call. Restore the retry (narrowed to actual sharing/lock-violation HRESULTs, ~9.5s budget), and keep the Dispose() call alongside it since it's still correct resource cleanup and may shrink the typical wait. Co-Authored-By: Claude Sonnet 5 --- .../dotnet/SeleniumDocs/Browsers/EdgeTest.cs | 45 +++++++++++++++---- 1 file changed, 37 insertions(+), 8 deletions(-) diff --git a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs index eb89cb724134..57f6e9ea3f09 100644 --- a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs +++ b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs @@ -2,6 +2,7 @@ using System.IO; using System.Linq; using System.Text.RegularExpressions; +using System.Threading; using Microsoft.VisualStudio.TestTools.UnitTesting; using OpenQA.Selenium; using OpenQA.Selenium.Chromium; @@ -104,8 +105,8 @@ public void LogsToFile() driver = new EdgeDriver(service, options); driver.Quit(); - service.Dispose(); // Force the service log file to fully close before reading - var lines = File.ReadAllLines(GetLogLocation()); + service.Dispose(); // Close the Service log file before reading + var lines = ReadLogLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver"))); } @@ -122,8 +123,8 @@ public void LogsLevel() driver = new EdgeDriver(service, options); driver.Quit(); - service.Dispose(); // Force the service log file to fully close before reading - var lines = File.ReadAllLines(GetLogLocation()); + service.Dispose(); // Close the Service log file before reading + var lines = ReadLogLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:"))); } @@ -142,8 +143,8 @@ public void ConfigureDriverLogs() driver = new EdgeDriver(service, options); driver.Quit(); - service.Dispose(); // Force the service log file to fully close before reading - var lines = File.ReadAllLines(GetLogLocation()); + service.Dispose(); // Close the Service log file before reading + var lines = ReadLogLines(GetLogLocation()); var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]"); Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0)); } @@ -161,12 +162,40 @@ public void DisableBuildCheck() driver = new EdgeDriver(service, options); driver.Quit(); - service.Dispose(); // Force the service log file to fully close before reading + service.Dispose(); // Close the Service log file before reading var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"; - var lines = File.ReadAllLines(GetLogLocation()); + var lines = ReadLogLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected))); } + // HRESULTs for the Win32 sharing/lock violations raised when a file is still open + // in another process; see https://learn.microsoft.com/windows/win32/debug/system-error-codes--0-499- + private const int ErrorSharingViolation = unchecked((int)0x80070020); + private const int ErrorLockViolation = unchecked((int)0x80070021); + + private static string[] ReadLogLines(string path) + { + const int maxAttempts = 20; + for (var attempt = 1; attempt <= maxAttempts; attempt++) + { + try + { + return File.ReadAllLines(path); + } + catch (IOException ex) when (attempt < maxAttempts && + (ex.HResult == ErrorSharingViolation || ex.HResult == ErrorLockViolation)) + { + // On Windows, the driver service can still hold the log file open for + // several seconds after driver.Quit(), so retry until the handle is released. + // Any other IOException (missing file, permissions, etc.) is a real failure + // and should surface immediately instead of being retried. + Thread.Sleep(500); + } + } + + return File.ReadAllLines(path); + } + private string GetLogLocation() { if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation)) From e18a147f36173cada1805c37191b524a3f8d3031 Mon Sep 17 00:00:00 2001 From: Diego Molina Date: Sat, 18 Jul 2026 22:49:39 +0200 Subject: [PATCH 9/9] simplify: drop HResult filtering and explanatory comments in EdgeTest This is a doc code example, not production code -- the narrowed sharing/lock-violation HResult check added unnecessary verbosity, and comments like "Close the Service log file before reading" get confusing once the file is translated. Keep the retry and service.Dispose(), drop the rest. --- .../dotnet/SeleniumDocs/Browsers/EdgeTest.cs | 22 +++++-------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs index 57f6e9ea3f09..6d6711dd9c8f 100644 --- a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs +++ b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs @@ -29,8 +29,6 @@ public void Cleanup() } catch (IOException) { - // On Windows, the driver service can still hold the log file open for a - // moment after driver.Quit(), so tolerate the race instead of failing cleanup. } } } @@ -105,7 +103,7 @@ public void LogsToFile() driver = new EdgeDriver(service, options); driver.Quit(); - service.Dispose(); // Close the Service log file before reading + service.Dispose(); var lines = ReadLogLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver"))); } @@ -123,7 +121,7 @@ public void LogsLevel() driver = new EdgeDriver(service, options); driver.Quit(); - service.Dispose(); // Close the Service log file before reading + service.Dispose(); var lines = ReadLogLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:"))); } @@ -143,7 +141,7 @@ public void ConfigureDriverLogs() driver = new EdgeDriver(service, options); driver.Quit(); - service.Dispose(); // Close the Service log file before reading + service.Dispose(); var lines = ReadLogLines(GetLogLocation()); var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]"); Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0)); @@ -162,17 +160,12 @@ public void DisableBuildCheck() driver = new EdgeDriver(service, options); driver.Quit(); - service.Dispose(); // Close the Service log file before reading + service.Dispose(); var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"; var lines = ReadLogLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected))); } - // HRESULTs for the Win32 sharing/lock violations raised when a file is still open - // in another process; see https://learn.microsoft.com/windows/win32/debug/system-error-codes--0-499- - private const int ErrorSharingViolation = unchecked((int)0x80070020); - private const int ErrorLockViolation = unchecked((int)0x80070021); - private static string[] ReadLogLines(string path) { const int maxAttempts = 20; @@ -182,13 +175,8 @@ private static string[] ReadLogLines(string path) { return File.ReadAllLines(path); } - catch (IOException ex) when (attempt < maxAttempts && - (ex.HResult == ErrorSharingViolation || ex.HResult == ErrorLockViolation)) + catch (IOException) when (attempt < maxAttempts) { - // On Windows, the driver service can still hold the log file open for - // several seconds after driver.Quit(), so retry until the handle is released. - // Any other IOException (missing file, permissions, etc.) is a real failure - // and should surface immediately instead of being retried. Thread.Sleep(500); } }