Use when creating page objects or refactoring Playwright tests for better maintainability with Page Object Model patterns.
View on GitHubTheBushidoCollective/han
jutsu-playwright
January 24, 2026
Select agents to install to:
npx add-skill https://github.com/TheBushidoCollective/han/blob/main/jutsu/jutsu-playwright/skills/playwright-page-object-model/SKILL.md -a claude-code --skill playwright-page-object-modelInstallation paths:
.claude/skills/playwright-page-object-model/# Playwright Page Object Model
Master the Page Object Model (POM) pattern to create maintainable, reusable,
and scalable test automation code. This skill covers modern Playwright
patterns including component-based architecture, locator strategies, and
app actions.
## Core POM Principles
### Single Responsibility
Each page object should represent one page or component with a single,
well-defined responsibility.
### Encapsulation
Hide implementation details and expose only meaningful actions and
assertions.
### Reusability
Create reusable components that can be composed into larger page objects.
### Maintainability
When UI changes, update page objects in one place rather than across
multiple tests.
## Basic Page Object Pattern
### Simple Page Object
```typescript
// pages/login-page.ts
import { Page, Locator } from '@playwright/test';
export class LoginPage {
readonly page: Page;
readonly emailInput: Locator;
readonly passwordInput: Locator;
readonly loginButton: Locator;
readonly errorMessage: Locator;
constructor(page: Page) {
this.page = page;
this.emailInput = page.getByLabel('Email');
this.passwordInput = page.getByLabel('Password');
this.loginButton = page.getByRole('button', { name: 'Login' });
this.errorMessage = page.getByRole('alert');
}
async goto() {
await this.page.goto('/login');
}
async login(email: string, password: string) {
await this.emailInput.fill(email);
await this.passwordInput.fill(password);
await this.loginButton.click();
}
async getErrorMessage() {
return await this.errorMessage.textContent();
}
}
```
### Using Page Object in Tests
```typescript
// tests/login.spec.ts
import { test, expect } from '@playwright/test';
import { LoginPage } from '../pages/login-page';
test.describe('Login', () => {
test('should login successfully', async ({ page }) => {
const loginPage = new LoginPage(page);
await loginPage.goto();
await loginPage.login('user@exa