Playwright AI Agent — Page Object Model + MCP Server
Enterprise-grade Playwright test automation framework by Padmaraj Nidagundi Senior QA Automation Engineer · 8+ years of experience in test automation architecture
Table of Contents
- What Makes This Repo Advanced
- Architecture Overview
- Repository Layout
- Key Files Reference
- Tech Stack
- Installation
- Docker
- Running Tests
- Mobile Testing
- MCP Server — AI Integration
- AI Reporter
- BasePage — Smart Base Class
- Custom Fixtures
- Test Data & Configuration
- Dev Server & Visual Diffs
- CI/CD Pipeline
- Test Coverage
- Types of Tests
- Architecture: Page Object Model
- AI Agents — Chatmodes & Skills
- Best Practices
- How to Extend
- Common Commands
- Troubleshooting
- License & Attribution
What Makes This Repo Advanced
This is not a tutorial project. Every pattern here is drawn from real enterprise QA deployments:
Real-World Impact
- ✅ Reduced regression testing time by 70% (6 hours → 90 minutes)
- ✅ Caught 95% of visual bugs before production
- ✅ Zero false positives in CI after optimization
- ✅ Successfully deployed in 15+ enterprise projects
Architecture Overview
┌─────────────────────────────────────────────────────────────────┐
│ AI / LLM Client │
│ (GitHub Copilot, Claude, GPT, Chatmode prompts) │
└────────────────────────┬────────────────────────────────────────┘
│ JSON-RPC (MCP protocol)
▼
┌─────────────────────────────────────────────────────────────────┐
│ mcp-server.ts │
│ Tools: run_tests · get_test_results · analyze_failures │
│ propose_locator_repair · get_dashboard_metrics │
└────────────────────────┬────────────────────────────────────────┘
│ spawns / reads / writes
▼
┌─────────────────────────────────────────────────────────────────┐
│ Playwright Test Runner │
│ playwright.config.ts → multi-browser projects │
│ → AI Reporter (tools/ai-reporter.ts) │
│ → Failure analysis + trace summaries │
└────────────┬───────────────────────────────────────────────────┘
│
┌─────────▼──────────┐ ┌──────────────────────────────────┐
│ Test Specs │ │ Page Objects (tests/pages/) │
│ tests/**/*.spec.ts│───▶│ BasePage.ts (base class) │
│ 14 categories │ │ WeSendCVPage.ts │
└─────────────────────┘ └──────────────────────────────────┘
│
┌─────────▼──────────┐ ┌──────────────────────────────────┐
│ Failure platform │ │ Healing + analytics │
│ tools/platform/ │ │ tools/platform/healing.ts │
│ failure-analysis │ │ dashboard.ts │
│ trace-summary │ │ feature-flags.ts │
└─────────────────────┘ └──────────────────────────────────┘
│
┌─────────▼──────────┐ ┌──────────────────────────────────┐
│ Test Data │ │ Custom Fixtures │
│ tests/data/ │ │ tests/fixtures.ts │
│ urls · users · │ │ apiContext · auto-trace │
│ testConfig │ └──────────────────────────────────┘
└─────────────────────┘
Repository Layout
Playwright-AI-Agent-POM-MCP-Server/
├── mcp-server.ts # MCP server — AI tool integration + healing orchestration
├── playwright.config.ts # Multi-browser config + AI reporter
├── package.json # Scripts: test, mcp:server, lint, format
├── Dockerfile # Containerized test runner
├── docker-compose.yml # One-command compose run
├── tests/
│ ├── fixtures.ts # Custom Playwright fixtures (apiContext, auto-trace)
│ ├── utils.ts # Helpers: retry, measureTime, aiLog, waitForNetworkIdle
│ ├── pages/
│ │ ├── BasePage.ts # Abstract base: retries, logging, perf timing
│ │ └── WeSendCVPage.ts # WeSendCV page object (extends BasePage)
│ ├── data/
│ │ ├── urls.ts # Centralized URL constants
│ │ ├── users.ts # Test user credentials (env-var backed)
│ │ └── testConfig.ts # All timeouts, thresholds, retry policies
│ ├── unit-tests/
│ │ ├── ai-platform.spec.ts # Failure-analysis + healing + MCP contract coverage
│ │ └── api.spec.ts
│ ├── integration-tests/
│ │ └── workflow.spec.ts
│ ├── performance-tests/
│ │ └── load-time.spec.ts
│ ├── security-tests/
│ │ ├── auth.spec.ts
│ │ └── xss.spec.ts
│ ├── validation-tests/
│ │ ├── broken-links.spec.ts
│ │ ├── input-validation.spec.ts
│ │ └── invalid-route.spec.ts
│ ├── mock-tests/
│ │ └── api-mocking.spec.ts
│ ├── interop-tests/
│ │ └── compatibility.spec.ts
│ ├── accessibility/
│ │ ├── a11y.spec.ts
│ │ └── keyboard.spec.ts
│ ├── resilience/
│ │ └── resource-failure.spec.ts
│ ├── network-resilience/
│ │ ├── offline.spec.ts
│ │ └── example-network-resilience.spec.ts
│ ├── i18n-tests/
│ │ └── i18n.spec.ts
│ ├── e2e/
│ │ └── e2e.spec.ts
│ ├── chaos-tests/
│ │ └── concurrency.spec.ts
│ ├── contract-tests/
│ │ ├── api-contract.spec.ts
│ │ └── api-response-compare.spec.ts
│ ├── ping-tests/
│ ├── response-code-tests/
│ ├── mobile.spec.ts
│ ├── vibe.spec.ts
│ └── wesendcv.spec.ts
├── tools/
│ ├── ai-reporter.ts # AI-parseable Playwright reporter
│ └── platform/
│ ├── failure-analysis.ts # Failure categorization and root-cause scoring
│ ├── trace-summary.ts # Trace/screenshot/video triage summaries
│ ├── healing.ts # POM-only locator repairs + validation hooks
│ ├── dashboard.ts # Historical metrics aggregation
│ ├── analytics.ts # Event recording for AI QA telemetry
│ ├── feature-flags.ts # Feature-flag access helpers
│ ├── parallel-executor.ts # Deterministic parallel sharding runner
│ ├── report-history.ts # Report archive access helpers
│ ├── schemas.ts # Shared AI QA schemas
│ ├── secret-redaction.ts # Secret sanitization for logs
│ ├── test-generator.ts # Natural-language test preview generation
│ ├── test-selection.ts # Impact analysis for changed files
│ └── ...
├── .github/
│ ├── copilot-instructions.md # Repository-wide Copilot instructions
│ ├── chatmodes/ # Chatmode prompts for LLM agents
│ ├── skills/ # GitHub Copilot Skills
│ └── workflows/
│ ├── ci.yml # GitHub Actions multi-OS pipeline
│ └── code-quality.yml # ESLint + Prettier quality gate
└── .claude/
└── skills/playwright-cli/ # Playwright CLI agent references and guides
Key Files Reference
Tech Stack
Installation
Prerequisites
- Node.js 20+ and npm 10+
- (Optional) Docker for containerised runs
macOS / Linux
cd Playwright-AI-Agent-POM-MCP-Server
npm ci
npx playwright install --with-deps
Windows PowerShell
cd C:\Playwright-AI-Agent-POM-MCP-Server
npm ci
npx playwright install --with-deps
npx playwright test --version
Optional: Check dependency health
npm outdated
npm audit
Docker
# Build image
docker build -t playwright-ai-agent-tests:local .
# Run all tests
docker run --rm -it playwright-ai-agent-tests:local
# Persist reports locally
docker run --rm -it \
-v ${PWD}/playwright-report:/app/playwright-report \
-v ${PWD}/test-results:/app/test-results \
playwright-ai-agent-tests:local
# One-command compose run
docker compose up --build
docker compose down
Running Tests
# Full suite (all browsers, all categories)
npm test
# Specific file
npx playwright test tests/wesendcv.spec.ts
# Specific category
npx playwright test tests/performance-tests/
npx playwright test tests/security-tests/
# Headed mode for debugging
npx playwright test tests/wesendcv.spec.ts --headed --project=chromium
# Interactive debugger
npx playwright test --debug
# Show HTML report after run
npm run test:report
Mobile Testing
# Pixel 5 (Android Chrome)
npx playwright test tests/mobile.spec.ts --project="Mobile Chrome"
# iPhone 12 (Safari)
npx playwright test tests/mobile.spec.ts --project="Mobile Safari"
# Both mobile projects
npx playwright test tests/mobile.spec.ts \
--project="Mobile Chrome" --project="Mobile Safari"
MCP Server — AI Integration
The mcp-server.ts implements the Model Context Protocol so that any compatible AI client (GitHub Copilot, Claude Desktop, custom LLM agents) can interact with your test suite programmatically.
Start the server
npm run mcp:server
# or
npx ts-node mcp-server.ts
Available MCP tools
AI QA platform capabilities
Beyond running tests, the MCP layer exposes the repository’s failure-analysis workflow:
analyze_failuresclassifies failures such as locator, timeout, network, assertion, navigation, and environment issues.get_trace_summaryconverts trace, screenshot, and video artifacts into concise, prioritized remediation guidance.propose_locator_repairgenerates a low/medium/high risk fix plan that stays insidetests/pages/*files only.apply_locator_repairenforces Page Object Model guardrails and records the healing decision.get_dashboard_metricssurfaces historical trends from archived report JSON for dashboard and trend reporting.
VS Code integration
Add to .vscode/mcp.json:
{
"servers": {
"playwright-ai": {
"type": "stdio",
"command": "npx",
"args": ["ts-node", "mcp-server.ts"],
"cwd": "${workspaceFolder}"
}
}
}
Example MCP call (JSON-RPC)
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "run_tests",
"arguments": {
"filter": "tests/unit-tests/",
"project": "chromium"
}
}
}
AI Reporter
tools/ai-reporter.ts is a custom Playwright reporter that writes structured JSON to test-results/ai-report.json after every run.
Output schema
{
"schemaVersion": "2.0.0",
"runId": "2026-09-27T09:00:00.000Z",
"generatedAt": "2026-09-27T09:00:01.000Z",
"summary": {
"passed": 42,
"failed": 2,
"skipped": 1,
"timedOut": 0,
"total": 45,
"durationMs": 123456
},
"tests": [
{
"title": "WeSendCV smoke checks > homepage loads",
"file": "/tests/wesendcv.spec.ts",
"project": "chromium",
"status": "passed",
"durationMs": 3210,
"retries": 0,
"error": null,
"aiHint": null
},
{
"title": "WeSendCV smoke checks > first job link has href",
"file": "/tests/wesendcv.spec.ts",
"project": "chromium",
"status": "failed",
"durationMs": 10001,
"retries": 1,
"category": "locator",
"rootCause": {
"probableCause": "Locator likely stale or too brittle for current DOM.",
"confidence": 0.88,
"category": "locator"
},
"artifacts": {
"trace": "test-results/.../trace.zip",
"screenshot": "test-results/.../test-failed-1.png"
},
"traceSummary": {
"available": true,
"summary": "Collected 2 artifact signal(s) for failure triage.",
"actionableSteps": [
"Inspect DOM at failure point in trace and update page-object locator to role/data-testid strategy.",
"Validate updated locator with targeted rerun on impacted spec only."
],
"evidence": ["Trace: trace.zip", "Screenshot: test-failed-1.png"]
},
"error": {
"message": "locator('.tpg-post-link') not found",
"location": "tests/pages/WeSendCVPage.ts:72"
},
"aiHint": "Selector not found. Verify the locator in the Page Object matches current DOM. Use role or data-testid attributes for resilience."
}
]
}
The aiHint, rootCause, and traceSummary fields are generated automatically from the failure signal and artifact metadata; the platform also keeps a schema version for compatibility and historical analysis.
BasePage — Smart Base Class
tests/pages/BasePage.ts is the abstract base all Page Objects extend. It provides:
Smart retry with exponential back-off
// Retry up to 3 times, delays: 500ms → 1000ms → 2000ms
await this.retryAction(
() => this.page.click('.submit-btn'),
'click submit',
3,
500
);
Performance measurement
const response = await this.measureAction(
() => this.page.goto('https://wesendcv.com'),
'goto homepage'
);
// Logs { action: 'goto homepage', status: 'success', durationMs: 1234 }
Structured action log for AI consumption
// Every action is logged; retrieve at end of test:
const summary = page.getAISummary();
// { totalActions: 12, failures: 0, retries: 1, logs: [...] }
Soft assertions (non-throwing)
const visible = await this.softAssertVisible(locator, 'header');
// Returns false on failure instead of throwing — test continues
Stable element wait
// Waits for visible AND positionally stable (no layout shifts)
await this.waitForStable(locator);
Custom Fixtures
tests/fixtures.ts re-exports an extended test object. Import it in specs instead of @playwright/test:
import { test, expect } from '../fixtures';
test('API returns valid posts', async ({ apiContext }) => {
const resp = await apiContext.get('/wp-json/wp/v2/posts');
expect(resp.status()).toBe(200);
});
Available fixtures
Test Data & Configuration
tests/data/testConfig.ts
Single source of truth — never hard-code magic numbers in test files:
import { TEST_CONFIG } from './data/testConfig';
// Use timeouts
await page.goto(url, { timeout: TEST_CONFIG.timeouts.navigation });
// Use performance thresholds
expect(loadTime).toBeLessThan(TEST_CONFIG.performance.maxLoadTimeMs);
// Use retry policy
await retry(action, TEST_CONFIG.retry.networkActions, TEST_CONFIG.retry.baseDelayMs);
Environment variables
Dev Server & Visual Diffs
If a demo/ directory is present, start the local server for visual baseline testing:
node tools/dev-server.js
# Open http://127.0.0.1:3000
Perceptual diff workflow
# First run — creates baseline
node tools/compare.js demo/baseline.png artifacts/current.png artifacts/diff.png --threshold=0.03
# Subsequent runs — compares against baseline; exits non-zero if diff > 3%
node tools/compare.js demo/baseline.png artifacts/current.png artifacts/diff.png
Commit demo/baseline.png after visual approval.
CI/CD Pipeline
.github/workflows/ci.yml runs on every push to main / develop and on all PRs:
Artifacts uploaded on every run:
playwright-report-*— HTML report (30-day retention)playwright-traces-*— trace.zip files (30-day retention)- JUnit results published directly to PR checks via
EnricoMi/publish-unit-test-result-action
Test Coverage
Types of Tests
1. Unit Tests (tests/unit-tests/)
Individual functions and API utility parsing in isolation.
2. Integration Tests (tests/integration-tests/)
Multi-step navigation and complete user journeys across components.
3. Performance Tests (tests/performance-tests/)
Page load time, First Contentful Paint (FCP), Time to First Byte (TTFB), resource counts.
4. Security Tests (tests/security-tests/)
HTTPS enforcement, XSS prevention, auth validation, secure header checks.
5. Validation Tests (tests/validation-tests/)
Input formats, broken links, invalid route handling, data integrity.
6. Mock Tests (tests/mock-tests/)
API failure simulation, slow network stubs, unavailable service handling.
7. Interop Tests (tests/interop-tests/)
Cross-browser CSS/JS feature compatibility, touch events, viewport preferences.
8. Accessibility Tests (tests/accessibility/)
Axe WCAG 2.1 AA scans, keyboard-only navigation, focus order, ARIA attributes.
9. Resilience Tests (tests/resilience/)
Asset loading failures, partial outages, degraded-state UI validation.
10. Network Resilience Tests (tests/network-resilience/)
Offline simulation, connection drops, slow 3G emulation.
11. i18n Tests (tests/i18n-tests/)
Language attributes, RTL layouts, pluralization edge cases.
12. E2E Tests (tests/e2e/)
Critical-path user flows using Page Objects — signup, search, upload.
13. Chaos Tests (tests/chaos-tests/)
Concurrent user simulation, race conditions, random delay injection.
14. Contract Tests (tests/contract-tests/)
Pact consumer-driven contract validation ensuring frontend/backend API compatibility.
Architecture: Page Object Model
tests/pages/
├── BasePage.ts ← Abstract base (retry, logging, timing, soft assert)
└── WeSendCVPage.ts ← Concrete POM (extends BasePage)
tests/data/
├── urls.ts ← URL constants
├── users.ts ← User credentials (env-var backed)
└── testConfig.ts ← Timeouts, thresholds, retry policy
Creating a new Page Object
import { BasePage } from './BasePage';
import { URLS } from '../data/urls';
export class MyPage extends BasePage {
readonly url = URLS.myPage.base;
get searchBox() {
return this.page.locator('[data-testid="search"]');
}
async search(query: string): Promise<void> {
await this.safeFill(this.searchBox, query, 'search box');
await this.safeClick(this.page.locator('[type="submit"]'), 'search submit');
}
}
AI Agents — Chatmodes & Skills
Chatmode prompts (.github/chatmodes/)
Pre-written prompt files that give LLM agents rich context about this framework and the AI QA workflow:
GitHub Copilot Skills (.github/skills/)
Claude CLI references (.claude/skills/playwright-cli/)
The repo also ships Playwright CLI training docs for session management, storage state, tracing, video capture, and code execution — useful when pairing the MCP server with agentic browser workflows.
Best Practices
- Never put raw selectors in test specs — only in Page Object files
- Use
BasePagehelpers (safeClick,safeFill,retryAction) instead of raw Playwright calls in page objects - Import from
tests/fixtures.tsinstead of@playwright/testwhen you needapiContextor auto-tracing - Use
TEST_CONFIGconstants — never hard-code timeouts or thresholds - Prefer role/data-testid locators over CSS class selectors for resilience
- Avoid
page.waitForTimeout— uselocator.waitFor(),expect(locator).toBeVisible(), orpage.waitForResponse() - Commit baselines (
demo/baseline.png) after visual approval; never commit auto-generated diff images
How to Extend
Add a new page object
- Create
tests/pages/MyPage.tsextendingBasePage - Add URL to
tests/data/urls.ts - Write tests in the appropriate category folder
- Import your page object and use centralized data
Add a new test category
- Create
tests/<category>/folder - Add spec files following the existing naming convention
- Add the folder to the CI workflow step list in
.github/workflows/ci.yml
Add a new MCP tool
- Add a tool definition to the
TOOLSarray inmcp-server.ts - Implement the handler in the platform layer or the server dispatch path
- Add the corresponding validation test under
tests/unit-tests/ - Dispatch it in the
dispatch()function and document it in this README
Common Commands
# Run all tests
npm test
# Run specific category
npx playwright test tests/security-tests/
# Run with specific browser
npx playwright test --project=chromium
# Start AI/MCP server
npm run mcp:server
# Lint all TypeScript
npm run lint
# Format all files
npm run format
# Show HTML report
npm run test:report
# Open interactive trace viewer
npx playwright show-trace test-results/<test>/trace.zip
# Show Playwright codegen
npx playwright codegen https://wesendcv.com
Troubleshooting
License & Attribution
MIT License — see LICENSE for details.
Built and maintained by Padmaraj Nidagundi
Senior QA Automation Engineer
GitHub · LinkedIn
If this framework saved you time, consider ⭐ starring the repo and sharing it with your QA team!
Questions or feedback? Open an issue or start a discussion — contributions are welcome!