diff --git a/examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs b/examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs index 1d0cf7630ba5..4419abd8dfc2 100644 --- a/examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs +++ b/examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs @@ -25,7 +25,7 @@ public void Cleanup() driver?.Quit(); if (_logLocation != null && File.Exists(_logLocation)) { - File.Delete(_logLocation); + LogFile.TryDelete(_logLocation); } } @@ -108,7 +108,7 @@ public void LogsToFile() driver = new ChromeDriver(service); driver.Quit(); // Close the Service log file before reading - var lines = File.ReadLines(GetLogLocation()); + var lines = LogFile.ReadLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver"))); } @@ -123,7 +123,7 @@ public void LogsLevel() driver = new ChromeDriver(service); driver.Quit(); // Close the Service log file before reading - var lines = File.ReadLines(GetLogLocation()); + var lines = LogFile.ReadLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:"))); } @@ -140,7 +140,7 @@ public void ConfigureDriverLogs() driver = new ChromeDriver(service); driver.Quit(); // Close the Service log file before reading - var lines = File.ReadLines(GetLogLocation()); + var lines = LogFile.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)); } @@ -157,7 +157,7 @@ public void DisableBuildCheck() driver = new ChromeDriver(service); 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 = LogFile.ReadLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected))); } diff --git a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs index 7020a3612666..dd1404c1d6a4 100644 --- a/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs +++ b/examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs @@ -173,7 +173,7 @@ private static string[] ReadLogLines(string path) { try { - return File.ReadAllLines(path); + return LogFile.ReadLines(path); } catch (IOException) when (attempt < maxAttempts) { @@ -181,7 +181,7 @@ private static string[] ReadLogLines(string path) } } - return File.ReadAllLines(path); + return LogFile.ReadLines(path); } private string GetLogLocation() diff --git a/examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs b/examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs index dd2fae29493c..ad837ba211d5 100644 --- a/examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs +++ b/examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs @@ -22,7 +22,7 @@ public void Cleanup() driver?.Quit(); if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation)) { - File.Delete(_logLocation); + LogFile.TryDelete(_logLocation); } if (_tempPath != null && Directory.Exists(_tempPath)) { @@ -65,7 +65,7 @@ public void LogsToFile() driver = new FirefoxDriver(service); driver.Quit(); // Close the Service log file before reading - var lines = File.ReadLines(GetLogLocation()); + var lines = LogFile.ReadLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver INFO Listening on"))); } @@ -97,7 +97,7 @@ public void LogsLevel() driver = new FirefoxDriver(service); driver.Quit(); // Close the Service log file before reading - var lines = File.ReadLines(GetLogLocation()); + var lines = LogFile.ReadLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG"))); } @@ -111,7 +111,7 @@ public void StopsTruncatingLogs() driver = new FirefoxDriver(service); driver.Quit(); // Close the Service log file before reading - var lines = File.ReadLines(GetLogLocation()); + var lines = LogFile.ReadLines(GetLogLocation()); Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... "))); } diff --git a/examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs b/examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs index 087863299c73..97f46eb9e9bb 100644 --- a/examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs +++ b/examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs @@ -21,7 +21,7 @@ public void Cleanup() _driver?.Quit(); if (_logLocation != null && File.Exists(_logLocation)) { - File.Delete(_logLocation); + LogFile.TryDelete(_logLocation); } if (_tempPath != null && File.Exists(_tempPath)) { @@ -55,7 +55,7 @@ public void LogsLevel() _driver = new InternetExplorerDriver(service); _driver.Quit(); // Close the Service log file before reading - var lines = File.ReadLines(GetLogLocation()); + var lines = LogFile.ReadLines(GetLogLocation()); Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null"))); } diff --git a/examples/dotnet/SeleniumDocs/LogFile.cs b/examples/dotnet/SeleniumDocs/LogFile.cs new file mode 100644 index 000000000000..e63e51fba335 --- /dev/null +++ b/examples/dotnet/SeleniumDocs/LogFile.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading; + +namespace SeleniumDocs +{ + // Driver log files can still be open by the driver process after Quit(), + // especially on Windows. Share the file instead of requesting exclusive access. + public static class LogFile + { + public static string[] ReadLines(string path) + { + using var stream = new FileStream(path, FileMode.Open, FileAccess.Read, + FileShare.ReadWrite | FileShare.Delete); + using var reader = new StreamReader(stream); + var lines = new List(); + string line; + while ((line = reader.ReadLine()) != null) + { + lines.Add(line); + } + return lines.ToArray(); + } + + public static void TryDelete(string path) + { + const int maxAttempts = 10; + for (var attempt = 1; attempt <= maxAttempts; attempt++) + { + try + { + File.Delete(path); + return; + } + catch (IOException) when (attempt < maxAttempts) + { + // Still held by the driver process; give it time to exit. + Thread.Sleep(200); + } + catch (IOException e) + { + Console.Error.WriteLine($"Could not delete driver log {path}: {e.Message}"); + } + } + } + } +}