Jordan Schilling | Technologist, Software Builder, and Engineer

Jordan Schilling — software engineer and technologist

Software engineer focused on automation systems, experimental tools, and developer productivity. Projects, dev logs, and technical writing.

6 March 2026

Exploring Playwright and Implementing OOP with Page Object Model

by Jordan Schilling

Devlog — 2026-03-06

Overview

Spent most of the day tackling this project — it’s been amazing learning so much. I decided I wanted to incorporate Object Oriented Programming into my automation framework given the complexity of it.

Why is OOP a desired option in this scenario? Because the website the automation is running on changes promos, sports leagues, and various other additions may be made. With how dynamic the website is, we can’t have code with hard-coded variables. We need to have an easy way to access and manipulate the variables, and that’s where OOP comes into play. OOP makes it so your code is clean, reusable, and maintainable.

From Selenium to Playwright

I first came across a Medium article on Selenium-based automation and it was a good stepping stone, although it involved Selenium and I wanted to use what is currently widely used in the industry — Playwright. So after tinkering with Selenium for a bit, I decided to pivot my mindset and find Playwright documentation.

The steps were straightforward, although I had a confusing interpreter spiderweb I had to fix to get the virtual environment running. After I was able to:

We were finally in a spot where some of the foundation could be built.

Page Object Model (POM)

At this point I wanted to get a stronger understanding of Playwright, so I read through some of the documentation you can find in the sources below. After spending some time on literature, I googled how to implement OOP (Object Oriented Programming) into a Python x Playwright automation framework. A technique named POM (Page Object Model) came up in the results and I began following that tutorial.

About halfway through the tutorial I felt I had a handle on it and finished the constructors of my class AddToCartPage:

class AddToCartPage:
    def __init__(self, page:Page):
        self.page = page
        self.selection_input = page.locator(".promo-option-indicator-" \
        "aodrsmzfpyxdet0hvraigenblock388c186ytkrd9")
        self.selection_input_promo = page.locator(".promo-option-card-" \
        "aodrsmzfpyxdet0hvraigenblock388c186ytkrd9.is-radio > " \
        ".promo-option-inner-aodrsmzfpyxdet0hvraigenblock388c186ytkrd9 > "
        ".promo-option-indicator-aodrsmzfpyxdet0hvraigenblock388c186ytkrd9")
        self.email = page.get_by_role("textbox", name="Email Address *")
        self.team_textbox = page.get_by_role("textbox", name="Favourite Team *")
        self.team_dropdown = page.get_by_label("Favourite EPL Team *")
        self.cart = page.get_by_role("button", name="Add to Cart")

    def select_input(self):
        self.selection_input.first.click()

    def select_input_promo(self):
        self.selection_input_promo.first.click()

    def input_email(self, email):
        self.email.fill(email)

    def input_team(self, text_teamname):
        self.team_textbox.fill(text_teamname)

    def select_team(self, teamname):
        self.team_dropdown.select_option(teamname)

    def select_cart(self):
        self.cart.click()

    def add_to_cart(self, email, text_teamname, teamname):
        self.selection_input.first.click()
        self.email.fill(email)
        self.team_textbox.fill(text_teamname)
        self.selection_input_promo.first.click()
        self.email.fill(email)
        self.team_dropdown.select_option(teamname)

Test Script Using POM

The add_to_cart object is now assigned to the class instance:

import re
import pytest
from playwright.sync_api import Page, expect
from pages.add_to_cart_page import AddToCartPage

def test_add_to_cart(page:Page) -> None:
    page.goto("https://gamedaytldr.live/")
    cart_flow = AddToCartPage(page)
    cart_flow.add_to_cart('jcschill12@gmail.com', 'USA', 'Arsenal')

How the Flow Works

Here’s what happens when add_to_cart is called:

  1. A selection locator finds the first option that needs to be selected to begin the checkout process
  2. Proceeds to the next option which is to select email
  3. The fill form fills out email and team
  4. Another locator selects the promo object — this selects a free package with the purchase
  5. Email is selected and form is filled out with email
  6. The dropdown locator finds the dropdown object, then clicks on the team provided
  7. Finally, checkout is selected

If checkout works, we get a checkmark and a success. If not, the pipeline still finishes but with a warning symbol and the exception is flagged with the reason: “Add to cart is currently unavailable.”

This automation framework is continuing development and this is a great start to what will end up being an amazing project!

Resources

tags: playwright - page-object-model - python - automation - e-commerce