DEV Community

tnypxl
tnypxl

Posted on • Updated on

Getting started in browser automation with .NET Core, NUnit, and Basin Framework

I built a Selenium WebDriver framework for .NET Core. Its primary goal is to provide portable configuration, readable element locators, and composable page objects.

For this demo, I will use The Internet as the subject site to write tests against. The Internet is a large collection of UI behaviors, patterns, and problem cases encountered while writing browser tests.

Step 1: Setup

Let's set up a new solution with 2 projects via the command line. The first project will contain the tests and the second will contain the page objects.

# Create and navigate to new directory

$ mkdir BasinDemo
$ cd BasinDemo

# Create solution

$ dotnet new sln

# Use dotnet templates to a unit test project and a class library project

$ dotnet new nunit -n BasinDemo.Tests --framework netcoreapp3.1
$ dotnet new classlib -n BasinDemo.PageObjects --framework netcoreapp3.1

# Add both projects to the solution

$ dotnet sln BasinDemo.sln add ./BasinDemo.Tests
$ dotnet sln BasinDemo.sln add ./BasinDemo.PageObjects

# Add dependencies to both projects

$ dotnet add ./BasinDemo.Tests package Selenium.WebDriver --version 3.141.0
$ dotnet add ./BasinDemo.PageObjects package Selenium.WebDriver --version 3.141.0
$ dotnet add ./BasinDemo.Tests package BasinFramework --version 1.2.0
$ dotnet add ./BasinDemo.PageObjects package BasinFramework --version 1.2.0

# Add BasinDemo.PageObjects as a reference BasinDemo.Tests

$ dotnet add ./BasinDemo.Tests/BasinDemo.Tests.csproj reference ./BasinDemo.PageObjects/BasinDemo.PageObjects.csproj
Enter fullscreen mode Exit fullscreen mode

Step 2: Add a JSON configuration file under the Basin.Tests project

Create the file via the command line

$ touch BasinDemo.Tests/BasinDemo.json
Enter fullscreen mode Exit fullscreen mode

If on Windows...

$ New-Item -Type file -Name "BasinDemo.json" -Path "BasinDemo.Tests\"
Enter fullscreen mode Exit fullscreen mode

BasinDemo.json should contain the following json:

{
    "Environment": {
        "Site": "The Internet",
        "Browser": "Chrome"
    },

    "Sites": [
        {
            "Id": "The Internet",
            "Url": "http://the-internet.herokuapp.com"
        }
    ],

    "Browsers": [
        {
            "Id": "Chrome",
            "Kind": "chrome",
            "Timeout": 10
        }
    ]
}
Enter fullscreen mode Exit fullscreen mode

Step 3: Set up and tear down (aka, "test hooks")

Later, I will create 2 simple tests that validate the behaviors from the Dynamic Controls example. For now, let's make sure any test I write can properly open a browser, navigate to the configured site, and close the browser when the test is finished.

There should be a file named UnitTest1.cs. Let's rename it to TestBase.cs. This will contain all of our test hooks.

Replace the code inside with:

using System.IO;
using NUnit.Framework;
using Basin;
using Basin.Selenium;

namespace BasinDemo.Tests
{
    public class TestBase
    {
        [SetUp]
        public void SetUp()
        {
            // Bootstrap our json configuration to the Basin environment
            BasinEnv.SetConfig(Path.GetFullPath("../../../") + "BasinDemo.json");

            // Instantiates a browser session using the details defined in BasinDemo.json
            BrowserSession.Init();

            // Navigates to the site definied in BasinDemo.json
            BrowserSession.Goto(BasinEnv.Site.Url);
        }

        [TearDown]
        public void TearDown()
        {
            // Closes the browser and kills the WebDriver instance
            BrowserSession.Current?.Quit();
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Conclusion

With our test framework setup and configured. We are ready to begin building page objects and write tests. STAY TUNED FOR PART 2.

If you want to know more, check out Basin Framework. Please be aware that this framework has only been in development for a couple months. APIs are likely to change, but I will do my best to keep this post updated with those changes.

Discussion (0)