Skip to content

Repository files navigation

Tests

Flakiness Node.js SDK

The Flakiness SDK provides a comprehensive set of tools for creating and managing Flakiness JSON Reports in Node.js.

Installation

npm i @flakiness/sdk @flakiness/flakiness-report

Requires Node.js ^20.17.0 or >=22.9.0.

Quick Start

Here's a minimal example of creating a Flakiness JSON Report:

import { FlakinessReport } from '@flakiness/flakiness-report';
import {
  GitWorktree,
  ReportUtils,
  writeReport,
  uploadReport,
  CIUtils 
} from '@flakiness/sdk';

// Initialize git worktree and environment
const result = GitWorktree.initialize(process.cwd());
if (!result.ok)
  throw new Error(result.error);
const { worktree, commitId } = result;
const env = ReportUtils.createEnvironment({ name: 'CI' });

// Create a simple test report
const report: FlakinessReport.Report = {
  category: 'testreport',
  commitId,
  title: process.env.FLAKINESS_TITLE,
  url: CIUtils.runUrl(),
  environments: [env],
  suites: [{
    title: 'My Test Suite',
    type: 'describe',
    tests: [{
      title: 'My Test',
      location: { file: 'test.spec.ts', line: 10, column: 1 },
      attempts: [{
        environmentIdx: 0,
        status: 'passed',
        expectedStatus: 'passed',
        duration: 100 as FlakinessReport.DurationMS,
      }],
    }],
  }],
  startTimestamp: Date.now() as FlakinessReport.UnixTimestampMS,
  duration: 100 as FlakinessReport.DurationMS,
};

// Write report to disk or upload to Flakiness.io
await writeReport(report, [], './flakiness-report');
// Or: await uploadReport(report, [], { flakinessAccessToken: 'your-token' });

Entry Points

The SDK provides two entry points:

@flakiness/sdk

The main entry point for Node.js environments. Provides full access to all SDK functionality including:

  • Git repository utilities
  • File system operations
  • System resource monitoring
  • Report upload/download
  • Local report viewing

@flakiness/sdk/browser

A browser-compatible entry point with a subset of utilities that work in browser environments. Exports:

  • ReportUtils - Browser-safe utilities (normalizeReport, stripAnsi, visitTests)

Use this entry point when you need to process or manipulate reports in browser-based tools or web applications.

Top-Level Exports

Building Reports

  • CIUtils - Utilities to extract CI/CD information (run URLs, run titles, environment detection)
  • GithubOIDC - GitHub Actions OIDC integration for passwordless Flakiness.io authentication
  • GitlabOIDC - GitLab CI/CD OIDC integration for passwordless Flakiness.io authentication
  • initializeOIDCFromEnv() - Detect the OIDC provider for the current CI environment
  • GitWorktree - Git repository utilities for path conversion and commit information
  • ReportUtils - Namespace with utilities for report creation and manipulation:
    • createEnvironment() - Create environment objects with system information
    • detectRuntime() - Detect the JS runtime (node / bun / deno) and its version; suitable for Report.runtime
    • normalizeReport() - Deduplicate environments, suites, and tests
    • collectSources() - Extract source code snippets for locations in the report
    • stripAnsi() - Remove ANSI escape codes from strings
    • visitTests() - Recursively visit all tests in a report
    • createFileAttachment() / createDataAttachment() - Create report attachments
  • CPUUtilization - Track CPU utilization over time via periodic sampling
  • RAMUtilization - Track RAM utilization over time via periodic sampling

Working with Reports

  • readReport() - Read a Flakiness report and its attachments from disk
  • fetchTestDurations() - Fetch historical test durations from Flakiness.io and return a report enriched with timings
  • showReport() - Start a local server and open the report in your browser
  • showReportCommand() - Build a shell command for opening the report later with the Flakiness CLI
  • showReportMessage() - Build the message a runner prints after writing a report (CI-aware: a one-liner with the report path on CI, open-in-CLI instructions otherwise)
  • uploadReport() - Upload reports and attachments to Flakiness.io
  • writeReport() - Write reports to disk in the standard Flakiness report format

Fetching Test Durations

fetchTestDurations() sends a report to Flakiness.io and returns a copy enriched with historical test durations. Test runners can use these timings to split tests into balanced shards.

import { fetchTestDurations } from '@flakiness/sdk';

const reportWithDurations = await fetchTestDurations(report, {
  flakinessAccessToken: 'your-token',
});

Authentication follows the same priority order as uploadReport():

  1. Access token — pass flakinessAccessToken option or set the FLAKINESS_ACCESS_TOKEN environment variable.
  2. GitHub Actions OIDC — when running inside GitHub Actions and the report has flakinessProject set.
  3. GitLab CI/CD OIDC — when running inside GitLab CI/CD with a FLAKINESS_ID_TOKEN ID token and the report has flakinessProject set.

Uploading Reports

uploadReport() authenticates using one of the following methods (in order of priority):

  1. Access token — pass flakinessAccessToken option or set the FLAKINESS_ACCESS_TOKEN environment variable.

  2. GitHub Actions OIDC — when running inside GitHub Actions, uploadReport can authenticate automatically without an access token. This works when both conditions are met:

    • The report has flakinessProject set to a flakiness project identifier (e.g. "org/proj").
    • The flakiness project is bound to the GitHub repository that runs the action.

    Your GitHub Actions workflow must grant the id-token: write permission:

    permissions:
      id-token: write
    const report: FlakinessReport.Report = {
      flakinessProject: 'my-org/my-project',
      // ... rest of the report
    };
    // No access token needed — OIDC authentication is used automatically.
    await uploadReport(report, attachments);
  3. GitLab CI/CD OIDC — when running inside GitLab CI/CD, uploadReport can authenticate automatically without an access token. This works when these conditions are met:

    • The report has flakinessProject set to a flakiness project identifier (e.g. "org/proj").
    • The flakiness project is bound to the GitLab project that runs the pipeline.
    • The job declares a FLAKINESS_ID_TOKEN ID token whose audience is that same project identifier.

    GitLab mints ID tokens when the job starts, so — unlike GitHub Actions, where the SDK picks the audience at runtime — the audience is declared in .gitlab-ci.yml:

    test:
      id_tokens:
        FLAKINESS_ID_TOKEN:
          aud: my-org/my-project
      script:
        - npm test

    aud expands CI/CD variables (GitLab 16.1+), so a shared pipeline template can use aud: $FLAKINESS_PROJECT and let each project set that variable in its CI/CD settings.

If none of these methods is available, the upload is skipped with a 'skipped' status.

Resolving OIDC credentials directly

uploadReport() and fetchTestDurations() do this for you. Tools that manage credentials themselves can run the same detection with initializeOIDCFromEnv(), which returns the provider for the current CI environment (GitHub Actions first, then GitLab CI/CD) or undefined:

import { initializeOIDCFromEnv } from '@flakiness/sdk';

const oidc = initializeOIDCFromEnv();
if (oidc) {
  console.log(`Authenticating via ${oidc.name} OIDC`);
  const flakinessAccessToken = await oidc.createFlakinessAccessToken('my-org/my-project');
}

oidc.name is for humans; use oidc instanceof GithubOIDC to branch on the provider.

About

Official Node.js SDK to build Flakiness JSON Reports

Resources

Contributing

Stars

1 star

Watchers

1 watching

Forks

Releases

Packages

Used by

Contributors

Languages