GCuser99 / SeleniumVBA

A comprehensive Selenium wrapper for browser automation developed for MS Office VBA running in Windows
MIT License
83 stars 17 forks source link

Chrome Driver 116 Missing #85

Closed dpgt closed 1 year ago

dpgt commented 1 year ago

I've really been enjoying using SeleniumVBA with my Access db. It is sure a help. I noticed today after Chrome updated to 116 that it couldn't update the driver to match. It appears that Chrome has made some changes to where they're stored. I manually updated mine but just wondering if you could change you're code to get the new location?

GHRyunosuke commented 1 year ago

I had the same problem as above and I am not sure how to manually update it... Hope this could be updated/fixed soon.

GCuser99 commented 1 year ago

Hi @dpgt - we are happy that you are finding SeleniumVBA useful and thanks for reporting this! After a quick google search, I see that you are correct that they have changed the api and storage location, and of course that has broken our auto-update feature. Sorry for that inconvenience. This is the link that I just found:

https://groups.google.com/g/chromedriver-users/c/clpipqvOGjE

Anyway, will look at this over the weekend and see if we can get the auto-update back up and running.

Cheers!

Mike

GCuser99 commented 1 year ago

@GHRyunosuke: I was able to manually download the driver from one of the links below:

https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/116.0.5845.0/win64/chromedriver-win64.zip https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/116.0.5845.0/win32/chromedriver-win32.zip

Unless you modified the driver location via the SeleniumVBA.ini file, you will need to placed the unzipped driver in your Downloads folder.

GHRyunosuke commented 1 year ago

@GHRyunosuke: I was able to manually download the driver from one of the links below:

https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/116.0.5845.0/win64/chromedriver-win64.zip https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/116.0.5845.0/win32/chromedriver-win32.zip

Unless you modified the driver location via the SeleniumVBA.ini file, you will need to placed the unzipped driver in your Downloads folder.

It worked, thank you so much @GCuser99 !

6DiegoDiego9 commented 1 year ago

I'm not sure if we want to auto-calculate those new URLs or we want to get them using the official endpoints.

If we choose the second way, here are a couple of functions to start with:

Function GetLatestDriverVersion(channel As String) As String
    'Get the JSON from the official endpoint
    With New MSXML2.ServerXMLHTTP60
        .Open "GET", "https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions.json", False
        .send
        Dim json As Object
        Set json = WebJsonConverter.ParseJson(.ResponseText)
    End With

    'Return the latest version
    GetLatestDriverVersion = json("channels")(channel)("version")
End Function

Function GetDownloadUrlFromJson(version As String, platform As String) As String
    'Get the JSON from the official endpoint
    With New MSXML2.ServerXMLHTTP60
        .Open "GET", "https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json", False
        .send
        Dim json As Object
        Set json = WebJsonConverter.ParseJson(.ResponseText)
    End With

    Dim ver
    For Each ver In json("versions")
      If ver("version") = version Then
        Dim download
        For Each download In ver("downloads")("chrome")
          If download("platform") = platform Then
            GetDownloadUrlFromJson = download("url")
            Exit Function
          End If
        Next
      End If
    Next
End Function

Sub Test()
    Debug.Print GetLatestDriverVersion("Stable")
    Debug.Print GetDownloadUrlFromJson("116.0.5845.96", "win64")
End Sub
GCuser99 commented 1 year ago

Thanks for helping to kick-start this @6DiegoDiego9!

After doing additional research based mostly from this post and some experimentation, here are some of my take-aways:

Building on @6DiegoDiego9's work above, below is a test flow to illustrate my findings. @6DiegoDiego9 maybe if you have the time you could check my RegExp pattern for correctness :-)

