From 4801be90a0ac263ea6d236f672df775f3360df1d Mon Sep 17 00:00:00 2001 From: Dan Bjorge Date: Wed, 16 Oct 2019 14:40:09 -0700 Subject: [PATCH] Improve windows dotnet firefox perf (#129) #### Description of changes During local testing of #128, I noticed that the .NET Core + Windows + Firefox environment combination was excessively slow compared to all other combinations (taking >2min per test run instead of <10s). This turns out to be caused by https://github.com/mozilla/geckodriver/issues/1496 / https://bugzilla.mozilla.org/show_bug.cgi?id=1525659 - if I'm understanding the bugs correctly, geckodriver listens for selenium commands on IPv4 only by default and selenium tries to connect via "http://localhost" rather than "http://127.0.0.1", but .NET Core's standard HttpClient behavior under Windows ends up attempting to connect to "localhost" URLs via IPv6 for a second before timing out and retrying on IPv4, so in practice this adds a second of overhead to every API call between Selenium and geckodriver. This change works around it by forcing both of them to use a `::1` to communicate. The linked bug suggested that using `localhost` or `127.0.0.1` should have also worked around the issue, but it didn't seem to help when I tried it. Using `::1` in all cases prevented it from working in our linux build agents, so I ended up having to do a platform check. Before: ``` > dotnet test --filter TestCategory!=IntentionallyFailsAsAnExample Test run for Q:\repos\axe-pipelines-samples\csharp-selenium-webdriver-sample\bin\Debug\netcoreapp2.2\CSharpSeleniumWebdriverSample.dll(.NETCoreApp,Version=v2.2) Microsoft (R) Test Execution Command Line Tool Version 16.0.1 Copyright (c) Microsoft Corporation. All rights reserved. Starting test execution, please wait... Total tests: 3. Passed: 3. Failed: 0. Skipped: 0. Test Run Successful. Test execution time: 2.3717 Minutes Command took 2:23.929. ``` After: ``` > dotnet test --filter TestCategory!=IntentionallyFailsAsAnExample Test run for Q:\repos\axe-pipelines-samples\csharp-selenium-webdriver-sample\bin\Debug\netcoreapp2.2\CSharpSeleniumWebdriverSample.dll(.NETCoreApp,Version=v2.2) Copyright (c) Microsoft Corporation. All rights reserved. Starting test execution, please wait... Total tests: 3. Passed: 3. Failed: 0. Skipped: 0. Test Run Successful. Test execution time: 5.4795 Seconds Command took 7.2035856 seconds. ``` #### Pull request checklist - [n/a] If this PR addresses an existing issue, it is linked: Fixes #0000 - [x] New sample content is commented at a similar verbosity as existing content - [x] All updated/modified sample code builds and runs in at least one PR/CI build - [x] PR checks for builds named `[failing example] ...` fail as expected --- csharp-selenium-webdriver-sample/WebDriverFactory.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/csharp-selenium-webdriver-sample/WebDriverFactory.cs b/csharp-selenium-webdriver-sample/WebDriverFactory.cs index 72f1af05..8bef0de7 100644 --- a/csharp-selenium-webdriver-sample/WebDriverFactory.cs +++ b/csharp-selenium-webdriver-sample/WebDriverFactory.cs @@ -54,7 +54,13 @@ public static IWebDriver CreateFromEnvironmentVariableSettings() { var firefoxOptions = new FirefoxOptions(); firefoxOptions.AddArgument("--headless"); - return new FirefoxDriver(geckoDriverDirectory, firefoxOptions); + var firefoxDriverService = FirefoxDriverService.CreateDefaultService(geckoDriverDirectory); + // This is a workaround for Windows-specific performance issues caused by https://github.com/mozilla/geckodriver/issues/1496 + if (Platform.CurrentPlatform.IsPlatformType(PlatformType.Windows)) { + firefoxDriverService.Host = "::1"; + } + + return new FirefoxDriver(firefoxDriverService, firefoxOptions); default: throw new ArgumentException($"Unknown browser type '{browserEnvVar}' specified in '{BROWSER_ENVIRONMENT_VARIABLE}' environment variable");