Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FindElement so slow on .NetCore Version #4988

Closed
MarioGK opened this issue Nov 1, 2017 · 9 comments
Closed

FindElement so slow on .NetCore Version #4988

MarioGK opened this issue Nov 1, 2017 · 9 comments

Comments

@MarioGK
Copy link

MarioGK commented Nov 1, 2017

Meta -

OS: Windows 10
Selenium Version: 3.7 latest on the github master branch, and 3.6 on nuget both .NET Core
Browser: Firefox and PhatomJS

Browser Version:
Firefox 47
PhatomJS 2.1

Python 3 bindings with practically the same code run way faster than the .net core version

In .net core with this code:
https://i.imgur.com/VdkiPdk.png

Output:
3168
3110

I believe it is not supposed to take 3 seconds to find an element on a simple page, in the python version it was so fast that i didn't even had to measure, it was way below 50 ms

@jimevans
Copy link
Member

jimevans commented Nov 1, 2017

This is a known issue with the .NET Core support, which is still considered experimental for this project. It is fully called out in the project CHANGELOG entry which outlines the support of .NET Core. The root cause of the issue is a bug in .NET Core itself.

@jimevans jimevans closed this as completed Nov 1, 2017
@MarioGK
Copy link
Author

MarioGK commented Nov 1, 2017

@jimevans Isnt there any hotfix for the moment ? like using 127.0.0.1 instead of localhost, as mentioned in one of the issues on the second link you sent me ?

@YevgeniyShunevych
Copy link
Contributor

This issue with command execution 1 second delay is a serious problem with using .NET Core. It reproduces with different browser drivers. And it makes unusable .NET Core version of WebDriver as 1 extra second for each WebDriver command decreases performance very much.

@MarioGK is right, using "127.0.0.1" instead of "localhost" fixes this issue. Here is how I had to implement a fix for Atata Framework: atata-framework/atata#101.

@jimevans is it possible to change the using of "localhost" with "127.0.0.1" in next WebDriver release? As I see, it is hardcoded in DriverService.ServiceUrl property and FirefoxDriver.CreateExtensionConnection method. As an alternative, it would be great if at least public configurational property/method will appear in WebDriver API to change "localhost" value to "127.0.0.1".

For people who wants to bypass this issue in current version of WebDriver (3.6.0 - 3.7.0) here is a method that replaces "localhost" to "127.0.0.1" in HttpCommandExecutor.remoteServerUri field and fixes the performance issue:

public static void FixDriverCommandExecutionDelay(RemoteWebDriver driver)
{
    PropertyInfo commandExecutorProperty = typeof(RemoteWebDriver).GetProperty("CommandExecutor", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.GetProperty);
    ICommandExecutor commandExecutor = (ICommandExecutor)commandExecutorProperty.GetValue(driver);

    FieldInfo remoteServerUriField = commandExecutor.GetType().GetField("remoteServerUri", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField);

    if (remoteServerUriField == null)
    {
        FieldInfo internalExecutorField = commandExecutor.GetType().GetField("internalExecutor", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField);
        commandExecutor = (ICommandExecutor)internalExecutorField.GetValue(commandExecutor);
        remoteServerUriField = commandExecutor.GetType().GetField("remoteServerUri", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.GetField | BindingFlags.SetField);
    }

    if (remoteServerUriField != null)
    {
        string remoteServerUri = remoteServerUriField.GetValue(commandExecutor).ToString();

        string localhostUriPrefix = "http://localhost";

        if (remoteServerUri.StartsWith(localhostUriPrefix))
        {
            remoteServerUri = remoteServerUri.Replace(localhostUriPrefix, "http://127.0.0.1");

            remoteServerUriField.SetValue(commandExecutor, new Uri(remoteServerUri));
        }
    }
}

Just copy this method to some class and invoke it passing RemoteWebDriver instance. The workaround is using .NET reflection, but it is the only way to handle this issue that I currently see.

@jimevans
Copy link
Member

jimevans commented Nov 3, 2017

What’s your solution for users who don’t have an IPv4 stack installed?

@YevgeniyShunevych
Copy link
Contributor

Should try "::1" instead of "127.0.0.1" for IPv6. That's why I pointed that will be good to have some configuration option.

@YevgeniyShunevych
Copy link
Contributor

Current "localhost" issue seems like a bug of .NET Core 2. Hopefully MS team will fix this issue in .NET Core someday. But it will be nice to have a workaround until that time. Having some writable host property with "localhost" value by default and ability to change this value.

@jimevans
Copy link
Member

jimevans commented Nov 3, 2017

But what’s to stop you from doing something like the following in the meantime as a workaround:

ChromeDriverService service = ChromeDriverService.CreateDefaultService();
service.Port = 5555; // Some port value.
service.Start();
IWebDriver driver = new RemoteWebDriver(new Uri(“http://127.0.0.1:5555”), new ChromeOptions());

Yes, I’m aware that’s supremely inelegant. No, I don’t like it any more than you do. And I’ll see what I can do about offering something a little cleaner for the local execution case when my limited time permits.

@YevgeniyShunevych
Copy link
Contributor

Thanks.

@Nefcanto
Copy link

Is it solved now?

@lock lock bot locked and limited conversation to collaborators Aug 16, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants