PageObjects

"Page objects are a classic example of encapsulation - they hide the details of the UI structure and widgetry from other components (the tests)." (c) Martin Fowler, PageObject.

So it's all about how you encapsulate "tech details". Here are just a few examples to compare.

No Encapsulation

public class GoogleTest {

    @BeforeClass 
    public static void setup() {
        Configuration.baseUrl = "http://google.com/ncr"
    }

    @Test
    public void userCanSearch() {
        open("/");
        $(By.name("q")).val("selenide").pressEnter();
        $$(".srg .g").shouldHave(size(10));
        $$(".srg .g").get(0).shouldHave(text("Selenide: concise UI tests in Java"));
    }
}

Mid-level encapsulation

public class GoogleTest {

    @BeforeClass 
    public static void setup() {
        Configuration.baseUrl = "http://google.com/ncr"
    }

    @Test
    public void userCanSearch() {
        GooglePage google = new GooglePage();
        google.open().searchFor("selenide");
        google.results().shouldHave(size(10));
        google.results().get(0).shouldHave(text("Selenide: concise UI tests in Java"));
    }
}

where:

public class GooglePage {
    public GooglePage open() {
        Selenide.open("/");
        return this;
    }

    public GooglePage searchFor(String text) {
        $(By.name("q")).val(text).pressEnter();
        return this;
    }

    public ElementsCollection results() {
        return $$(".srg .g");
    }
}

Higher level encapsulation

public class GoogleTest {

    GooglePage google = new GooglePage();
    SearchResults results = new SearchResults();

    @BeforeClass 
    public static void setup() {
        Configuration.baseUrl = "http://google.com/ncr"
    }

    @Test
    public void userCanSearch() {
        GooglePage google = new GooglePage();
        google.open().searchFor("selenide");
        results.shouldHaveSize(10)
               .shouldHaveResult(0, "Selenide: concise UI tests in Java");
    }
}

where:

public class GooglePage {
    public GooglePage open() {
        Selenide.open("/");
        return this;
    }

    public SearchResults searchFor(String text) {
        $(By.name("q")).val(text).pressEnter();
        return new SearchResults();
    }
}
public class SearchResults {
    private final ElementsCollection elements = $$(".srg .g");

    public SearchResults shouldHaveSize(int size) {
        elements.shouldHaveSize(size);
        return this;
    }

    public SearchResults shouldHaveResult(int index, String text) {
        elements.shouldHave(text(text));
        return this;
    }
}

More examples

More examples and variations of this pattern can be found in the following talks:

  • "KISS PageObjects" by Iakiv Kramarenko [en]:
  • "PageObjects: Better simpler and better" by Alexei Vinogradov [ru]

results matching ""

    No results matching ""