SOLID Principles with Playwright Examples (TypeScript)

Introduction

SOLID is a set of five object-oriented design principles introduced by Robert C. Martin (Uncle Bob). These principles help developers build software that is:

  • Easy to maintain
  • Easy to extend
  • Highly reusable
  • Loosely coupled
  • Easy to test

In enterprise Playwright frameworks, following SOLID principles results in cleaner Page Objects, reusable utilities, scalable workflows, and better test automation architecture.


Why SOLID is Important in Automation Frameworks

Without SOLID principles, frameworks often become:

  • Huge Page Objects (1000+ lines)
  • Duplicate code
  • Difficult to maintain
  • Hard to extend
  • Strongly coupled
  • Fragile when the application changes

With SOLID principles:

  • Classes have clear responsibilities
  • New features require minimal changes
  • Code becomes reusable
  • Frameworks scale efficiently

What does SOLID stand for?

PrincipleFull Form
SSingle Responsibility Principle
OOpen Closed Principle
LLiskov Substitution Principle
IInterface Segregation Principle
DDependency Inversion Principle

S — Single Responsibility Principle (SRP)

Definition

A class should have only one reason to change.

Each class should have one responsibility.


Bad Example

A LoginPage doing everything.

class LoginPage {

    login() {}

    logout() {}

    readExcel() {}

    generateRandomUser() {}

    takeScreenshot() {}

    sendEmail() {}

}

Problems

  • Too many responsibilities
  • Difficult maintenance
  • Hard to reuse
  • Large file

Good Example

Separate responsibilities.

LoginPage

↓

Login only
ExcelUtility

↓

Read Excel
ScreenshotUtility

↓

Capture Screenshot
Logger

↓

Logging

Each class has a single purpose.


Enterprise Folder Structure

pages/

    LoginPage.ts

utils/

    ExcelUtility.ts

    Logger.ts

    ScreenshotUtility.ts

Benefits

✔ Small classes

✔ Easy maintenance

✔ Better readability

✔ Easier testing


Interview Question

Why is SRP important in Playwright?

Answer

It prevents Page Objects from becoming large and difficult to maintain. By separating responsibilities into page objects, utilities, workflows, and services, the framework becomes cleaner, reusable, and easier to extend.


O — Open Closed Principle (OCP)

Definition

Software entities should be open for extension but closed for modification.

Instead of changing existing code, extend it.


Bad Example

if(browser=="chromium"){

}

else if(browser=="firefox"){

}

else if(browser=="webkit"){

}

Whenever a new browser is added, this code must be modified.


Better Approach

Use the Strategy Pattern.

Browser Strategy

↓

Chromium

Firefox

WebKit

Adding a new browser:

Edge Strategy

No existing code changes.


Playwright Example

Instead of modifying

BrowserLauncher.ts

Create

ChromiumStrategy

FirefoxStrategy

WebKitStrategy

EdgeStrategy

Benefits

✔ Easy extension

✔ No modification

✔ Low risk

✔ Better architecture


Interview Question

Explain OCP using Playwright.

Answer

A browser launcher should support new browsers without changing existing code. Using Strategy Pattern, each browser has its own implementation, allowing new browsers to be added by creating new strategy classes rather than modifying the launcher.


L — Liskov Substitution Principle (LSP)

Definition

A derived class should be replaceable with its base class without breaking the application.


Example

Suppose

BasePage

contains

open()

waitForPage()

verifyTitle()

Now

LoginPage

DashboardPage

CheckoutPage

extend BasePage.

Any of them should work wherever a BasePage is expected.


Good Example

BasePage

↓

LoginPage

↓

DashboardPage

↓

CartPage

Each subclass honors the behavior defined by the base class.


Bad Example

Suppose BasePage defines

openPage()

but CheckoutPage throws an exception because it cannot open itself.

That violates LSP.


Benefits

✔ Better inheritance

✔ Predictable behavior

✔ Easier maintenance


Interview Question

How does LSP help automation?

Answer

It ensures that all page objects derived from a common base behave consistently. Shared framework code can work with any page object without requiring special handling.


I — Interface Segregation Principle (ISP)

Definition

Clients should not be forced to depend on interfaces they don’t use.


Bad Example

interface Utility{

readExcel();

takeScreenshot();

sendEmail();

uploadFile();

downloadFile();

}

Every implementing class must define unnecessary methods.


Better Example

Separate interfaces.

ExcelReader

↓

readExcel()

ScreenshotService

↓

takeScreenshot()

FileUploader

↓

upload()

Benefits

✔ Small interfaces

✔ Easier implementation

✔ Better readability


Interview Question

Why is ISP useful in Playwright?

Answer

It avoids creating large interfaces that force unrelated implementations. Separate interfaces for reporting, screenshots, file handling, and data readers keep the framework modular and easier to maintain.


D — Dependency Inversion Principle (DIP)

Definition

High-level modules should not depend on low-level modules.

