DEV Community

Cover image for WebDriverIO Framework: Combining Page Object Model with Advanced Concepts
JigNect Technologies
JigNect Technologies

Posted on

WebDriverIO Framework: Combining Page Object Model with Advanced Concepts

The requirement for high-quality and efficient web applications keeps growing with each passing day; therefore, the need for automation frameworks supporting automated testing is on a rise. Thus, automated testing can save the required amount of manual effort while providing reliable and consistent results. WebDriverIO is the next-generation automation framework, built on Node.js specifically for end-to-end testing in modern web applications. Notably, it is gaining popularity in JavaScript applications due to seamless integration into the whole JavaScript ecosystem along with the powerful features in simple browser automation and testing.

There is an even more effective way in WebDriverIO to structure and maintain scalable test code, that is the Page Object Model, or POM, pattern. The POM design pattern separates from the test logic the UI structure and interactions of a webpage, encapsulating them into reusable page classes. This way, the test scripts in light of UI changes are cleaner, more readable, and thus more easily updated. The use of POM with WebDriverIO enables the building of modular, testable, and maintainable test suites that can face the complexity of a web application workflow easily.

Apart from POM, WebDriverIO supports data-driven tests and integration tests, custom commands, and continuous integration (CI) setups. This makes WebDriverIO flexible, especially in large-scale projects where automation at multiple browsers and platforms is required.

Getting Started with the Page Object Model (POM)

Advantages of Using POM in WebDriverIO
WebDriverIO integrates seamlessly with the POM design pattern, offering several benefits:

Modularity and Reusability: Page objects allow each page or component to be modularized, with reusable methods that can be called across different tests.

Ease of Maintenance: Since all UI elements for a page are centralized in a single class, updates due to UI changes can be easily managed, reducing maintenance time and effort.

Enhanced Readability: By separating page-specific operations from test logic, POM makes test scripts more readable. Test scripts are shorter, easier to understand, and more descriptive.

Error Reduction: With well-structured page objects, potential bugs related to UI changes are minimized, as element locators and actions are encapsulated within page classes.

Basic Structure of a POM Class in JavaScript

In WebDriverIO, POM classes are written in JavaScript or TypeScript. A page class typically includes:

  • Selectors for the elements on the page.
  • Methods that interact with those elements, such as filling out forms, clicking buttons, or verifying text.
  • Custom Commands that abstract complex actions or workflows.

Here’s a basic structure of a POM class in JavaScript:
// LoginPage.js
class LoginPage {
// Element selectors
get usernameInput() { return $('#username'); }
get passwordInput() { return $('#password'); }
get loginButton() { return $('#login'); }

// Method to perform login
async login(username, password) {
    await this.usernameInput.setValue(username);
    await this.passwordInput.setValue(password);
    await this.loginButton.click();
}
Enter fullscreen mode Exit fullscreen mode

}
module.exports = new LoginPage();

Now, in this example, the LoginPage class represents an application’s login page. Properties such as the username, password fields, and the login button are all there in it along with its method that performs the action of logging in. Test scripts can now use LoginPage.login() to execute the login function without needing to interact with individual elements directly.

To create effective page objects in WebDriverIO, consider the following best practices:

Encapsulate Element Locators: Keep element selectors private to the class, accessible only through methods. This keeps them hidden from the test scripts, making it easier to refactor when necessary.

Avoid Logic in Page Classes: Page objects should focus on actions related to the UI, not on business logic. Avoid implementing conditions or complex workflows within page classes.

Limit Each Class to a Specific Page or Component:
Keep each page object focused on a single page or component. For complex pages with multiple sections, consider creating separate page objects for each section.

**Use Descriptive Method Names: **Method names should describe what the method does, like clickLoginButton or enter username, to make tests easy to read.

Here’s an example of how a test might use the login page page object:

// login.test.js
const LoginPage = require('../pageobjects/LoginPage');

describe('Login tests', () => {
it('should log in with valid credentials', async () => {
await LoginPage.open();
await LoginPage.login('testUser', 'password123');
expect(await browser.getUrl()).toContain('/dashboard'); Ss
});
});

In this example, the LoginPage class enables the test script to execute the login function in a clean and straightforward way, with minimal repetition. This use of POM not only improves the test’s readability but also makes it more resilient to changes in the UI, as all selectors and actions are defined in a single location.

**Click the link🔗 to read and share the full blog with others.
**

Top comments (0)