8

Sorry didn't find a similar question and maybe somebody can help.

Due to additional requirements we have to test our project not only with Chrome but with Firefox as well. When we simply changed a test context to Firefox it turned out that all calls of findElement took 10 times more time than with Chrome. All tests are completely ruined. We tried to use different test machines but the results are the same. The project is on Core .Net. For testing we use MSTest V2, Firefox 63 (64 bit) and Geckodriver 0.22 (64 bit) .

Very appreciate any help.

Nick
  • 101
  • 1
  • 3
  • When a client connects to a server using http there is a negotiation that takes place using the http headers to find a common mode of operation. For example if a server can support french and english the headers determines the language to use.It is possible that the difference is due to either http 1.0 (stream mode) being used instead of http 1.1 (chunk mode).Or the response is using gzip mode and the data is packed. So I would use a sniffer like wireshark or fiddler and compare the http headers to see the differences. Usually adding a missing header to you application resolves these issues. – jdweng Dec 05 '18 at 10:04
  • 1
    You got any data/test result to conclude _...findElement took 10 times more time than with Chrome..._? – undetected Selenium Dec 05 '18 at 10:04

4 Answers4

12

By referring to the previous answer, my issue was solved by below code.

string geckoDriverDirectory = "Path of geckodriver.exe"
FirefoxDriverService geckoService = 
FirefoxDriverService.CreateDefaultService(geckoDriverDirectory);
geckoService.Host = "::1";
var firefoxOptions = new FirefoxOptions();
firefoxOptions.AcceptInsecureCertificates = true;
Driver = new FirefoxDriver(geckoService, firefoxOptions);
gary.zhang
  • 275
  • 3
  • 9
  • 2
    Holy s**t. I just copy pasted it and it made my code 100x faster. Also as a side note, If geckodriver is in your path, you can create `geckoService` without specifying geckodriver's directory. – PNarimani Feb 05 '20 at 13:51
  • 1
    Same. Setting the host to `"::1"` made Firefox just as fast as Chrome. What the heck, Firefox. As @MdNarimani mentioned, you can do this in 3 lines if you don't need to specify the path: `var svc = FirefoxDriverService.CreateDefaultService(); svc.Host = "::1"; return new FirefoxDriver(svc);` – qJake Apr 24 '20 at 18:20
  • 1
    I cannot get anything to work when I set the Host property. Whatever string I put in there, even if it is ::1, just causes the driver to error with: OpenQA.Selenium.WebDriverException : Cannot start the driver service on http://localhost:51778/ – Fieldfare Oct 19 '21 at 09:59
2

Yep. You’re definitely hitting the performance issue that is part of .NET Core. It doesn’t happen on Chrome, IE, or Edge, because the driver executables for each of those browsers (unlike geckodriver) listen on both the IPv4 and IPv6 loopback addresses. If you were to specify “::1” as the host for geckodriver with .NET, the problem would disappear.

Refer to https://github.com/SeleniumHQ/selenium/issues/6597

Owen Cao
  • 7,955
  • 2
  • 27
  • 35
Nick
  • 101
  • 1
  • 3
1

A complete .Net Core webdriver for Firefox 7/14/2020:

// .Net Core workaround #1: Slow Firefox webdriver
string projectFolder = Directory.GetParent(Directory.GetCurrentDirectory()).FullName;
string geckoDriverDirectory = projectFolder + "\\netcoreapp3.1\\";
FirefoxDriverService geckoService = 
FirefoxDriverService.CreateDefaultService(geckoDriverDirectory);
geckoService.Host = "::1";

var ffOptions = new FirefoxOptions();
ffOptions.BrowserExecutableLocation = @"C:\Program Files\Mozilla Firefox\Firefox.exe"; 
ffOptions.AcceptInsecureCertificates = true;

// This profile will by-pass *ALL* credentials. Note that Chrome uses Internet Explorer settings, so it does not need this.
// You must pre-setup the profile, by launching Firefox and doing phone authentication
// The profile's location is: C:\Users\<windows logon>\AppData\Local\Mozilla\Firefox\Profiles
// Without this, if your AUT uses SSO, you will always get prompted for the PIN or Two factor authentication
FirefoxProfile profile = new FirefoxProfileManager().GetProfile("Selenium");
ffOptions.Profile = profile;

// DotNet Core workaround #2- Code page
// https://stackoverflow.com/questions/56802715/firefoxwebdriver-no-data-is-available-for-encoding-437
// https://stackoverflow.com/questions/50858209/system-notsupportedexception-no-data-is-available-for-encoding-1252
CodePagesEncodingProvider.Instance.GetEncoding(437);
Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);

_driver = new FirefoxDriver(geckoService, ffOptions);
Charlesdwm
  • 71
  • 5
0

In case anyone is trying gary.zhang's answer in Javascript, it looks like this:

let driver = new Builder()
.forBrowser('firefox')
.setFirefoxService(new firefox.ServiceBuilder('path_to_driver', host='::1'))
.setFirefoxOptions(new firefox.Options().headless())
.build();

Took me a bit of staring at it to figure out how to convert the syntax.

Grant Curell
  • 1,321
  • 2
  • 16
  • 32