Skip to content
CI/CDDoc

Bring Your Test Framework

Push results from Playwright, Cypress, Jest, Vitest, pytest, and any framework that emits JUnit XML.

Certyn ingests results from the tests you already run in CI. Two report formats cover almost every framework:

  • Playwright JSON (format=playwright): read natively, including retry and attachment detail.
  • JUnit XML (format=junit): the lingua franca almost every test runner can emit.

Point your existing suite at POST /api/ci/results and each run lands next to your agent runs, with pass and fail history per test. Failing runs are triaged automatically: flaky vs regression, grouped by root cause.

No format query? Certyn sniffs it

If you omit format, Certyn detects it from the first byte: a leading < is treated as JUnit XML, otherwise Playwright JSON. Passing format explicitly is still recommended.

Framework matrix

FrameworkFormatEmit the report
Playwrightplaywrightnpx playwright test --reporter=json > report.json
Cypressjunit--reporter junit (or cypress-multi-reporters + mocha-junit-reporter)
Jestjunitjest-junit reporter → junit.xml
Vitestjunitvitest run --reporter=junit --outputFile=junit.xml
Mochajunitmocha --reporter mocha-junit-reporter
pytestjunitpytest --junitxml=junit.xml
PHPUnitjunitphpunit --log-junit junit.xml
Go (gotestsum)junitgotestsum --junitfile junit.xml
JUnit / TestNGjunitnative XML report
NUnit / xUnitjunittrx2junit, or a JUnit logger

Anything not listed works too as long as it can produce JUnit XML.

Push a report

Create an API key with the ci:results scope in Settings -> API Keys and store it as a CI secret. A key that only has ci:trigger cannot upload results.

Run your tests, then upload the report. Use continue-on-error (or || true) so a failing test suite still uploads its results.

# JUnit XML from any framework
curl -sS -X POST \
  "$CERTYN_API_URL/api/ci/results?projectSlug=$PROJECT_SLUG&suite=e2e&environmentKey=staging&format=junit" \
  -H "X-API-Key: $CERTYN_API_KEY" \
  -H "Idempotency-Key: $CI_RUN_ID" \
  --data-binary @junit.xml
# Playwright JSON
curl -sS -X POST \
  "$CERTYN_API_URL/api/ci/results?projectSlug=$PROJECT_SLUG&suite=e2e&environmentKey=staging&format=playwright" \
  -H "X-API-Key: $CERTYN_API_KEY" \
  -H "Idempotency-Key: $CI_RUN_ID" \
  --data-binary @report.json

The first upload for a suite slug auto-creates an automation process for it; later uploads append to its history.

Sharded Playwright

Running Playwright across shards produces one report per shard. Merge them into a single blob report first (npx playwright merge-reports) and upload once, so a commit maps to one run rather than one per shard.

Optional query parameters

Pass these so a result links back to the change that produced it:

  • repository, ref, commitSha: the source under test.
  • event: e.g. push, pull_request, pipeline.
  • externalUrl: a link back to the CI run.

See Push results for the full parameter list, the response shape, and error codes.

What you get back

Once results are flowing, the suite behaves like any other process in Certyn:

  • its runs appear in the project's run list, next to agent runs and scheduled suites
  • each test carries its own pass rate, flaky rate, and duration over time
  • failures are triaged as flaky or regression rather than dumped as a list
  • release readiness counts these runs, so a red CI suite blocks the ship call

See Release Readiness for how the signals combine.