Appearance
easytrace.config.json
One file at the repository root tells the CLI which project to upload to and which report files form which suite. It contains no secret: commit it, so every developer and CI upload the same suites.
Example
json
{
"project": "01933c2e-5f0a-7cc1-9a4e-2b1d9f3e6a10",
"apiUrl": "https://api.easytrace.dev",
"suites": {
"server": {
"reports": "apps/server/.easytrace/vitest.json",
"coverage": "apps/server/coverage/coverage-final.json"
},
"unit": {
"reports": ["packages/*/.easytrace/vitest.json", "apps/web/.easytrace/vitest.json"]
},
"e2e": {
"reports": ".easytrace/playwright.json",
"attachments": "test-results"
}
}
}Fields
| Field | Required | Meaning |
|---|---|---|
project | With easytrace login | Project id the login uploads to. Ignored when a project token is used (the token decides the project). --project overrides it. |
apiUrl | No | EasyTrace API. Default https://api.easytrace.dev. --api-url and EASYTRACE_API_URL override it — set it here when the whole team uses a self-hosted instance. |
suites | Yes, at least one | Suite name → where its files are. Names: 1–40 characters of a-z, 0-9, ., _, -. |
suites.<name>.reports | Yes | Report file(s) or glob(s), a string or a list. Every matching file goes into one run. |
suites.<name>.format | No | auto (default: detected from content), vitest-json, jest-json, playwright-json, mochawesome, junit. |
suites.<name>.coverage | No | Istanbul coverage-final.json / coverage-summary.json file(s) or glob(s); merged. Vitest and Jest suites only. |
suites.<name>.attachments | No | Folder(s) with the screenshots, videos and traces the report refers to (e.g. Playwright's test-results). |
- Paths are relative to the folder containing the config file.
- The CLI looks for the file from the current directory up to the git root, so commands work from any sub-folder.
- There is no build id in the file: a build belongs to one invocation, not to the repository.
- Unknown fields are ignored with a warning. Invalid JSON or a missing required field prints
EasyTrace: easytrace.config.json is invalid: …and uploads nothing. - Suites are uploaded in the order they are declared.
Choosing suites
- One suite per package (
server,web,ui…) gives each package its own history, pass rate and coverage in the dashboard. - One suite for several packages (
unitwith a glob) gives a single run per build — simpler, but one coverage figure and one history for all of them. - Keep unit and end-to-end tests in separate suites: they have different speeds, flakiness and artifacts.
Renaming a suite starts a new history for it.
easytrace init
init writes the file for you:
bash
easytrace init # interactive
easytrace init --project <id> \
--suite unit=packages/*/.easytrace/vitest.json \
--coverage unit=coverage/coverage-final.json # no questions (scripts, CI images)- Project: with
easytrace login, it lists your organizations and their projects to pick from (skipped when there is only one).--project <id>skips this and needs no login. No project yet → create one in the dashboard first. - Suites: suggested from
package.jsondependencies of the root and the workspaces —vitest→unitwith.easytrace/vitest.jsonper workspace pattern,@playwright/test→e2ewithtest-resultsattachments,jest→unit. Accept, add coverage, or add your own suites. - It prints the command that makes each detected runner write its report and reminds you to ignore
.easytrace/.
An existing file is only replaced after confirmation, or with --force. Re-running init keeps the file's apiUrl unless --api-url is passed. Suites are rewritten from the answers, so review the diff before committing.
| Option | |
|---|---|
--project <id> | Skip the organization/project questions |
--suite <name>=<glob> | Declare a suite without questions (repeatable) |
--coverage <name>=<file> | Coverage for suite <name> (repeatable) |
--api-url <url> | Write apiUrl |
--force | Overwrite an existing file |