{"id":25392247,"url":"https://github.com/cucumber/cucumber-node","last_synced_at":"2025-10-30T17:31:31.261Z","repository":{"id":277553006,"uuid":"919188068","full_name":"cucumber/cucumber-node","owner":"cucumber","description":null,"archived":false,"fork":false,"pushed_at":"2025-02-14T14:26:43.000Z","size":103,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-02-14T15:33:04.050Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cucumber.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"open_collective":"cucumber","github":"cucumber"}},"created_at":"2025-01-19T23:01:12.000Z","updated_at":"2025-02-14T14:25:10.000Z","dependencies_parsed_at":"2025-02-14T15:43:45.794Z","dependency_job_id":null,"html_url":"https://github.com/cucumber/cucumber-node","commit_stats":null,"previous_names":["cucumber/cucumber-node"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cucumber%2Fcucumber-node","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cucumber%2Fcucumber-node/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cucumber%2Fcucumber-node/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cucumber%2Fcucumber-node/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cucumber","download_url":"https://codeload.github.com/cucumber/cucumber-node/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238956757,"owners_count":19558527,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-02-15T16:27:48.590Z","updated_at":"2025-10-30T17:31:31.243Z","avatar_url":"https://github.com/cucumber.png","language":"TypeScript","funding_links":["https://opencollective.com/cucumber","https://github.com/sponsors/cucumber"],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003e\n  \u003cimg alt=\"\" width=\"75\" src=\"https://github.com/cucumber.png\"/\u003e\n  \u003cbr\u003e\n  cucumber-node\n\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\n  \u003cb\u003eAutomated tests in plain language, for the Node.js test runner\u003c/b\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@cucumber/node\" style=\"text-decoration: none\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@cucumber/node?style=flat\u0026color=dark-green\" alt=\"Latest version on npm\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/cucumber/cucumber-node/actions\" style=\"text-decoration: none\"\u003e\u003cimg src=\"https://github.com/cucumber/cucumber-node/actions/workflows/test.yaml/badge.svg\" alt=\"Build status\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n[Cucumber](https://github.com/cucumber) is a tool for running automated tests written in plain language. Because they're\nwritten in plain language, they can be read by anyone on your team. Because they can be\nread by anyone, you can use them to help improve communication, collaboration and trust on\nyour team.\n\n⚠️⚠️⚠️  \nThis is a new implementation of Cucumber built around the [Node.js test runner](https://nodejs.org/api/test.html). It's still in the pre-1.0.0 phase, so APIs and behaviour might change. The stable canonical implementation of Cucumber for JavaScript continues to be [@cucumber/cucumber](https://github.com/cucumber/cucumber-js) for now.  \n⚠️⚠️⚠️\n\n## Install\n\ncucumber-node is [available on npm](https://www.npmjs.com/package/@cucumber/node):\n\n```shell\nnpm install --save-dev @cucumber/node\n```\n\nYou'll need Node.js 22 or 24.\n\n## Get started\n\nSay we have this small class:\n\n```js\nexport class Greeter {\n  sayHello() {\n    return 'hello'\n  }\n}\n```\n\nLet's write a feature file specifying how it should work, in `features/greeting.feature`:\n\n```gherkin\nFeature: Greeting\n\n  Scenario: Say hello\n    When the greeter says hello\n    Then I should have heard \"hello\"\n```\n\nNext, we need to provide automation to turn that spec into tests, in `features/support/steps.js`:\n\n```js\nimport assert from 'node:assert'\nimport { When, Then } from '@cucumber/node'\nimport { Greeter } from '../../lib/Greeter.js'\n\nWhen('the greeter says hello', (t) =\u003e {\n  t.world.whatIHeard = new Greeter().sayHello()\n})\n\nThen('I should have heard {string}', (t, expectedResponse) =\u003e {\n  assert.equal(t.world.whatIHeard, expectedResponse)\n})\n```\n\nFinally, run `node --test` with some special arguments:\n\n```shell\nnode --import @cucumber/node/bootstrap --test \"features/**/*.feature\"\n```\n\n## Running tests\n\nSince cucumber-node augments the standard Node.js test runner, you can use many of its options in the same way you would when running tests written in JavaScript, like:\n\n- 🔀 [`--test-concurrency`](https://nodejs.org/api/cli.html#--test-concurrency) to control the number of concurrent processes\n- 🏃 [`--test-force-exit`](https://nodejs.org/api/cli.html#--test-force-exit) to forcibly exit once all tests have executed\n- 😷 [`--test-isolation=none`](https://nodejs.org/api/cli.html#--test-isolationmode) to have all tests run in a single process\n- 🔍 [`--test-name-pattern`](https://nodejs.org/api/cli.html#--test-name-pattern) to target some scenarios by name\n- 💎 [`--test-shard`](https://nodejs.org/api/cli.html#--test-shard) to shard execution across multiple runs/environments\n- ⏩ [`--test-skip-pattern`](https://nodejs.org/api/cli.html#--test-skip-pattern) to omit some scenarios by name\n- 👀 [`--watch`](https://nodejs.org/api/cli.html#--watch) to watch for changes and automatically re-run\n\n(In all cases you still need the `--import @cucumber/node/bootstrap` so that cucumber-node kicks in when a feature file is encountered.)\n\n## Writing steps\n\nFull API documentation is at https://cucumber.github.io/cucumber-node and includes:\n\n- `Given`, `When` and `Then` for steps\n- `Before` and `After` for hooks\n- `ParameterType` for custom parameter types\n- `DataTable` for working with data tables\n\n### Test context\n\nWhen you write a step or hook function, the first argument will always be a [`TestCaseContext`](https://cucumber.github.io/cucumber-node/types/TestCaseContext.html) object, similar to the one that `node --test` gives you when writing tests in JavaScript and with many of the same properties, plus the \"world\" where you can keep your state, and methods for attaching content.\n\n### Finding your code\n\nDiscovery of your code is based on the following glob (relative to the working directory):\n\n```\nfeatures/**/*.{cjs,js,mjs,cts,mts,ts}\n```\n\nThis isn't configurable ([yet](https://github.com/cucumber/cucumber-node/issues/10)).\n\n### ESM and CommonJS\n\ncucumber-node is an ESM package, but you can write your code in either format:\n\n- ESM - e.g. `import { Given } from '@cucumber/node'`\n- CommonJS - e.g. `const { Given } = require('@cucumber/node')`\n\n### TypeScript\n\nYou also can write your code in TypeScript.\n\nWe recommend bringing in [`tsx`](https://www.npmjs.com/package/tsx) to handle the transpilation, plus the Node.js types:\n\n```shell\nnpm install --save-dev tsx @types/node\n```\n\nThen, add `tsx` as another import when you run:\n\n```shell\nnode --import @cucumber/node/bootstrap --import tsx --test \"features/**/*.feature\"\n```\n\nRemember to add a [`tsconfig.json`](https://www.typescriptlang.org/tsconfig/) to your project. If you're not sure what you need, [`@tsconfig/node22`](https://www.npmjs.com/package/@tsconfig/node22) is a good place to start.\n\n#### Without dependencies\n\nYou might even be able to go without any extra dependencies and instead lean on [Node.js built-in TypeScript support](https://nodejs.org/api/typescript.html), although this is still very new and has several limitations.\n\n## Reporters\n\nSome Cucumber formatters are included as Node.js test reporters:\n\n- HTML `--test-reporter=@cucumber/node/reporters/html --test-reporter-destination=./report.html`\n- JUnit `--test-reporter=@cucumber/node/reporters/junit --test-reporter-destination=./TEST-cucumber.xml`\n- Message `--test-reporter=@cucumber/node/reporters/message --test-reporter-destination=./messages.ndjson`\n\nFor now, avoid using the `spec` reporter at the same time as one of the above reporters - because we're abusing the `diagnostic` channel to send messages to the reporter, it makes the `spec` output very noisy - we recommend the `dot` reporter instead.\n\n## Mixing tests\n\nYou can execute Cucumber tests and normal JavaScript tests in the same test run - cucumber-node won't interfere with the other tests. But the reporters mentioned above will only report on the Cucumber tests in your run.\n\n## Limitations\n\nThere are some pretty standard Cucumber features that are missing (but not for long):\n\n- [Filtering by tag expression](https://github.com/cucumber/cucumber-node/issues/9)\n- [BeforeAll/AfterAll hooks](https://github.com/cucumber/cucumber-node/issues/8)\n- [Regular expression steps](https://github.com/cucumber/cucumber-node/issues/6)\n- [Snippets](https://github.com/cucumber/cucumber-node/issues/36)\n\n## What's different?\n\nSome behaviour of cucumber-node is different - and better - than in cucumber-js:\n\n### Concurrency by default\n\n`node --test` by default runs each test file in a separate process, and runs them concurrently as much as possible within the constraints of the system. This is markedly different to cucumber-js which is single-process and serial by default. This is also a good thing, helping you identify and fix unintentional dependencies between scenarios.\n\n### Arrow functions\n\nThere's no reliance on `this` in your step and hook functions to access state, since we pass a context object as the first argument to those functions. This means you're free to use arrow functions as you normally would in JavaScript.\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcucumber%2Fcucumber-node","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcucumber%2Fcucumber-node","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcucumber%2Fcucumber-node/lists"}