JSON-driven E2E test runner with parallel execution via Puppeteer and Chrome pool
194
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.
docker pull fastslack/e2e-runner:latest
# 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
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" }
]
}
]
| Action | Fields | Description |
|---|---|---|
goto | value | Navigate to URL (relative to baseUrl or absolute) |
click | selector or text | Click element by CSS selector or visible text |
type / fill | selector, value | Clear field and type text |
wait | selector, text, or value (ms) | Wait for element, text, or delay |
assert_text | text | Assert text exists on page |
assert_url | value | Assert current URL contains value |
assert_visible | selector | Assert element is visible |
assert_count | selector, value | Assert element count matches |
screenshot | value (filename) | Take a screenshot |
select | selector, value | Select dropdown option |
clear | selector | Clear an input field |
press | value | Press a keyboard key |
scroll | selector or value (pixels) | Scroll to element or by pixels |
hover | selector | Hover over element |
evaluate | value | Run JavaScript in the browser |
# 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
| Flag | Default | Description |
|---|---|---|
--base-url <url> | http://host.docker.internal:3000 | App base URL |
--pool-url <ws-url> | ws://localhost:3333 | Chrome pool WebSocket URL |
--tests-dir <dir> | e2e/tests | Tests directory |
--screenshots-dir <dir> | e2e/screenshots | Screenshots directory |
--concurrency <n> | 3 | Parallel test workers |
--timeout <ms> | 10000 | Action timeout |
--retries <n> | 0 | Retry failed tests N times |
--retry-delay <ms> | 1000 | Delay between retries |
--test-timeout <ms> | 60000 | Per-test timeout |
--output <format> | json | Report format: json, junit, both |
--env <name> | default | Environment profile |
--pool-port <port> | 3333 | Chrome pool port |
--max-sessions <n> | 5 | Max pool sessions |
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.
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.
Individual tests can override global retry and timeout settings:
{
"name": "flaky-test",
"retries": 3,
"timeout": 15000,
"actions": []
}
| Variable | Maps to |
|---|---|
BASE_URL | baseUrl |
CHROME_POOL_URL | poolUrl |
CONCURRENCY | concurrency |
DEFAULT_TIMEOUT | defaultTimeout |
RETRIES | retries |
RETRY_DELAY | retryDelay |
TEST_TIMEOUT | testTimeout |
OUTPUT_FORMAT | outputFormat |
E2E_ENV | env |
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: [...] }])
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.
Content type
Image
Digest
sha256:3e7acfff8…
Size
59.8 MB
Last updated
7 months ago
docker pull fastslack/e2e-runner:0.1.0