Gherkin Lint
Gherkin Lint is a JavaScript-based linter and validator for Gherkin feature files, inspired by ESLint. It ensures consistency and adherence to predefined style and structural rules within Behavior-Driven Development (BDD) scenarios. The current stable version is 4.2.4, with recent releases focusing on dependency updates and minor bug fixes. The package helps teams maintain high-quality, readable, and maintainable Gherkin files by catching common pitfalls such as incorrect indentation, duplicate tags, unnamed features or scenarios, and structural inconsistencies. Its primary differentiator is its comprehensive set of configurable rules and its integration capabilities within CI/CD pipelines and development environments, allowing for early detection of issues in Gherkin syntax and style.
Common errors
-
glob.sync missing absolute: true causes MODULE_NOT_FOUND on Windows with glob v11+
cause An incompatibility between `gherkin-lint`'s internal file path resolution and `glob` library versions on Windows systems.fixThis is an open issue. As a temporary workaround, try using an older version of `glob` if possible, or ensure consistent path separators. Check the `gherkin-lint` GitHub issues for updates and potential patches. -
Configuration verification would fail for custom rules
cause Historically, there was a bug in `gherkin-lint` that caused issues when validating the configuration of custom-defined rules.fixThis specific bug was fixed in `v2.11.1`. Ensure you are using `gherkin-lint@2.11.1` or newer. If you are on an older version, upgrade. If the error persists with a newer version, double-check your custom rule's configuration format. -
Variables were not correctly detected in scenario names or step arguments (DocString or DataTable)
cause Prior to specific bug fixes, the linter had shortcomings in correctly identifying and processing variables enclosed in `<...>` within Gherkin syntax.fixThis issue was resolved in `v2.13.2`. Upgrade `gherkin-lint` to version `2.13.2` or later to ensure proper variable detection and avoid false positives or negatives related to variable usage.
Warnings
- breaking Major version updates (e.g., v2 to v3, v3 to v4) often introduce breaking changes, including changes to rule names, configuration formats, or the programmatic API. Always consult the official GitHub releases and changelog when upgrading major versions.
- gotcha The `gherkin-lint` package requires Node.js version 10 or higher. Running it with older Node.js versions may lead to unexpected errors or installation failures.
- gotcha Incorrectly configured `.gherkin-lintrc` files or misnamed custom rules can lead to the linter not applying expected rules or failing during configuration parsing. Rule configurations are case-sensitive and expect specific formats (e.g., 'on', 'off', or array with options).
- deprecated Users may encounter 'Deprecated Packages When Installing gherkin-lint' warnings during `npm install`. This indicates that some of `gherkin-lint`'s internal dependencies might be using deprecated packages, though `gherkin-lint` itself remains active.
Install
-
npm install gherkin-lint -
yarn add gherkin-lint -
pnpm add gherkin-lint
Imports
- Linter
const Linter = require('gherkin-lint').Linter;import { Linter } from 'gherkin-lint'; - runCLI
import { runCLI } from 'gherkin-lint/dist/bin/gherkin-lint'; - GherkinParser
import { GherkinParser } from 'gherkin-lint/dist/src/gherkin-parser';
Quickstart
import { Linter } from 'gherkin-lint';
import * as fs from 'fs';
import * as path from 'path';
async function lintFeatureFile(filePath: string) {
const linter = new Linter();
const featureContent = fs.readFileSync(filePath, 'utf8');
// A .gherkin-lintrc file should be present in the project root
// or specified via linter options for rules to be applied.
// Example .gherkin-lintrc (JSON format with comments):
// {
// "no-unnamed-scenarios": "on",
// "indentation": ["on", {"Feature": 0, "Background": 2, "Scenario": 2, "Step": 4, "Examples": 2, "example": 4}],
// "no-duplicate-tags": "on"
// }
const result = await linter.lint({
featureFile: featureContent,
fileName: path.basename(filePath)
});
if (result.length > 0) {
console.error(`Linting issues in ${filePath}:`);
result.forEach(issue => {
console.error(` [${issue.rule}] Line ${issue.line}: ${issue.message}`);
});
process.exit(1);
} else {
console.log(`No linting issues found in ${filePath}.`);
}
}
// To run this, create a dummy.feature file and a .gherkin-lintrc in the same directory
// Example dummy.feature:
// Feature: My Feature
// Scenario: My Scenario
// Given a step
// When another step
// Then a final step
const featurePath = path.resolve(__dirname, 'dummy.feature');
if (!fs.existsSync(featurePath)) {
fs.writeFileSync(featurePath, 'Feature: Example\n Scenario: Test\n Given a passing step');
console.log('Created dummy.feature. Please create a .gherkin-lintrc file in the same directory.');
}
lintFeatureFile(featurePath).catch(console.error);