diff --git a/.github/workflows/test-javascript.yml b/.github/workflows/test-javascript.yml index e1817828..b297d7f9 100644 --- a/.github/workflows/test-javascript.yml +++ b/.github/workflows/test-javascript.yml @@ -27,7 +27,7 @@ jobs: matrix: os: - ubuntu-latest - node-version: [22.x, 24.x] + node-version: [22.x, 24.x, 26.x] include: - os: windows-latest node-version: 22.x @@ -60,7 +60,7 @@ jobs: strategy: fail-fast: false matrix: - node-version: [22.x, 24.x] + node-version: [22.x, 24.x, 26.x] steps: - name: set git core.autocrlf to 'input' diff --git a/CHANGELOG.md b/CHANGELOG.md index 9547c470..12836117 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). ## [Unreleased] +### Changed +- BREAKING CHANGE: [JavaScript] Switch to ESM ([#513](https://github.com/cucumber/html-formatter/pull/513)) ## [23.1.0] - 2026-04-13 ### Changed diff --git a/javascript/.mocharc.json b/javascript/.mocharc.json index c929b6cc..d1690433 100644 --- a/javascript/.mocharc.json +++ b/javascript/.mocharc.json @@ -1,5 +1,5 @@ { - "require": ["ts-node/register", "source-map-support/register"], + "node-option": ["loader=ts-node/esm", "require=source-map-support/register"], "spec": "src/**/*.spec.ts", "extension": ["ts", "tsx"], "recursive": true, diff --git a/javascript/package.json b/javascript/package.json index ba7aa299..1c151f87 100644 --- a/javascript/package.json +++ b/javascript/package.json @@ -2,6 +2,7 @@ "name": "@cucumber/html-formatter", "version": "23.1.0", "description": "HTML formatter for Cucumber", + "type": "module", "main": "dist/src/index.js", "types": "dist/src/index.d.ts", "repository": { @@ -15,6 +16,7 @@ "build:tsc": "tsc --build tsconfig.build.json", "build:webpack": "webpack", "build": "npm run clean && npm run build:tsc && npm run prepare && npm run build:webpack", + "postbuild": "node -e \"require('.')\"", "prepare": "shx mkdir -p dist/src && shx cp src/*.scss dist/src && shx cp src/index.mustache dist/src && shx cp src/icon.url dist/src", "test": "mocha", "prepublishOnly": "npm run build", diff --git a/javascript/src/CucumberHtmlStream.spec.ts b/javascript/src/CucumberHtmlStream.spec.ts index 21bee1d5..14a4f939 100644 --- a/javascript/src/CucumberHtmlStream.spec.ts +++ b/javascript/src/CucumberHtmlStream.spec.ts @@ -2,7 +2,7 @@ import assert from 'node:assert' import { Writable } from 'node:stream' import type { Envelope } from '@cucumber/messages' -import { CucumberHtmlStream } from './CucumberHtmlStream' +import { CucumberHtmlStream } from './CucumberHtmlStream.js' async function renderAsHtml(...envelopes: Envelope[]): Promise { return new Promise((resolve, reject) => { @@ -15,8 +15,8 @@ async function renderAsHtml(...envelopes: Envelope[]): Promise { }) sink.on('finish', () => resolve(html)) const cucumberHtmlStream = new CucumberHtmlStream( - `${__dirname}/dummy.css`, - `${__dirname}/dummy.js` + `${import.meta.dirname}/dummy.css`, + `${import.meta.dirname}/dummy.js` ) cucumberHtmlStream.on('error', reject) cucumberHtmlStream.pipe(sink) diff --git a/javascript/src/CucumberHtmlStream.ts b/javascript/src/CucumberHtmlStream.ts index 91bdd9a8..84c1a468 100644 --- a/javascript/src/CucumberHtmlStream.ts +++ b/javascript/src/CucumberHtmlStream.ts @@ -15,9 +15,9 @@ export class CucumberHtmlStream extends Transform { * @param iconPath */ constructor( - private readonly cssPath: string = path.join(__dirname, '..', 'main.css'), - private readonly jsPath: string = path.join(__dirname, '..', 'main.js'), - private readonly iconPath: string = path.join(__dirname, 'icon.url') + private readonly cssPath: string = path.join(import.meta.dirname, '..', 'main.css'), + private readonly jsPath: string = path.join(import.meta.dirname, '..', 'main.js'), + private readonly iconPath: string = path.join(import.meta.dirname, 'icon.url') ) { super({ objectMode: true }) } @@ -140,7 +140,7 @@ export class CucumberHtmlStream extends Transform { if (this.template !== null) { return callback(null, this.template) } - fs.readFile(`${__dirname}/index.mustache`, { encoding: 'utf-8' }, (err, template) => { + fs.readFile(`${import.meta.dirname}/index.mustache`, { encoding: 'utf-8' }, (err, template) => { if (err) { return callback(err) } diff --git a/javascript/src/index.ts b/javascript/src/index.ts index fd3544f6..eaa67059 100644 --- a/javascript/src/index.ts +++ b/javascript/src/index.ts @@ -1,6 +1,6 @@ -import { CucumberHtmlStream } from './CucumberHtmlStream' +import { CucumberHtmlStream } from './CucumberHtmlStream.js' -export * from './CucumberHtmlStream' +export * from './CucumberHtmlStream.js' /** * @deprecated use the named export `CucumberHtmlStream` instead diff --git a/javascript/test/acceptance.spec.ts b/javascript/test/acceptance.spec.ts index 972fb284..133da159 100644 --- a/javascript/test/acceptance.spec.ts +++ b/javascript/test/acceptance.spec.ts @@ -6,12 +6,12 @@ import { NdjsonToMessageStream } from '@cucumber/message-streams' import { expect, test } from '@playwright/test' import { sync } from 'glob' -import { CucumberHtmlStream } from '../src' +import { CucumberHtmlStream } from '../src/index.js' const fixtures = sync(`./node_modules/@cucumber/compatibility-kit/features/**/*.ndjson`) test.beforeAll(async () => { - const outputDir = path.join(__dirname, './__output__') + const outputDir = path.join(import.meta.dirname, './__output__') for (const fixture of fixtures) { const name = path.basename(fixture, '.ndjson') @@ -21,9 +21,9 @@ test.beforeAll(async () => { fs.createReadStream(fixture, { encoding: 'utf-8' }), new NdjsonToMessageStream(), new CucumberHtmlStream( - path.join(__dirname, '../dist/main.css'), - path.join(__dirname, '../dist/main.js'), - path.join(__dirname, '../dist/src/icon.url') + path.join(import.meta.dirname, '../dist/main.css'), + path.join(import.meta.dirname, '../dist/main.js'), + path.join(import.meta.dirname, '../dist/src/icon.url') ), fs.createWriteStream(outputFile) ) diff --git a/javascript/webpack.config.js b/javascript/webpack.config.js index 5082a3eb..75861b4e 100644 --- a/javascript/webpack.config.js +++ b/javascript/webpack.config.js @@ -1,6 +1,6 @@ -const MiniCssExtractPlugin = require('mini-css-extract-plugin') +import MiniCssExtractPlugin from 'mini-css-extract-plugin' -module.exports = { +export default { entry: './dist/src/main.js', module: { rules: [