0

When building an automation framework some examples I see use a "Base Page" object that all other Page Objects derive from.

Typically these include a default constructor passing whatever driver or session needed, along with a open or goto method that defines the URL of the page (Which the Base page object is typically just the default url).

However I'm having a hard time coming up with a real need for a Base page object outside of that.

Some people suggest storing "common" locators that all pages see (Floating headers/footers/etc...) but isn't it better to store those in components?

I suppose you could also put in common UI actions/methods in here, but again those seem to usually be in utility classes.

1 Answer 1

2

However I'm having a hard time coming up with a real need for a Base page object outside of that.

Remember You Ain't Gonna Need It: Solve your problem simply; to not try to find opportunities to create code. Code is trash, it gets complicated and costly to change. The less you build to solve your problem, the better.

Some people suggest storing "common" locators that all pages see (Floating headers/footers/etc...) but isn't it better to store those in components?

This may increase the level of coupling your code have. It's the typical case where you should prefer composition over inheritance and to improve the naming of your classes.

A master BasePage with components such as headers and footers will work until you have pages without headers, footers. You may ended, by mistake, using this BasePage in these different pages - it will compile and work, but your concrete page will have more behavior that necessary/capable of doing.

Try to create components that you can inject base locators/web elements, and they will have behavior hidden in the class.

E.g. here we have two instance of a... QuestionLinkList:

enter image description here

class QuestionLinkList {

    QuestionLinkList(WebElement base) { this.base = base; }

    public void clickOnLinkAt(Int position) { 
      base.findElements(ITEM_LOCATOR).get(position).click();
      enter code here
    }
}

Then on the QuestionPage, you can say you have two instances of this component:

class QuestionPage {

    QuestionPage(WebDriver driver) { 
      this.relatedQuestions = new QuestionLinkList(driver.findElement(RELATED_QUESTIONS));
      this.hotNetworkQuestions = new QuestionLinkList(driver.findElement(HOT_NETWORK_QUESTIONS));
    }
}

With time, discovering similarities in the pages or duplications in your code, you can enhance your library of components, creating components of components, etc.

I would suggest using inheritance when you indeed discover specific types of pages or components.

For instance, you can have an abstract BasePage that holds a WebDriver and has a goto method. You can have an abstract SearchablePage, that inherits from BasePage, and has a private search bar component and provide the method searchFor(String). And then you can the QuestionPage and the HomePage, both inheriting from SearchPage - because both are pages that you can search stuff over: You inherit the method/behavior, not the component.

utility classes

Here you may be creating spaghetti code. Here is a detailed explanation of why.

2
  • This is a good point, I have a hard time of really seeing how it "saves" code tbh. And this is a good explanation.
    – Mercfh
    Aug 30 at 17:58
  • Thank you @Mercfh. If you found the answer satisfactory, could you mark it as accepted, so other will know that it tackles the question? Aug 31 at 12:32

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.