rosolko / WebDriverManager.Net

Automatic Selenium Webdriver binaries management for .Net
MIT License
269 stars 83 forks source link

[🐛 Bug]: WebDriverManager.Net not working with new chromedriver endpoints for Chrome since version 115 #253

Closed mtadla-sii closed 1 year ago

mtadla-sii commented 1 year ago

Problem

After updatating Chrome to version 115 the code below:

new DriverManager().SetUpDriver(new ChromeConfig(), VersionResolveStrategy.MatchingBrowser);

finishes with error:

System.Net.WebException
The remote server returned an error: (404) Not Found.
   at System.Net.HttpWebRequest.GetResponse()
   at WebDriverManager.DriverConfigs.Impl.ChromeConfig.GetLatestVersion(String url)
   at WebDriverManager.DriverConfigs.Impl.ChromeConfig.GetMatchingBrowserVersion()
   at WebDriverManager.DriverManager.GetVersionToDownload(IDriverConfig config, String version)
   at WebDriverManager.DriverManager.SetUpDriver(IDriverConfig config, String version, Architecture architecture)

Looks like there are changes for downloading chromedriver since v115 https://chromedriver.chromium.org/downloads "If you are using Chrome version 115 or newer, please consult the Chrome for Testing availability dashboard. This page provides convenient JSON endpoints for specific ChromeDriver version downloading."

stevekiszow commented 1 year ago

Hi folks, do we have a time frame for this issue? Just seeing this today also and wondering if there is a work around?

mtadla-sii commented 1 year ago

FYI there is also issue for that in selenium 4 'buil-in' driver manager https://github.com/SeleniumHQ/selenium/pull/12208

drswin01 commented 1 year ago

Some context around this issue. The ChromeDriver team has changed the chromedriver download location for any Chrome version >114 https://groups.google.com/g/chromedriver-users/c/clpipqvOGjE

IvanQL commented 1 year ago

@stevekiszow

We moved to selenium 4 'built-in' driver manager. It also have some issues in our test runs, but we fixed it on our side

stevekiszow commented 1 year ago

Thanks @IvanQL - I'll take a look at that this morning, thanks for your post. Kind regards 👍

mokkymiah commented 1 year ago

We have the same issue. Alot of our automated systems are failing due to this. We upgraded to latest webdriver manager and selenium but both have the same issue. It seems selenium is not going to update to handle this and instead waiting for the chrome team to release the drivers on the current site?

MatadorQA commented 1 year ago

Ditto - our automated scripts are starting to fail re: Chrome 115. Any approximate timescale to fix would be appreciated - many thanks.

mokkymiah commented 1 year ago

We temporarily patched our systems by adding an override for the GetMatchingBrowserVersion with a quick chrome 115 version check to redirect the URL.


public partial class ChromeConfigOverride : ChromeConfig
{

    private const string BaseVersionPatternUrl = "https://chromedriver.storage.googleapis.com/<version>/";
    private const string LatestReleaseVersionUrl = "https://chromedriver.storage.googleapis.com/LATEST_RELEASE";

    private const string ExactReleaseVersionPatternUrl =
        "https://chromedriver.storage.googleapis.com/LATEST_RELEASE_<version>";

    public virtual string GetName()
    {
        return "Chrome";
    }

    public virtual string GetUrl32()
    {
        return GetUrl();
    }

    public virtual string GetUrl64()
    {
        return GetUrl();
    }

    private string GetUrl()
    {
#if NETSTANDARD
            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                var architectureExtension =
                    RuntimeInformation.ProcessArchitecture == System.Runtime.InteropServices.Architecture.Arm64
                        ? "_arm64"
                        : "64";
                return $"{BaseVersionPatternUrl}chromedriver_mac{architectureExtension}.zip";
            }

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                return $"{BaseVersionPatternUrl}chromedriver_linux64.zip";
            }
#endif

        return $"{BaseVersionPatternUrl}chromedriver_win32.zip";
    }

    public virtual string GetBinaryName()
    {
#if NETSTANDARD
            var isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
#else
        var isWindows = true;
#endif
        var suffix = isWindows ? ".exe" : string.Empty;
        return $"chromedriver{suffix}";
    }

    public virtual string GetLatestVersion()
    {
        return GetLatestVersion(LatestReleaseVersionUrl);
    }

    private static string GetLatestVersion(string url)
    {
        var uri = new Uri(url);
        var webRequest = WebRequest.Create(uri);
        using (var response = webRequest.GetResponse())
        {
            using (var content = response.GetResponseStream())
            {
                if (content == null) throw new ArgumentNullException($"Can't get content from URL: {uri}");
                using (var reader = new StreamReader(content))
                {
                    var version = reader.ReadToEnd().Trim();
                    return version;
                }
            }
        }
    }

    public virtual string GetMatchingBrowserVersion()
    {
        var rawChromeBrowserVersion = GetRawBrowserVersion();
        if (string.IsNullOrEmpty(rawChromeBrowserVersion))
        {
            throw new Exception("Not able to get chrome version or not installed");
        }

        var chromeBrowserVersion = VersionHelper.GetVersionWithoutRevision(rawChromeBrowserVersion);

        var url = ExactReleaseVersionPatternUrl.Replace("<version>", chromeBrowserVersion);
        Version chromeVersion = new Version(chromeBrowserVersion);

        if (chromeVersion >= new Version(115, 0, 0))
        {
            url = ExactReleaseVersionPatternUrl.Replace("<version>", @"https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/<version>/win32/chromedriver-win32.zip");
        }

        return GetLatestVersion(url);
    }

    private string GetRawBrowserVersion()
    {
#if NETSTANDARD
            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                return RegistryHelper.GetInstalledBrowserVersionOsx("Google Chrome", "--version");
            }

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                return RegistryHelper.GetInstalledBrowserVersionLinux(
                    "google-chrome", "--product-version",
                    "chromium", "--version",
                    "chromium-browser", "--version");
            }

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                return RegistryHelper.GetInstalledBrowserVersionWin("chrome.exe");
            }

            throw new PlatformNotSupportedException("Your operating system is not supported");
#else
        return RegistryHelper.GetInstalledBrowserVersionWin("chrome.exe");
#endif
    }

}
MuteMO commented 1 year ago

Thanks for providing the above.

However, this line is returning a 404 error

url = ExactReleaseVersionPatternUrl.Replace("", @"https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing//win32/chromedriver-win32.zip");

mokkymiah commented 1 year ago

@MuteMO You are missing the chrome version in the URL you generated.

It should be like this https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/115.0.5790.102/linux64/chrome-linux64.zip

MuteMO commented 1 year ago

I am afraid I am still getting the error when this is called from the code. it works fine when I paste the url into a browser

mokkymiah commented 1 year ago

If you debug and console log the URL that has been generated, then paste it here please?

MuteMO commented 1 year ago

OK its failing at this line of code:

new WebDriverManager.DriverManager().SetUpDriver(new ChromeConfigOverride(), VersionResolveStrategy.MatchingBrowser)

but its not returning any url just a 404 error on MatchingBrowser

would I need to change this 'VersionResolveStrategy.MatchingBrowser' based on the new changes or should your code in the Override class take care of it. If so what am I missing please?

SPECSTET commented 1 year ago

If you can (temporarily) live with the latest chrome version, just change the ResolveStrategy to 'Latest'. Then it will works fine.

    return new WebDriver
    {
        BrowserName = Browsers.Chrome,
        Driver = new ChromeDriver(
            Path.GetDirectoryName(new DriverManager().SetUpDriver(new ChromeConfig(),
                VersionResolveStrategy.Latest)), // <= no problem with 'Latest'
            options)
    };
ms6073 commented 1 year ago

