Page Object Modeling with Python and Playwright

How to construct effective models for Playwright frameworks.

Jonathan Thompson
Analytics Vidhya
4 min readFeb 8, 2021

--

Photo by Chris Ried on Unsplash

Microsoft’s Playwright quietly released in May of 2020. Written by a group of engineers who originally wrote the Puppeteer library, Playwright is intentionally similar to Puppeteer. While Microsoft has provided an example of a page object within Playwright’s documentation, the example is fairly simple and does not delve into the use of page properties or helper methods.

What is a Page Object?

A page object is an abstraction of a web page using a programming language. The intention is to represent all of the page within code so as to take action against specific elements. Page objects are routinely used in the field of test automation where a Quality Engineer creates objects and tests for the purpose of testing application user journeys.

This tutorial will focus on building a page object for the DemoQA Bookstore application login page. The login page features a username input, a password input, a login button, and a new user button.

Getting Started

In order to begin, we need to install our dependencies. The following packages should be installed:

  • pytest
  • pytest-playwright
  • playwright

Simply install the above using pip (or the dependency manager of your choosing).

The pytest library is included as it is the most popular test runner for Python. The pytest-playwright package provides simple fixtures for use within tests, such as the page fixture which automates browser setup. It can also be configured to take screenshots upon failure which is helpful in debugging flakey or failing tests.

Abstracting Page Elements

Our first task is to create a class object that represents the login page which features a page attribute when initialized. The page attribute will be used when creating properties and methods.

The reason for building a class object is that it allows our code to remain organized while increasing reusability.

Now that we have our Login class, we can begin adding properties that represent elements within the page. We use the @property built-in decorator as it makes using getters and setters easier within Python.

Each property returns what Playwright calls an ElementHandle. This is Playwright’s representation of a DOM element. Playwright ElementHandle objects may be used by themselves or as arguments to other methods.

The property username_field is called from within the user_form. This is because the username field is a child element of the user form in the DOM. This is a good practice as it narrows the scope of the driver to a specific area rather than the entirety of the page.

Playwright’s wait_for_selector method allows us to call elements safely as it will wait for the element to be visible within the DOM until a timeout limit has been reached. An error is raised if the selector is not found within the timeout limit.

The wait_for_selector method may also be used to wait for a specific element state such as waiting until hidden. However, that is out of scope for this guide.

Writing Helper Methods

Page object properties may be used in the construction of helper methods. Helper methods should be constructed for workflows which are repeated often.

The above methods allow for page navigation and form submission, both workflows which will be used frequently during Login page testing.

Writing and Running a Test

Now that we have a page object built with both properties and helper methods, we can begin writing a test for a user journey.

In the above test, we initialized both our Login page and a Profile page (example not shown) which is used in the assertion of the test. We navigate to the login page, then input user information using the submit_login_form helper method.

Once our form is submitted, we check to see whether an element on the Profile page is shown. We then use this check in our assertion as this element is shown after successful login.

To run this test, input one of the following commands to your terminal:

  • pytest to run headlessly
  • pytest --headful to run in a headful state

Project Directory

Your directory should resemble the following upon completion of this tutorial:

Summary

Writing tests using Page Object Model is fairly quick and convenient. Using Python and Playwright, we can effortlessly abstract web pages into code while automatically waiting for elements.

Jonathan Thompson is a Senior Quality Engineer specializing in test automation. He currently resides in Raleigh, NC with his wife and a Goldendoodle named Winston. You can connect with him on LinkedIn, or follow him on either Twitter (@jacks_elsewhere) or Github (ThompsonJonM).

--

--

Jonathan Thompson
Analytics Vidhya

Writing about Golang, JavaScript, and Python with a little test automation