Annotations and test control

Introduction

CSTesting lets you focus or skip tests and suites so you can run a subset of tests or temporarily disable some. Skipped tests are counted and shown in the HTML report.

This page describes what is supported. Features like custom annotations, conditional skip, or "expected to fail" are not implemented in the current version; the table at the end summarizes supported vs not supported. Tag-based running is supported; see Tags.

You will learn

  • How to focus tests (run only certain tests)
  • How to skip tests or suites
  • How to run by tag (see Tags)
  • What is not yet supported (custom annotations, conditional skip, etc.)

Focus a test or suite

When you mark tests or suites with only, only those run. All others are skipped. Use this to quickly run one test or one group while developing.

Run only one test

const { describe, it, expect, createBrowser, beforeAll, afterAll } = require('cstesting');

describe('My suite', () => {
  it('this test runs', async () => {
    expect(1).toBe(1);
  });

  it.only('only this test runs', async () => {
    expect(2).toBe(2);
  });

  it('this test is skipped', async () => {
    expect(3).toBe(3);
  });
});

When you use it.only, only that test runs in the whole project (across all loaded files). The other tests in the same suite are skipped.

Run only one suite

describe('this suite runs', () => {
  it('test one', () => {});
  it('test two', () => {});
});

describe.only('only this suite runs', () => {
  it('test a', () => {});
  it('test b', () => {});
});

describe('this suite is skipped', () => {
  it('test x', () => {});
});

When you use describe.only, only that suite's tests run. All other suites (and their tests) are skipped.

You can combine describe.only and it.only: if any suite or test has only, only the ones marked with only run.


Skip a test or suite

Mark a test or suite as skip so it is not run. Skipped tests are still counted and appear in the terminal summary and in the HTML report under "Skipped".

Skip one test

it.skip('skip this test', async () => {
  // This test is not run.
});

Skip a whole suite

describe.skip('skip this suite', () => {
  it('test one', () => {});
  it('test two', () => {});
});

Use skip when a test is broken, not applicable yet, or you want to disable it without deleting it.


Report

  • Focus (only): Tests/suites without only are skipped when any only is present. They appear in the report as Skipped.
  • Skip: Tests/suites marked with skip are not run and appear as Skipped in the report.

The HTML report has a "Skipped" section listing all skipped tests (both from only and from skip). The terminal output shows: Passed: X Failed: Y Skipped: Z Total: N.


Tag-based test runs

CSTesting can include or exclude tests by tags. Tag filters apply to normal script tests (*.test.js, *.spec.ts, etc.), not to .conf config runs.

How tags are attached to a test

Effective tags for each test are the union of:

  1. Tags on describe blocks from the root down to the test (suite tags apply to every nested test).
  2. Tags on the it itself, from:
    • @words in the test title (only tokens that look like @tag after the start of the string or whitespace), and/or
    • The tags option on it / it.only / it.skip.

Tag names use letters, digits, hyphen, and underscore ([a-zA-Z][\w-]* after @). Tokens such as user@domain.com are not treated as tags (the @ must follow start or whitespace).

Examples in code

const { describe, it, expect } = require('cstesting');

describe('Checkout', { tags: ['e2e', 'regression'] }, () => {
  // Inherits e2e, regression

  it('@sanity @smoke completes purchase', async () => {
    // Also has sanity, smoke (from title)
  });

  it('named only in options', { tags: ['flaky', 'slow'] }, async () => {
    // Effective: e2e, regression, flaky, slow
  });
});
import { describe, it, expect } from 'cstesting';

describe('API', { tags: ['api'] }, () => {
  it('@smoke health check', async () => {
    expect(1).toBe(1);
  });
});

Normalization

  • Leading @ is optional in filters and is stripped when matching.
  • Comparison is case-insensitive (Smoke, smoke, @SMOKE match the same tag).
  • Whitespace around names is trimmed.

CLI: run only tests that have certain tags (include, OR)

