{"id":31720611,"url":"https://github.com/aboviq/bun-test-cucumber","last_synced_at":"2026-05-02T23:37:15.378Z","repository":{"id":318663255,"uuid":"1072227783","full_name":"aboviq/bun-test-cucumber","owner":"aboviq","description":"Run Cucumber tests with Bun's test runner and full TypeScript support","archived":false,"fork":false,"pushed_at":"2025-11-26T09:06:28.000Z","size":73,"stargazers_count":2,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-28T18:56:27.285Z","etag":null,"topics":["bunjs","cucumber","testing"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aboviq.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/funding.yml","license":null,"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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":["joakimbeng","aboviq"]}},"created_at":"2025-10-08T12:37:34.000Z","updated_at":"2025-11-26T09:06:32.000Z","dependencies_parsed_at":"2025-10-08T14:42:28.754Z","dependency_job_id":null,"html_url":"https://github.com/aboviq/bun-test-cucumber","commit_stats":null,"previous_names":["aboviq/bun-test-cucumber"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/aboviq/bun-test-cucumber","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboviq%2Fbun-test-cucumber","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboviq%2Fbun-test-cucumber/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboviq%2Fbun-test-cucumber/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboviq%2Fbun-test-cucumber/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aboviq","download_url":"https://codeload.github.com/aboviq/bun-test-cucumber/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aboviq%2Fbun-test-cucumber/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32553688,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-02T22:28:24.418Z","status":"ssl_error","status_checked_at":"2026-05-02T22:28:14.225Z","response_time":132,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["bunjs","cucumber","testing"],"created_at":"2025-10-09T03:17:42.616Z","updated_at":"2026-05-02T23:37:15.372Z","avatar_url":"https://github.com/aboviq.png","language":"TypeScript","funding_links":["https://github.com/sponsors/joakimbeng","https://github.com/sponsors/aboviq"],"categories":[],"sub_categories":[],"readme":"# @aboviq/bun-test-cucumber\n\n\u003e Run Cucumber tests with Bun's test runner and full TypeScript support\n\nIn comparison with [@cucumber/cucumber](https://github.com/cucumber/cucumber-js) which uses its own test runner, this package integrates Cucumber with [Bun's built-in test runner](https://bun.sh/docs/cli/test), allowing you to run your Cucumber tests using `bun test`. It also provides full TypeScript support with type inference for step definitions and hooks.\n\nThis package is inspired by [vitest-cucumber-plugin](https://github.com/samuel-ziegler/vitest-cucumber-plugin).\n\nFor state management between steps, it uses a simple object instead of class instances that is passed from one step to the next, which can be typed using generics.\n\n**NOTE:** this package is published as TypeScript source code and doesn't include any compiled JavaScript files.\n\n## Setup\n\n### Install the package as a dev dependency\n\n```bash\nbun add -D @aboviq/bun-test-cucumber\n```\n\n### Configure and preload the plugin\n\nCreate a `test-plugins.ts` file in your project root with the following content:\n\n```ts\nimport { plugin } from 'bun';\nimport { bunTestCucumber } from '@aboviq/bun-test-cucumber';\n\nawait plugin(\n  bunTestCucumber({\n    stepDefinitionsPattern: 'tests/**/*.steps.ts', // Adjust the pattern to match your step definition files\n  }),\n);\n```\n\nThen preload this file when running your tests:\n\n```bash\nbun test --preload ./test-plugins.ts\n```\n\nOr add it to your `bunfig.toml`:\n\n```toml\n[test]\npreload = [\"./test-plugins.ts\"]\n```\n\n### Loading feature files\n\n**NOTE:** Due to a limitation in Bun's current implementation, feature files can't be loaded automatically as the default glob pattern for test files only matches `.ts` and `.js` files. And it's not working by passing the feature files directly to `bun test` either for the same reason. (See: \u003chttps://github.com/oven-sh/bun/issues/3440\u003e)\n\nTo work around this, you can create a `features.test.ts` file somewhere in your project that imports all your feature files. For example:\n\n```ts\nimport { loadFeatures } from '@aboviq/bun-test-cucumber';\n\nawait loadFeatures('features/**/*.feature'); // Adjust the pattern to match your feature files, relative to cwd (which can be customized using the second argument)\n```\n\n## Usage\n\nCreate your feature files (e.g. `features/example.feature`):\n\n```gherkin\nFeature: Example feature\n  Scenario: Example scenario\n    Given I have a step definition\n    When I run the tests\n    Then I should see the results\n```\n\nCreate your step definitions (e.g. `tests/example.steps.ts`):\n\n```ts\nimport { Given, When, Then } from '@aboviq/bun-test-cucumber';\n\nGiven('I have a step definition', (state) =\u003e {\n  // Step definition implementation\n  return state;\n});\n\nWhen('I run the tests', (state) =\u003e {\n  // Step implementation\n  return state;\n});\n\nThen('I should see the results', (state) =\u003e {\n  // Step implementation\n  return state;\n});\n```\n\nRun your tests:\n\n```bash\nbun test\n```\n\n## TypeScript Support\n\nThe package is written in TypeScript and provides full type definitions for step definitions and hooks. You can define the state type for your steps and hooks to get type safety and autocompletion.\n\nThe package also automatically infers expression types for step definitions based on the step text.\n\n### Example with state and argument types\n\n#### Using `withState` to define state type\n\n```ts\nimport { withState } from '@aboviq/bun-test-cucumber';\n\ninterface MyState {\n  count: number;\n}\n\nconst { Before, Given, When } = withState\u003cMyState\u003e();\n\nBefore((state) =\u003e ({ ...state, count: 0 }));\n\nGiven('the count is {int}', (state, [count]) =\u003e {\n  typeof count; // inferred as number\n  return { ...state, count };\n});\n\nWhen('I am {word} the count', (state, [operation]) =\u003e {\n  typeof operation; // inferred as string\n  switch (operation) {\n    case 'increasing':\n      return { ...state, count: state.count + 1 };\n    case 'decreasing':\n      return { ...state, count: state.count - 1 };\n    case 'doubling':\n      return { ...state, count: state.count * 2 };\n    default:\n      throw new Error(`Unknown operation: ${operation}`);\n  }\n});\n```\n\n#### Without `withState`\n\n```ts\nimport { Before, Given, When } from '@aboviq/bun-test-cucumber';\n\ninterface MyState {\n  count: number;\n}\n\nBefore\u003cMyState\u003e((state) =\u003e ({ ...state, count: 0 }));\n\nGiven('the count is {int}', (state: MyState, [count]) =\u003e {\n  typeof count; // inferred as number\n  return { ...state, count };\n});\n\nWhen('I am {word} the count', (state: MyState, [operation]) =\u003e {\n  typeof operation; // inferred as string\n  switch (operation) {\n    case 'increasing':\n      return { ...state, count: state.count + 1 };\n    case 'decreasing':\n      return { ...state, count: state.count - 1 };\n    case 'doubling':\n      return { ...state, count: state.count * 2 };\n    default:\n      throw new Error(`Unknown operation: ${operation}`);\n  }\n});\n```\n\n#### Using with RegExp\n\n```ts\nimport { Before, Given, When } from '@aboviq/bun-test-cucumber';\n\ninterface MyState {\n  count: number;\n}\n\nBefore\u003cMyState\u003e((state) =\u003e ({ ...state, count: 0 }));\n\n// untyped regexp\nGiven(/the count is (\\\\d+|zero)/, (state: MyState, [count]) =\u003e {\n  // inferred as string | undefined\n  if (!count || count === 'zero') {\n    return { ...state, count: 0 };\n  }\n\n  return { ...state, count: Number(count) };\n});\n\n// simple typed regexp (note that it's a regex-like string)\nWhen('/I am (increasing|decreasing|doubling) the count/', (state: MyState, [operation]) =\u003e {\n  typeof operation; // inferred as 'increasing' | 'decreasing' | 'doubling'\n  switch (operation) {\n    case 'increasing':\n      return { ...state, count: state.count + 1 };\n    case 'decreasing':\n      return { ...state, count: state.count - 1 };\n    case 'doubling':\n      return { ...state, count: state.count * 2 };\n    default:\n      throw new Error(`Unknown operation: ${operation}`);\n  }\n});\n```\n\n## License\n\nMIT © [Aboviq AB](https://aboviq.com)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faboviq%2Fbun-test-cucumber","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faboviq%2Fbun-test-cucumber","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faboviq%2Fbun-test-cucumber/lists"}