Jest

npm install @tracera/jest

Requires Node.js ≥ 22.19 (see Autotest adapters). @tracera/jest on npm.

In jest.config.cjs (or your Jest config):

module.exports = {
  testEnvironment: 'node',
  setupFilesAfterEnv: ['@tracera/jest/setup'],
  reporters: ['default', '@tracera/jest/reporter'],
};

Only the final Jest attempt is reported when retries are enabled. If that attempt is a retry (retry > 0), the result Env tab includes JEST_RETRY (1 is the second run).

Environment variables and run mode: Autotest adapters.

Bind testCaseId and autotestName

Import test / expect / hooks from @jest/globals (or use Jest-injected globals), and tracera / annotations / skip from @tracera/jest. @tracera/jest/setup instruments the runner so steps and bind work with stock Jest APIs. If you omit autotestName, the adapter uses the Jest test title.

At declaration (preferred — bind runs even if the body skips early):

import { test, expect } from '@jest/globals';
import { annotations } from '@tracera/jest';

test(
  'login',
  annotations(42, 'e2e/login', async () => {
    expect(true).toBe(true);
  }),
);

Inside the test (optional if annotations already bind the case):

import { test, expect } from '@jest/globals';
import { tracera } from '@tracera/jest';

test('login', async () => {
  tracera.testCase(42, 'e2e/login');
  expect(true).toBe(true);
});

Skip

Prefer not entering the body when the decision is known up front (test.skip, or skip before the suite). Jest has no mid-body test.skip(reason) — use skip from this package:

import { test } from '@jest/globals';
import { annotations, skip } from '@tracera/jest';

test(
  'login',
  annotations(42, 'e2e/login', () => {
    if (!process.env.READY) skip('env not ready');
    // …
  }),
);

Steps

Use tracera.step. Stock beforeEach / afterEach from @jest/globals are instrumented: steps inside them go to Setup / Teardown.

import { test, beforeEach, afterEach } from '@jest/globals';
import { tracera } from '@tracera/jest';

beforeEach(async () => {
  await tracera.step('open shop', async () => {
    // …
  });
});

test('checkout', async () => {
  tracera.testCase(10, 'e2e/checkout');
  await tracera.step('add to cart', async () => {
    // …
  });
});

afterEach(async () => {
  await tracera.step('cleanup', async () => {
    // …
  });
});

Comments, errors, and attachments

Inside a step — fields on that step. Outside a step — fields on the result. Use tracera.attachment for files (at most 10 on the result and on each step).

import { test } from '@jest/globals';
import { tracera } from '@tracera/jest';

test('login', async () => {
  tracera.testCase(42, 'e2e/login');
  tracera.comment('result-level note');
  tracera.error('result-level error text');

  await tracera.step('open login', async () => {
    tracera.comment('landed on login');
    tracera.attachment({
      fileName: 'suite-log.txt',
      mimeType: 'text/plain',
      data: new TextEncoder().encode('finished login flow'),
    });
  });
});