If you pass any include tag(s), only tests whose effective tags intersect that list are executed. Multiple values mean any of (OR), not all (AND).

FormExample
--tag <names>npx cstesting --tag smoke
--tags <names>npx cstesting --tags smoke,sanity
-t <names>npx cstesting -t smoke,sanity
--tag=a,bnpx cstesting tests/ --tag=smoke,sanity
-t=a,bnpx cstesting -t=@smoke,sanity

You can combine with a path or glob as usual:

npx cstesting tests/ --tag smoke
npx cstesting "**/*.test.js" -t sanity,regression

Tests without any of the requested tags are skipped (counted as skipped in the report), not failed.

CLI: skip tests that have certain tags (exclude)

Exclude is applied after the include filter is considered: if a test would run, but any of its effective tags matches an excluded tag, it is skipped.

FormExample
--skip-tag <names>npx cstesting --skip-tag slow
--skip-tags a,bnpx cstesting --skip-tags slow,flaky
--exclude-tag / --exclude-tagsSame behavior as --skip-tag / --skip-tags
--skip-tag=a,bnpx cstesting --skip-tag=slow,flaky

Include and exclude together

Run tests that have smoke, but not if they are also tagged slow:

npx cstesting tests/ --tag smoke --skip-tag slow

Order of rules:

  1. If the test has any excluded tag → skip.
  2. Else, if you passed no include tags → run (subject to it.skip, describe.skip, .only, etc.).
  3. Else, if the test has any included tag → run; otherwise → skip.

Programmatic API

const { run } = require('cstesting');

await run({
  file: 'tests/e2e.test.js',
  tags: ['smoke', 'sanity'],       // optional: same as CLI include (OR)
  excludeTags: ['slow', 'flaky'],  // optional: same as --skip-tag
});

Options match RunOptions in the package types (tags, excludeTags, file, pauseOnFailure, …).

HTML report

Passed/failed/skipped entries can carry tags for search and display in report/report.html.

What tag filters do not apply to

  • cstesting run flow.conf / cstesting flow.conf — config-driven runs are separate flows; use different config files or sections if you need to split them.

What is not supported (current version)

The following are not implemented in CSTesting. Use the workarounds below if you need similar behavior.

FeatureSupported?Workaround
Focus (it.only, describe.only)Yes
Skip (it.skip, describe.skip)Yes
Expected to fail (run test and expect it to fail)NoRun the test normally; if it fails, that's the outcome. No "must fail" annotation.
Fixme (skip because broken/slow, with message)NoUse it.skip('message') to skip; the message is in the test name only.
Slow (e.g. triple timeout)NoNo per-test timeout or "slow" annotation. Use a longer global timeout or split slow tests.
Tags (e.g. @fast, @slow in title or options)YesSee Tag-based test runs: describe/it options, @words in titles, CLI --tag / --skip-tag.
Custom annotations (type + description, e.g. issue URL)NoNo annotation API; report does not show custom annotations. Add context in the test name or in step() text.
Conditional skip (e.g. skip if browser is Firefox)NoCSTesting runs one browser (Chrome). Use a normal if and return early, or skip the whole suite with describe.skip if needed.
Runtime annotations (add annotation during test)NoNo test.info() or similar. Use step('description') to add steps that appear in the report.
Filter by tag from CLI (--tag, --skip-tag, etc.)YesSee Tag-based test runs. Jest-style --grep is not used; use tag flags instead.

Summary

ActionSyntaxEffect
Focus one testit.only('name', fn)Only this test runs (others skipped).
Focus one suitedescribe.only('name', fn)Only tests in this suite run.
Skip one testit.skip('name', fn)This test is not run (reported as skipped).
Skip one suitedescribe.skip('name', fn)No tests in this suite run (all reported as skipped).

Skipped tests (from only or skip) are included in the total count and listed in the HTML report under "Skipped". Tag-based runs use include/exclude tags. Custom annotations, conditional skip, and Jest-style --grep are not available in the current version.