Automated testing with Selenium Web Driver in .NET
Selenium Web Driver is a popular tool used to automate the front-end testing of web applications. It uses drivers provided by various browsers (Chrome, Firefox, etc.) to simulate user actions, and is very powerful when combined with testing frameworks such as xUnit or NUnit.
In our case, we decided to use Selenium with .NET Core 3.1 and xUnit. Let me share with you what I’ve learned so far.
Downloading the web driver of your choice
To get started, you will need to download the web driver for the browser you want to test. Note that each web driver is tied to a specific version of the browser (although this doesn’t seem to be uniformly enforced). Therefore, it is best to download the file that corresponds to your browser version.
For Chrome, the driver can be downloaded from https://sites.google.com/a/chromium.org/chromedriver/downloads. Extract
chromedriver.exe into your project. In your code, you will use
For Firefox, the driver can be downloaded from https://github.com/mozilla/geckodriver. Extract
geckodriver.exe into your project and use the
FirefoxDriver class from
OpenQA.Selenium.Firefox in your code.
For Microsoft Edge, go to https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/ and download the appropriate installer under “Microsoft Edge” (not “Microsoft Edge Legacy”, unless you want to use a very old version of Edge). Extract
msedgedriver.exe into your project. Warning: I had to rename this file to
MicrosoftWebDriver.exe for Selenium to recognize it.
When instantiating the driver class, pass in the path of the containing directory for the driver EXE file, e.g.
var driver = new ChromeDriver("C:\Drivers\Chrome");
Adding the NuGet packages
To use any of the web drivers supported by Selenium, add the NuGet package Selenium.WebDriver to your project:
dotnet add package Selenium.WebDriver
This gives you access to
OpenQA.Selenium.Chrome, etc. You will likely also need some supporting classes, such as
ExpectedConditions. You can get these from the DotNetSeleniumExtras.WaitHelpers package.
dotnet add package DotNetSeleniumExtras.WaitHelpers
Note: It appears there is a separate package, SeleniumExtras.WaitHelpers, for version 4 of the
On the speed of Firefox
Incidentally, I found that my Firefox driver took several times longer than the Chrome or Edge drivers to perform the same tests. As per comments by user jimevans on issue 6597 on GitHub, it seems this has to do with how the Gecko driver listens on loopback addresses. Explicitly setting the host to “::1” on the Gecko service resolved this for me. This changes the initialization code for Firefox slightly, e.g.
var driverService = FirefoxDriverService.CreateDefaultService("C:\Drivers\Firefox");
driverService.Host = "::1";
var driver = new FirefoxDriver(driverService);
The Firefox driver should now be about as fast as Chrome and Edge. 🚀
Dealing with insecure certificates
When using Selenium on an environment that doesn’t have secure certificates configured, you might not want your tests to fail because of pages like these:
You can tell the Selenium web driver to automatically bypass such warnings by setting the
AcceptInsecureCertificates option to
true. This property lives on the options class that corresponds to the driver you are using, e.g.
EdgeOptions. (An instance of the options class is passed as the second argument when instantiating the web driver.)
Selecting dropdown items with Selenium
Selecting items from dropdown boxes in C# is done using the
SelectElement class (confusingly known as
Select in libraries for other languages) from the
OpenQA.Selenium.Support.UI namespace. You need to install the Selenium.Support NuGet package to use this:
dotnet add package Selenium.Support
This creates an ambiguity with DotNetSeleniumExtras when it comes to the
ExpectedConditions class, which is obsolete in this package. You can resolve this by using
Your code might look something like this:
var countrySelect = new OpenQA.Selenium.Support.UI.SelectElement(driver.FindElementById("CountryId"));
Dealing with iframes
Fortunately, Selenium doesn’t seem to have any trouble working with iframes, provided you tell it which frame to switch to.
To switch to the outer frame (i.e. the parent frame), you can do this:
To switch to a specific inner frame, you can do something like this:
Once switched, the web driver will operate within the context of the selected frame. Don’t forget to switch back to the parent when you’re done!
There doesn’t seem to be any tricks to combining Selenium with xUnit. You can call the web driver directly from your test code and harness the power of the framework to organise and execute your automated tests. Here’s a useful blog post about some of the things you can do with xUnit.
If you want to run your tests without seeing a browser window pop-up, you can run the browser in headless mode. Selenium allows you to do this by calling the
AddArgument method of the appropriate options class (discussed above) to send the following command-line argument to the browser:
Note that, at the time of writing, the Selenium bindings for Edge do not support
AddArgument on the
EdgeOptions class, so it is not possible to pass parameters to the browser in this way. However, this functionality should be included in the next release, as it is already available in the
The way forward
Selenium Web Driver is a powerful tool for automated front-end testing, but there are some quirks to work through. Thankfully, there are lots of helpful resources online. I might do a follow-up article as I learn more about it, so keep a lookout!
Used for this article
- Visual Studio Code 1.46.1
- .NET Core 3.1.201
- Selenium.WebDriver 3.141.0 (NuGet)
- Selenium.Support 3.141.0 (NuGet)
- Selenium.Essentials 1.0.2 (NuGet)
- xUnit 2.4.0 (NuGet)
- Chrome 83.0.4103.116
- Firefox 77.0.1
- Firefox Web Driver (Geckodriver) 188.8.131.5222
- Edge 83.0.478.56
- Edge Web Driver 83.0.478.56