Search code examples
c#seleniumpageobjectspage-factory

Can extension methods use non-static fields?


I'm not sure if this preamble is necessary (in its entirety or at all) but I think it conveys my use-case for needing to use a non-static field inside a static extension method.

I have a test suite implemented with Selenium/C#/NUnit.

I used to use PageFactory to define my page elements. PageFactory has been deprecated so it seemed logical to switch to defining my elements as IWebElements:

HomePage.cs...

IWebElement UsernameTextBox = driver.FindElement(By.Id("username"));
IWebElement PasswordTextBox = driver.FindElement(By.Id("password"));
IWebElement LoginButton = driver.FindElement(By.Id("login"));

The trouble with this approach is that prior to any tests being run, this file is read, line by line, and the DOM is being queried for all of these elements before my tests try to use them. They are throwing ElementNotFound exceptions because of course - at the time the elements are being queried, no test has been run yet, which means we're not even on the homepage to interact with them.

To resolve this, I changed the type of the elements to By:

HomePage.cs...

By UsernameTextBox = By.Id("username");
By PasswordTextBox = By.Id("password");
By LoginButton = By.Id("login");

This allows me to define the elements, then query the DOM at the right time. Great, problem solved. Except, now I have another problem. I liked being able to chain methods off of the IWebElements, for readability purposes:

LoginButton.Click();

But the 'By' type doesn't contain the methods that IWebElement does. So the next logical step is: create an extension method.

public static class ByExtensionMethods {
    public static void Click(this By elementLocator) {
        driver.FindElement(elementLocator);
    }
}

Great, problem solved. Except, now I have another problem. My test suite cannot use a static IWebDriver because I want to execute my tests in parallel. Sadly, the extension method approach requires that the driver is static.

So unless I can somehow use my non-static IWebDriver inside the extension method, it looks like I cannot achieve my goal of chaining methods off of the 'By' elements...


Solution

  • Can extension methods use non-static fields?

    No.

    So unless I can somehow use my non-static IWebDriver inside the extension method, it looks like I cannot achieve my goal of chaining methods off of the 'By' elements...

    Just pass your driver object to the extension method and use it.

    Example:

    public static class ByExtensionMethods {
        public static void Click(this By elementLocator, IWebDriver driver) {
            driver.FindElement(elementLocator);
        }
    }