Sub testWebDriverDownload()
    'Finds the compatible driver version for the given browser version

    'Get the JSON from the official endpoint "latest-patch-version-per-build"
    'from docs: The latest versions for which all CfT assets are available for download,
    'for each known combination of MAJOR.MINOR.BUILD versions.

    Dim responseTxt As String
    Dim verMajor As String
    Dim verMinor As String
    Dim verBuild As String
    Dim driverVersion As String
    Dim driverUrl As String

    'these are the test inputs
    browserVersion = "117.0.5938.99"
    platform = "win64"

    'remove the patch number from the browser version
    verMajor = Split(browserVersion, ".")(0)
    verMinor = Split(browserVersion, ".")(1)
    verBuild = Split(browserVersion, ".")(2)

    browserBuild = verMajor & "." & verMinor & "." & verBuild

    With New MSXML2.ServerXMLHTTP60
        .Open "GET", "https://googlechromelabs.github.io/chrome-for-testing/latest-patch-versions-per-build.json", False
        .send
        responseTxt = .ResponseText
    End With

    'This below works but is VERY SLOW
    'Dim json As Object
    'Set json = WebJsonConverter.ParseJson(responseTxt)
    'driverVersion = json("builds")(browserBuild)("version")

    'let's use RegExp because this Json file could grow to be very large and
    'this is the fastest (2000x faster than Json parse above!!)
    Dim oRegExp As New VBScript_RegExp_55.RegExp
    Dim matches As VBScript_RegExp_55.MatchCollection

    browserBuild = Replace(browserBuild, ".", "\.") 'escape periods in browser build for search pattern

    oRegExp.Global = False 'should only be one match!
    'searchPattern = """" & browserBuild & """:{""version"":""(.*?)"",""revision"":"".*?""}"
    searchPattern = """(" & browserBuild & "\..*?)"""
    oRegExp.Pattern = searchPattern

    driverVersion = oRegExp.execute(responseTxt)(0).SubMatches(0)

    Debug.Print driverVersion

    'as per https://groups.google.com/g/chromedriver-users/c/clpipqvOGjE/m/yywxERcZAwAJ,
    'every chrome release returned by the json end-point since build 115.0.5763 has a 
    'corresponding driver release with same version
    'so we should be able to calculate the driver url...
    '(the above tested true for builds 115.0.5763 to 118.0.5958)
    driverUrl = "https://edgedl.me.gvt1.com/edgedl/chrome/chrome-for-testing/" & driverVersion & "/" & platform & "/chromedriver-" & platform & ".zip"

    Debug.Print driverUrl
End Sub
GCuser99 commented 1 year ago

I updated the WebDriverManager class to handle the new ChromeDriver release api. Due to the importance of timely fixing this "bug", I did not do my normal testing due diligence but hopefully you all will report back issues or suggestions for improvement, if any.

One interesting change with the new api is that there is now a 64-bit version of the ChromeDriver, where there was not before. With this new update, the default is to check the bit-ness of the OS to decide which version to install, as we have always done with the EdgeDriver. Hopefully this change does not cause you any problems...

I'll leave this issue open for comments/feedbacks for a while...

6DiegoDiego9 commented 1 year ago

100% OK with you solution, @GCuser99! Thanks for being always so responsive and thorough in your approach :-) I didn't see the updated WebDriverManager class in your 4.5 update, but I'll try it with my Chrome 116 as soon as I see it. Cheers!

6DiegoDiego9 commented 1 year ago

Ah, I actually overlooked your update to WebDriverManager as you did so much work that GitHub hid it by default: image

Tested with my Chrome and an old 114 driver, and it transparently updated it in a few seconds and worked like a charm!

Thank you again for the great job! :-D

GCuser99 commented 1 year ago

Awesome! If you are doing an incremental update to your code base, be sure to include the small changes to the private "start" procedure in the WebDriver class - I incorporated your "platform" idea from your code above.... Cheers!

Oh, and I also included your code above in the GetLatestDriverVersion method of the WebDriverManager class - thanks for the help!

6DiegoDiego9 commented 1 year ago

for updating my code base I always replace all the Web* module/classes. Thanks anyway for the note! :)