Merging Reports
When running tests in parallel — Playwright shards or Appium/WDIO multi-worker runs — each shard or worker generates its own TestRelic report. You can merge these into a single comprehensive report.
Merging gives you:
- A complete view of all tests across all shards/workers
- Unified timeline showing all navigations or device sessions
- Aggregated summary statistics
- Single file for analysis and upload
How do I merge reports?
- For AI agents
- For Human
Merge with an AI assistant
Playwright — shard merge:
I have TestRelic shard reports in ./test-results/ named shard-1.json, shard-2.json,
shard-3.json, and shard-4.json.
Show me the CLI command to merge them into ./test-results/merged-analytics.json
using npx testrelic merge.
Write a Node.js script that uses mergeReports from '@testrelic/playwright-analytics/merge'
to merge:
./test-results/shard-1/analytics.json
./test-results/shard-2/analytics.json
./test-results/shard-3/analytics.json
Output to ./test-results/merged-analytics.json. Use top-level async/await.
Write a GitHub Actions workflow that:
1. Runs Playwright tests across 4 shards in a matrix strategy
2. Uploads each shard's analytics-timeline.json as an artifact
3. In a separate merge job (needs: test), downloads all artifacts and runs:
npx testrelic merge <all four shard files> -o merged-analytics.json
4. Uploads the merged report as an artifact
Show me the complete workflow YAML.
Appium / WDIO — multi-worker merge:
I have TestRelic Appium reports at:
./test-results/report-worker-1.json
./test-results/report-worker-2.json
Show me the CLI command to merge them using npx testrelic-appium merge.
Write a Node.js script that uses mergeReports from '@testrelic/appium-analytics/merge'
to merge ./test-results/report-1.json and ./test-results/report-2.json
into ./test-results/merged.json. Use top-level async/await.
- Playwright
- Appium / WDIO
Why merge Playwright shards?
Sharding distributes tests across multiple workers or machines for faster execution:
npx playwright test --shard=1/4 # Machine 1
npx playwright test --shard=2/4 # Machine 2
npx playwright test --shard=3/4 # Machine 3
npx playwright test --shard=4/4 # Machine 4
Each shard writes its own analytics-timeline.json. Merge them into one file for a complete view.
CLI merge
npx testrelic merge \
./test-results/shard-1/analytics.json \
./test-results/shard-2/analytics.json \
./test-results/shard-3/analytics.json \
-o ./test-results/merged-analytics.json
Available options:
npx testrelic merge <input-files...> [options]
Options:
-o, --output <path> Output file path (required)
-h, --help Display help
Programmatic merge
import { mergeReports } from '@testrelic/playwright-analytics/merge';
await mergeReports(
[
'./test-results/shard-1/analytics.json',
'./test-results/shard-2/analytics.json',
'./test-results/shard-3/analytics.json',
],
{ output: './test-results/merged-analytics.json' }
);
API signature:
async function mergeReports(
inputPaths: string[],
options: { output: string }
): Promise<void>
inputPaths— Array of file paths to shard JSON reportsoptions.output— Output path for the merged report file- Returns:
Promise<void>— resolves when the merged file has been written - Throws:
Errorif any input file cannot be read, fails schema validation, or the output path is not writable
GitHub Actions shard merge workflow
name: Test with Sharding
on: [push]
jobs:
test:
runs-on: ubuntu-latest
strategy:
matrix:
shard: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
- run: npm ci
- run: npx playwright install
- run: npx playwright test --shard=${{ matrix.shard }}/4
- uses: actions/upload-artifact@v3
with:
name: shard-${{ matrix.shard }}-report
path: test-results/analytics-timeline.json
merge:
needs: test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/download-artifact@v3
with:
path: artifacts
- run: |
npx testrelic merge \
artifacts/shard-1-report/analytics-timeline.json \
artifacts/shard-2-report/analytics-timeline.json \
artifacts/shard-3-report/analytics-timeline.json \
artifacts/shard-4-report/analytics-timeline.json \
-o merged-analytics.json
- uses: actions/upload-artifact@v3
with:
name: merged-report
path: merged-analytics.json
Why merge Appium worker reports?
When running WDIO with maxInstances > 1, each worker writes its own JSON report. Merge them into one timeline for a complete view.
CLI merge
npx testrelic-appium merge \
./test-results/report-worker-1.json \
./test-results/report-worker-2.json \
-o ./test-results/merged.json
Programmatic merge
import { mergeReports } from '@testrelic/appium-analytics/merge';
await mergeReports(
['./test-results/report-1.json', './test-results/report-2.json'],
{ output: './test-results/merged.json' }
);
What does the merged report look like?
The merged report combines data from all shards/workers:
{
"schemaVersion": "1.0.0",
"testRunId": "original-run-id",
"startedAt": "2026-02-07T10:00:00.000Z",
"completedAt": "2026-02-07T10:15:00.000Z",
"totalDuration": 900000,
"summary": {
"total": 100,
"passed": 95,
"failed": 3,
"flaky": 2,
"skipped": 0
},
"ci": { /* CI metadata from first shard */ },
"timeline": [ /* Combined, sorted chronologically */ ]
}
How does the merge handle each field?
- Timeline — All entries are combined and sorted chronologically by
visitedAt - Summary — Test counts are aggregated across shards/workers
- Duration —
totalDurationreflects wall-clock elapsed time (latestcompletedAtminus earlieststartedAt) - Timestamps —
startedAtis the earliest,completedAtis the latest - Test Run ID — Taken from the first shard; configure a consistent
testRunIdin your reporter options so all shards share the same ID - CI Metadata — Taken from the first shard
How does TestRelic validate the merged report?
After merging, TestRelic validates the merged report to ensure:
- Schema version compatibility
- Timeline chronological order
- Summary statistics correctness
If validation fails, the merge operation throws an error with details.