Skip to content

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 ​

FieldRequiredMeaning
projectWith easytrace loginProject id the login uploads to. Ignored when a project token is used (the token decides the project). --project overrides it.
apiUrlNoEasyTrace 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.
suitesYes, at least oneSuite name → where its files are. Names: 1–40 characters of a-z, 0-9, ., _, -.
suites.<name>.reportsYesReport file(s) or glob(s), a string or a list. Every matching file goes into one run.
suites.<name>.formatNoauto (default: detected from content), vitest-json, jest-json, playwright-json, mochawesome, junit.
suites.<name>.coverageNoIstanbul coverage-final.json / coverage-summary.json file(s) or glob(s); merged. Vitest and Jest suites only.
suites.<name>.attachmentsNoFolder(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 (unit with 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)
  1. 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.
  2. Suites: suggested from package.json dependencies of the root and the workspaces — vitest → unit with .easytrace/vitest.json per workspace pattern, @playwright/test → e2e with test-results attachments, jest → unit. Accept, add coverage, or add your own suites.
  3. 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
--forceOverwrite an existing file