Automatic WebDriver download/alignment #29
Replies: 21 comments 12 replies
-
Those all sound like useful optimizations. I'm a little concerned about a few changes though. I think the binary location should at least be user-configurable. That has been helpful to me in the past when I was testing multiple versions of the drivers (64bit vs 32bit for example). Presently user can change it through the DefaultBinaryFolder property. I don't see any compelling reason to remove that ability. But I have no problem with you changing the default to Temp folder, such as in:
On the removing the optionality for auto-checking driver-browser alignment - what do you mean "or after it's called and an error specifically stating wrong-version occurs." Are you referring to an error generated by the Selenium WebDriver? As it stands now, the auto-update occurs when the major version is misaligned - that seems to be the web consensus on when to update. Are you saying to instead wait until the Selenium WebDriver throws an error due to misalignment? Do you know how to trap that error for Edge, Chrome, and Firefox? And are you sure that waiting for the WebDriver to complain is the best policy for knowing when to update? Or am I misunderstanding what you are saying. Let's discuss this some more... Thanks! |
Beta Was this translation helpful? Give feedback.
-
On the driver auto-alignment: I did some quick testing and found that the error you referred to, which happens on OpenBrowser for me, does not seem guaranteed to happen when the major version is misaligned. For example, on the current 105 version of Edge browser, the error occurs for me when I use WebDriver version 103.0.1264, but does not occur when I use WebDriver version 104.0.1293. So what does this mean? I have no idea... If the error does not occur, regardless of major version misalignment, does that mean the WebDriver is fully compatible with the browser version? Also, since the Edge/Chrome incompatibility error occurs (at least for me) at OpenBrowser, how would you recover from that error since the WebDriver has already started? I have no doubt that you could solve that, but at what cost in terms of your time and potential complications in the code? Furthermore, I do not get an incompatibility error for Firefox on OpenBrowser when I use a supposedly incompatible driver. It works until it hits a place where it does not. That raises the concern that even if Chrome and Edge are not throwing the OpenBrowser error with a major version mismatch, will they throw an error or misbehave somewhere else downstream? I mention all of the above just to make the point that it may be more complicated than either one of us think or know. :-) In case you are not aware, I had anticipated some of this complication (aka my lack of knowledge) when I designed the WebDriverManager. I set the WebDriverManager default minimum compatibility level to match just the major version so that we aren't over-updating - look at class_initialize:
But user can change that to a more restrictive level through this property:
On the default binary location - I have no problem with changing that to the user temp directory if that solves or prevents a problem for you or your users. As I said before, I just don't want to get locked into that without any control, so I would push for allowing user the option to set the location to something different, and also be able to easily change it in the class_initalize subs, as user can do currently. Were you able to make the web requests more robust with auto-proxy? I am interested to hear more... Oh, and I am interested in getting rid of the checkDriverBrowserVersionAlignment switch, or at least setting the default to true, if we can get it to work robustly. It works fine on my system, but it sounds like you have had problems with it. Anyway, I'm excited that someone else is looking at this with a critical and different perspective. Thanks for your enthusiasm and hard work! |
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9 thanks for sharing your research. So on your business PC, it only fails using ServerXMLHTTP on the driver download request in the DownloadAndInstallDriver method of WebDriverClass, but does not fail in the other methods that request version info, such as in GetCompatibleDriverVersion? I'm ok with your recommendation above. I tested it and it worked on my end. Do you think we should use XMLHTTP only for the download, and ServerXMLHTTP for all other requests like the version API requests, since these will be used frequently if we turn the auto-version-alignment feature in WebDriver to True? |
Beta Was this translation helpful? Give feedback.
-
BTW, I tested how long it takes to check version alignment with checkDriverBrowserVersionAlignment = True after making your suggested change above. On my system after many tests this morning I found that it always took less than .5 secs and with 90% of the time less than .1 secs. So the overhead seems tolerable to me. One small thing that needs to be modified with auto-checking is that we should trap an error caused by being disconnected to the internet. I was doing some personal work with SeleniumVBA the other day where I was accessing and processing some local web pages when the power in our area went out for a brief period of time, which affected internet service. I could still keep working because I wasn't navigating to www. But if I had had the auto-check turned on, I would have had to manually turn it off until service came back on. |
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9 - thanks for starting this discussion - you have got me rethinking a lot of this... So the general approach that I was taking to check alignment was to:
For Firefox, that general approach still looks optimal to me. But since Edge and Chrome maintain (at least currently) synchronized version numbers between browser and driver, I realize now that it is more efficient to check the installed driver version against the installed browser version to determine whether the threshold is met, while bypassing the api web request. I'm hoping that approach should make you happy :-). To illustrate the difference, compare the revised logic below in the Start method between Edge/Chrome versus Firefox. What do you think? I tested it with a timer on my machine and the check for Edge when driver and browser are aligned takes only an average .0564 secs (20 trials) and of course does not require a web api request.
|
Beta Was this translation helpful? Give feedback.
-
Yes, that is true - if the major version is same and minor version is different, then setting the desired compatibility level=svbaMinor will trigger an update in the example that you raised. But, as far as I can tell, the minor version does not change much - in fact I have yet to see it to be other than 0! However, I would have no problem setting the desired compatibility level=svbaMajor. That is what I have it set to now and I have yet to get compatibility "burned" using that setting. By "bverInstalled is higher than dverInstalled" do you mean "bverInstalled's vermajor > dverInstalled's vermajor"? So if user manually installs a higher major version of the driver than the installed browser, we assume that it was intentional, and do not update? If that is what you mean, then it's an endpoint that I am indifferent about, and would be happy to try to build that in. It should be noted that the api for getting a compatible driver version for Edge browser only takes as input the browser major version anyway, which implies to me that perhaps that's all that really matters. On the other hand, the Chrome api actually can take as input major.minor.buildmajor to look for what they call an "exact match", which implies that it might matter - so pretty much the mixed message that you got from the links above. Like I said already, I think matching major version for auto-align is good enough, and if user feels the need to optimize, they can update programmatically more frequently. Anyway, I found some buggy WebDriverManager code and am making changes now. I will keep you posted on progress. Thanks much for your ideas. |
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9 - I'm having trouble following your proposed checking/updating strategy. Here is the way I am thinking about this - maybe you can tell me where I am going wrong:
Under the scenario above: I don't understand how the driver version gets AHEAD of the browser version, as in your "(bverInstalled's vermajor < dverInstalled's vermajor)". It's always either in sync because we decided to update whenever there is a browser build change, or its behind because we wait until there is a browser major/minor change. If we use your "(bverInstalled is higher than dverInstalled)" and we assume as above that dverInstalled<=bverInstalled, that would imply that we call trigger the check/update routine as often as possible, which would be equivalent to: 'below evaluates to true if the browser and driver versions are not exactly the same
If mngr.CheckCompatibilityLevel(bverInstalled, dverInstalled) < svbaBuildMinor then Is that what you want? I thought originally you were concerned about minimizing web requests from an efficiency perspective, and my proposal above was meant to address your concern. I suppose in rare cases a user manually downloads a driver that happens to be ahead of their installed browser. In that case using my original proposal, the auto-align would update the driver in the backwards direction. I think that would be a good thing personally since I'm not sure that drivers are backward compatible with older versions of browsers. BTW, I looked at Chrome version numbers back to below major version 90. Out of the nearly 4000 not one had a minor version <> 0. So it appears that using either svbaMajor and svbaMinor for desired compatibility level is effectively the same in terms of frequency of checks/updates. Below is a slightly updated version with comments... If checkDriverBrowserVersionAlignment Then
Dim mngr As New WebDriverManager
Dim bverInstalled, dverInstalled, dverCompat
Select Case browserName_
Case "msedge"
bverInstalled = mngr.GetInstalledBrowserVersion(Edge)
dverInstalled = mngr.GetInstalledDriverVersion(Edge)
If mngr.CheckCompatibilityLevel(bverInstalled, dverInstalled) < svbaMinor Then
'the installed driver major/minor version is different than the installed browser major/minor version
'so find the most compatible driver version for installed browser
dverCompat = mngr.GetCompatibleDriverVersion(Edge, bverInstalled)
'its possible that the browser version is a dev version, and there is not yet
'an updated driver version, so check to make sure dverCompat is not already installed
'if they are different, then install the compatible driver
If dverCompat <> dverInstalled Then mngr.DownloadAndInstallDriver Edge, dverCompat, driverPath
End If
Case "chrome"
bverInstalled = mngr.GetInstalledBrowserVersion(Chrome)
dverInstalled = mngr.GetInstalledDriverVersion(Chrome)
If mngr.CheckCompatibilityLevel(bverInstalled, dverInstalled) < svbaMinor Then
'the installed driver major/minor version is different than the installed browser major/minor version
'so find the most compatible driver version for installed browser
dverCompat = mngr.GetCompatibleDriverVersion(Chrome, bverInstalled)
'its possible that the browser version is a dev version, and there is not yet
'an updated driver version, so check to make sure dverCompat is not already installed
If dverCompat <> dverInstalled Then mngr.DownloadAndInstallDriver Chrome, dverCompat, driverPath
End If
Case "firefox"
bverInstalled = mngr.GetInstalledBrowserVersion(Firefox)
dverInstalled = mngr.GetInstalledDriverVersion(Firefox)
dverCompat = mngr.GetCompatibleDriverVersion(Firefox, bverInstalled)
If mngr.CheckCompatibilityLevel(dverCompat, dverInstalled) < svbaMinor Then
'the installed driver major/minor version is different than the most compatible driver major/minor version
'so install it
mngr.DownloadAndInstallDriver Firefox, dverCompat, driverPath
End If
End Select
End If |
Beta Was this translation helpful? Give feedback.
-
Ok I'll default it to ignoring the build minor, but add a constant in the declare section to make it easy to change. We can try that for a while and if in future we run into compatibility issues we can change it to match exactly. I also like this compromise because its driver-server responsible in terms of minimizing the number of web requests. At the same time, it mostly takes advantage of the auto-check ability (better than the manual "match major/minor" practice) - drawing a good balance I think. Thanks again for the collaboration! |
Beta Was this translation helpful? Give feedback.
-
I had a new idea that could change all: we could store the last-web-check timestamp in the webdriver file name (as suffix) or in one of its hidden properties! So that we could simply do a new web-check every once in a while, I'd say "always unless recently checked" Recently = maybe <1hr? |
Beta Was this translation helpful? Give feedback.
-
That's an interesting idea... But I think we should go with the current compromise solution first. If we find problems with it, then work on solutions to fix. I honestly feel that the current solution is going to work great. Let's give it a try. :-) |
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9, I need your help... With the change to using XMLHTTP60, we broke the geckodriver download. Below is a test sub - do you know of a way to fix? I'm pretty ignorant in this area... the only solution I can think of is instantiating client using late binding as in the commented-out section below, but hoping you know of a cleaner solution...?
|
Beta Was this translation helpful? Give feedback.
-
I can get the download to work using:
But wondering whether that breaks on your business pc? Also had luck using this one...
|
Beta Was this translation helpful? Give feedback.
-
I found that the reason is that XMLHTTP denies access to sites that aren't trusted by IE. ServerXMLHTTP doesn't perform those checks. I was able to make it work with XMLHTTP by adding "https://github.com" in trusted sites and setting the Security level for trusted sites to "Low". However this is not a viable option for us. ServerXMLHTTP60 and WinHTTP don't work on my business PC unless proper proxy settings are configured. URLDownloadToFile was the solution! :-) |
Beta Was this translation helpful? Give feedback.
-
Awesome - thanks for your help! |
Beta Was this translation helpful? Give feedback.
-
@6DiegoDiego9 - I refactored the WebDriverManager class for improved logic and clarity. I set the default minimum compatibility for Align*DriverWithBrowser to update to the latest and greatest compatible driver so that when user updates programmatically, as in test_Update_Driver module they get the most current. However, as we discussed, in order to minimize what are probably frequent and unnecessary web requests, the setting in the WebDriver class Start method is update only when there is a new build major. The auto-check-and-align in WebDriver class is set to True, so that the software functions out-of-the-box as per your encouragement at the start of this thread. I implemented a runSilent mode for the auto-check-and-align in WebDriver Start method so that the process is less-likely to interrupt browser automation in case of an updating error. Thanks for your help on this! |
Beta Was this translation helpful? Give feedback.
-
Thanks for another exciting update! :) BTW I just read that you changed ServerXMLHTTP60 to XMLHTTP60 while after this message I expected it to be changed to URLDownloadToFile for complete compatibility with all possible URLs including "https://github.com/mozilla/..." |
Beta Was this translation helpful? Give feedback.
-
We are using XMLHTTP60 for getting the compatible driver version using the respective api's, and URLDownloadToFile for the actual install download for all three browser drivers. Do you see a problem with that? Thanks... |
Beta Was this translation helpful? Give feedback.
-
Ah you're right!
Results: 1 ok, 2 fail, then I expected 3 to fail too but it succeded! (I don't know why) |
Beta Was this translation helpful? Give feedback.
-
After many uses during last weeks on both my business and personal PCs, including a couple of other users trying it, I must say that I'm happy with the new automatic download. It always worked seamlessly. I still prefer to always set the binary into the Downloads* or Temp** folder mainly for three reasons:
I'd vote to set the Downloads folder as default (still leaving the DefaultBinaryFolder property Let procedure), or at least as default (of optional) parameter of the DefaultBinaryFolder property Let. What do you think? |
Beta Was this translation helpful? Give feedback.
-
Yes @6DiegoDiego9, I agree with you that defaulting to a central location would be an improvement. As far as implementation is concerned - is this what you are thinking of doing in the WebDriver class? Private Sub Class_Initialize()
InitCommands
Me.CommandWindowStyle = vbHide
'note that user has control through the DefaultIOFolder and DefaultBinaryFolder
'properties so these below are just reasonable starting points...
'ThisWorkbook.Path and ActiveVBAProjectFolderPath will be different for a project
'referencing the SeleniumVBA Add-in, but same otherwise
Dim oShell As New Shell
Me.DefaultBinaryFolder = oShell.Namespace("shell:Downloads").Self.Path 'ThisWorkbook.Path
Me.DefaultIOFolder = ActiveVBAProjectFolderPath
End Sub And similarly, in WebDriverManager class? Private Sub Class_Initialize()
Dim oShell As New Shell
Me.DefaultBinaryFolder = oShell.Namespace("shell:Downloads").Self.Path 'ThisWorkbook.Path
End Sub If so, I would be ok with that... Should we rename "DefaultBinaryFolder" to "DefaultDriverFolder" to clarify that we are referring to the driver and not the browser? On the options for the default, what do you think the pros/cons are for Downloads vs Temp? Thanks again for your ideas, effort and teamwork! |
Beta Was this translation helpful? Give feedback.
-
|
Beta Was this translation helpful? Give feedback.
-
I believe that making SeleniumVBA work out-of-the-box is very important to make it popular.
Automatic WebDriver download/alignment also helps in making it portable on multiple own machines.
This is why today I'm working on this:
Automatic WebDriver download/alignment optimizations:
auto-proxy (if any) is now used to download WebDriver (tested working on my business PC)
checkDriverBrowserVersionAlignment switch removed. The WebDriver download/alignment procedure is now called just when needed, inside (pre-existing) error handling, i.e. when WebDriver file doesn't exist or after it's called and an error specifically stating wrong-version occurs.
The result is like a permanent (now removed) "checkDriverBrowserVersionAlignment = True" without the overhead of always checking in advance for driver version alignment.
WebDriver path changed to user PC temporary folder (VBA.environ("Temp")) to avoid conflicting WebDriver files when multiple users, with possibly different browsers, work with WebDriver files stored on a network folder.
Not user configurable.
@GCuser99 are you OK with this change?
I read that you didn't "checkDriverBrowserVersionAlignment = True" because of insufficient testing.
I can say that I'll commit myself to make it work flawlessy because it's important to me.
Beta Was this translation helpful? Give feedback.
All reactions