How large is too large when it comes to page object classes in playwright?

I’ve been implementing the Page Object Model (POM) in my test automation, and I’m running into a dilemma. My page class has already grown significantly, containing over 15 helper functions for various UI interactions like filling input fields, selecting dropdown values, and clicking buttons. Each function is used in different test flows, such as regression and smoke tests.

This page class is just for 1 module. This module has creation page, list view page and a filters menu.

Now, I need to add filter functionality, which will introduce even more methods. My concern is that the page class is becoming too large. While I want to keep things organized, I also don’t want to overcomplicate things by splitting it into too many abstractions that make maintenance difficult.

  • What’s the best approach here?
  • Should I keep everything in one large page class, break it down into separate modules for different sections (like creation, details, and filters), or use a hybrid approach?
  • How do you balance class size with maintainability in POM?
3 Likes

I had this question too. On a Playwright POM I maintained one class had grown so large it was hard to remember which functions were in it. I split the class into sub-classes and made the original class an abstract class. I found the useful heuristic on how large a class should be is whether the class is easy to understand. If the class’s size makes it hard to understand then it is too large.

2 Likes

I coming up with a similar idea. Dividing a class up on the basis of the CRUD abbreviation so it makes it easier to manage. I guess the heuristic you’re referring to is called SOLID?

Trust your gut. The fact that you’re asking is already a good sign there might be something there.

This question is very relevant on the development side of things and there’s a funny correlation there. Page objects generally map to units of UI, even more so with component based frameworks. If the UI implementation itself has issues with things being too big, doing too much, too coupled together, then you’ll feel it in the page objects. This also means the pains you’re feeling could be an issue with the apps implementation/design.

Recognizing that things are too big (symptom) though is a solid first step in understanding the underlying issue.

1 Like

@hananurrehman I found @kristinjackvony’s post very helpful: SOLID Principles for Testers: The Single Responsibility Principle

1 Like

Great question!
I break them down into separate modules like you said.

Basically Design them by section of your page.
If your POM contains a createpage, listview, filter menu’s etc.
Split them up like this:

  1. CreationPage.ts – Handles form interactions
  2. ListViewPage.ts – Handles the list of items
  3. FiltersMenu.ts – Handles filter interactions

Each of these classes would contain methods only relevant to that specific view. Then your test files can use them as needed.

You can use composition instead of inheritance.

class ModulePage {
    readonly creationPage: CreationPage;
    readonly listViewPage: ListViewPage;
    readonly filtersMenu: FiltersMenu;

    constructor(page: Page) {
        this.creationPage = new CreationPage(page);
        this.listViewPage = new ListViewPage(page);
        this.filtersMenu = new FiltersMenu(page);
    }
}

Then your testcases can access all of the above.

It’s a way to create smaller classes and then combining them.

1 Like

Thanks i’ll check it out!