Skip to content

Vitest integration

Blop ships a first-party Vitest reporter that streams run results to Blop Cloud using the same CloudEvents protocol as the blop CLI. This gives you counts, top failures, CI metadata, and a report-bundle artifact in the blop dashboard — for any vitest suite, browser or otherwise.

Terminal window
pnpm add -D @blopai/ingest

Add the reporter to your vitest.config.ts:

import { defineConfig } from "vitest/config";
export default defineConfig({
test: {
reporters: ["default", "@blopai/ingest/vitest"],
},
});

That’s it — no other config in the file. The reporter reads everything from environment variables.

.github/workflows/test.yml
name: Tests
on: [pull_request, push]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- run: pnpm install
- name: Run vitest
run: pnpm test
env:
BLOP_INGEST_URL: ${{ vars.BLOP_INGEST_URL }}
BLOP_INGEST_SECRET: ${{ secrets.BLOP_INGEST_SECRET }}
BLOP_PROJECT_ID: ${{ vars.BLOP_PROJECT_ID }}
Variable Required Role
BLOP_INGEST_URL yes Platform ingest endpoint (e.g. https://app.blop.ai/api/ingest)
BLOP_INGEST_SECRET yes Per-project ingest secret
BLOP_PROJECT_ID yes Project id the run belongs to
BLOP_RUN_ID no Run id (auto-generated if unset)
BLOP_TRIGGER no Trigger source: ci | manual | schedule | healer_verify

When BLOP_INGEST_URL or BLOP_INGEST_SECRET is unset, the reporter silently no-ops — it never breaks your test run.

  • onInit → emits qa.run.started.v1 (creates the run row on the platform, marks it running).
  • onFinished → computes counts (passed/failed/skipped/flaky) from the test modules, collects top 25 failures (message capped at 2000 chars), uploads a vitest-report.json artifact if R2 is configured, and emits qa.run.finished.v1.

CI metadata (branch, commit_sha, ci_url) is attached automatically on GitHub Actions. See CI integration for the full env reference.