Abstraction in Page Object Model

First, let Pine Tree State justify the expression”Abstraction”, what will it mean? once can we use it?

Abstraction may be a technique utilized in package style that aims to change logical entities code illustration and permits the software developer to “hide” advanced implementations. The goal is to make an abstract (simple) layers which can solely expose the foremost relevant properties and capabilities for the precise entity.

The Abstraction technique comes handy additionally once writing a check automation project; we are able to use it to cover complexness and establish desired actions on prime of the page we have a tendency to are acting on. in an exceedingly matter of truth, we are able to outline the project as a multi layer structure, this structure can facilitate to implement the logic of useful testing with minimum effort and exposure to the complexness of the infrastructure.

Page Object Model Multi-Layer Structure:

1. First layer– consists of the driver layer which could be either Appium or Selenium and the implementation of methods and logic we don’t change often (such as cross browser support, reporting module, data driven implementation).

2. Second layer-  can be a library code that is built on top of the driver layer (Appium or Selenium), good examples for such are: Robot framework and Selenide. These layers are used to hide any complex actions as waits, page elements validations and more.

3. Third layer- the third layer could be used by the test automation developer for any complexes action that can come on top of the first or second layer. For example, after utilizing the wait function and validation in the second layer, we’ll be able to add several other actions such as calls to externals libraries or any other specific logic.

4. Fourth layer- we’ll be able to easily call actions we established in the third layer creating functional test cases and will eventually become our testing layer.

First, we’ll create a class named Page and connect a builder to it which will receive the driver and the time frame which will be the upper limit for all ‘waits’ in our test implementation.

public class Page
{
    private IWebDriver driver;
    private TimeSpan defaultTimeSpan;

    public Page(IWebDriver driver, TimeSpan defaultTimeSpan)
    {
        this.driver = driver;
        this.defaultTimeSpan = defaultTimeSpan;
    }
}

Now, we will implement the locators which are the methods for identification, and the same object that Selenium uses to identify elements. Overall, we’ll have 8 different types of locators (read more about determining element locators).

By.Id
By.Name
By.ClassName
By.TagName
By.LinkText
By.PartialLinkText
By.CssSelector
By.XPath

‘By’ is the object also called the locator and the implementation will look as follows:

private By ByLocator(string element, Locator locator)
{
    switch (locator)
    {
        case Locator.Id:
            return By.Id(element);
        case Locator.Name:
            return By.Name(element);
        case Locator.TagName:
            return By.TagName(element);
        case Locator.ClassName:
            return By.ClassName(element);
        case Locator.LinkText:
            return By.LinkText(element);
        case Locator.PartialLinkText:
            return By.TagName(element);
        case Locator.XPath:
            return By.XPath(element);
        case Locator.CssSelector:
            return By.CssSelector(element);
        default:
            throw new Exception("No Locator Found");
    }

Next we’ll implement the ‘Find’ method which will be the base for several locations later on (using the ByLocator method we created earlier):

public IWebElement Find(string element, Locator locator)
{
    return driver.FindElement(ByLocator(element, locator));
}

We will continue implementing the rest of the methods (while utilizing the Find method)

public Page Fill(string element, string value, Locator locator)
{
    Find(element, locator).Clear();
    Find(element, locator).SendKeys(value);
    return this;
}
public Page WaitUntil(Func<IWebDriver, TResult> condiction)
{
    new WebDriverWait(driver, this.defaultTimeSpan).Until(condiction);
    return this;
}
public Page NavigateTo(string url, string proofElement, Locator locator)
{
    driver.Navigate().GoToUrl(url);
    new WebDriverWait(driver, this.defaultTimeSpan)
            .Until(d => d.FindElement(ByLocator(proofElement, locator)));

    return this;
}

In the top layer, we will initialize the methods same as ‘Fill’, while sending the required arguments (these arguments come from the same tester as a part of the automated test). Nonetheless, the test automation engineer which creates the test case scenario, is unfamiliar with the complexity of the Fill method which itself uses other methods.

Please note: the example presented above, does not represent a classic case of an Abstract Class in which we are declaring methods and making sure to implement in inherited classes, but another method to use abstraction over pages.

Add a Comment

Your email address will not be published. Required fields are marked *