Question: What is the best Page Object framework for Java?

TLDR; Q: what is the best Page Object framework? A: I don’t know. I don’t use any

Question: What is the best Page Object framework for Java? And are there any tools to build Page Objects e.g. scan the page and create a class with all the @FindBy annotations on WebElements etc.

Answer:

I don’t know. I have not researched any Page Object frameworks. I don’t use any, and don’t recommend any.

I know there are plenty of libraries for other languages

Ruby:

Python:

And there are bound to be more. I don’t know.

I prefer to:

  • write the classes I need by hand,
  • as I need them,
  • adding methods and WebElements as I use them
  • refactoring the classes as they, and my understanding, and our use of them, evolve

I don’t even recommend using the Page Factory built in to Selenium WebDriver e.g. @FindBy’s etc. because every time I’ve used it, I have eventually moved away from those annotations and the PageFactory.initElements to allow more flexible synchronisation and more flexibility in general.

But note the “every time I’ve used it”. Because…

There was a time when I did want a framework to make it easy.

And there was a time where I not only wanted a tool to scan the page and build a class, but I actually thought about building a tool which would scan the page and build the class, and I think I created some prototype code, but I can’t find it now.

But that was when I viewed writing the Page Objects as drudge work. Work that added no value to the automating.

In fact. Every class we add has a reason. The classes represent a model of my understanding of the application and how we would go about automating it.

I think being aware of that allows me to build cleaner and simpler code.

Automatically building Page Objects would have led to ‘large’ Page Objects which would be unmaintainable [“Ah, but I wouldn’t have to maintain them because they would be automatically created” 🙂 ]

They would also be hard to use. Imagine code completion on an automatically created Page Object, there would be no grouping of elements into headers and footers, or identified widgets, there would just be a big list of stuff – and would the automatically generated names read well enough to explain what they were for?

I can understand why such a tool or framework would look attractive, but longer term I think it would hamper, rather than improve, productivity.

It might even prevent you from experimenting.

In the Page Objects and Beyond tutorial and talk, I show code which has many different approaches to abstraction for Page Objects:

  • Element abstractions
  • Physical abstractions (which are analogous to automatically generated abstractions but with full human control)
  • Logical Abstractions
  • Slow Loadable Abstractions
  • Navigation Abstractions

And there are more. You would miss out on Actor/Task type approaches like screenplay pattern.

I have a general aversion to frameworks.

I don’t mind libraries, but anything that controls the way I write the code, I try to minimize my exposure to.

Because I’ve learned to value flexibility.

I know the code is going to evolve, because I know my understanding will evolve. And my understanding is encoded into the abstractions I write.

I know the application is going to evolve. And I want my code to adapt gracefully as the application changes.

I know I’m going to refactoring my code, to improve the structure and implementation.

I don’t want anything that might get in the way of my doing that.

It could be that there is a perfect framework out there for me, and because I’m not looking for it, I’ll never find it.

But I haven’t needed it.

PS. Having said all that, if you find one that works well then let me know.

This entry was posted in Selenium Simplified Blog, WebDriver. Bookmark the permalink.

3 Responses to Question: What is the best Page Object framework for Java?

  1. Rick Devaney says:

    I use the Page Object Generator Chrome extension . You simply enter a target (C#, Java or Robot Framework) then enter a file name to save to and then press Generate. The generated page objects provide all css selectors and methods to access them. It really saves time finding all the selectors on the page. The methods names are not always descriptive but the generated code can be refactored. Here is some sample output for this web page:
    public class SeleniumSimplified {
    private Map data;
    private WebDriver driver;
    private int timeout = 15;

    @FindBy(css = “a[href=’http://seleniumsimplified.com/about-2nd-edition/’]”)
    @CacheLookup
    private WebElement aboutTheBook;

    @FindBy(css = “a[href=’http://seleniumsimplified.com/archive/’]”)
    @CacheLookup
    private WebElement allPosts;

    @FindBy(css = “#text-3 div.textwidget a:nth-of-type(2)”)
    @CacheLookup
    private WebElement onlineSelenium2WebdriverApiTraining;

    @FindBy(css = “#text-3 div.textwidget a:nth-of-type(1)”)
    @CacheLookup
    private WebElement onlineSelenium2WebdriverJava;

    // more FindBy’s here

    public SeleniumSimplified(WebDriver driver, Map data, int timeout) {
    this(driver, data);
    this.timeout = timeout;
    }

    /**
    * Click on Webdriver Windows 10 Anniversary Build And Edge 14393 Link.
    *
    * @return the SeleniumSimplified class instance.
    */
    public SeleniumSimplified clickWebdriverWindows10AnniversaryBuildAnd2Link() {
    webdriverWindows10AnniversaryBuildAnd2.click();
    return this;
    }
    /**
    * Fill every fields in the page.
    *
    * @return the SeleniumSimplified class instance.
    */
    public SeleniumSimplified fill() {
    setCommentTextareaField();
    setNameTextField();
    setEmail1TextField();
    setWebsiteTextField();
    setIfYouAreAHumanAndTextField();
    setEmail2TextField();
    setCategoriesDropDownListField();
    setPostsDropDownListField();
    return this;
    }

    /**
    * Verify that the page loaded completely.
    *
    * @return the SeleniumSimplified class instance.
    */
    public SeleniumSimplified verifyPageLoaded() {
    (new WebDriverWait(driver, timeout)).until(new ExpectedCondition() {
    public Boolean apply(WebDriver d) {
    return d.getPageSource().contains(pageLoadedText);
    }
    });
    return this;
    }

    /**
    * Verify that current page URL matches the expected URL.
    *
    * @return the SeleniumSimplified class instance.
    */
    public SeleniumSimplified verifyPageUrl() {
    (new WebDriverWait(driver, timeout)).until(new ExpectedCondition() {
    public Boolean apply(WebDriver d) {
    return d.getCurrentUrl().contains(pageUrl);
    }
    });
    return this;
    }
    // more methods here

  2. Duvivier Nicolas says:

    Great article !

    I once thought about developing myself a framework to scan pages, but I realized after I started writing my first classes, that I organize my Page Objects the way I understand the content of the app (to reuse your words). Actually, the name Page Objects doesn’t always suits the way you organize your project. To put simpler words on my thoughts, I would prefer to call them “Components Objects”. Of course, a component can be a page. And of course, on some applications, it WILL be pages… for one tester/team, maybe not for an other one.

    I liked to use the word “Page” at the end of each Page class… I’m not always doing it anymore. Sometimes, I can name a class like ThisThingModal or DatePickerWidget, and so on…

    We should not forget that we are learning everyday. Something that you thought would be the best solution a month ago… you will maybe refactor it and write it differently. Of course frameworks exist to make your life easier… but if you can do it yourself… and you can do it : Better ? More understandable ? Easier to use ? …. and it doesn’t take to much time, do it. (don’t forget you are working, not experimenting everything that is possible).

    Thanks again. I still consider myself as a noobie (a bit less than 3 years of experience)… so seeing that people like you have the same way of thinking than I am is pretty comforting 😀

    Looking forward to hear you at automation guild conference !

    • Alan says:

      Thanks for describing your experiences in the comment, and glad to see you are evaluating the naming you use and the approaches. I’m looking forward to the Automation Guild.

Leave a Reply

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