Page Abstractions enhance the way your tests are written. They make your tests more robust and therefore more reliable.
To see their power let's start with little bit of motivation. Do you often see Graphene (or Selenium Webdriver) tests like this:
In the previous example you can notice that tests are tightly coupled with the HTML structure of the tested page. So once the structure of the page will change (it can be even slight change in class attribute of some element) tests are affected as well. These small changes can effectively break lot of tests, in other words increases the time spent on the tests maintenance.
Basically it is an encapsulation of the tested page structure into one class, which will contain all the page fragments (parts, components, widgets) together with all handy methods which you will find useful while testing the encapsulated page.
Very simple Page Object which results from the previous test example is below:
The test can be now decoupled from the underlying HTML structure of the tested page. Once the structure change, the only modification will be needed in Page Object. The test would look like below snippet:
To read more about how Graphene helps with utilization of this concept, please follow the child page Page Objects.
Page Objects pattern are well known concept, which greatly improves tests robustness. However, is there more space for improvement ? Consider previous example, where we were testing three autocomplete widgets. Each of the test had to deal with the interaction between driver and that component on its own. Unfortunately not only tests in that one test class, but all the tests which interact with the same autocomplete widget implemented with the same UI framework. It is a huge DRY violation.
What are Page Fragments in short ?
- Page Fragments stands for any part of the tested page, any widget, web component, etc.
- A concept of encapsulation of these parts into completely reusable pieces across all your tests.
- Powerful mechanism for creating own page fragments, like Autocomplete (Calendar, Login, etc.) page fragment.
- A concept which differentiate each fragment by its root element and make other parts referenced from it.
- A solution which leverages Selenium WebDriver under the hood together with all Graphene killer features.
- Set of utilities which simplify using of this feature in tests, together with better support for Page Objects pattern.
So we already know that autocomplete widget from the previous example can be encapsulated into one object. As it is part of the page, its fragment, let's call that object Page Fragment. Better than words, let's see an example of such encapsulation below.
It is nothing special. The only difference between Page Objects and Page Fragments is the element annotated with the @Root annotation. All other WebElement fields annotated with @FindBy are referenced from that root element. It makes such implementation pretty generic and reusable across all tests which need to interact with the encapsulated Page Fragment.
|The @Root annotation is optional, you typically use it when you need to directly invoke methods on it in your fragment's code. Therefore, you do not need to declare such element. Graphene will take care of it. You denote whether it is Page Fragment or Page Object in the way you use it (a particular Page Object is annotated with @Page, a Page Fragment with @FindBy annotation).|
To introduce Page Fragments into previous test example, one need to do for example following:
- Move autocomplete specific methods from TestingPage to the AutocompleteFragment<T> implementation, so they can be reused in other tests for different applications or pages too.
- Declare Page Fragments into Page Object (TestingPage, preferred option) or directly into the tests (this again couples tests with the structure of the testing page, less preffered).
- Rewrite Page Object methods so they will interact with the Page Fragments instead of plain WebElements.
Following snippet shows that:
For more information about how Page Fragments are declared, initialized and more, please continue with Page Fragments.