Skip to main content
Version: 2x

Tags & Filtering

Tags let you categorize scenarios and control which tests run. They are standard Cucumber tags prefixed with @.

Defining Tags

Add tags above a Feature, Scenario, Scenario Outline, or Examples block:

@smoke
Feature: User authentication

@happy-path
Scenario: Login with valid credentials
Given I open '$loginUrl' url
When I type '$username' to 'Username Input'
And I type '$password' to 'Password Input'
And I click 'Login Button'
Then I expect 'Dashboard' to be visible

@wip
Scenario: Login with expired token
Given I open '$loginUrl' url
When I type '$expiredToken' to 'Token Field'
Then I expect 'Session Expired Message' to be visible

Tags on a Feature are inherited by all scenarios inside it. Tags on Examples apply to the specific parameterized run.

Running by Tag

CLI

npx qavajs run --tags "@smoke"
npx qavajs run --tags "@smoke and @happy-path"
npx qavajs run --tags "@smoke and not @wip"
npx qavajs run --tags "@smoke or @regression"

Config file

export default {
// ...
tags: '@smoke and not @wip'
}

The CLI flag takes precedence over the config file value.

Tag Expressions

Combine tags using Boolean operators:

OperatorMeaningExample
andBoth tags must be present@smoke and @login
orEither tag must be present@smoke or @regression
notTag must not be presentnot @wip
()Grouping@smoke and (not @slow)

Examples:

# Run all smoke tests that are not marked as work-in-progress
npx qavajs run --tags "@smoke and not @wip"

# Run login or checkout flows
npx qavajs run --tags "@login or @checkout"

# Run regression but exclude performance-heavy scenarios
npx qavajs run --tags "@regression and not @performance"

Tags and Sharding

Tags combine cleanly with --shard for distributed CI runs:

# Machine 1: smoke tests, first half
npx qavajs run --tags "@smoke" --shard 1/2

# Machine 2: smoke tests, second half
npx qavajs run --tags "@smoke" --shard 2/2

Tags and Hooks

Use tag expressions in Before/After hooks to scope setup/teardown to specific scenarios:

import { Before, After } from '@qavajs/core';

Before({ tags: '@authenticated' }, async function() {
await this.playwright.page.goto('/login');
await this.playwright.page.fill('#username', 'admin');
await this.playwright.page.fill('#password', 'secret');
await this.playwright.page.click('#submit');
});

After({ tags: '@db-cleanup' }, async function() {
await this.playwright.page.request.delete('/api/test-data');
});

Tags and Fixtures

Fixtures are activated by tags. Define the fixture name to match the tag (without @):

import { Fixture } from '@qavajs/core';

Fixture('cart', async function() {
await this.playwright.page.goto('/products');
await this.playwright.page.click('.add-to-cart');

return async function() {
await this.playwright.page.request.delete('/api/cart');
}
});
@cart
Scenario: User views cart
Then I expect 'Cart Item' to be visible

Establishing a consistent tagging strategy makes it easy to target specific subsets of tests across teams and CI pipelines.

TagPurpose
@smokeCritical path — fast, run on every PR
@regressionFull regression suite — run nightly
@wipWork in progress — excluded from CI
@slowLong-running tests excluded from quick runs
@flakyKnown flaky tests to investigate
@authenticatedScenarios requiring login (used with hooks/fixtures)
@apiAPI-only tests
@mobileMobile-specific tests

Example CI strategy:

# PR check — fast feedback
npx qavajs run --tags "@smoke and not @wip"

# Nightly full regression
npx qavajs run --tags "@regression and not @wip"

# Debug a specific area
npx qavajs run --tags "@checkout"