Page object pattern
by Željko Filipin
Simplicity versus readability and maintainability.
There are two main purposes of the page object pattern.
- Move parts of the application that change a lot (user interface) to a central location. When the user interface changes, the test suite only needs to be updated in one place.
- Make tests easier to read and understand by moving complexity to page objects.
Let’s describe the two purposes with code samples from MediaWiki Core (as of June 2021).
With page object pattern
The code is split into two files.
user.js contains the test.
createaccount.page.js contains the page object. Code is available at 702327.
Please notice how readable
user.js is. You can immediately see that the point of
User should be able to create account is to create an user account with
password as arguments.
Please notice that
createaccount.page.js has two major sections. In the first section are elements on the page (
username()…). The second section contains actions (
Without page object pattern
Let’s compare that to a solution without page object pattern. Code is available at 702341.
With page object pattern, the framework is more complex, there are more files (two instead of one) and there is more overall code, but the tests are more readable and more maintainable.
Without page object pattern, the framework is simpler, there are less files (one instead of two) and there is less overall code, but the tests are less readable and less maintainable.
To keep this blog post short, I’ve selected a simple example. If the test suite creates accounts a lot, without page object pattern, code for creating account would have to be copy/pasted, leading to duplication and harder maintenance.
With the page object pattern, creating an account is just a call to
CreateAccountPage.createAccount() function. If any of the elements for creating the account changes, only
CreateAccountPage needs to be updated. If the logic of creating and account changes (for example, not requiring password re-entry) only
CreateAccountPage.createAccount() needs to be updated.