npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

testera-sdk

v0.2.0

Published

Official TypeScript SDK for the Testera test-management API

Downloads

48

Readme

Testera TypeScript SDK

Official TypeScript/JavaScript client for the Testera test-management API. Fully typed, zero runtime dependencies, works in Node.js 18+ (and any runtime with fetch).

Installation

npm install testera-sdk

Quick start

import { TesteraClient } from "testera-sdk";

const testera = new TesteraClient({
  apiKey: process.env.TESTERA_API_KEY, // "tk_..." — create one under Settings > API Keys
});

const projects = await testera.projects.list();
console.log(projects.map((p) => p.name));

Or build the client from environment variables (TESTERA_API_BASE_URL, TESTERA_API_KEY, TESTERA_EMAIL, TESTERA_PASSWORD):

import { createClientFromEnv } from "testera-sdk";

const testera = createClientFromEnv();

Authentication

The SDK supports three credential styles, in order of recommendation:

| Method | Config | Notes | |--------|--------|-------| | API key | { apiKey: "tk_..." } | Best for CI and machine-to-machine integrations. | | Pre-issued JWT | { apiKey: "<jwt>" } | Any non-tk_ token is sent as a Bearer JWT. | | Email + password | { email, password } | The SDK logs in automatically and caches the JWT (7-day TTL). Accounts with MFA enabled must use an API key. |

All requests send Authorization: Bearer <token>. Tenant context is derived from the authenticated user — no extra headers needed.

Configuration

const testera = new TesteraClient({
  baseUrl: "http://localhost:3001/api", // default: https://app.testera.io/api
  apiKey: "tk_...",
  timeoutMs: 15_000,                    // default 30000; 0 disables
  defaultHeaders: { "X-My-Header": "1" },
  fetch: customFetch,                   // e.g. for proxies or testing
});

Resources

| Property | Endpoints covered | |----------|-------------------| | testera.projects | list, create, update, delete | | testera.testCases | list, create, update, assign, delete | | testera.testPlans | list, get, create, update, delete | | testera.testRuns | list, get, create, update, recordResults, updateAssignments, compare, compareEnvironments, archive, unarchive, delete | | testera.environments | list, get, create, update, delete | | testera.testLabels | list, create, update, delete | | testera.tasks | list, create, update, delete | | testera.documents | list, get, create, update, delete | | testera.users | me, updateMe, login, signup, changePassword, list, listAssignees, create, update, delete | | testera.apiKeys | list, create, rename, revoke |

Plus testera.health() and a raw testera.request(path, options) escape hatch for anything else (uploads, AI endpoints, audit logs, integrations, admin routes).

Examples

Create a test case

const testCase = await testera.testCases.create({
  title: "User can log in with valid credentials",
  project: "Web App", // project NAME, not ID
  priority: "High",
  category: "Functional",
  steps: [
    { step: "Navigate to /login", expectedResult: "Login form is shown" },
    { step: "Submit valid credentials", expectedResult: "Redirected to dashboard" },
  ],
});

Run a test plan and report results (e.g. from CI)

// 1. Start a run
const run = await testera.testRuns.create({
  name: `CI run ${new Date().toISOString()}`,
  projectId: project._id,
  testPlanId: plan._id,
  environmentId: staging._id, // optional
});

// 2. Report results (up to 100 per call) and finalize
await testera.testRuns.recordResults(
  run._id,
  [
    { testCaseId: "665f...", status: "passed" },
    { testCaseId: "6660...", status: "failed", notes: "Timeout on step 3" },
  ],
  { finalize: true },
);

Compare two runs

const diff = await testera.testRuns.compare(runA._id, runB._id);
for (const c of diff.cases) {
  if (c.change === "regressed") console.log(`REGRESSION: ${c.title}`);
}

Create a document (rich text or imported Markdown/HTML)

// Plain rich-text document
const doc = await testera.documents.create({
  title: "Release notes 1.2",
  content: "<h1>Release 1.2</h1><p>Highlights…</p>",
});

// Import an HTML file, preserving the original source
import { readFile } from "node:fs/promises";
const html = await readFile("User_Journey_Book.html", "utf8");
await testera.documents.create({
  title: "User Journey Book",
  sourceFormat: "html",
  rawSource: html,
  originalFileName: "User_Journey_Book.html",
});

// List omits bodies; fetch by ID for content/rawSource
const docs = await testera.documents.list({ q: "journey" });
const full = await testera.documents.get(docs[0]._id);

Filter and search

const myOpenTasks = await testera.tasks.list({ assignedTo: "me", done: false });
const stagingRuns = await testera.testRuns.list({
  environmentId: staging._id,
  archived: false,
  q: "smoke",
  limit: 50,
});

Error handling

Every non-2xx response throws a TesteraApiError with the HTTP status and parsed body:

import { TesteraApiError } from "testera-sdk";

try {
  await testera.projects.create({ name: "New Project" });
} catch (err) {
  if (err instanceof TesteraApiError) {
    if (err.isAuthError) {
      // 401 — invalid or missing token
    } else if (err.isSubscriptionRequired) {
      // 402 — active subscription needed for writes
    } else if (err.isForbidden) {
      // 403 — insufficient role (Viewer vs Editor/Admin)
    }
    console.error(err.status, err.message, err.body?.code);
  }
}

Common error codes in err.body.code: email_not_verified, seat_limit_reached, google_auth_required, mfa_session_invalid.

Roles and permissions

Testera roles gate write access:

  • Viewer — read-only.
  • Editor — create/update/delete projects, test cases, plans, and runs.
  • Admin — everything, plus environments, labels, users, integrations, and audit logs. Only Admins see secret environment variable values (environments.list({ revealSecrets: true })).

Most write endpoints also require an active subscription (402 otherwise).

Development

npm install
npm run typecheck   # tsc --noEmit
npm test            # vitest
npm run build       # tsup → dist/ (ESM + CJS + .d.ts)

License

MIT