Сообщение об исключительной ситуации ChromeDriver "целевое окно уже закрыто" в автономном режиме

Я использую xUnit, SpecFlow, Selenium и Chrome без головы для запуска автоматических тестов, но время от времени я получаю серию сбоев при работе на localhost при попытке сделать снимок экрана с окончательным окном браузера.

Существует два сценария, каждый в отдельном файле объектов, что означает, что они работают параллельно. Похоже, это сценарий, который запускается вторым, который всегда терпит неудачу.

Вот как я создаю свой экземпляр браузера:

    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);

Вот как я закрываю свой браузер / драйвер:

[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]
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 не имеет никакого перехвата, но с удалением скриншота, он больше не выдает. Помещение точки остановки в зацепку определения шага показывает, что браузер был закрыт.

ОБНОВЛЕНИЕ 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

Та же ошибка с тем же кодом.

1 ответ

Решение

Как уже говорилось, проблема может быть из-за нескольких причин

  1. svc.Port = Randomiser.Next(29700, 29900);, Вы никогда не должны назначать порт самостоятельно, он может конфликтовать с другим портом программы, и даже тот же номер порта может быть сгенерирован случайным образом, что вызовет проблему

  2. Вы запускаете сценарии параллельно. В редких случаях при запуске драйвера может возникнуть состояние гонки, при котором драйвер может не запуститься. Поэтому я бы добавил шаблон Factory в код инициализации моего драйвера, как показано ниже

    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
  1. Поскольку у вас есть параллельное выполнение, я бы рекомендовал вместо использования предложения № 2 установить сетку селена, ограничить счетчик в браузере и использовать его. Это сделает вашу жизнь намного проще
Другие вопросы по тегам