Skip to content

Custom formatter throws an error when importing IFormatterOptionsΒ #2548

@luis-embroker

Description

@luis-embroker

πŸ‘“ What did you see?

I am trying to build a custom formatter in TypeScript and I am getting an error when trying to run cucumber programmatically.

./formatter.ts

import { Envelope } from '@cucumber/messages';
import { IFormatterOptions, Formatter } from '@cucumber/cucumber';

export default class SimpleFormatter extends Formatter {
  constructor(options: IFormatterOptions) {
    super(options);
    options.eventBroadcaster.on('envelope', (envelope: Envelope) => {
      if (envelope.testCaseFinished) {
        this.log('Custom formatter: test case finished');
      } else if (envelope.testRunFinished) {
        this.log('Custom formatter: test run finished');
      }
    });
  }
}

The IDE doesn't show importing errors and everything looks ok, but when running cucumber it throws an error:


~/node_modules/@cucumber/cucumber/src/formatter/import_code.ts:14
    throw new Error(`Failed to import formatter ${specifier}`, {
          ^
Error: Failed to import formatter ./my-formatter.ts
    at importCode (~/node_modules/@cucumber/cucumber/src/formatter/import_code.ts:14:11)
    at async resolveImplementation (~/node_modules/@cucumber/cucumber/src/formatter/resolve_implementation.ts:18:20)
    ... 2 lines matching cause stack trace ...
    at async runCucumber (~/node_modules/@cucumber/cucumber/src/api/run_cucumber.ts:93:29) {
  [cause]: file:///~/my-formatter.ts:2
  import { IFormatterOptions } from '@cucumber/cucumber';
           ^^^^^^^^^^^^^^^^^
  SyntaxError: The requested module '@cucumber/cucumber' does not provide an export named 'IFormatterOptions'
      at ModuleJob._instantiate (node:internal/modules/esm/module_job:182:21)
      at async ModuleJob.run (node:internal/modules/esm/module_job:265:5)
      at async onImport.tracePromise.__proto__ (node:internal/modules/esm/loader:600:26)
      at async importCode (~/node_modules/@cucumber/cucumber/src/formatter/import_code.ts:12:12)
      at async resolveImplementation (~/node_modules/@cucumber/cucumber/src/formatter/resolve_implementation.ts:18:20)
      at async initializeFormatter (~/node_modules/@cucumber/cucumber/src/api/formatters.ts:52:28)
      at async initializeFormatters (~/node_modules/@cucumber/cucumber/src/api/formatters.ts:86:3)
      at async runCucumber (~/node_modules/@cucumber/cucumber/src/api/run_cucumber.ts:93:29)
}

βœ… What did you expect to see?

Cucumber running and displaying messages from the custom formatter:
Custom formatter: test case finished and Custom formatter: test run finished

πŸ“¦ Which tool/library version are you using?

node: v23.9.0
@cucumber/cucumber: 11.2.0

πŸ”¬ How could we reproduce it?

  1. Install node v23.9.0, cucumber 11.2.0 and typescript
  2. Create these files:

package.json

{
  "name": "test",
  "version": "1.0.0",
  "main": "index.js",
  "scripts": {
    "start": "ts-node index.ts"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "@cucumber/cucumber": "^11.2.0",
    "ts-node": "^10.9.2"
  }
}

index.ts

import { loadConfiguration, runCucumber } from '@cucumber/cucumber/api';

async function runTests()  {
  const { runConfiguration } = await loadConfiguration({
    provided: {
      paths: ['*.feature'],
      format: ['./my-formatter.ts'],
    },
  });
  await runCucumber(runConfiguration);
}

runTests().then(() => {
    console.log('Finished running tests programmatically');
})
  

my-formatter.ts

import { Envelope } from '@cucumber/messages';
import { IFormatterOptions, Formatter } from '@cucumber/cucumber';

export default class SimpleFormatter extends Formatter {
  constructor(options: IFormatterOptions) {
    super(options);
    options.eventBroadcaster.on('envelope', (envelope: Envelope) => {
      if (envelope.testCaseFinished) {
        this.log('Custom formatter: test case finished');
      } else if (envelope.testRunFinished) {
        this.log('Custom formatter: test run finished');
      }
    });
  }
}

test.feature

Feature: Test

  Scenario: just a test
    Given I create a custom formatter
    When I run the formatter
    Then I should see the output
  1. Install the dependencies with npm install
  2. Run the project with npm start

πŸ“š Any additional context?

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    ❓ questionConsider using support forums: https://cucumber.io/tools/cucumber-open/support

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions