11

Every now and then when the Chrome is updated, the existing chrome driver used in the script becomes invalid and the below error message is displayed:

selenium.common.exceptions.SessionNotCreatedException: Message: session not created: This version of ChromeDriver only supports Chrome version 77

I have to manually update the chrome-driver in the written script. Is there any way to update it automatically with the updated chrome version?

  • 1
    Which dependency management tool do you use? – João Farias Dec 22 '19 at 11:17
  • Currently not using any dependency tool. I am writing the script in Python. Can you mention any tool that can be used. – Divya Anchan Jan 9 at 7:20
4

Try using webdriver-manager from npm:

https://www.npmjs.com/package/webdriver-manager

And call webdriver-manager update using batch file from your java, python or what ever tool .

To create batch file , open a text file and add webdriver-manager update as the content and now save it as file.bat

| improve this answer | |
3

Yes, it can be done. You need to follow these steps, and you need to choose a tool in which you implement them.

Let's have a look at a few lines in Python, I'll outline the main flow and you might want to build it more powerful (like command line parameters etc.)

First I'll import requests:

import requests

Then I'll save the necessary links into two varibles + I define the file name of the desired version of chrome driver:

url = 'https://chromedriver.storage.googleapis.com/LATEST_RELEASE_'
url_file = 'https://chromedriver.storage.googleapis.com/'
file_name = 'chromedriver_linux64.zip'

Now I'll let the user choose a version, and I get the version from the site:

version = input()
version_response = requests.get(url + version)

Finally, it's time to download the zip file (if it exists):

if version_response.text:
    file = requests.get(url_file + version_response.text + '/' + file_name)
    with open(file_name, "wb") as code:
        code.write(file.content)

The result of these steps will be a zip file with a chrome driver in the current directory (from where you ran the script). You also might use zipfile library to extract the zip file after a successful download.

If you want to fully automate this, you probably need to built in command line parameters and pipe chrome version into your Python script. E.g. in Arch-like systems, you might use $ pacman -Qs chromium for getting Chromium version. Since you don't mention a system architecture on which you want to build this, I've chosen mine.

When ready, you can let it run with cron or similar.

| improve this answer | |
1

Use WebdriverManage. It downloads the required Driver binary file (if not present locally) into Cache (default location ~/.m2/repository/webdriver)

And this is how you can add it in your code:

WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();

latest version dependency :

<!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager -->
<dependency>
    <groupId>io.github.bonigarcia</groupId>
    <artifactId>webdrivermanager</artifactId>
    <version>3.7.1</version>
</dependency>
| improve this answer | |
1

A solution that works for ANY programming language you want to automate with. This way, your team can automate using any Selenium tool.

Using Docker, you can run your own WebDriverManager server, then all you need to do is write really simple code to download drivers from that:

# Mac OSX command
docker run -p 4041:4041 -v $HOME/wdm:/root/.m2/repository bonigarcia/webdrivermanager:4.0.0

# Windows command
docker run -p 4041:4041 -v %USERPROFILE%/wdm:/root/.m2/repository bonigarcia/webdrivermanager:4.0.0

The drivers will be stored in your local $HOME/wdm folder and also inside the docker image. In Docker, set it to remain daemonized with auto-restart policy. It would be very very cheap to host this service on AWS or Azure as it only requires the most minimal hardware to run it.

Here is what it looks like querying the service (using Insomnia rest client):

