Search code examples
c#selenium-webdriverautomationstatic-methodspageobjects

Selenium Automation with static Page Object Model


I’ve been looking at a lot of example Selenium frameworks with Page Object Models, they typically show:

[Test]
public void Test_Login_To_Home_Page()
{
  var login = new LoginPage(this.driver);
  login.LoginAs(“user”, “password1”); 

  var home = new HomePage(this.driver);
  home.GoTo();
  Assert.IsTrue(home.IsAt(), "failed to login successfully");
}

If the content (methods, web elements) were static in the page object classes and they were exposed to the Instance of the driver class it would look like:

[Test]
public void Test_Login_To_Home_Page()
{
  LoginPage.LoginAs(“user”, “password1”); 
  HomePage.GoTo();
  Assert.IsTrue(HomePage.IsAt(), "failed to login successfully");
}

I cannot see what is gained by creating an instance of the page object classes. The latter method looks much cleaner, it removes a lot of noise from the tests, and is easier to train inexperienced automation testers lacking programming skills.

Is there any inherent draw backs in using the latter method? I cant think of any but nowhere seems to promote this approach, they all seem to use the former method. Are there any disadvantages?

An example of how the driver is called to find an element in a page object:

using static SeleniumWebDriver;

public class housesPage
{

private static IWebElement houses_SelectMenu => Instance.FindElement(By.Id("housesSelect"));

and in the SeleniumWebDriver class:

public static class SeleniumWebDriver
{

public static IWebDriver Instance { get; set; }

public static IWebDriver CreateWebDriver()
{
 Instance = CreateChromeDriver();
 return Instance;

Solution

  • I see one big disadvantage - you cannot run your tests parallel. If you have a static driver that means, you can execute only one test at the time. One of the rules of tests is that test should not be dependent on any other test. It would be violated.

    So what are the choices? I prefer to chain the methods, to make it more fluent. Let's assume that the LoginPage looks like this:

    public class LoginPage
    {
        private IWebDriver _driver;
        public LoginPage(IWebDriver driver)
        {
            _driver = driver;
        }
        public HomePage LoginAs(string user, string password)
        {
            // Providing user and password and clicking login button
            return new HomePage(_driver);
        }
    }
    

    HomePage:

    public class HomePage
    {
        private IWebDriver _driver;
        public HomePage(IWebDriver driver)
        {
            _driver = driver;
        }
        public HomePage GoTo()
        {
            // Do something
            return this;
        }
        public bool IsAt()
        {
            return true;
        }
    }
    

    I also advise to use FluentAssertion. With all of that, the test would look like:

    [Test]
    public void Test_Login_To_Home_Page()
    {
        new LoginPage(this.driver)
            .LoginAs("user", "password")
            .GoTo()
            .IsAt()
            .Should()
            .BeTrue();
    }