Jest
npm install @tracera/jest
Tested on Node.js 22.19–26.12 and Jest 30–30.5 (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'],
};
Environment variables, run mode, and retries: Autotest adapters.
Retry Env key: JEST_RETRY.
Bind testCaseId and autotestName
Import test, expect, and hooks from @jest/globals (or use Jest-injected globals), and tracera, annotations, and skip from @tracera/jest. Load @tracera/jest/setup so steps and bind work with stock Jest APIs.
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
If you already know the test should be skipped — use test.skip or describe.skip. If the skip condition is computed inside the test — use skip from this package: Jest has no test.skip(reason).
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: the call tracera.step(title, fn), @tracera.step("…") on a class method, or tracera.step("…")(fn). In a decorator title, {name} / {0} are filled from the method arguments; you can also pass a function that returns the title. In the call form, {name} / {0} are not filled in — pass a finished title string (or build it yourself). Async methods and Promises are awaited. Stock beforeEach / afterEach from @jest/globals are instrumented: steps inside them go to the result’s Setup / Teardown. Suite-level hooks such as beforeAll / afterAll are not reported.
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 () => {
// …
});
});
Decorator on a method:
import { tracera } from '@tracera/jest';
class Cart {
@tracera.step('add {item}')
async addToCart(item: string) {
// …
}
}
Comments, errors, and attachments
Comments, errors, and attachments: Autotest adapters.
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'),
});
});
});
Parameterized tests
With test.each, wrap the callback: annotations(id, 'login as {login}', fn) so fields from the row object fill {login} and similar placeholders.
import { test, expect } from '@jest/globals';
import { annotations } from '@tracera/jest';
test.each([{ login: 'ok' }, { login: 'sso' }])(
'login as $login',
annotations(42, 'login as {login}', async ({ login }) => {
expect(login).toBeTruthy();
}),
);