Selenium C# NUnit Test Automating Angular, React, VueJS and 20 More

Selenium C# NUnit Test Automating Angular, React, VueJS and 20 More

In the new article from the Web Automation Series with C#, we will talk about creating a data-driven NUnit test automating all major web technologies such as React, Angular, Vue.js, and many more. Many people speculate that Selenium WebDriver is outdated and cannot work for modern web technologies, thus promoting other questionable tools such as CypressPlaywrightProtractor (which is going away). Again if you apply the proper design patterns and best practices, you can make almost any tool work. I am not entirely against the mentioned solutions. You can still succeed. I am just saying that many people started recently saying awful stuff about Selenium. I can say the same about these solutions. With the proper knowledge, you can easily automate everything with Selenium. This article is the proof.

The Use Case

What are we going to test? Recently, I watched a webinar organized by the Test team of JetBrains. It was OK. It was in Java. The most helpful thing I got was this fantastic website on which we will experiment. The website is called TodoMVC and is implementing the same TODO app functionality using 30+ most popular web technologies. Everything is open-source and free.

todomvc front

When you click on a particular technology, the corresponding app written on it opens.

todomvc-todo-app

We will create a single data-driven test using NUnit, where we will open 20+ technologies. Then we will add a few TODO items, mark as complete the first one and verify the numbers of the items left.

The Selenium Test

I suggest to check out NUnit Cheat Sheet. Below you can see how a single test looks like automating the jQuery TODO app. On purpose I organized the login into few private methods.


public void VerifyTodoListCreatedSuccessfully_When_jQuery()
{
    _driver.Navigate().GoToUrl("https://todomvc.com/");
    OpenTechnologyApp("jQuery");
    AddNewToDoItem("Clean the car");
    AddNewToDoItem("Clean the house");
    AddNewToDoItem("Buy Ketchup");
    GetItemCheckBox("Buy Ketchup").Click();
    AssertLeftItems(2);
}
private void AssertLeftItems(int expectedCount)
{
    var resultSpan = WaitAndFindElement(By.XPath("//footer/*/span | //footer/span"));
    if (expectedCount <= 0)
    {
        ValidateInnerTextIs(resultSpan, $"{expectedCount} item left");
    }
    else
    {
        ValidateInnerTextIs(resultSpan, $"{expectedCount} items left");
    }
}
private void ValidateInnerTextIs(IWebElement resultSpan, string expectedText)
{
    _webDriverWait.Until(ExpectedConditions.TextToBePresentInElement(resultSpan, expectedText));
}
private IWebElement GetItemCheckBox(string todoItem)
{
    return WaitAndFindElement(
        By.XPath($"//label[text()='{todoItem}']/preceding-sibling::input")
    );
}
private void AddNewToDoItem(string todoItem)
{
    var todoInput = WaitAndFindElement(
        By.XPath("//input[@placeholder='What needs to be done?']")
    );
    todoInput.SendKeys(todoItem);
    _actions.Click(todoInput).SendKeys(Keys.Enter).Perform();
}
private void OpenTechnologyApp(string name)
{
    var technologyLink = WaitAndFindElement(By.LinkText(name));
    technologyLink.Click();
}
private IWebElement WaitAndFindElement(By locator)
{
    return _webDriverWait.Until(ExpectedConditions.ElementExists(locator));
}

The method WaitAndFindElement waits for the web elements to appear on the page, and then we return them. We use the WebDriverWait + the ExpectedConditions methods that come from the DotNetSeleniumExtras.WaitHelpers NuGet package. We use another method part of the same package in the ValidateInnerTextIs method - TextToBePresentInElement

Another interesting point is that I used lots of XPath Axes locators for most elements to make the tests stable and maintainable. You can check two articles that can help you write maintainable good locators - Most Underrated WebDriver Locator – XPath and Most Exhaustive XPath Locators Cheat Sheet. I suggest you learn to write the XPath yourself than relying on plugins since they generate, most of the time, ugly, not maintainable XPath.

Another interesting point is how we add a TODO item to the list. We don’t have a submit button, but instead, we need to press Enter. To do that, we use the Actions class, which allows us to do all sorts of advanced interactions. To learn all different actions you can do in WebDriver check - Most Complete Selenium WebDriver C# Cheat Sheet

Data-driven Test for 22 Web Technologies

