Sign inSign up

fastslack/e2e-runner

By fastslack

Updated 7 months ago

JSON-driven E2E test runner with parallel execution via Puppeteer and Chrome pool

Image
API management
Machine learning & AI
Developer tools
0

194

fastslack/e2e-runner repository overview

A JSON-driven end-to-end test runner that executes browser tests in parallel against a Chrome pool via Puppeteer. No JavaScript test files needed — define your tests as simple JSON action arrays.

Features

  • Parallel execution with configurable concurrency
  • JSON-based tests — no code, just action sequences
  • Retry on flaky tests with per-test override
  • Per-test timeout via Promise.race
  • JUnit XML output for CI/CD integration
  • Before/After hooks (beforeAll, afterAll, beforeEach, afterEach)
  • Environment profiles for staging, production, etc.
  • Auto error screenshots on test failure
  • Zero config — sensible defaults, override via config file, env vars, or CLI flags

Installation

docker pull fastslack/e2e-runner:latest

Quick Start

# Scaffold project structure
docker run --rm -v $(pwd):/app fastslack/e2e-runner init

# Start Chrome pool
docker run --rm -v $(pwd):/app fastslack/e2e-runner pool start

# Run all tests
docker run --rm -v $(pwd):/app fastslack/e2e-runner run --all

Test Example

Each JSON file contains an array of tests with sequential actions:

[
  {
    "name": "login-flow",
    "actions": [
      { "type": "goto", "value": "/login" },
      { "type": "type", "selector": "#email", "value": "[email protected]" },
      { "type": "type", "selector": "#password", "value": "secret" },
      { "type": "click", "selector": "#submit" },
      { "type": "assert_text", "text": "Welcome" },
      { "type": "screenshot", "value": "after-login.png" }
    ]
  }
]

Available Actions

ActionFieldsDescription
gotovalueNavigate to URL (relative to baseUrl or absolute)
clickselector or textClick element by CSS selector or visible text
type / fillselector, valueClear field and type text
waitselector, text, or value (ms)Wait for element, text, or delay
assert_texttextAssert text exists on page
assert_urlvalueAssert current URL contains value
assert_visibleselectorAssert element is visible
assert_countselector, valueAssert element count matches
screenshotvalue (filename)Take a screenshot
selectselector, valueSelect dropdown option
clearselectorClear an input field
pressvaluePress a keyboard key
scrollselector or value (pixels)Scroll to element or by pixels
hoverselectorHover over element
evaluatevalueRun JavaScript in the browser

CLI Usage

# Run tests
e2e-runner run --all                  # All suites in e2e/tests/
e2e-runner run --suite <name>         # Single suite
e2e-runner run --tests <file.json>    # Specific JSON file
e2e-runner run --inline '<json>'      # Inline JSON

# Pool management
e2e-runner pool start
e2e-runner pool stop
e2e-runner pool status

# Other
e2e-runner list                       # List available suites
e2e-runner init                       # Scaffold e2e/ directory

CLI Options

FlagDefaultDescription
--base-url <url>http://host.docker.internal:3000App base URL
--pool-url <ws-url>ws://localhost:3333Chrome pool WebSocket URL
--tests-dir <dir>e2e/testsTests directory
--screenshots-dir <dir>e2e/screenshotsScreenshots directory
--concurrency <n>3Parallel test workers
--timeout <ms>10000Action timeout
--retries <n>0Retry failed tests N times
--retry-delay <ms>1000Delay between retries
--test-timeout <ms>60000Per-test timeout
--output <format>jsonReport format: json, junit, both
--env <name>defaultEnvironment profile
--pool-port <port>3333Chrome pool port
--max-sessions <n>5Max pool sessions

Configuration

Create e2e.config.js in your project root:

export default {
  baseUrl: 'http://host.docker.internal:3000',
  concurrency: 3,
  retries: 2,
  testTimeout: 30000,
  outputFormat: 'both',

  hooks: {
    beforeEach: [{ type: 'goto', value: '/' }],
    afterEach: [{ type: 'screenshot', value: 'after-test.png' }],
  },

  environments: {
    staging: { baseUrl: 'https://staging.example.com' },
    production: { baseUrl: 'https://example.com', concurrency: 5 },
  },
};

Priority (highest to lowest): CLI flags > env vars > config file > defaults.

Suite JSON with Hooks

Suites support an object format with per-suite hooks:

{
  "hooks": {
    "beforeAll": [{ "type": "goto", "value": "/login" }],
    "beforeEach": [{ "type": "goto", "value": "/" }]
  },
  "tests": [
    { "name": "test-1", "actions": [] }
  ]
}

The plain array format still works for backward compatibility.

Per-Test Overrides

Individual tests can override global retry and timeout settings:

{
  "name": "flaky-test",
  "retries": 3,
  "timeout": 15000,
  "actions": []
}

Environment Variables

VariableMaps to
BASE_URLbaseUrl
CHROME_POOL_URLpoolUrl
CONCURRENCYconcurrency
DEFAULT_TIMEOUTdefaultTimeout
RETRIESretries
RETRY_DELAYretryDelay
TEST_TIMEOUTtestTimeout
OUTPUT_FORMAToutputFormat
E2E_ENVenv

Programmatic API

import { createRunner } from '@matware/e2e-runner';

const runner = await createRunner({ baseUrl: 'http://localhost:3000' });
const report = await runner.runAll();
// or: runner.runSuite('auth')
// or: runner.runFile('path/to/tests.json')
// or: runner.runTests([{ name: 'test', actions: [...] }])

Requirements

  • Docker
  • A running Chrome pool (browserless/chrome)

License

Copyright 2025 Matias Aguirre (fastslack)

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Tag summary

Content type

Image

Digest

sha256:3e7acfff8

Size

59.8 MB

Last updated

7 months ago

docker pull fastslack/e2e-runner:0.1.0