> GET /firefoxdriver?os=LINUX HTTP/1.1
> Host: localhost:4041
> User-Agent: insomnia/7.1.1
> Accept: */*

< HTTP/1.1 200 OK
< Date: Sat, 04 Jul 2020 17:56:07 GMT
< Server: Javalin
< Content-Type: text/plain
< Content-Disposition: attachment; filename="geckodriver"
< Transfer-Encoding: chunked


* Received 15.8 KB chunk
* Received 15.6 KB chunk
  ....

NOTE: I really like this solution, but when it comes down to it, I probably prefer to automate with Aerokube dockerized browser containers, such as with "Moon framework", which only costs $5/thread/month for a selenium grid that runs dockerized browser tests.

| improve this answer | |
0

First @Asyranok is right, even when implemented auto update code will not work 100% of the time. However, for many of us, this occasional downtime is "ok" as long as it's just a few days.

I've found that manually updating X servers every few months to be incredibly irritating and while there are well written instructions on the selenium website on how to "auto update" the driver I've yet to see one openly available non-library implementation of this guide.

My answer is specific to C#, for this language the solution typically suggested is to use NuGet to pull the latest driver automatically, this has two issues:

  1. You need to deploy at the frequency of chrome updating (most companies aren't there yet, neither are we) or your application will be "broken" for the time between chrome updating and your "new" version of the application deploying, and again this is only if you release on a schedule, if you release ad-hoc your going to have to go through a series of manual steps to update, build, release etc. to get your application working again.

  2. You need (typically, without a work around) to pull the latest chromedrive from NuGet by hand, again a manual process.

What would be nice would be what python has and @leminhnguyenHUST suggests which is using a library that will automatically pull the latest chromedriver on runtime. I've looked around and haven't yet found anything for C# that does this, so I decided to roll my own and build that into my application:

public void DownloadLatestVersionOfChromeDriver()
{
    string path = DownloadLatestVersionOfChromeDriverGetVersionPath();
    var version = DownloadLatestVersionOfChromeDriverGetChromeVersion(path);
    var urlToDownload = DownloadLatestVersionOfChromeDriverGetURLToDownload(version);
    DownloadLatestVersionOfChromeDriverKillAllChromeDriverProcesses();
    DownloadLatestVersionOfChromeDriverDownloadNewVersionOfChrome(urlToDownload);
}

public string DownloadLatestVersionOfChromeDriverGetVersionPath()
{
    //Path originates from here: https://chromedriver.chromium.org/downloads/version-selection            
    using (RegistryKey key = Registry.LocalMachine.OpenSubKey("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\chrome.exe"))
    {
        if (key != null)
        {
            Object o = key.GetValue("");
            if (!String.IsNullOrEmpty(o.ToString()))
            {
                return o.ToString();
            }
            else
            {
                throw new ArgumentException("Unable to get version because chrome registry value was null");
            }
        }
        else
        {
            throw new ArgumentException("Unable to get version because chrome registry path was null");
        }
    }
}

public string DownloadLatestVersionOfChromeDriverGetChromeVersion(string productVersionPath)
{
    if (String.IsNullOrEmpty(productVersionPath))
    {
        throw new ArgumentException("Unable to get version because path is empty");
    }

    if (!File.Exists(productVersionPath))
    {
        throw new FileNotFoundException("Unable to get version because path specifies a file that does not exists");
    }

    var versionInfo = FileVersionInfo.GetVersionInfo(productVersionPath);
    if (versionInfo != null && !String.IsNullOrEmpty(versionInfo.FileVersion))
    {
        return versionInfo.FileVersion;
    }
    else
    {
        throw new ArgumentException("Unable to get version from path because the version is either null or empty: " + productVersionPath);
    }
}

public string DownloadLatestVersionOfChromeDriverGetURLToDownload(string version)
{
    if (String.IsNullOrEmpty(version))
    {
        throw new ArgumentException("Unable to get url because version is empty");
    }

    //URL's originates from here: https://chromedriver.chromium.org/downloads/version-selection
    string html = string.Empty;
    string urlToPathLocation = @"https://chromedriver.storage.googleapis.com/LATEST_RELEASE_" + String.Join(".", version.Split('.').Take(3));

    HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlToPathLocation);
    request.AutomaticDecompression = DecompressionMethods.GZip;

    using (HttpWebResponse response = (HttpWebResponse)request.GetResponse())
    using (Stream stream = response.GetResponseStream())
    using (StreamReader reader = new StreamReader(stream))
    {
        html = reader.ReadToEnd();
    }

    if (String.IsNullOrEmpty(html))
    {
        throw new WebException("Unable to get version path from website");
    }

    return "https://chromedriver.storage.googleapis.com/" + html + "/chromedriver_win32.zip";
}

public void DownloadLatestVersionOfChromeDriverKillAllChromeDriverProcesses()
{
    //It's important to kill all processes before attempting to replace the chrome driver, because if you do not you may still have file locks left over
    var processes = Process.GetProcessesByName("chromedriver");
    foreach (var process in processes)
    {
        try
        {
            process.Kill();
        }
        catch
        {
            //We do our best here but if another user account is running the chrome driver we may not be able to kill it unless we run from a elevated user account + various other reasons we don't care about
        }
    }
}

public void DownloadLatestVersionOfChromeDriverDownloadNewVersionOfChrome(string urlToDownload)
{
    if (String.IsNullOrEmpty(urlToDownload))
    {
        throw new ArgumentException("Unable to get url because urlToDownload is empty");
    }

    //Downloaded files always come as a zip, we need to do a bit of switching around to get everything in the right place
    using (var client = new WebClient())
    {
        if (File.Exists(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\chromedriver.zip"))
        {
            File.Delete(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\chromedriver.zip");
        }

        client.DownloadFile(urlToDownload, "chromedriver.zip");

        if (File.Exists(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\chromedriver.zip") && File.Exists(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\chromedriver.exe"))
        {
            File.Delete(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\chromedriver.exe");
        }

        if (File.Exists(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\chromedriver.zip"))
        {
            System.IO.Compression.ZipFile.ExtractToDirectory(System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\chromedriver.zip", System.IO.Path.GetDirectoryName(Assembly.GetEntryAssembly().Location));
        }
    }
}

Then usually I'll stick this very hacky invocation at the beginning of my application to invoke this feature and ensure that the latest chromedriver is available for my application:

//This is a very poor way of determining if I "need" to update the chromedriver,     
//however I've yet to figure out a better way of doing this...
try
{
    using (var chromeDriver = SetupChromeDriver())
    {
        chromeDriver.Navigate().GoToUrl("www.google.com");
        chromeDriver.Quit();
    }
}
catch
{
    DownloadLatestVersionOfChromeDriver();
}

I'm sure this could be improved significantly, but so far it's worked for me.

Note: Cross Posted Here

| improve this answer | |
0

The best way to use package

chromedriver-autoinstaller

that works perfect for me. I use some automation scripts on regular basis for report creating. Please check documentation for more details.

https://pypi.org/project/chromedriver-autoinstaller/

| improve this answer | |
New contributor
kmpatel100 is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.