If you debug and console log the URL that has been generated, then paste it here please?

[https://chromedriver.storage.googleapis.com/LATEST_RELEASE_115.0.5790]

Which returns

NoSuchKey The specified key does not exist.
No such object: chromedriver/LATEST_RELEASE_115.0.5790

This is due to the changes that Google annoucned in May that would take effect with the 115 release and includes

The download location for ChromeDriver releases will change.

This applies to both the old ChromeDriver Stable + Beta downloads at https://chromedriver.storage.googleapis.com/ as well as the old Canary downloads at https://chromedriver.chromium.org/chromedriver-canary. We won’t publish new downloads to these locations in the future.

Here are the new end points

tampopo7 commented 1 year ago

No need to use WebDriverManager

var options = new ChromeOptions(); var service = ChromeDriverService.CreateDefaultService();

var driver = new ChromeDriver(service, options); driver.Navigate().GoToUrl(@"https://www.google.com/");

iouym commented 1 year ago

Hey everyone, this issue should get resolved once a version is released containing #254 FYI - I think there may be another addition to this change where we need to look at applying the WithProxy settings to the ChromeForTestingClient.

mokkymiah commented 1 year ago

Is this supposed to be downloading driver version 114.0.5735.90 instead of 115?

inflextion commented 1 year ago

Hey everyone, this issue should get resolved once a version is released containing #254 FYI - I think there may be another addition to this change where we need to look at applying the WithProxy settings to the ChromeForTestingClient.

Any ETA on that ?

ms6073 commented 1 year ago

Hey everyone, this issue should get resolved once a version is released containing #254 FYI - I think there may be another addition to this change where we need to look at applying the WithProxy settings to the ChromeForTestingClient.

Any ETA on that ? 2.17.0 is now available

inflextion commented 1 year ago

@ms6073 I was referring to the implementation of WithProxy + ChromeForTestingClient

stevekiszow commented 1 year ago

Hi folks, sorry to be pain. I'm seeing "The remote certificate is invalid according to the validation procedure: RemoteCertificateNameMismatch" when trying to run _ = new DriverManager().SetUpDriver(new ChromeConfig(), "MatchingBrowser"); - using 2.17.0 - any ideas? Not sure if others are seeing that too? And I've missed something simple :)

Venkata823 commented 1 year ago

hi , I am able to resolve the issue ["The remote server returned an error: (404) Not Found."] after updating WebdriverManager to 2.17. Thanks for that. But still I am getting the same issue for Firefox . Is there any solution for that as well ?

Thanks in advance, Ramesh

smutekgmc commented 1 year ago

Hi, I am able to resolve the issue ["The remote server returned an error: (404) Not Found."] as well after updating to 2.17. But DriverManager SetUpDriver() looks unstable., when i call SetUpDriver(new ChromeConfig(), version: "115.0.5790.102") sometimes the result is 200 OK (correct driver is downloaded) and sometimes 404 Not Found. When it does, the stack trace is like this: System.Net.WebException : The remote server returned an error: (404) Not Found. StackTrace: at System.Net.HttpWebRequest.GetResponse() at System.Net.WebClient.GetWebResponse(WebRequest request) at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream) at System.Net.WebClient.DownloadFile(Uri address, String fileName) at WebDriverManager.Services.Impl.BinaryService.DownloadZip(String url, String destination) at WebDriverManager.Services.Impl.BinaryService.SetupBinary(String url, String zipPath, String binaryPath) at WebDriverManager.DriverManager.SetUpDriverImpl(String url, String binaryPath) at WebDriverManager.DriverManager.SetUpDriver(IDriverConfig config, String version, Architecture architecture) Any hint what could be the reason?

Venkata823 commented 1 year ago