To test all major technologies in a single test, we can use the NUnit TestCase attribute. Next, the TestInit method marked with the SetUp attribute executes before each test. There we start the browser each time and initialize the WebDriverWait + Actions classes. Finally, the TestCleanup method marked with the TearDown attribute closes the browser.


public class TodoTests
{
    private const int WAIT_FOR_ELEMENT_TIMEOUT = 30;
    private IWebDriver _driver;
    private WebDriverWait _webDriverWait;
    private Actions _actions;
    
    public void TestInit()
    {
        _driver = new ChromeDriver();
        _driver.Manage().Window.Maximize();
        _webDriverWait = new WebDriverWait(_driver, TimeSpan.FromSeconds(WAIT_FOR_ELEMENT_TIMEOUT));
        _actions = new Actions(_driver);
    }
    
    public void TestCleanup()
    {
        _driver.Quit();
    }
    [TestCase("Backbone.js")]
    [TestCase("AngularJS")]
    [TestCase("React")]
    [TestCase("Vue.js")]
    [TestCase("CanJS")]
    [TestCase("Ember.js")]
    [TestCase("KnockoutJS")]
    [TestCase("Marionette.js")]
    [TestCase("Polymer")]
    [TestCase("Angular 2.0")]
    [TestCase("Dart")]
    [TestCase("Elm")]
    [TestCase("Closure")]
    [TestCase("Vanilla JS")]
    [TestCase("jQuery")]
    [TestCase("cujoJS")]
    [TestCase("Spine")]
    [TestCase("Dojo")]
    [TestCase("Mithril")]
    [TestCase("Kotlin + React")]
    [TestCase("Firebase + AngularJS")]
    [TestCase("Vanilla ES6")]
    public void VerifyTodoListCreatedSuccessfully(string technology)
    {
        _driver.Navigate().GoToUrl("https://todomvc.com/");
        OpenTechnologyApp(technology);
        AddNewToDoItem("Clean the car");
        AddNewToDoItem("Clean the house");
        AddNewToDoItem("Buy Ketchup");
        GetItemCheckBox("Buy Ketchup").Click();
        AssertLeftItems(2);
    }
    // private methods
}

Related Articles

Specflow, Web Automation

Advanced SpecFlow: 4 Ways for Handling Parameters Properly

As you can see the type seconds binding doesn't contain anything special about these inputs. All of the magic is happening in the StepArgumentTransformation ste

Advanced SpecFlow: 4 Ways for Handling Parameters Properly

Web Automation

Design Grid Control Automated Tests Part 1

Once upon a time, I showed you how you can automate complex custom-tuned controls like a grid. You can read about it in my article Automate Telerik Kendo Grid w

Design Grid Control Automated Tests Part 1

Web Automation

Most Complete Selenium WebDriver 4.0 Overview

In this article part of the WebDriver Series, we will look at the new exciting features and improvements coming in the new version of Selenium WebDriver 4.0. We

Most Complete Selenium WebDriver 4.0 Overview

Web Automation

10 Advanced WebDriver Tips and Tricks Part 3

As you probably know I am developing a series posts called- Pragmatic Automation with WebDriver. They consist of tons of practical information how to start writ

10 Advanced WebDriver Tips and Tricks Part 3

Web Automation

Advanced Reuse Tactics for Grid Controls Automated Tests

In my previous articles Design Grid Control Automated Tests Part 1, Design Grid Control Automated Tests Part 2, Design Grid Control Automated Tests Part 3 I sta

Advanced Reuse Tactics for Grid Controls Automated Tests

Resources, Web Automation

Most Complete Selenium WebDriver C# Cheat Sheet

As you know, I am a big fan of Selenium WebDriver. You can find tonnes of useful code in my WebDriver Series. I lead automated testing courses and train people

Most Complete Selenium WebDriver C# Cheat Sheet
Anton Angelov

About the author

Anton Angelov is Managing Director, Co-Founder, and Chief Test Automation Architect at Automate The Planet — a boutique consulting firm specializing in AI-augmented test automation strategy, implementation, and enablement. He is the creator of BELLATRIX, a cross-platform framework for web, mobile, desktop, and API testing, and the author of 8 bestselling books on test automation. A speaker at 60+ international conferences and researcher in AI-driven testing and LLM-based automation, he has been recognized as QA of the Decade and Webit Changemaker 2025.