无头模式下的 ChromeDriver 异常报告 "target window already closed"
ChromeDriver exception reporting "target window already closed" in headless mode
我正在使用 xUnit、SpecFlow、Selenium 和 headless Chrome 到 运行 自动化测试,但是当 运行 在 [=] 上时,我经常会遇到一系列崩溃21=] 尝试捕获最终浏览器的屏幕截图时 window。
有两个场景,每个场景都在一个单独的功能文件中,这意味着它们 运行 是并行的。好像是先启动后总是失败的场景
以下是我创建浏览器实例的方式:
private static readonly string UserDataDir = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName;
var options = new ChromeOptions();
options.AddArguments("--disable-gpu");
options.AddArguments("--no-sandbox");
options.AddArgument("--ignore-certificate-errors");
options.AddArgument("--disable-web-security");
options.AddArgument("--allow-insecure-localhost");
options.AddArgument("--allow-running-insecure-content");
options.AddArgument("--acceptInsecureCerts=true");
options.AddArgument("--proxy-server='direct://'");
options.AddArgument("--proxy-bypass-list=*");
options.AddArgument("--disable-extensions");
options.AddArgument($@"--user-data-dir={UserDataDir}\prof-{ProfileCounter++}");
options.AddArgument("--incognito");
options.AddArgument("--headless");
var svc = ChromeDriverService.CreateDefaultService();
svc.Port = Randomiser.Next(29700, 29900);
Context.Driver = new ChromeDriver(svc, options, TimeSpan.FromMinutes(2));
Context.Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(ImplicitWaitSeconds);
Context.Driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(PageLoadSeconds);
Context.Driver.Manage().Timeouts().AsynchronousJavaScript = TimeSpan.FromSeconds(AsynchronousJavaScriptSeconds);
这就是我关闭 browser/driver:
的方式
[AfterScenario]
public void AfterScenario()
{
Context.Driver.Quit();
Context.Driver.Dispose();
Context.Driver = null;
}
这是异常发生的地方:
Context.Driver.GetScreenshot().SaveAsFile($@"{folder}{filename}.jpg", ScreenshotImageFormat.Jpeg);
这是输出窗格中的完整异常:
------ Run test started ------
NUnit Adapter 3.10.0.21: Test execution started
Running all tests in C:\git\Testing\bin\Debug\Testing.dll
NUnit couldn't find any tests in C:\git\Testing\bin\Debug\Testing.dll
NUnit Adapter 3.10.0.21: Test execution complete
[xUnit.net 00:00:00.5180673] Discovering: Testing
[xUnit.net 00:00:01.0205999] Discovered: Testing
[xUnit.net 00:00:01.0244487] Starting: Testing
[xUnit.net 00:00:14.7836328] View the Daring Fireball talk show [FAIL]
[xUnit.net 00:00:14.7874843] OpenQA.Selenium.NoSuchWindowException : no such window: target window already closed
from unknown error: web view not found
(Session info: headless chrome=65.0.3325.181)
(Driver info: chromedriver=2.38.551601 (edb21f07fc70e9027c746edd3201443e011a61ed),platform=Windows NT 6.1.7601 SP1 x86_64)
[xUnit.net 00:00:14.7898949] Stack Trace:
[xUnit.net 00:00:14.7911454] at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
[xUnit.net 00:00:14.7916551] at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
[xUnit.net 00:00:14.7923841] at OpenQA.Selenium.Remote.RemoteWebDriver.GetScreenshot()
[xUnit.net 00:00:14.7929467] C:\git\Testing\StepDefinitions\Common\Implementation\PageNavigationStepsImplementation.cs(90,0): at Testing.StepDefinitions.Common.Implementation.PageNavigationStepsImplementation.TakeScreenshot(String filename)
[xUnit.net 00:00:14.7933710] C:\git\Testing\StepDefinitions\FeatureProperties.cs(122,0): at Testing.StepDefinitions.FeatureProperties.AfterScenario()
[xUnit.net 00:00:14.7939053] at lambda_method(Closure , IContextManager )
[xUnit.net 00:00:14.7944826] at TechTalk.SpecFlow.Bindings.BindingInvoker.InvokeBinding(IBinding binding, IContextManager contextManager, Object[] arguments, ITestTracer testTracer, TimeSpan& duration)
[xUnit.net 00:00:14.7949636] at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.InvokeHook(IBindingInvoker invoker, IHookBinding hookBinding, HookType hookType)
[xUnit.net 00:00:14.7956197] at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.FireEvents(HookType hookType)
[xUnit.net 00:00:14.7960898] at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.FireScenarioEvents(HookType bindingEvent)
[xUnit.net 00:00:14.7966550] at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.OnScenarioEnd()
[xUnit.net 00:00:14.7971662] at TechTalk.SpecFlow.TestRunner.OnScenarioEnd()
[xUnit.net 00:00:14.7975471] at SpecFlow.xUnitAdapter.SpecFlowPlugin.Runners.ScenarioTestCaseRunner.RunScenario(SpecFlowDocument gherkinDocument, Scenario scenario)
[xUnit.net 00:00:14.7979477] at SpecFlow.xUnitAdapter.SpecFlowPlugin.Runners.ScenarioTestCaseRunner.<>c__DisplayClass9_0.<RunTestAsync>b__2()
[xUnit.net 00:00:14.7990766] Output:
[xUnit.net 00:00:14.7995180] Given I am on the https://daringfireball.net/ page
[xUnit.net 00:00:14.7998653] -> done: PageNavigationSteps.IAmOnThePage("https://daringfir...") (11.5s)
[xUnit.net 00:00:14.8002840] When I click element THE TALK SHOW found by text
[xUnit.net 00:00:14.8006231] -> error: no such window: target window already closed
from unknown error: web view not found
(Session info: headless chrome=65.0.3325.181)
(Driver info: chromedriver=2.38.551601 (edb21f07fc70e9027c746edd3201443e011a61ed),platform=Windows NT 6.1.7601 SP1 x86_64)
[xUnit.net 00:00:14.8009870] Then I arrive on the page titled Daring Fireball: The Talk Show
[xUnit.net 00:00:14.8013918] -> skipped because of previous errors
[xUnit.net 00:00:18.8364913] Finished: Testing
========== Run test finished: 3 run (0:00:20.3) ==========
更新
步骤代码:
[When(@"I click element (.*)")]
public void IClickElement(string id)
{
try {
Context.Driver.FindElementsByPartialLinkText(id).FirstOrDefault();
} catch (Exception ex) {
var mssg = ex.Message; // debugger stops here (see exception below)
}
}
AfterScenario 代码:
[AfterScenario]
public void AfterScenario()
{
Context.Driver.Quit();
Context.Driver.Dispose();
Context.Driver = null;
Context.NgDriver = null;
}
虚假的、不规则的错误消息:
no such window: target window already closed
from unknown error: web view not found
(Session info: headless chrome=65.0.3325.181)
(Driver info: chromedriver=2.38.551601 (edb21f07fc70e9027c746edd3201443e011a61ed),platform=Windows NT 6.1.7601 SP1 x86_64)
关联堆栈跟踪:
at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElements(String mechanism, String value)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElementsByPartialLinkText(String partialLinkText)
at Testing.StepDefinitions.Common.Implementation.GenericNavigationStepsImplementations.FindElement(Matcher match, String id, String attributeValue) in C:\git\Testing\Testing\StepDefinitions\Common\Implementation\GenericNavigationStepsImplementations.cs:line 73
AfterScenario 没有任何捕获,但随着屏幕截图尝试的删除,它不再抛出。在步骤定义的catch中放一个停止点,表示浏览器已经关闭
更新 2
已将 Chrome 更新为 66。异常消息:
no such window: target window already closed
from unknown error: web view not found
(Session info: headless chrome=66.0.3359.117)
(Driver info: chromedriver=2.38.551601 (edb21f07fc70e9027c746edd3201443e011a61ed),platform=Windows NT 6.1.7601 SP1 x86_64)
堆栈跟踪:
at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElements(String mechanism, String value)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElementsByPartialLinkText(String partialLinkText)
at Testing.StepDefinitions.Common.Implementation.GenericNavigationStepsImplementations.FindElement(Matcher match, String id, String attributeValue) in C:\git\Testing\Testing\StepDefinitions\Common\Implementation\GenericNavigationStepsImplementations.cs:line 73
同样的代码,同样的错误。
正如所讨论的,这个问题可能是由于多种原因造成的
svc.Port = Randomiser.Next(29700, 29900);
。你不应该自己分配端口,它也可能与其他一些程序端口冲突,甚至可以随机生成相同的端口号,这将导致问题
您正在并行启动脚本。在极少数情况下,驱动程序启动可能存在竞争条件,驱动程序可能无法启动。所以我会将工厂模式添加到我的驱动程序初始化代码中,如下所示
public sealed class ChromeFactory
{
private static readonly object padlock = new object();
ChromeFactory()
{
}
public static WebDriver NewInstance
{
get
{
lock (padlock)
{
return new ChromeDriver();
}
}
}
}
并像下面这样初始化驱动程序
Context.Driver = ChromeFactory.NewInstance
- 因为你有并行执行,我建议不要使用 #2 建议,设置一个浏览器限制计数的 selenium 网格并使用它。这将使您的生活变得更加简单
我正在使用 xUnit、SpecFlow、Selenium 和 headless Chrome 到 运行 自动化测试,但是当 运行 在 [=] 上时,我经常会遇到一系列崩溃21=] 尝试捕获最终浏览器的屏幕截图时 window。
有两个场景,每个场景都在一个单独的功能文件中,这意味着它们 运行 是并行的。好像是先启动后总是失败的场景
以下是我创建浏览器实例的方式:
private static readonly string UserDataDir = new FileInfo(Assembly.GetExecutingAssembly().Location).DirectoryName;
var options = new ChromeOptions();
options.AddArguments("--disable-gpu");
options.AddArguments("--no-sandbox");
options.AddArgument("--ignore-certificate-errors");
options.AddArgument("--disable-web-security");
options.AddArgument("--allow-insecure-localhost");
options.AddArgument("--allow-running-insecure-content");
options.AddArgument("--acceptInsecureCerts=true");
options.AddArgument("--proxy-server='direct://'");
options.AddArgument("--proxy-bypass-list=*");
options.AddArgument("--disable-extensions");
options.AddArgument($@"--user-data-dir={UserDataDir}\prof-{ProfileCounter++}");
options.AddArgument("--incognito");
options.AddArgument("--headless");
var svc = ChromeDriverService.CreateDefaultService();
svc.Port = Randomiser.Next(29700, 29900);
Context.Driver = new ChromeDriver(svc, options, TimeSpan.FromMinutes(2));
Context.Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(ImplicitWaitSeconds);
Context.Driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(PageLoadSeconds);
Context.Driver.Manage().Timeouts().AsynchronousJavaScript = TimeSpan.FromSeconds(AsynchronousJavaScriptSeconds);
这就是我关闭 browser/driver:
的方式[AfterScenario]
public void AfterScenario()
{
Context.Driver.Quit();
Context.Driver.Dispose();
Context.Driver = null;
}
这是异常发生的地方:
Context.Driver.GetScreenshot().SaveAsFile($@"{folder}{filename}.jpg", ScreenshotImageFormat.Jpeg);
这是输出窗格中的完整异常:
------ Run test started ------
NUnit Adapter 3.10.0.21: Test execution started
Running all tests in C:\git\Testing\bin\Debug\Testing.dll
NUnit couldn't find any tests in C:\git\Testing\bin\Debug\Testing.dll
NUnit Adapter 3.10.0.21: Test execution complete
[xUnit.net 00:00:00.5180673] Discovering: Testing
[xUnit.net 00:00:01.0205999] Discovered: Testing
[xUnit.net 00:00:01.0244487] Starting: Testing
[xUnit.net 00:00:14.7836328] View the Daring Fireball talk show [FAIL]
[xUnit.net 00:00:14.7874843] OpenQA.Selenium.NoSuchWindowException : no such window: target window already closed
from unknown error: web view not found
(Session info: headless chrome=65.0.3325.181)
(Driver info: chromedriver=2.38.551601 (edb21f07fc70e9027c746edd3201443e011a61ed),platform=Windows NT 6.1.7601 SP1 x86_64)
[xUnit.net 00:00:14.7898949] Stack Trace:
[xUnit.net 00:00:14.7911454] at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
[xUnit.net 00:00:14.7916551] at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
[xUnit.net 00:00:14.7923841] at OpenQA.Selenium.Remote.RemoteWebDriver.GetScreenshot()
[xUnit.net 00:00:14.7929467] C:\git\Testing\StepDefinitions\Common\Implementation\PageNavigationStepsImplementation.cs(90,0): at Testing.StepDefinitions.Common.Implementation.PageNavigationStepsImplementation.TakeScreenshot(String filename)
[xUnit.net 00:00:14.7933710] C:\git\Testing\StepDefinitions\FeatureProperties.cs(122,0): at Testing.StepDefinitions.FeatureProperties.AfterScenario()
[xUnit.net 00:00:14.7939053] at lambda_method(Closure , IContextManager )
[xUnit.net 00:00:14.7944826] at TechTalk.SpecFlow.Bindings.BindingInvoker.InvokeBinding(IBinding binding, IContextManager contextManager, Object[] arguments, ITestTracer testTracer, TimeSpan& duration)
[xUnit.net 00:00:14.7949636] at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.InvokeHook(IBindingInvoker invoker, IHookBinding hookBinding, HookType hookType)
[xUnit.net 00:00:14.7956197] at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.FireEvents(HookType hookType)
[xUnit.net 00:00:14.7960898] at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.FireScenarioEvents(HookType bindingEvent)
[xUnit.net 00:00:14.7966550] at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.OnScenarioEnd()
[xUnit.net 00:00:14.7971662] at TechTalk.SpecFlow.TestRunner.OnScenarioEnd()
[xUnit.net 00:00:14.7975471] at SpecFlow.xUnitAdapter.SpecFlowPlugin.Runners.ScenarioTestCaseRunner.RunScenario(SpecFlowDocument gherkinDocument, Scenario scenario)
[xUnit.net 00:00:14.7979477] at SpecFlow.xUnitAdapter.SpecFlowPlugin.Runners.ScenarioTestCaseRunner.<>c__DisplayClass9_0.<RunTestAsync>b__2()
[xUnit.net 00:00:14.7990766] Output:
[xUnit.net 00:00:14.7995180] Given I am on the https://daringfireball.net/ page
[xUnit.net 00:00:14.7998653] -> done: PageNavigationSteps.IAmOnThePage("https://daringfir...") (11.5s)
[xUnit.net 00:00:14.8002840] When I click element THE TALK SHOW found by text
[xUnit.net 00:00:14.8006231] -> error: no such window: target window already closed
from unknown error: web view not found
(Session info: headless chrome=65.0.3325.181)
(Driver info: chromedriver=2.38.551601 (edb21f07fc70e9027c746edd3201443e011a61ed),platform=Windows NT 6.1.7601 SP1 x86_64)
[xUnit.net 00:00:14.8009870] Then I arrive on the page titled Daring Fireball: The Talk Show
[xUnit.net 00:00:14.8013918] -> skipped because of previous errors
[xUnit.net 00:00:18.8364913] Finished: Testing
========== Run test finished: 3 run (0:00:20.3) ==========
更新
步骤代码:
[When(@"I click element (.*)")]
public void IClickElement(string id)
{
try {
Context.Driver.FindElementsByPartialLinkText(id).FirstOrDefault();
} catch (Exception ex) {
var mssg = ex.Message; // debugger stops here (see exception below)
}
}
AfterScenario 代码:
[AfterScenario]
public void AfterScenario()
{
Context.Driver.Quit();
Context.Driver.Dispose();
Context.Driver = null;
Context.NgDriver = null;
}
虚假的、不规则的错误消息:
no such window: target window already closed
from unknown error: web view not found
(Session info: headless chrome=65.0.3325.181)
(Driver info: chromedriver=2.38.551601 (edb21f07fc70e9027c746edd3201443e011a61ed),platform=Windows NT 6.1.7601 SP1 x86_64)
关联堆栈跟踪:
at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElements(String mechanism, String value)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElementsByPartialLinkText(String partialLinkText)
at Testing.StepDefinitions.Common.Implementation.GenericNavigationStepsImplementations.FindElement(Matcher match, String id, String attributeValue) in C:\git\Testing\Testing\StepDefinitions\Common\Implementation\GenericNavigationStepsImplementations.cs:line 73
AfterScenario 没有任何捕获,但随着屏幕截图尝试的删除,它不再抛出。在步骤定义的catch中放一个停止点,表示浏览器已经关闭
更新 2
已将 Chrome 更新为 66。异常消息:
no such window: target window already closed
from unknown error: web view not found
(Session info: headless chrome=66.0.3359.117)
(Driver info: chromedriver=2.38.551601 (edb21f07fc70e9027c746edd3201443e011a61ed),platform=Windows NT 6.1.7601 SP1 x86_64)
堆栈跟踪:
at OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError(Response errorResponse)
at OpenQA.Selenium.Remote.RemoteWebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElements(String mechanism, String value)
at OpenQA.Selenium.Remote.RemoteWebDriver.FindElementsByPartialLinkText(String partialLinkText)
at Testing.StepDefinitions.Common.Implementation.GenericNavigationStepsImplementations.FindElement(Matcher match, String id, String attributeValue) in C:\git\Testing\Testing\StepDefinitions\Common\Implementation\GenericNavigationStepsImplementations.cs:line 73
同样的代码,同样的错误。
正如所讨论的,这个问题可能是由于多种原因造成的
svc.Port = Randomiser.Next(29700, 29900);
。你不应该自己分配端口,它也可能与其他一些程序端口冲突,甚至可以随机生成相同的端口号,这将导致问题您正在并行启动脚本。在极少数情况下,驱动程序启动可能存在竞争条件,驱动程序可能无法启动。所以我会将工厂模式添加到我的驱动程序初始化代码中,如下所示
public sealed class ChromeFactory { private static readonly object padlock = new object(); ChromeFactory() { } public static WebDriver NewInstance { get { lock (padlock) { return new ChromeDriver(); } } } }
并像下面这样初始化驱动程序
Context.Driver = ChromeFactory.NewInstance
- 因为你有并行执行,我建议不要使用 #2 建议,设置一个浏览器限制计数的 selenium 网格并使用它。这将使您的生活变得更加简单