Hi, I am able to resolve the issue ["The remote server returned an error: (404) Not Found."] as well after updating to 2.17. But DriverManager SetUpDriver() looks unstable., when i call SetUpDriver(new ChromeConfig(), version: "115.0.5790.102") sometimes the result is 200 OK (correct driver is downloaded) and sometimes 404 Not Found. When it does, the stack trace is like this: System.Net.WebException : The remote server returned an error: (404) Not Found. StackTrace: at System.Net.HttpWebRequest.GetResponse() at System.Net.WebClient.GetWebResponse(WebRequest request) at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream) at System.Net.WebClient.DownloadFile(Uri address, String fileName) at WebDriverManager.Services.Impl.BinaryService.DownloadZip(String url, String destination) at WebDriverManager.Services.Impl.BinaryService.SetupBinary(String url, String zipPath, String binaryPath) at WebDriverManager.DriverManager.SetUpDriverImpl(String url, String binaryPath) at WebDriverManager.DriverManager.SetUpDriver(IDriverConfig config, String version, Architecture architecture) Any hint what could be the reason?

@smutekgmc Can you try " new DriverManager().SetUpDriver(new FirefoxConfig(), VersionResolveStrategy.MatchingBrowser); " ?

ms6073 commented 1 year ago

Hi, I am able to resolve the issue ["The remote server returned an error: (404) Not Found."] as well after updating to 2.17. But DriverManager SetUpDriver() looks unstable., when i call SetUpDriver(new ChromeConfig(), version: "115.0.5790.102") sometimes the result is 200 OK (correct driver is downloaded) and sometimes 404 Not Found. When it does, the stack trace is like this: System.Net.WebException : The remote server returned an error: (404) Not Found. StackTrace: at System.Net.HttpWebRequest.GetResponse() at System.Net.WebClient.GetWebResponse(WebRequest request) at System.Net.WebClient.DownloadBits(WebRequest request, Stream writeStream) at System.Net.WebClient.DownloadFile(Uri address, String fileName) at WebDriverManager.Services.Impl.BinaryService.DownloadZip(String url, String destination) at WebDriverManager.Services.Impl.BinaryService.SetupBinary(String url, String zipPath, String binaryPath) at WebDriverManager.DriverManager.SetUpDriverImpl(String url, String binaryPath) at WebDriverManager.DriverManager.SetUpDriver(IDriverConfig config, String version, Architecture architecture) Any hint what could be the reason?

@smutekgmc Can you try " new DriverManager().SetUpDriver(new FirefoxConfig(), VersionResolveStrategy.MatchingBrowser); " ?

I suspect that @smutekgmc may have a use case that requires a specific driver version.

niklausburren commented 1 year ago

Hi together

We have upgraded to version 2.17.0. Now we get an AggregateException with a HttpRequestException as inner exception with the following call:

driverManager.SetUpDriver(new ChromeConfig(), VersionResolveStrategy.MatchingBrowser);

System.AggregateException : One or more errors occurred. (One or more errors occurred. (A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. (googlechromelabs.github.io:443)))

