> cucumber

When the user wants to write behavior-driven development (BDD) tests using Gherkin syntax and Cucumber step definitions. Also use when the user mentions "cucumber," "BDD," "Gherkin," "feature files," "given-when-then," "step definitions," or "behavior-driven." For contract testing, see pact.

fetch
$curl "https://skillshub.wtf/TerminalSkills/skills/cucumber?format=md"
SKILL.mdcucumber

Cucumber

Overview

You are an expert in Cucumber and BDD testing. You help users write feature files in Gherkin syntax, implement step definitions in JavaScript/TypeScript or other languages, organize test suites with tags and hooks, and integrate Cucumber into CI. You value well-written scenarios that serve as living documentation — readable by developers, testers, and stakeholders.

Instructions

Initial Assessment

  1. Language — JavaScript/TypeScript, Java, Ruby, or Python?
  2. Scope — API testing, UI testing, or both?
  3. Team — Who writes feature files? (developers, QA, product)
  4. Existing tests — Adding BDD to an existing suite or starting fresh?

Setup (JavaScript)

# setup-cucumber.sh — Install Cucumber.js with TypeScript support.
npm install --save-dev @cucumber/cucumber ts-node typescript
mkdir -p features/step_definitions features/support

Feature File

# features/login.feature — Login feature with multiple scenarios.
# Written in Gherkin syntax for non-technical stakeholders.
Feature: User Login
  As a registered user
  I want to log in to my account
  So that I can access my dashboard

  Background:
    Given the application is running
    And the database has been seeded with test users

  Scenario: Successful login with valid credentials
    Given I am on the login page
    When I enter "user@example.com" as the email
    And I enter "password123" as the password
    And I click the login button
    Then I should be redirected to the dashboard
    And I should see "Welcome back" on the page

  Scenario: Failed login with invalid password
    Given I am on the login page
    When I enter "user@example.com" as the email
    And I enter "wrongpassword" as the password
    And I click the login button
    Then I should see an error message "Invalid credentials"
    And I should remain on the login page

  Scenario Outline: Login validation
    Given I am on the login page
    When I enter "<email>" as the email
    And I enter "<password>" as the password
    And I click the login button
    Then I should see an error message "<error>"

    Examples:
      | email              | password    | error                    |
      |                    | password123 | Email is required        |
      | user@example.com   |             | Password is required     |
      | not-an-email       | password123 | Invalid email format     |

Step Definitions

// features/step_definitions/login.steps.ts — Step definitions for the login feature.
// Maps Gherkin steps to test automation code.
import { Given, When, Then, Before } from '@cucumber/cucumber';
import { expect } from 'chai';

let app: any;
let currentPage: string;
let pageContent: string;
let errorMessage: string;

Before(async function () {
  app = await startTestApp();
});

Given('the application is running', async function () {
  const health = await app.get('/health');
  expect(health.status).to.equal(200);
});

Given('the database has been seeded with test users', async function () {
  await app.post('/test/seed', {
    users: [{ email: 'user@example.com', password: 'password123' }],
  });
});

Given('I am on the login page', async function () {
  currentPage = '/login';
  const res = await app.get('/login');
  expect(res.status).to.equal(200);
});

When('I enter {string} as the email', async function (email: string) {
  this.email = email;
});

When('I enter {string} as the password', async function (password: string) {
  this.password = password;
});

When('I click the login button', async function () {
  const res = await app.post('/login', {
    email: this.email,
    password: this.password,
  });
  this.response = res;
  if (res.status === 200) {
    currentPage = '/dashboard';
    pageContent = res.data.message;
  } else {
    errorMessage = res.data.error;
  }
});

Then('I should be redirected to the dashboard', function () {
  expect(currentPage).to.equal('/dashboard');
});

Then('I should see {string} on the page', function (text: string) {
  expect(pageContent).to.include(text);
});

Then('I should see an error message {string}', function (message: string) {
  expect(errorMessage).to.equal(message);
});

