How to UI test using Selenium and .NET Core on Windows, Ubuntu, and maybe MacOS? 🤷‍♀️🤷‍♂️
Tags: dotnet, csharp, selenium, ubuntu
Published: 2020-09-09 17:57:30

---
title: How to UI test using Selenium and .NET Core on Windows, Ubuntu, and maybe MacOS? 🤷‍♀️🤷‍♂️
published: true
tags: dotnet, csharp, selenium, ubuntu
canonical_url: https://swimburger.net/blog/dotnet/how-to-ui-test-using-selenium-and-net-core-on-windows-ubuntu-and-maybe-macos
cover_image: https://swimburger.net/media/1164/dotnet-core-selenium-social.png?anchor=center&mode=crop&width=1000&height=420&rnd=132085016540000000
---

Selenium is a browser automation tool mainly used for UI testing and automating tasks. Selenium is agnostic of operating system, programming language, and browser.  
You can automate Chrome on MacOS using C#, Firefox using Python on Windows, or Opera using NodeJS on Linux to give you a few examples. Refer to this page on the [Selenium website for a full list of supported OS's, programming languages, and browsers](https://www.seleniumhq.org/about/platforms.jsp).

In this post you'll learn how to create a minimal Selenium test using .NET Core on both Windows and Ubuntu (Linux).   
_FYI, this post should also apply for MacOS, though I have not verified this._ To follow along you'll need the following:

- [.NET Core SDK](https://dotnet.microsoft.com/download/dotnet-core) (2.2)
- Windows, Linux, or MacOS dev machine
- [Chrome WebDriver](https://chromedriver.chromium.org/downloads) (pick the driver matching your target OS)

## 1. Creating the .NET Core test project

Run the following commands using bash, powershell, or any other shell which will create a .NET solution and MSTest project.

```sh
mkdir Selenium_DotNet
cd Selenium_DotNet
dotnet new solution
mkdir Demo.SeleniumTests
cd Demo.SeleniumTests
dotnet new mstest
cd ..
dotnet sln add Demo.SeleniumTests
```

Using the following command, the skeleton of your test project is ready. Navigate to your test project and run the following command to test out the dummy test:

```sh
dotnet test
```

## 2. Add Selenium to the test project

To start integrating Selenium into your test project, you'll need to add the Selenium.WebDriver NuGet package.  
Use the following dotnet cli command to add the dependency.

```sh
dotnet add package Selenium.WebDriver --version 3.141.0
```

Once the package has been added, you'll be able to use the Selenium API in your C# project but you'll need to make the ChromeDriver available before it'll start working. More on that later.

## 3. Write a UI test using Selenium

Using your editor of choice, write a UI test. Keep it simple for now, you can write a more advanced test after getting a simple test working.  
Here's a more advanced sample, but feel free to strip it to the minimum:

```csharp
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Linq;

namespace Demo.SeleniumTests
{
    [TestClass]
    public class DotNetSiteTests
    {
        [TestMethod]
        public void TestGetStarted()
        {
            // Chrome Driver was manually downloaded from https://sites.google.com/a/chromium.org/chromedriver/downloads
            // parameter "." will instruct to look for the chromedriver.exe in the current folder
            using (var driver = new ChromeDriver("."))
            {
                //Navigate to DotNet website
                driver.Navigate().GoToUrl("https://dotnet.microsoft.com/");
                //Click the Get Started button
                driver.FindElement(By.LinkText("Get Started")).Click();

                // Get Started section is a multi-step wizard
                // The following sections will find the visible next step button until there's no next step button left
                IWebElement nextLink = null;
                do
                {
                    nextLink?.Click();
                    nextLink = driver.FindElements(By.CssSelector(".step:not([style='display:none;']):not([style='display: none;']) .step-select")).FirstOrDefault();
                } while (nextLink != null);

                // on the last step, grab the title of the step wich should be equal to "Next steps"
                var lastStepTitle = driver.FindElement(By.CssSelector(".step:not([style='display:none;']):not([style='display: none;']) h2")).Text;

                // verify the title is the expected value "Next steps"
                Assert.AreEqual(lastStepTitle, "Next steps");
            }
        }
    }
}
```

_Note: The test is likely to break when the dotnet site changes._

Pay attention to the constructor of 'ChromeDriver' on line 16. **By default the ChromeDriver class when instantiated without parameters will search for​ the chromedriver executable (from [chromedriver.chromium.org](https://chromedriver.chromium.org/downloads)) inside your Path environment variable**.  
Alternatively, you can pass in the path of the ChromeDriver executable to the constructor. **By passing in ".", Selenium will search for the executable in the current working directory.**

## 4. Run the UI test

To run the test follow these steps:

1. Run the **dotnet build** command inside your test project
2. Copy the chromedriver.exe/chromedriver executable to "Selenium\_DotNet\Demo.SeleniumTests\bin\Debug\netcoreapp2.2​"
3. Run the **dotnet test** command and watch the magic 🧙‍♂️

For Ubuntu you can use these commands to download the ChromeDriver (modify driver URL as needed):
```bash
cd bin/Debug/netcoreapp2.2/
wget https://chromedriver.storage.googleapis.com/75.0.3770.140/chromedriver_linux64.zip
unzip chromedriver_linux64.zip # sudo apt install unzip
chmod 774 chromedriver
```

For Windows you can use this PowerShell script (modify driver URL as needed):
```powershell
cd bin/Debug/netcoreapp2.2/;
Invoke-WebRequest -Uri "https://chromedriver.storage.googleapis.com/75.0.3770.90/chromedriver_win32.zip" -OutFile ./chromedriver_win32.zip;
Expand-Archive ./chromedriver_win32.zip -DestinationPath ./chromedriver_win32;
Copy-Item ./chromedriver_win32/chromedriver.exe -Destination .;
```
**Troubleshooting**: if the test fails due to Chrome/Chromium errors, follow these steps
- Make sure you have Chrome/Chromium installed. 
- Make sure the ChromeDriver supports your version of Chrome/Chromium
- Make sure you have the permissions to execute the ChromeDriver executable
- If your OS is shell based without any GUI, you have to use Chrome in headless mode.
[This snippet shows how to start the ChromeDriver+Chrome in headless mode](https://gist.github.com/Swimburger/ffa02a2f3080e30204336632244f95aa).

## Summary

Using .NET Core you can write cross-platform UI tests using C# and Selenium. You can swap out the ChromeDriver with any other supported browser to verify cross-browser compatibility. You can use this [GitHub repository as a reference](https://github.com/Swimburger/AzureDevOps_Selenium_DotNet) in case you run into any roadblocks.  
In a follow-up post, I'll share how to run these UI tests inside of Azure DevOps deployment pipelines.  
  
Cheers 🥂

**Notes:**

1. The reason I **don't suggest using Nuget packages to pull in the ChromeDriver executable** is because executable is **only offered by 3rd party unverified package owners** which introduces a risky dependency into your codebase.
2. I suggest not including the ChromeDriver executable in your .csproj file or Source Control since there's no guarantee ahead of time that your Chrome browser will be compatible with your ChromeDriver. For example, when you pass this test to a test server, the Chrome browser may be on a version incompatible with your ChromeDriver. Some solutions to this would be to:
  - include the ChromeDriver in the path environment variable of the test server;
  - download the correct ChromeDriver as part of your CI/CD system and copy it next to your test dll's;
  - pass in the location of the ChromeDriver through [TestRunParameters](https://docs.microsoft.com/en-us/visualstudio/test/configure-unit-tests-by-using-a-dot-runsettings-file?view=vs-2019#example-runsettings-file);