Cypress
npm install @tracera/cypress
Tested on Node.js 22.19–26.12 and Cypress 14–16.2 (see Autotest adapters). @tracera/cypress on npm.
In cypress.config.ts:
import { defineConfig } from 'cypress';
import { registerTraceraPlugin } from '@tracera/cypress';
export default defineConfig({
e2e: {
setupNodeEvents(on, config) {
return registerTraceraPlugin(on, config);
},
supportFile: 'cypress/support/e2e.ts',
},
});
In the support file:
import '@tracera/cypress/support';
For Component Testing, call registerTraceraPlugin from component.setupNodeEvents and import the same support entry from the component testing support file.
Environment variables, run mode, and retries: Autotest adapters.
Retry Env key: CYPRESS_RETRY.
Bind testCaseId and autotestName
Import tracera and annotations from @tracera/cypress/runtime, or use cy.traceraTestCase in tests (the command is available once import '@tracera/cypress/support' is in the support file). Annotation names are literal (no {param}).
At declaration (preferred — bind runs even if you this.skip() early):
import { annotations } from '@tracera/cypress/runtime';
it('login', annotations(42, 'e2e/login'), () => {
cy.visit('/login');
cy.get('[data-testid=sign-in]').should('be.visible');
});
Inside the test (optional if annotations already bind the case):
import { tracera } from '@tracera/cypress/runtime';
it('login', () => {
tracera.testCase(42, 'e2e/login');
cy.visit('/login');
cy.get('[data-testid=sign-in]').should('be.visible');
});
Or: cy.traceraTestCase(42, "e2e/login").
Skip
Use stock Cypress skip (this.skip()). Optional: set a result comment with tracera.comment before calling skip.
import { tracera, annotations } from '@tracera/cypress/runtime';
it('login', annotations(42, 'e2e/login'), function () {
if (!Cypress.env('READY')) {
tracera.comment('env not ready');
this.skip();
}
cy.visit('/login');
});
Steps
Use tracera.step or cy.traceraStep: the call tracera.step(title, fn) / cy.traceraStep(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 work follows the Cypress command queue. After import "@tracera/cypress/support", stock beforeEach / afterEach are instrumented — steps inside them go to the result’s Setup / Teardown. Suite-level hooks such as before / after are not reported.
import { tracera } from '@tracera/cypress/runtime';
beforeEach(() => {
tracera.step('open shop', () => {
return cy.visit('/shop');
});
});
it('checkout', () => {
tracera.testCase(10, 'e2e/checkout');
tracera.step('add to cart', () => {
return cy.get('[data-testid=add]').click();
});
});
afterEach(() => {
tracera.step('cleanup', () => {
// …
});
});
Decorator on a method:
import { tracera } from '@tracera/cypress/runtime';
class Cart {
@tracera.step('add {item}')
async addToCart(item: string) {
// …
}
}
Comments, errors, and attachments
Comments, errors, and attachments: Autotest adapters. Failure screenshots are added to the result when the plugin is registered.
import { tracera } from '@tracera/cypress/runtime';
it('login', () => {
tracera.testCase(42, 'e2e/login');
tracera.comment('result-level note');
tracera.error('result-level error text');
tracera.step('open login', () => {
return cy.visit('/login').then(() => {
tracera.comment('landed on login');
tracera.attachment({
fileName: 'suite-log.txt',
mimeType: 'text/plain',
data: 'finished login flow',
});
});
});
});
Parameterized tests
import { annotations } from '@tracera/cypress/runtime';
const rows = [
{ id: 42, name: 'e2e/login-ok', path: '/login' },
{ id: 43, name: 'e2e/login-sso', path: '/login/sso' },
];
for (const row of rows) {
it(row.name, annotations(row.id, row.name), () => {
cy.visit(row.path);
});
}
Or call tracera.testCase(row.id, row.name) inside the test instead of annotations.