A demo of a Playwright test automation framework built with TypeScript, diplaying best practices for functional and e2e testing using the Page Object Model (POM) pattern.
This project demonstrates a Playwright testing framework featuring:
- Page Object Model (POM) architecture for maintainable test code
- TypeScript for type safety and better developer experience
- Docker support for consistent testing environments
- GitHub Actions CI/CD pipeline with optimized caching
- ESLint & Prettier for code quality and formatting
- Modular test structure with reusable components
- Test Framework: Playwright v1.55.0
- Language: TypeScript 5.9+
- Runtime: Node.js 18+
- Code Quality: ESLint + Prettier
- CI/CD: GitHub Actions
- Containerization: Docker + Docker Compose
- Environment Management: dotenv
- Node.js 18.0.0 or higher
- npm or yarn package manager
-
Clone the repository
git clone https://github.com/oponcefranco/playwright-typescript-demo.git cd playwright-typescript-demo -
Install dependencies
npm install
-
Install Playwright browsers
npx playwright install
-
Set up environment variables
cp .env.example .env
Create a .env file in the project root:
# Base URL for your application under test
BASE_URL=<TEST_URL_HERE>The project uses playwright.config.ts for test configuration:
- Test Directory:
./src/tests - Base URL: Configured via
BASE_URLenvironment variable - Browsers: Currently optimized for Chromium (Firefox and WebKit available)
- Reports: HTML reporter with screenshots on failure
- Parallel Execution: Enabled for faster test runs
# Run specific test file
npx playwright test homePage.spec.ts
# Run tests matching a pattern
npx playwright test --grep "homepage"
# Run tests in headed mode
npx playwright test --headed
# Run tests with specific number of workers
npx playwright test --workers=2This project implements a robust Page Object Model (POM) architecture:
BasePage: Foundation class for all page objects with common functionalityScenarioPage: Manages test scenarios, screenshots, and shared database.ts: Test fixtures that automatically inject page objects
// src/pom/homepage/home.ts
export class HomePage extends BasePage {
constructor(page: Page, scenarioPage: ScenarioPage) {
super(page, scenarioPage)
}
async open() {
await this.page.goto('/')
}
async verifyHeaderIsDisplayed(headerText: string) {
const header = this.page.locator(locators.header, {
hasText: headerText,
})
await expect(header).toBeVisible()
}
}// src/tests/homePage.spec.ts
import test from '../pom/common/base'
test.describe('Homepage Tests', () => {
test('should display homepage elements', async ({ homepage }) => {
await homepage.open()
await homepage.verifyHomeIconIsDisplayed()
...
})
})- Maintainability: Page changes require updates in one location
- Reusability: Page objects can be shared across multiple test files
- Type Safety: TypeScript provides compile-time error checking
- Auto-injection: Page objects are automatically available in tests
This project includes Docker support for testing environments.
# Build and run tests
docker build -t playwright-demo .
docker run --rm -e BASE_URL=https://example.com playwright-demo
# Using Docker Compose (recommended)
docker-compose run --rm playwright-testsFor detailed Docker instructions, see DOCKER.md.
The project includes a GitHub Actions workflow (.github/workflows/playwright.yml) featuring:
- Lint and TypeScript checks before running tests
- Browser caching for faster CI runs
- Matrix strategy for multi-browser testing (currently optimized for Chromium)
- Artifact uploads for test reports and results
- Optimized caching for dependencies and Playwright browsers
act -W '.github/workflows/playwright.yml' --container-architecture linux/amd64- TypeScript-specific rules
- Prettier integration for consistent formatting
- Custom rules for Playwright best practices
# Check for linting errors
npm run eslint-check-only
# Fix auto-fixable linting issues
npm run eslint-fix
# Format code with Prettier
npm run prettier- Strict mode enabled for type safety
- Modern ES modules support
- Optimized for Node.js environment
- Source maps for debugging
- Fork and clone the repository
- Create a feature branch:
git checkout -b feature/your-feature - Install dependencies:
npm install - Run tests:
npm test - Check code quality:
npm run eslint-check-only - Format code:
npm run prettier - Commit changes: Follow conventional commit format
- Push and create PR: Target the
mainbranch
- Follow the existing Page Object Model structure
- Add tests for new page objects
- Update documentation for significant changes
- Ensure all tests pass before submitting PR
- Follow TypeScript best practices
- Create page objects in
src/pom/[page-name]/ - Add locators in separate files (e.g.,
locators.ts) - Write tests in
src/tests/using the base test fixture - Follow the existing naming conventions