Then('I should remain on the login page', function () {
  expect(currentPage).to.equal('/login');
});

Hooks and World

// features/support/world.ts — Custom World object for sharing state between steps.
// Provides helpers and context available in all step definitions.
import { setWorldConstructor, World, IWorldOptions } from '@cucumber/cucumber';

export class CustomWorld extends World {
  app: any;
  authToken: string | null = null;

  constructor(options: IWorldOptions) {
    super(options);
  }

  async authenticate(email: string, password: string) {
    const res = await this.app.post('/login', { email, password });
    this.authToken = res.data.token;
    return res;
  }

  async apiGet(path: string) {
    return this.app.get(path, {
      headers: this.authToken ? { Authorization: `Bearer ${this.authToken}` } : {},
    });
  }
}

setWorldConstructor(CustomWorld);

Cucumber Configuration

// cucumber.js — Cucumber.js configuration file.
// Defines profiles for different test environments.
module.exports = {
  default: {
    requireModule: ['ts-node/register'],
    require: ['features/step_definitions/**/*.ts', 'features/support/**/*.ts'],
    format: ['progress', 'html:reports/cucumber.html', 'json:reports/cucumber.json'],
    publishQuiet: true,
  },
  ci: {
    requireModule: ['ts-node/register'],
    require: ['features/step_definitions/**/*.ts', 'features/support/**/*.ts'],
    format: ['json:reports/cucumber.json'],
    tags: 'not @wip',
    publishQuiet: true,
  },
};

Running Cucumber

# run-cucumber.sh — Common Cucumber commands.
# Run all features, specific tags, or individual scenarios.

# Run all features
npx cucumber-js

# Run with specific profile
npx cucumber-js --profile ci

# Run by tag
npx cucumber-js --tags "@smoke"
npx cucumber-js --tags "@login and not @wip"

# Run specific feature
npx cucumber-js features/login.feature

CI Integration

# .github/workflows/cucumber.yml — Run Cucumber BDD tests in CI.
# Publishes HTML report as artifact.
name: BDD Tests
on: [push]
jobs:
  cucumber:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: 20
      - run: npm ci
      - run: npx cucumber-js --profile ci
      - uses: actions/upload-artifact@v4
        if: always()
        with:
          name: cucumber-report
          path: reports/

> related_skills --same-repo

> zustand

You are an expert in Zustand, the small, fast, and scalable state management library for React. You help developers manage global state without boilerplate using Zustand's hook-based stores, selectors for performance, middleware (persist, devtools, immer), computed values, and async actions — replacing Redux complexity with a simple, un-opinionated API in under 1KB.

> zoho

Integrate and automate Zoho products. Use when a user asks to work with Zoho CRM, Zoho Books, Zoho Desk, Zoho Projects, Zoho Mail, or Zoho Creator, build custom integrations via Zoho APIs, automate workflows with Deluge scripting, sync data between Zoho apps and external systems, manage leads and deals, automate invoicing, build custom Zoho Creator apps, set up webhooks, or manage Zoho organization settings. Covers Zoho CRM, Books, Desk, Projects, Creator, and cross-product integrations.

> zod

You are an expert in Zod, the TypeScript-first schema declaration and validation library. You help developers define schemas that validate data at runtime AND infer TypeScript types at compile time — eliminating the need to write types and validators separately. Used for API input validation, form validation, environment variables, config files, and any data boundary.

> zipkin

Deploy and configure Zipkin for distributed tracing and request flow visualization. Use when a user needs to set up trace collection, instrument Java/Spring or other services with Zipkin, analyze service dependencies, or configure storage backends for trace data.

┌ stats

installs/wk0
░░░░░░░░░░
github stars17
███░░░░░░░
first seenMar 17, 2026
└────────────

┌ repo

TerminalSkills/skills
by TerminalSkills
└────────────

┌ tags

└────────────