Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

67 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Playwright EasyScale

🎯 Template Repository: Fork this repo to create your own distributed Playwright testing infrastructure!

A distributed browser testing framework for running large-scale Playwright tests across multiple Railway containers. This is a template repository - fork it and add your own tests!

πŸš€ Quick Start

1. Deploy Railway Template

Deploy on Railway

Click the button above to deploy the complete infrastructure to Railway. This will:

  • Set up the worker service with all environment variables
  • Configure S3-compatible storage (Railway Buckets recommended)
  • Create the orchestrator service
  • Connect everything automatically

2. Eject to Your Own Repository

After deploying the template, you need to create your own fork:

  1. Go to your Railway project dashboard
  2. Click on any service (e.g., worker)
  3. Go to the Settings tab
  4. Find Source Repo section
  5. Click "Eject" button

Railway will automatically:

  • Create a fork of the repository in your GitHub account
  • Connect the fork to your Railway project
  • Handle the monorepo structure for all services

3. Clone Your Forked Repository

Now clone your own repository:

git clone https://github.com/YOUR_USERNAME/playwright-easyscale.git
cd playwright-easyscale

# Install orchestrator dependencies locally
cd orchestrator && npm install

4. Add Your Tests

Create your Playwright tests in worker/tests/:

// worker/tests/my-test.spec.js
const { test, expect } = require('@playwright/test');

const userRangeStart = parseInt(process.env.USER_RANGE_START || '1');
const userRangeEnd = parseInt(process.env.USER_RANGE_END || '1');

for (let userId = userRangeStart; userId <= userRangeEnd; userId++) {
  test(`User ${userId} workflow`, async ({ page }) => {
    // Your test logic here
  });
}

5. Run Your Tests

# Test locally (dry run)
cd orchestrator
node src/index.js --config=../configs/example.json --dry-run

# Deploy to Railway
node src/index.js --config=../configs/example.json

All Railway credentials and storage configuration are already set up via the template!

πŸ“– Overview

Break free from single-machine hardware limits!

This project solves the fundamental problem of running large-scale browser tests: your local machine can't handle hundreds of concurrent browser instances. Traditional approaches like Puppeteer clusters quickly hit CPU, memory, and network bottlenecks on a single machine.

Playwright EasyScale distributes your tests across multiple Railway containers, giving you:

  • Unlimited horizontal scaling - Add more containers, not more RAM
  • Unlimited vertical scaling - Each container gets dedicated resources
  • No hardware constraints - Break through the limits of a single machine

Perfect For

  • πŸ§ͺ Stress Testing - Simulate hundreds or thousands of concurrent users
  • πŸ“Š Load Testing - Test application performance under realistic load
  • πŸ”„ Large Test Suites - Run massive regression suites in parallel
  • πŸ‘₯ Multi-User Scenarios - Test complex user interactions at scale

Why This Exists

The Problem: Running 100+ concurrent browser instances on one machine causes:

  • Memory exhaustion
  • CPU throttling
  • Network saturation
  • Flaky tests due to resource contention

The Solution: Distribute tests across cloud containers where each gets dedicated resources. Scale horizontally by adding more containers, not by buying bigger machines.

Key Features

  • πŸš€ Automatic Distribution - Splits tests across N containers automatically
  • πŸ’° Cost Effective - Pay only for test duration (~$0.20 per 200-user test)
  • πŸ“Š Centralized Logging - Aggregates logs from all containers to S3-compatible storage
  • πŸ”§ Simple Configuration - JSON-based test configuration
  • ⚑ Railway Template - One-click deployment, no infrastructure setup
  • ♻️ Template Repository - Fork and customize for your needs

πŸ—οΈ Architecture

playwright-easyscale/
β”œβ”€β”€ orchestrator/          # Coordinator service (runs locally)
β”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ index.js      # Main CLI
β”‚   β”‚   β”œβ”€β”€ config.js     # Configuration loader
β”‚   β”‚   β”œβ”€β”€ distributor.js # User distribution logic
β”‚   β”‚   β”œβ”€β”€ railway.js    # Railway API client
β”‚   β”‚   └── logger.js     # Logging utilities
β”‚   └── package.json
β”‚
β”œβ”€β”€ worker/               # Test runner container (runs on Railway)
β”‚   β”œβ”€β”€ tests/           # πŸ‘ˆ Add your tests here!
β”‚   β”‚   └── example.spec.js
β”‚   β”œβ”€β”€ helpers/
β”‚   β”‚   β”œβ”€β”€ utils.js
β”‚   β”‚   └── logUpload.js
β”‚   β”œβ”€β”€ index.js         # Centralized worker service (main entry point)
β”‚   β”œβ”€β”€ state-manager.js # Worker state management
β”‚   β”œβ”€β”€ upload-results.js # Result upload handler (modular)
β”‚   β”œβ”€β”€ Dockerfile
β”‚   β”œβ”€β”€ playwright.config.js
β”‚   └── package.json
β”‚
β”œβ”€β”€ test-app/             # Demo app for example tests (optional)
β”‚   β”œβ”€β”€ index.html       # Simple login/dashboard app
β”‚   β”œβ”€β”€ Dockerfile       # For Railway deployment
β”‚   └── README.md        # Deployment instructions
β”‚
β”œβ”€β”€ configs/              # Test configurations
β”‚   └── example.json     # πŸ‘ˆ Copy and customize this!
β”‚
└── docs/                 # Documentation
    └── SETUP.md

🎯 How It Works

1. Orchestrator (Local)

The orchestrator runs on your machine and:

  • Reads test configuration
  • Calculates optimal container distribution
  • Deploys worker containers to Railway via API
  • Passes unique environment variables to each container
  • Monitors deployment status
  • Aggregates results from storage

