Page Object Pattern
Version 5 of WebdriverIO was designed with Page Object Pattern support in mind. By introducing the "elements as first class citizens" principle, it is now possible to build up large test suites using this pattern.
There are no additional packages required to create page objects. It turns out that clean, modern classes provide all necessary features we need:
- inheritance between page objects
- lazy loading of elements
- encapsulation of methods and actions
The goal of using page objects is to abstract any page information away from the actual tests. Ideally, you should store all selectors or specific instructions that are unique for a certain page in a page object, so that you still can run your test after you've completely redesigned your page.
Making A Page Object
First off, we need a main page object that we call Page.js
. It will contain general selectors or methods which all page objects will inherit from.
// Page.js
export default class Page {
constructor() {
this.title = 'My Page'
}
async open (path) {
await browser.url(path)
}
}
We will always export
an instance of a page object, and never create that instance in the test. Since we are writing end-to-end tests, we always consider the page as a stateless construct—just as each HTTP request is a stateless construct.
Sure, the browser can carry session information and therefore can display different pages based on different sessions, but this shouldn't be reflected within a page object. These sorts of state changes should live in your actual tests.
Let's start testing the first page. For demo purposes, we use The Internet website by Elemental Selenium as guinea pig. Let's try to build a page object example for the login page.