Search code examples
c#selenium-chromedriver.net-4.6.1

ChromeDriver exception reporting "target window already closed" in headless mode


I am using xUnit, SpecFlow, Selenium and headless Chrome to run automated tests, but every so often I will get a series of crashes when running on localhost when trying to capture a screenshot of the final browser window.

There are two scenarios, each in a separate feature file, which means they run in parallel. It appears to be the scenario which starts up second which always fails.

Here is how I'm creating my browser instance:

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

This is how I close down my browser/driver:

[AfterScenario]
public void AfterScenario()
{
    Context.Driver.Quit();
    Context.Driver.Dispose();
    Context.Driver = null;
}

This is where the exception is occuring:

    Context.Driver.GetScreenshot().SaveAsFile($@"{folder}{filename}.jpg", ScreenshotImageFormat.Jpeg);

Here is the full exception from the output pane:

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

UPDATE

Step code:

[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 code:

[AfterScenario]
public void AfterScenario()
{
    Context.Driver.Quit();
    Context.Driver.Dispose();
    Context.Driver = null;
    Context.NgDriver = null;
}

Spurious, irregular error message:

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)

Associated stack trace:

   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 does not have any catching but with the removal of the screenshot attempt, it no longer throws. Putting a stop point in the catch of the step definition shows that the browser has been closed.

UPDATE 2

Updated Chrome to 66. Exception message:

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)

Stack trace:

   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

The same error with the same code.


Solution

  • As discussed the issue could be because of multiple reasons

    1. svc.Port = Randomiser.Next(29700, 29900);. You should never assign the port yourself, it can be conflicting with some other program port as well and even the same port number can be generated in random which will cause the issue

    2. You are launching scripts in parallel. In rare cases there could be a race condition in driver launch and the driver may fail to launch. So I would add Factory pattern to my driver initialization code like below

      public sealed class ChromeFactory 
      { 
          private static readonly object padlock = new object();
      
          ChromeFactory()
          {
          }
      
          public static WebDriver NewInstance
          {
              get
              {
                  lock (padlock)
                  {
                      return new ChromeDriver();
                  }
              }
          }
      }
      

    And initialize the driver like below

    Context.Driver = ChromeFactory.NewInstance
    
    1. Since you have parallel execution, I would recommend instead of using #2 suggestion, setup a selenium grid a browser limit count and use that. This will make life much more simpler for you