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