Both should depend on abstractions.


Bad Example

class LoginWorkflow{

private login=new LoginPage(page);

}

Strong coupling.


Better Example

Inject dependency.

constructor(private loginPage: LoginPage){

}

Now

LoginWorkflow

doesn’t create LoginPage.

Someone else provides it.


Architecture

Test

↓

Fixture

↓

Workflow

↓

Page Object

Each layer receives dependencies instead of creating them.


Playwright Example

Playwright Fixtures naturally support Dependency Injection.

Instead of

const page=new LoginPage(browserPage);

Fixtures inject

loginPage

directly into the test.


Benefits

✔ Loose coupling

✔ Easy testing

✔ Easy mocking

✔ Better scalability


Interview Question

How does Playwright support Dependency Injection?

Answer

Playwright fixtures inject dependencies such as browser instances, pages, authenticated sessions, and page objects into test functions. This reduces object creation inside tests and promotes loose coupling.


SOLID Applied to a Playwright Framework

                     Test Layer
                         │
                         ▼
                  Workflow Layer
                         │
                         ▼
                 Page Object Layer
                         │
                         ▼
                 Utility/Service Layer
                         │
                         ▼
                Playwright Framework
                         │
                         ▼
                     Browser

Each layer follows a specific responsibility.


Before SOLID

LoginPage

1000 Lines

↓

Login

Logout

Excel

JSON

API

Logger

Screenshot

Database

Email

Random Data

Very difficult to maintain.


After SOLID

LoginPage

↓

Login Only
Logger

↓

Logging Only
API Client

↓

API Only
Excel Utility

↓

Excel Only
Workflow

↓

Business Process

Clean architecture.


SOLID + Design Patterns

SOLID PrincipleDesign Pattern
SRPPage Object Model
OCPStrategy Pattern
LSPBase Page Inheritance
ISPSmall Interfaces
DIPFixtures + Dependency Injection

Real Enterprise Example

Suppose you’re automating an e-commerce application.

Without SOLID

CheckoutPage

↓

Login

↓

Search

↓

Add Product

↓

Payment

↓

Database

↓

Email

↓

Report

↓

Screenshot

One class controls everything.


With SOLID

CheckoutWorkflow

↓

LoginPage

↓

ProductPage

↓

CartPage

↓

PaymentPage

↓

OrderPage

Utilities

Logger

API

Screenshot

Excel

JSON

Random Data

Every class has one responsibility.


Enterprise Benefits

Following SOLID results in:

  • Smaller Page Objects
  • Better readability
  • Easier debugging
  • Cleaner architecture
  • Reusable code
  • Easier onboarding for new team members
  • Better unit and integration testing
  • Faster feature development
  • Simpler code reviews

Common SOLID Mistakes in Playwright

❌ Putting business workflows inside page objects

Move business flows to a separate Workflow (Facade) layer.


❌ Creating one huge Utility class

Split it into focused utilities:

  • Logger
  • DateUtility
  • JsonUtility
  • ExcelUtility
  • ScreenshotUtility

❌ Hardcoding object creation

Avoid:

const loginPage = new LoginPage(page);

Prefer dependency injection through Playwright fixtures or a factory.


❌ Large BasePage classes

Keep BasePage limited to truly common functionality such as navigation, waiting, or shared helpers. Don’t force unrelated pages to inherit unnecessary behavior.


❌ Large interfaces

Create small, purpose-specific interfaces rather than one interface containing dozens of unrelated methods.


Senior Playwright Interview Questions

1. What are SOLID principles?

Answer

SOLID is a set of five object-oriented design principles that improve maintainability, extensibility, reusability, and scalability. They help reduce coupling and encourage clean architecture.


2. Which SOLID principle is most important in automation?

Answer

All five are valuable, but Single Responsibility Principle (SRP) is often the most impactful because it prevents oversized Page Objects and encourages separation of concerns across pages, workflows, utilities, and services.


3. How does Playwright support Dependency Inversion?

Answer

Playwright fixtures provide dependency injection by supplying browser instances, contexts, pages, and custom page objects to tests. Tests depend on abstractions provided by fixtures instead of creating concrete objects themselves.


4. How do SOLID principles improve a Playwright framework?

Answer

They make the framework modular, reusable, easier to extend, and simpler to maintain. New functionality can often be added by introducing new classes rather than modifying existing ones, reducing the risk of breaking stable automation.


5. How do SOLID principles relate to design patterns?

Answer

Design patterns are practical implementations of SOLID ideas. For example:

  • SRP → Page Object Model, Workflow layer
  • OCP → Strategy Pattern
  • LSP → Base Page inheritance
  • ISP → Focused interfaces
  • DIP → Fixtures and Dependency Injection

Using SOLID together with patterns like Factory, Builder, Strategy, and Facade results in an enterprise-grade Playwright framework that is easier to scale and maintain over time.

Leave a Comment