Transcripted Summary
Before we proceed further, I want to actually enhance this test. We're going to create a method called `CleanUp` and we're going to add a brand new attribute that you have not seen before called `[TestCleanup]`.

        [TestCleanup]
        public void CleanUp()
        {
        
        }

This will automatically execute after every single test method. So, this test method is going to run, and then afterwards, the CleanUp method is going to execute.

The reason I want to do that is I actually want to kill my ChromeDriver every time I run it. I am a lazy automation engineer at the end of the day, and I do like to automate things. So, let's do that.

I'm going to add a class variable: IWebDriver _driver;


    [TestClass]
    public class HomePageFeature
    {
        IWebDriver _driver;
        [TestMethod]
        public void ShouldBeAbleToLogin()

        ...

So right now, you can see the compiler complaining about IWebDriver. We're going to fix that by using OpenQA.Selenium;

using System;
using System.IO;
using System.Reflection;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumCore
{
    [TestClass]
    public class HomePageFeature
    {
        IWebDriver _driver;
        [TestMethod]
        public void ShouldBeAbleToLogin()
        {
            var outPutDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
            var driver = new ChromeDriver(outPutDirectory);
            driver.Navigate().GoToURL("https://www.saucedemo.com/");
		}
		
		[TestCleanup]
        public void CleanUp()
        {
            _driver.Quit();
        }
	}
}

So now we have a variable called _driver. And we can use this variable. Add that and then do a _driver.Quit().

And so now, every single time this test executes, it's going to automatically exit for me. And we actually need to make sure that we store our driver in this variable.

So now we've successfully stored the driver in this new class variable. And whenever our test runs, it will automatically clean up.

Let's give this a run and see what happens. It's probably going to be really quick, so keep your eyes open. Boom! Did you see? It was really fast, but you could see it open up the browser, and it cleaned it up for me. So now I don't have to close the browser manually and I can just continue to automate.

The next step that we want to do is interact with the login form, so we need to navigate to a URL and start finding some elements.

So, let's go ahead and take a look at our browser and see how we can do that.

Here we have this page (https://www.saucedemo.com/), and now we actually want to assert that this page has loaded successfully. We can probably locate this element and make sure that this element is in the appropriate state. So, I'm going to come here. I'm going to look for this element, and I'm going to try to find the property that tells me that this element is unique on the page.

I like this class name here. It's called the "login-button." I'm going to copy it. I'm also going to do Command F, which will open up this Find window, and I can search for strings. This tells me that the "login-button" is unique because I only have a single match. But, for example, if I searched for an input, you can see that I have many inputs on the page, three inputs on the page, which is not unique. So, I'm going to be using a class name login-button.

So, with that let's locate our element. We're going to use our driver, and call a method called FindElement that helps us to locate an element. We're going to use the Selenium By class and use ClassName, all this provided by Selenium to locate that element.

	var loginButton = _driver.FindElement(By.ClassName("login-button"));

Now that we have the element here, we can do many kinds of different actions that I already showed you, but we first want to make sure this element is actually in the right state before interacting with it. In order to do that, we're going to use a synchronization technique known as an explicit wait to locate that this element in in the appropriate state. In order to do that, we need another NuGet package. Let's go ahead and get that NuGet package.

What you can do is look for the NuGet package WaitHelpers. We're going to add it to our solution as well. You can see that it was added successfully. And now let's use these WaitHelpers to wait for an element.

            var loginButtonLocator = By.ClassName("login-button");
            var wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(10));
            wait.Until(ExpectedConditions.ElementIsVisible(loginButtonLocator));

Okay, so what I've done here is, I've created an object that's known as the WebDriverWait type. This will wait for up to a maximum of 10 seconds for an element to be in a specific condition before it throws an exception. Now, here's the specific condition that we're using from Selenium, from the ExpectedConditions class, we're going to check that the element is visible.

Also, what I've done is, because element is visible now takes in a By locator. I've renamed that this variable to call it loginButtonLocator and instead of finding the element, what we did would just store the locator and I passed that locator in here as well. So now our test will open up the page and wait for up to 10 seconds for that element to be visible.

Now we want to interact with the form. Let's go ahead and identify all the elements with the form. So how are we going to locate the username?

So, here's the user name, which has an ID, fantastic. ID is one of the best locators to use because they are unique.

Alright, so I've located all our fields we need to interact with the page.

            var userNameField = _driver.FindElement(By.Id("user-name"));
            var passwordField = _driver.FindElement(By.Id("password"));
            var loginButton = _driver.FindElement(loginButtonLocator);

And now we just simply have to interact with them. So, let's do that.

            userNameField.SendKeys("standard_user");
            passwordField.SendKeys("secret_sauce");
            loginButton.Click();

Here what we've done is, used the userNameField and we're using the SendKeys method from Selenium to type in the username. Then we're using the passwordField to type in the password. And then we're using the loginButton that we've located previously and we're clicking. And that will allow us to login.

And there's one more step left that we want to make sure and that we are successfully logged in. Let's go ahead and implement that as well. The final step is we just need to validate that we're logged into the correct page, right? Let's go ahead and do that.

Let's see how that works once we're logged in. What happens? Well we're actually redirected to this URL — https://www.saucedemo.com/inventory.html — so I'm just going to use that. Here is where our beautiful assertion comes in. We can use the Assert class. So, with this assertion, we're just going to Assert that our URL contains inventory.html, and we're going to check that this statement is true.

            Assert.IsTrue(_driver.Url.Contains("inventory.html"));

The reason why I didn't want to put the whole URL in there, because I don't like to tie it into an environment. Because if you're using dev, test, or prod, the domain part might be different. That's changing so you don't want to tie that. But if it contains inventory.html in the URL, that is sufficient enough for me to know that we are at the correct page.

Let's give this a run and see what happens. Success. Our test is passing which is amazing.

One other recommendation I like to make, which whenever we're doing test automation, especially with UI, we don't always do is, make sure your test will actually fail. So, if I do something like this — inventorys.html — our test should fail.

Congratulations, you've just written your very first automated Selenium test using .NET Core in Visual Studio.

Give yourself a pat on the back. You certainly deserve it.



Resources



© 2024 Applitools. All rights reserved. Terms and Conditions Privacy Policy GDPR