Skip to content
Pablo Company edited this page Jan 19, 2022 · 14 revisions

Selenium.AutomatedTests is a package to easily write maintainable end-to-end tests by writing scenarios in a fluent fashion

Setup

Install the web driver: https://www.selenium.dev/documentation/webdriver/getting_started/install_drivers/

Selenium.AutomatedTests has dependencies on Selenium.WebDriver 4.1.0, Selenium.Support 4.1.0 and DotNetSeleniumExtras.WaitHelpers 3.11.0. By installing this package it will be everything you need to run automation scenarios.

Getting started

You will need to create a test using the testing framework of your preference.

Note that the following examples are using xUnit, but it is similar to any other testing framework.

public class ExampleScenarios : AutomatedTestBase
{
    [Fact]
    public void SearchForATextInGoogle()
    {
        var builder = new AutomationScenarioBuilder(new ChromeDriver()); // you need to provide a web driver

        builder
            .NavigateTo("https://google.com")
            .WithSteps<GoogleSearchSteps>(step =>
            {
                step.WaitUntilSearchBarIsLoaded();
                step.ClickOnAcceptTermsAndConditions();
                step.Search("This is fine gif");
            });

        AutomationScenarioRunner.Run(builder);
    }
}

The builder will let you enqueue steps to define the automation scenario. Then you can build and run the automation scenario and a test report with all the execution information will be returned as an execution result.

It's recommended to use AutomationScenarioRunner to run and handle the execution of your scenario. However you can ejecute builder.BuildAndRun() to handle test execution report manually, logging the summary, etc.

[Fact]
public void SearchForATextInGoogle()
{
    var builder = new AutomationScenarioBuilder(ProvideWebDriver());

    builder
        .NavigateTo("https://google.com")
        .WaitUntilVisible(By.Id("webElementId"))
        .WithStep(
            description: $"Some step description",
            selectionPredicate: webDriver => webDriver.FindElement(By.Id("elementId")),
            action: webElement => { webElement.SendKeys("Some input"); }
        )
        .WithStep(
            description: $"Some other step description",
            selectionPredicate: webDriver => webDriver.FindElements(By.ClassName("elementClassName")),
            action: webElements => 
            { 
                Assert.NotEmpty(webElements);
                // ...
            }
        );
    });

    var testReport = builder.BuildAndRun();

    Assert.False(testReport.HasFailure);
}

Sample test output:

Selenium.AutomatedTests.Core.AutomationScenarioRunFailedException : 

Step 1: Navigating to https://google.com/... : 

Step 2: Waiting until element with #webElementId is visible... : 
	 Exception on step : Waiting until element with #webElementId is visible... 

 OpenQA.Selenium.WebDriverTimeoutException: Timed out after 15 seconds
 ---> OpenQA.Selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"css selector","selector":"#webElementId"}
  (Session info: chrome=97.0.4692.71)
   at OpenQA.Selenium.WebDriver.UnpackAndThrowOnError(Response errorResponse)
   at OpenQA.Selenium.WebDriver.Execute(String driverCommandToExecute, Dictionary`2 parameters)
   at OpenQA.Selenium.WebDriver.FindElement(String mechanism, String value)
   at OpenQA.Selenium.By.<.ctor>b__11_0(ISearchContext context)
   at OpenQA.Selenium.By.FindElement(ISearchContext context)
   at OpenQA.Selenium.WebDriver.FindElement(By by)
   at SeleniumExtras.WaitHelpers.ExpectedConditions.<>c__DisplayClass7_0.<ElementIsVisible>b__0(IWebDriver driver)
   at OpenQA.Selenium.Support.UI.DefaultWait`1.Until[TResult](Func`2 condition, CancellationToken token)
   --- End of inner exception stack trace ---
   at OpenQA.Selenium.Support.UI.DefaultWait`1.ThrowTimeoutException(String exceptionMessage, Exception lastException)
   at OpenQA.Selenium.Support.UI.DefaultWait`1.Until[TResult](Func`2 condition, CancellationToken token)
   at OpenQA.Selenium.Support.UI.DefaultWait`1.Until[TResult](Func`2 condition)
   at Selenium.AutomatedTests.AutomationScenarioBuilder.<>c__DisplayClass6_0.<WaitUntilVisible>b__0(IWebDriver webDriver)

Bundling your steps by component/view

Following SRP, Selenium.AutomatedTests package provides a way to group your steps by component or view. It's very common to have a collection of steps that interacts with a concrete component of your application.

So to segregate responsabilities and build more maintainable and reusable steps you can create a class to expose component capabilities and use it in tests like that:

public class GoogleSearchSteps : SetupSteps
{
    private static readonly By SearchBarElementLocator = By.ClassName("gLFyf");
    private static readonly By AcceptTermsAndConditionsElementLocator = By.ClassName("sy4vM");

    public GoogleSearchSteps(AutomationScenarioBuilder scenarioBuilder) : base(scenarioBuilder)
    {
    }

    public void WaitUntilSearchBarIsLoaded()
    {
        _scenarioBuilder.WaitUntilVisible(SearchBarElementLocator);
    }

    public void ClickOnAcceptTermsAndConditions()
    {
        _scenarioBuilder
            .WithStep(
                description: $"Clicking on accept terms and conditions...",
                selectionPredicate: webDriver => webDriver.FindElement(AcceptTermsAndConditionsElementLocator),
                action: webElement => { webElement.Click(); });
    }

    public void Search(string text)
    {
        _scenarioBuilder
            .WaitUntilVisible(SearchBarElementLocator)
            .WithStep(
                description: $"Filling search var with text: {text}",
                selectionPredicate: webDriver => webDriver.FindElement(SearchBarElementLocator),
                action: webElement => { webElement.SendKeys(text); })
            .WithStep(
                description: $"Executing search...",
                selectionPredicate: webDriver => webDriver.FindElement(By.ClassName("gLFyfasdasd")),
                action: webElement => { });
    }
}

And using these steps:

[Fact]
public void SearchForATextInGoogle()
{
    RunAutomatedTest(builder =>
    {
        builder
            .NavigateTo("https://google.com")
            .WithSteps<GoogleSearchSteps>(step =>
            {
                step.WaitUntilSearchBarIsLoaded();
                step.ClickOnAcceptTermsAndConditions();
                step.Search("This is fine gif");
            });
    });
}