2. Worker Containers (Railway)

Each worker container runs a centralized service (index.js) that:

  • Reports "ready" state when deployed
  • Waits for "start" command from orchestrator
  • Spawns Playwright as a child process
  • Runs a subset of users (e.g., users 1-5, 6-10, etc.)
  • Executes Playwright tests in parallel (5 workers per container)
  • Monitors for "stop" command during execution
  • Kills Playwright process tree when stopped
  • Uploads logs and screenshots to S3-compatible storage
  • Reports "finished" or "stopped" state when complete

Key Architecture: Single Node.js process manages the entire worker lifecycle, ensuring reliable state transitions and proper process management.

3. Distribution Example

Configuration: 100 users, 5 users per container

Container 1: Users 1-5    (5 users)
Container 2: Users 6-10   (5 users)
Container 3: Users 11-15  (5 users)
...
Container 20: Users 96-100 (5 users)

Each container receives:

  • USER_RANGE_START and USER_RANGE_END
  • SHARD_INDEX and SHARD_TOTAL
  • Custom environment variables from config

πŸ“ Configuration

Create a config file in configs/:

{
  "name": "My Stress Test",
  "totalUsers": 100,
  "usersPerContainer": 5,
  "testFile": "my-test.spec.js",
  "environment": {
    "LOGIN_URL": "https://your-app.com",
    "PASSWORD": "test-password"
  },
  "railway": {
    "projectId": "${RAILWAY_PROJECT_ID}",
    "serviceId": "${RAILWAY_SERVICE_ID}",
    "apiToken": "${RAILWAY_API_TOKEN}"
  },
  "storage": {
    "endpoint": "${S3_ENDPOINT}",
    "accessKey": "${S3_ACCESS_KEY}",
    "secretKey": "${S3_SECRET_KEY}",
    "bucket": "${S3_BUCKET}",
    "region": "${S3_REGION}"
  },
  "options": {
    "headless": true,
    "timeout": 300000,
    "retries": 0,
    "maxConcurrency": 5
  }
}

πŸ› οΈ Writing Tests Locally

Important: You don't need to replicate the full cloud infrastructure locally. The point of this project is to leverage cloud resources to overcome hardware limits. Local development is only for writing and testing individual test logic.

Prerequisites

  • Node.js 18+ (for running orchestrator and Playwright)

Workflow

  1. Write your tests in worker/tests/:

    cd worker
    npm install
    
    # Run a single test locally to verify logic
    npx playwright test tests/my-test.spec.js --headed
  2. Test the orchestrator (dry run to verify configuration):

    cd orchestrator
    npm install
    
    # Verify your config and distribution plan
    node src/index.js --config=../configs/my-test.json --dry-run
  3. Deploy to Railway for actual scale testing:

    # This deploys N containers to Railway
    node src/index.js --config=../configs/my-test.json

Why not test locally at scale? Because that defeats the purpose! Running 100 browser instances locally will hit the exact hardware limits this project solves. Write tests locally, deploy to Railway for scale.

πŸ“š Documentation

🚦 Current Status

βœ… Ready for Testing

This is a functional template repository with:

  • βœ… Working orchestrator with Railway API integration
  • βœ… Worker container with Playwright and log upload
  • βœ… Example tests and configuration
  • βœ… Documentation and setup guides

βœ… Recently Added:

  • Web UI dashboard for managing test runs
  • Worker state management (ready/testing/finished/stopped)
  • Start/Stop/Reset controls for test runs
  • Real-time worker status monitoring

⚠️ Not Yet Implemented:

  • Real-time log streaming in UI
  • Advanced error recovery
  • Automatic retry logic

πŸŽ“ Example Usage

Test Locally (Dry Run)

cd orchestrator
node src/index.js --config=../configs/example.json --dry-run

Output:

πŸš€ Playwright EasyScale Orchestrator

βœ” Configuration loaded and validated

πŸ“Š Distribution Plan:
   Test: Example Stress Test
   Total Users: 20
   Users per Container: 5
   Total Containers: 4

   Container Breakdown:
   Container 1: Users 1-5 (5 users)
   Container 2: Users 6-10 (5 users)
   Container 3: Users 11-15 (5 users)
   Container 4: Users 16-20 (5 users)

βœ“ Dry run complete - no containers deployed

Deploy to Railway

node src/index.js --config=../configs/example.json

πŸ§ͺ Test User Credentials

For testing purposes, here are 10 test user credentials in JSON format:

[
  {"email": "user1@example.com", "password": "TestPass123!"},
  {"email": "user2@example.com", "password": "TestPass123!"},
  {"email": "user3@example.com", "password": "TestPass123!"},
  {"email": "user4@example.com", "password": "TestPass123!"},
  {"email": "user5@example.com", "password": "TestPass123!"},
  {"email": "user6@example.com", "password": "TestPass123!"},
  {"email": "user7@example.com", "password": "TestPass123!"},
  {"email": "user8@example.com", "password": "TestPass123!"},
  {"email": "user9@example.com", "password": "TestPass123!"},
  {"email": "user10@example.com", "password": "TestPass123!"}
]

Usage: Copy this JSON array and paste it into the test parameters field when creating a run in the web UI.

🀝 Contributing

This is a template repository - feel free to:

  • Fork it and customize for your needs
  • Submit PRs with improvements
  • Report issues or request features
  • Share your use cases

See CONTRIBUTING.md for guidelines.

πŸ“„ License

MIT License - see LICENSE for details.

πŸ™ Acknowledgments

Built with:

πŸ“ž Support


Made with ❀️ by CultureDrivers

Fork this repo and start scaling your Playwright tests today! πŸš€

About

Easily deploy hundreds of concurrent Playwright tests to load test and stress test web applications.

Resources

Contributing

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages