TestHarbor is a local-first test telemetry stack with API, ingest, worker, and browser surfaces.
- Start the stack with
docker compose up -d postgres redis minio ingest api worker web. - Apply migrations with
npm run db:migrate:container. - Seed a baseline workspace and project with
npm run seed:localor create your own from the browser. - Open
http://localhost:3000/login. - Use
/app/onboardingto create/select workspace + project. - Mint a project ingest token from onboarding/connect and copy it immediately (raw token is shown once).
- Use the Cypress-first snippet to emit
run.startedand verify ingestion. - Use
/app/connectfor API/ingest/worker status and notification test events. - Use
/app/team,/app/runs,/app/runs/:id,/app/tests/:id/history,/app/artifacts/:id, and/app/adminfor day-to-day operation.
- API routes:
GET|POST /v1/projects/:id/ingest-tokens,PATCH /v1/projects/:id/ingest-tokens/:tokenId,POST /v1/projects/:id/ingest-tokens/:tokenId/revoke - Stored fields are hash + hint only (
token_hash,token_hint); plaintext token is only returned on create. - Ingest auth accepts either:
- global
INGEST_AUTH_TOKEN - active project token scoped to the run/project context.
- global
Token issue (admin/member with workspace access):
curl -X POST "http://localhost:4000/v1/projects/<projectId>/ingest-tokens" \
-H "Authorization: Bearer <api-token>" \
-H "Content-Type: application/json" \
-d '{"label":"cypress-ci","ttlDays":90}'Use returned token as TESTHARBOR_INGEST_TOKEN in Cypress reporter configuration.
Generate parity artifacts and static verifier output:
npm run parity:packOptional HTML capture for key shell pages:
TH_PARITY_WEB_BASE_URL=http://localhost:3000 \
TH_AUTH_TOKEN='<session-token-from-/v1/auth/login>' \
npm run parity:packArtifacts are written to artifacts/parity/ (manifest + static verify log + optional HTML captures).
npm run smoke:allfor API and ingest basicsnpm run smoke:auth-explorerfor auth, artifacts, analytics, and explorer routesnpm run smoke:web-shellfor the browser shell flownpm run smoke:webhooks:suitefor webhook delivery behavior
Run this single command to bring up TestHarbor locally, run migrations, and seed baseline data:
npm run activate:localThis is the recommended "get to green" path when you just want local parity-ready services running. If you want a full smoke validation immediately after activation, run:
npm run smoke:allOr run a full clean reset + activation + smoke in one command:
npm run activate:local:cleanUse the reporter helper with only projectId in your Cypress config. Token and ingest URL stay in env and are pulled automatically.
const { withTestHarborCypress } = require("@testharbor/cypress-reporter");
module.exports = defineConfig({
e2e: {
setupNodeEvents: withTestHarborCypress({
projectId: process.env.TESTHARBOR_PROJECT_ID, // required: paste this in config
}),
},
});Recommended env for runtime:
export TESTHARBOR_INGEST_URL="http://localhost:4010/v1/ingest/events"
export TESTHARBOR_INGEST_TOKEN="<project-ingest-token>"If your project uses non-local branch/commit details, pass them directly:
withTestHarborCypress({
projectId: 'your-testharbor-project-id',
branch: 'main',
commitSha: process.env.GIT_COMMIT,
runId: process.env.CI_RUN_ID,
})