at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) at System.Threading.Tasks.Task.Wait() at WebDriverManager.Clients.ChromeForTestingClient.GetResultFromHttpTask[TResult](Task`1 taskToRun) at WebDriverManager.Clients.ChromeForTestingClient.GetKnownGoodVersionsWithDownloads() at WebDriverManager.DriverConfigs.Impl.ChromeConfig.GetVersionFromChromeForTestingApi(String noRevisionVersion) at WebDriverManager.DriverConfigs.Impl.ChromeConfig.GetMatchingBrowserVersion() at WebDriverManager.DriverManager.GetVersionToDownload(IDriverConfig config, String version) at WebDriverManager.DriverManager.SetUpDriver(IDriverConfig config, String version, Architecture architecture)

We also use the WithProxy method could this be a problem?

niklausburren commented 1 year ago

Probably, in the method WithProxy of the class DriverManager new you should set not only the default proxy of WebRequest but also of HttpClient, because in the class ChromeForTestingClient new the HttpClient is used.

If we set the default proxy of HttpClient, the exception described above will no longer occur.

public DriverManager WithProxy(IWebProxy proxy)
{
    _binaryService = new BinaryService
    {
        Proxy = proxy
    };
    WebRequest.DefaultWebProxy = proxy;
    // add this line here?
    HttpClient.DefaultProxy = proxy;
    return this;
}
inflextion commented 1 year ago

Probably, in the method WithProxy of the class DriverManager new you should set not only the default proxy of WebRequest but also of HttpClient, because in the class ChromeForTestingClient new the HttpClient is used.

If we set the default proxy of HttpClient, the exception described above will no longer occur.

public DriverManager WithProxy(IWebProxy proxy)
{
    _binaryService = new BinaryService
    {
        Proxy = proxy
    };
    WebRequest.DefaultWebProxy = proxy;
    // add this line here?
    HttpClient.DefaultProxy = proxy;
    return this;
}

another option is to add a Proxy variable, same manner as in BinaryService and set it like ChromForTestClient.Proxy = proxy in the DriverManager ( as you mentioned)

This way, it will work at least by getting the system proxy before calling the DriverManager

@niklausburren would you like to open a PR on this?

niklausburren commented 1 year ago

@inflextion I have added a pull request now: #259

smutekgmc commented 1 year ago

@ms6073 Yes, I'm specifing chrome driver version, not using Latest or MatchingBrowser.

ms6073 commented 1 year ago

Hey everyone, this issue should get resolved once a version is released containing #254 FYI - I think there may be another addition to this change where we need to look at applying the WithProxy settings to the ChromeForTestingClient.

You might want to update your unit test for ChromeConfigs as I think you will find it fails when comparing the min version for google for testing api (note I am using FluentAssertions in the code below).

`public void GetLatestVersionTest() { var actual = GetLatestVersion(); var expected = new Version("115.0.5763.0"); var regex = new Regex(@"^\d+.\d+.\d+.\d+$"); var reason = $" the value of the latest version {actual} was not in the expected format"; var latestVersion = new Version(actual);

    Assert.NotEmpty(version);
    Assert.Matches(regex, version);
    actual.Should().MatchRegex(regex, reason);

Assert. latestVersion.CompareTo(expected).Should().BeGreaterThan(0); }

[TestMethod] [TestCategory(Categories.Unit)] public void GetMatchingVersionTest() { var actual = GetMatchingBrowserVersion(); var expected = new Version("115.0.5763.0"); var regex = new Regex(@"^\d+.\d+.\d+.\d+$"); var reason = $" the value of the latest version {actual} was not in the expected format"; var latestVersion = new Version(actual);

    actual.Should().NotBeNullOrEmpty();
    actual.Should().MatchRegex(regex, reason);
    latestVersion.CompareTo(expected).Should().BeGreaterThan(0);

} `

The logic in line 94 of ChromeConfigs.cs that compares versions is not working as expected. It might be better to use the ICOmparer between the two versions instead.

`var matchedVersion = new Version(rawChromeBrowserVersion);

switch (matchedVersion.CompareTo(MinChromeForTestingDriverVersion)) { case 0: case 1: _chromeVersion = GetFromChromeForTesting(chromeVersion).Version; break; default: var url = ExactReleaseVersionPatternUrl.FormatWith(chromeVersion); _chromeVersion = GetFromChromeStorage(url); break; }`

ms6073 commented 1 year ago

Also noticed that in the GetUrl method of the ChromeConfig.cs class, when _chromeVersionInfo has a value, then the GetUrlFromChromeForTestingApi method is called. The problem is that if we are using the VersionResolveStrategy.MatchingBrowser arg when calling SetUpDriver and the user's browser is newer than the minimum browser version for the new Chrome For Testing APIs, then the code will try to get the version from goolge storage instead of the new location because while the value of _chromeVersion is not set when using this VersionResolveStrategy.

private string GetUrl()
{
    // Handle newer versions of chrome driver only being available for download via the Chrome for Testing API's
    // whilst retaining backwards compatibility for older versions of chrome/chrome driver.
    if (_chromeVersionInfo != null)
    {
        return GetUrlFromChromeForTestingApi();
    }

    return GetUrlFromChromeStorage();
}
Raans12 commented 1 year ago

If you can (temporarily) live with the latest chrome version, just change the ResolveStrategy to 'Latest'. Then it will works fine.

    return new WebDriver
    {
        BrowserName = Browsers.Chrome,
        Driver = new ChromeDriver(
            Path.GetDirectoryName(new DriverManager().SetUpDriver(new ChromeConfig(),
                VersionResolveStrategy.Latest)), // <= no problem with 'Latest'
            options)
    };

This worked like a charm for 115 but my chrome upgraded to 116 now. I get another issue This version of ChromeDriver only supports Chrome version 114 Current browser version is 116.0.5845.97

new WebDriverManager.DriverManager().SetUpDriver(new ChromeConfig(), VersionResolveStrategy.Latest) - I tried MatchingBrowser and getting 404 for that. Anyone tried with 116?

ms6073 commented 1 year ago

finishes with error: Are you using the latest release version 2.17.1.

Raans12 commented 1 year ago

finishes with error: Are you using the latest release version 2.17.1.

Ah thanks, it was my bad. Upgraded to 2.17.1 and it works now. Thanks again

sage-git-projects commented 1 year ago

I use 2.17.1 and has the same problem after Chrome updated to 116. It works correctly before (115).

evilgenius786 commented 1 year ago

Got problems with version 116

sudgarre commented 1 year ago

I use 2.17.1 and has the same problem after Chrome updated to 116. It works correctly before (115).

Facing issues with 2.17.1 & Chrome 116. Works fine with Selenium 4.10.0 but fails after upgrade to 4.11.0.

Sharing the logs below.

OpenQA.Selenium.NoSuchDriverException: Unable to obtain chrome using Selenium Manager; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location
 ---> System.TypeInitializationException: The type initializer for 'OpenQA.Selenium.SeleniumManager' threw an exception.
 ---> OpenQA.Selenium.WebDriverException: Unable to locate or obtain Selenium Manager binary at C:\<removed the data>\bin\Debug\net5.0\SpecFlowPlusRunner\net5.0\selenium-manager/windows/selenium-manager.exe
SeleniumManager.cctor()
   --- End of inner exception stack trace ---
SeleniumManager.DriverPath(DriverOptions options)
DriverFinder.FullPath(DriverOptions options)
   --- End of inner exception stack trace ---
DriverFinder.FullPath(DriverOptions options)
ChromeDriverService.CreateDefaultService(ChromeOptions options)
sudgarre commented 1 year ago

This workaround may help others so posting here

            var driverPath = new DriverManager().SetUpDriver(new ChromeConfig());
            driver = new ChromeDriver(driverPath);
ms6073 commented 1 year ago

Facing issues with 2.17.1 & Chrome 116. Works fine with Selenium 4.10.0 but fails after upgrade to 4.11.0.

Sharing the logs below.

OpenQA.Selenium.NoSuchDriverException: **Unable to obtain chrome using Selenium Manager**; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location

That is not an error from WebDriverManager, but an error thrown by OpenQA's Selenium Manager code.

sudgarre commented 1 year ago

Facing issues with 2.17.1 & Chrome 116. Works fine with Selenium 4.10.0 but fails after upgrade to 4.11.0. Sharing the logs below.

OpenQA.Selenium.NoSuchDriverException: **Unable to obtain chrome using Selenium Manager**; For documentation on this error, please visit: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location

That is not an error from WebDriverManager, but an error thrown by OpenQA's Selenium Manager code.

Yes @ms6073 .issue raised with Selenium team #https://github.com/SeleniumHQ/selenium/issues/12675