New tricks with Chromium Edge and msedgedriver.exe
Since the release of Edge 81 last month, it has its own WebDriver exectuable: “msedgedriver.exe” I have been playing with it recently and thought I would share some new tricks that you couldn’t do with the old edgehtml based Edge browser and Selenium WebDriver.
Chromium Edge is natively supported in the pre-release Selenium WebDriver version 4, but in this post I will look at what you can do using the current stable version 3.14.59. (Microsoft info here)
The WebDriver Executable
- The first thing that you need to do is to download a copy of the msedgedriver executable – either
msedgedriver.exe
(Windows) ormsedgedriver
(Mac) appropriate to the version of Edge installed on your system, and place it somewhere in your System Path. - Remember that this is a specialised version of the chromedriver executable so will only support the specified version and 1 future version of the browser. Normally this would mean that it doesn’t suddenly stop working; but as Chrome and Edge both skipped version 82 you may have had that problem last week.
- Be aware that it is not available in a nuget package on nuget.org at this time.
Creating your WebDriver
At the code level you simply need to:
- add the package
Microsoft.Edge.SeleniumTools
and replace usingOpenQA.Selenium.Edge.EdgeOptions
withMicrosoft.Edge.SeleniumTools.EdgeOptions
. - This then allows you to launch either a (Classic) EdgeHtml
EdgeDriver
or a (New) ChromiumEdgeDriver
by using:new Microsoft.Edge.SeleniumTools.EdgeDriver(edgeOptions);
- The bool property
edgeOptions.UseChromium
controls which version of the EdgeDriver to select. The default is the EdgeHtml version (false
)
As ever I will include some code to demonstrate these tricks. The code below shows the minimal code required to launch a Chromium Edge WebDriver (with a few extra lines required for later tests.)
using System; using System.Globalization; using FluentAssertions; using FluentAssertions.Execution; using Microsoft.Edge.SeleniumTools; using NUnit.Framework; using OpenQA.Selenium; using OpenQA.Selenium.Remote; namespace AoT.EdgeDriver.Tests { public class Tests { private IWebDriver driver1; private IWebDriver driver2; private EdgeOptions edgeOptions; [SetUp] public void SetUp() { edgeOptions = new Microsoft.Edge.SeleniumTools.EdgeOptions(); edgeOptions.UseChromium = true; } [Test] public void CanLaunchEdgeDriver() { driver1 = new Microsoft.Edge.SeleniumTools.EdgeDriver(edgeOptions); driver1.Url = "http://example.com"; driver1.Title.Should().Be("Example Domain"); } [TearDown] public void TearDown(){ driver1?.Quit(); driver1?.Dispose(); driver2?.Quit(); driver1?.Dispose(); } } }
New tricks
#1 Multiple instances
I’m almost ashamed to say that I really liked the old Edge as a browser, but as a Test Automation Engineer it had one inexcusable flaw. There I am, Browser open editing a form (e.g. a bug repro) and click to run some tests. The minute my tests ask for an Edge browser and my instance closes with all its unsaved changes.
Fortunately with it based off of Chromium I no longer have to worry about this. Even running Edge tests in parallel on a single machine? No problem.
[Test] public void CanLaunchMultipleEdgeDrivers() { driver1 = new Microsoft.Edge.SeleniumTools.EdgeDriver(edgeOptions); driver1.Url = "http://example.com"; driver2 = new Microsoft.Edge.SeleniumTools.EdgeDriver(edgeOptions); driver2.Url = "http://example.com"; //assert that both drivers are still active using (new AssertionScope()) { driver1.Title.Should().Be("Example Domain"); driver2.Title.Should().Be("Example Domain"); } }
#2 Headless support
When writing new tests, I generally prefer to be able to watch the WebDriver run on screen in front of me, but when you want to try a suite of tests against you code before checking in, having it continually launch browsers on screen and grab focus of you keyboard and mouse is a major pain. For this reason Firefox and Chrome have supported headless mode for some time. Now Edge supports it too.
[Test] public void CanLaunchEdgeDriverInHeadlessMode() { edgeOptions.AddArgument("headless"); driver1 = new Microsoft.Edge.SeleniumTools.EdgeDriver(edgeOptions); driver1.Url = "http://example.com"; var executor = (IJavaScriptExecutor) driver1; string userAgent = executor.ExecuteScript("return window.navigator.userAgent").ToString(); using (new AssertionScope()) { driver1.Title.Should().Be("Example Domain"); userAgent.ToLower().Should().Contain("headless"); } }
#3 WebDriver with a given preferred language.
As I discussed a couple of months ago, it is prefectly possible to launch WebDrivers to check that your internationalisation support is working correctly. Chromium support now adds this to Edge.
[Test] public void CanLaunchEdgeDriverWithAPreferredLanguageCulture() { CultureInfo cultureInfo = new CultureInfo("de"); edgeOptions.AddUserProfilePreference("intl.accept_languages", cultureInfo.ToString()); driver1 = new Microsoft.Edge.SeleniumTools.EdgeDriver(edgeOptions); driver1.Url = "https://manytools.org/http-html-text/browser-language/"; var executor = (IJavaScriptExecutor) driver1; string language = executor.ExecuteScript("return window.navigator.userlanguage || window.navigator.language").ToString(); using (new AssertionScope()) { driver1.Title.Should().Be("Browser language - display the list of languages your browser says you prefer"); language.Should().BeEquivalentTo(cultureInfo.ToString()); } }
As this is based on Chromium, this is ONLY supported in on screen browsers: Trying to launch one headless will not work and your WebDriver instance will request your System language:
[Test] public void CannotLaunchHeadlessEdgeDriverWithAPreferredLanguageCulture() { CultureInfo cultureInfo = new CultureInfo("nl"); edgeOptions.AddUserProfilePreference("intl.accept_languages", cultureInfo.ToString()); edgeOptions.AddArgument("headless"); driver1 = new Microsoft.Edge.SeleniumTools.EdgeDriver(edgeOptions); driver1.Url = "https://manytools.org/http-html-text/browser-language/"; var executor = (IJavaScriptExecutor) driver1; string language = executor.ExecuteScript("return window.navigator.userlanguage || window.navigator.language").ToString(); using (new AssertionScope()) { driver1.Title.Should().Be("Browser language - display the list of languages your browser says you prefer"); //unless your system language is nl! language.Should().NotBeEquivalentTo(cultureInfo.ToString()); } }
The missing trick: Remote running
Getting the above working when running locally were all very simple and didn’t take long. Trying to get remote webdrivers working however was an exercise in yak shaving.
I suspect I would need to dig out my Java memory and add the Microsot.Edge.SeleniumTools and compile my own selenium_standalone_server.jar to get it working. I have tried with a Selenium 4 grid too without success as demonstrated by the following code:
[Test] public void RequestingRemoteChromiumEdgeDriverThrowsWebDriverException() { edgeOptions.PlatformName = PlatformType.Windows.ToString(); Uri gridUri = new Uri("http://192.168.0.200:4444/wd/hub"); Action action = () => driver1 = new RemoteWebDriver(gridUri, edgeOptions); action.Should().Throw<OpenQA.Selenium.WebDriverException>(); }
Anything else?
Being based upon chromedriver, there are many well documented chromedriver options that are likely to work with Chromium Edge, but I haven’t tried more.
Final thoughts : TL/DR
So I should add Chromium Edge to my scheduled UI test runs?
Well I am rather conflicted here:
On the one hand, this is Chromium based. If you are running your tests against Chrome, I would not expect different results in Edge, so I think that to do so just for the sake of it would be pointless.
On the other hand, if you are required to demonstrate support for Microsoft Edge, this does lead to a future where you only can stop having to support EdgeHtml to support the latest versions of Microsoft’s latest browser. Of course if you sell to enterprise clients with slow update cycles who currently require Edge support, you may be some way away from being able to ditch EdgeHtml Support.
Only you and your business can make the call on return on investment for this.
Did I miss anything or make a mistake?
Did you get the working as a RemoteWebDriver
? Did I get anything wrong or do you know extra tricks that I should add?
Please do let me know, in the comments below or on Twitter if I have made any mistakes or missed anything helpful.
As Microsoft Edge is already available on MacOs and is headed to Linux I also had a go at writing the code for this in Visual Studio Code; Microsoft’s only free IDE available on all three platforms. More on my thought abot this next time.
Progress made:
- Played with some of the new functionality unlocked with msedgedriver on Edge versions 81 on.
- Reminded myself how to develop in C# on Visual Studio Code
- Confirmed that both the browser and the WebDriver implementation work just fine on MacOs as well as Windows.
- Edge for Linux has not been unveiled yet YET, but the same code and conclusions should apply when it is.
Lessons learnt:
- From Edge Version 81 onwards, msedgedriver unlocks the Chromium based Edge browser for automated testing with Selenium WebDriver
- If you want to use the production version 3.14 of WebDriver, Microsoft.Edge.SeleniumTools unlocks it for local testing (available for JavaScript and Python too)
- Whilst it works great and unlocks some nice new functionality, I don’t see a great deal of benefit in testing this AS WELL as Google Chrome based on the same Chromium browser engine.
- Of course it also goes to say, that this will tell you nothing about how your site / app will act on Classic (EdgeHtml based) Microsoft Edge
A reminder:
If you want to ask me a question, Twitter is undoubtedly the fastest place to get a response: My Username is @AlexanderOnTest so I am easy to find. My DMs are always open for questions, and I publicise my new blog posts there too.