Selenium/C#测试套件中如何处理Mac上挂起的SafariDriver及残留Safari浏览器实例问题
Selenium/C#测试套件中如何处理Mac上挂起的SafariDriver及残留Safari浏览器实例问题
我太懂这种糟心的情况了——Safari死死限制单实例,加上WebDriver偶尔“掉链子”没彻底关掉浏览器,直接导致后续测试卡壳。你用的Driver.Close()和Driver.Quit()只能干掉驱动进程,却碰不到Safari本身,这其实是因为有时候驱动和浏览器的进程关联会意外断裂,驱动的退出命令根本传不到浏览器那边。
给你几个亲测有效的解决方案,按稳妥程度排序:
1. 双重保险:先正常销毁驱动,再强制杀Safari进程
先优化你的清理逻辑,确保驱动资源被彻底释放,再用Mac终端命令强制结束Safari。把下面的方法加到你的AfterScenario里,甚至BeforeScenario开头也可以加一次,从根源杜绝残留:
using System.Diagnostics; private IWebDriver Driver; // 你的WebDriver实例 public void FullSafariCleanup() { try { // 第一步:正常销毁驱动实例 if (Driver != null) { Driver.Quit(); Driver.Dispose(); Driver = null; } // 第二步:强制关闭所有Safari进程,双重保险 var killProcess = new ProcessStartInfo { FileName = "/bin/bash", Arguments = "-c \"killall Safari 2>/dev/null\"", RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; using (var process = Process.Start(killProcess)) { process?.WaitForExit(); } } catch (Exception ex) { // 这里可以加日志记录,比如"清理Safari资源失败:" + ex.Message } }
解释下:2>/dev/null是为了避免如果没有Safari进程时终端输出错误信息,让命令执行更安静。
2. 用AppleScript优雅关闭Safari(适合正常响应的情况)
如果不想用强制杀进程的方式,也可以用Mac的AppleScript给Safari发送正常的退出信号,这种方式更“友好”,适合大部分正常场景:
public void GracefullyCloseSafari() { try { var scriptProcess = new ProcessStartInfo { FileName = "osascript", Arguments = "-e 'tell application \"Safari\" to quit' -e 'delay 1'", CreateNoWindow = true, UseShellExecute = false }; using (var process = Process.Start(scriptProcess)) { process?.WaitForExit(); } } catch (Exception ex) { // 日志记录异常 } }
delay 1是给Safari留一点时间完成退出操作,避免进程还没完全关掉就开始下一个测试。
3. 测试前的前置检查
在BeforeScenario开头加一段检查,确保没有运行中的Safari进程再启动新测试,这样就算之前的测试崩溃了,也不会影响下一次:
public void EnsureNoSafariRunningBeforeTest() { try { var checkProcess = new ProcessStartInfo { FileName = "/bin/bash", Arguments = "-c \"pgrep Safari\"", RedirectStandardOutput = true, UseShellExecute = false, CreateNoWindow = true }; using (var process = Process.Start(checkProcess)) { process?.WaitForExit(); var output = process?.StandardOutput.ReadToEnd(); if (!string.IsNullOrEmpty(output)) { // 如果有Safari进程,先杀掉 KillSafariProcesses(); } } } catch (Exception ex) { // 日志记录 } } // 复用之前的KillSafariProcesses方法 private void KillSafariProcesses() { var killProcess = new ProcessStartInfo { FileName = "/bin/bash", Arguments = "-c \"killall Safari 2>/dev/null\"", RedirectStandardOutput = true, RedirectStandardError = true, UseShellExecute = false, CreateNoWindow = true }; using (var process = Process.Start(killProcess)) { process?.WaitForExit(); } }
最后提个小注意:如果你的测试是在CI/CD环境(比如Mac上的Jenkins)运行,要确保执行测试的用户有足够权限执行这些终端命令,一般本地测试的普通用户权限就够了。
内容来源于stack exchange
相关产品推荐
相关产品推荐

