Skip to content

Commit d5732a8

Browse files
author
deepshekhardas
committed
feat: Backend esm vitest
Port of upstream #7605 Converts backend tests from mocha to vitest and migrates to ESM.
1 parent d426181 commit d5732a8

328 files changed

Lines changed: 4001 additions & 4582 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/backend-tests.yml

Lines changed: 52 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,19 @@ jobs:
6666
run: pnpm build
6767
-
6868
name: Run the backend tests
69-
run: pnpm test
70-
- name: Run the new vitest tests
71-
working-directory: src
72-
run: pnpm run test:vitest
69+
env:
70+
NODE_OPTIONS: "--report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=${{ github.workspace }}/node-report"
71+
run: |
72+
mkdir -p "${{ github.workspace }}/node-report"
73+
pnpm test
74+
- name: Upload Node diagnostic reports on failure
75+
if: ${{ failure() }}
76+
uses: actions/upload-artifact@v7
77+
with:
78+
name: node-diagnostic-report-${{ runner.os }}-node${{ matrix.node }}-${{ github.job }}
79+
path: node-report/
80+
if-no-files-found: ignore
81+
retention-days: 7
7382

7483
withpluginsLinux:
7584
env:
@@ -136,10 +145,19 @@ jobs:
136145
ep_table_of_contents
137146
-
138147
name: Run the backend tests
139-
run: pnpm test
140-
- name: Run the new vitest tests
141-
working-directory: src
142-
run: pnpm run test:vitest
148+
env:
149+
NODE_OPTIONS: "--report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=${{ github.workspace }}/node-report"
150+
run: |
151+
mkdir -p "${{ github.workspace }}/node-report"
152+
pnpm test
153+
- name: Upload Node diagnostic reports on failure
154+
if: ${{ failure() }}
155+
uses: actions/upload-artifact@v7
156+
with:
157+
name: node-diagnostic-report-${{ runner.os }}-node${{ matrix.node }}-${{ github.job }}
158+
path: node-report/
159+
if-no-files-found: ignore
160+
retention-days: 7
143161

144162
# Windows tests only run on push to develop/master, not on PRs
145163
withoutpluginsWindows:
@@ -200,12 +218,19 @@ jobs:
200218
name: Run the backend tests
201219
shell: bash
202220
working-directory: src
203-
# --exit makes mocha call process.exit() after the run so a leaked handle
204-
# cannot hang the job on Windows.
205-
run: pnpm test -- --exit
206-
- name: Run the new vitest tests
207-
working-directory: src
208-
run: pnpm run test:vitest
221+
env:
222+
NODE_OPTIONS: "--report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=${{ github.workspace }}/node-report"
223+
run: |
224+
mkdir -p "${{ github.workspace }}/node-report"
225+
pnpm test
226+
- name: Upload Node diagnostic reports on failure
227+
if: ${{ failure() }}
228+
uses: actions/upload-artifact@v7
229+
with:
230+
name: node-diagnostic-report-${{ runner.os }}-node${{ matrix.node }}-${{ github.job }}
231+
path: node-report/
232+
if-no-files-found: ignore
233+
retention-days: 7
209234

210235
withpluginsWindows:
211236
env:
@@ -294,9 +319,16 @@ jobs:
294319
name: Run the backend tests
295320
shell: bash
296321
working-directory: src
297-
# --exit makes mocha call process.exit() after the run so a leaked handle
298-
# cannot hang the job on Windows.
299-
run: pnpm test -- --exit
300-
- name: Run the new vitest tests
301-
working-directory: src
302-
run: pnpm run test:vitest
322+
env:
323+
NODE_OPTIONS: "--report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=${{ github.workspace }}/node-report"
324+
run: |
325+
mkdir -p "${{ github.workspace }}/node-report"
326+
pnpm test
327+
- name: Upload Node diagnostic reports on failure
328+
if: ${{ failure() }}
329+
uses: actions/upload-artifact@v7
330+
with:
331+
name: node-diagnostic-report-${{ runner.os }}-node${{ matrix.node }}-${{ github.job }}
332+
path: node-report/
333+
if-no-files-found: ignore
334+
retention-days: 7

CHANGELOG.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ A bundle of defence-in-depth tightening picked up during an internal audit pass
7272

7373
# 3.0.0
7474

75-
3.0 is a feature-heavy release that closes out the self-update programme (Tiers 2 and 3 land alongside Tier 1 from 2.7.3), removes the last identified upstream telemetry vector, and ships a parsed JSONC settings editor, native DOCX export, in-place pad history scrubbing, and an admin UI for GDPR author erasure. It also marks the start of the broader Etherpad app ecosystem (see *Companion apps* below).
75+
3.0 is a feature-heavy release that closes out the self-update programme (Tiers 2 and 3 land alongside Tier 1 from 2.7.3), removes the last identified upstream telemetry vector, and ships a parsed JSONC settings editor, native DOCX export, in-place pad history scrubbing, and an admin UI for GDPR author erasure. It also completes the backend ESM migration and replaces mocha with vitest as the backend test runner, and marks the start of the broader Etherpad app ecosystem (see *Companion apps* below).
7676

7777
### Breaking changes
7878

@@ -81,6 +81,11 @@ A bundle of defence-in-depth tightening picked up during an internal audit pass
8181
- **`swagger-ui-express` removed.** `/api-docs` now serves a vendored, telemetry-free copy of [Scalar](https://github.com/scalar/scalar) (see the privacy item below). The route, the OpenAPI document, and the rendered output are unchanged for downstream consumers, but anything that introspected `swagger-ui-express` internals will need updating.
8282
- **Debian package depends on `nodejs (>= 24)`.** The signed apt repository at `etherpad.org/apt` is rebuilt against this floor; older Node packages are no longer acceptable as a dependency (#7754).
8383

84+
### Breaking changes for plugin authors
85+
86+
- Migrated the Etherpad backend (everything under `src/node/` and the server-side parts of `src/static/js/pluginfw/`) from CommonJS to ECMAScript modules. **Existing CommonJS plugins continue to load unchanged** — the plugin loader now uses Node's `createRequire` to keep `require()` working synchronously against CJS plugin entry files. ESM plugins are also supported (use `"type": "module"` or `.mjs`, export hooks with `export const`). One contract change: the accessor-property shim that exposed `Settings` top-level fields directly on the `require()` result has been removed (it was dead code under ESM). Plugins reading core settings via `require('ep_etherpad-lite/node/utils/Settings').toolbar` must now use `import settings from '...'` (ESM) or `require('...').default.toolbar` (CJS via the bridge). See `doc/plugins.md` for the full updated contract.
87+
- Replaced mocha with vitest as the backend test runner. `pnpm test` now runs vitest. Plugin authors with backend test suites that ran under the core mocha runner via `../node_modules/ep_*/static/tests/backend/specs/**` should expect to migrate their tests to vitest.
88+
8489
### Companion apps
8590

8691
This release coincides with the launch of two ecosystem projects, both maintained under the [`ether` org](https://github.com/ether) and able to talk to any 3.x Etherpad server over its existing HTTP / WebSocket API:

doc/plugins.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,18 @@ name of a function exported by the named module. See
9090
[`module.exports`](https://nodejs.org/docs/latest/api/modules.html#modules_module_exports)
9191
for how to export a function.
9292

93+
> **Note (Etherpad ≥ 2.7.x):** the core was migrated to ECMAScript modules,
94+
> but the plugin loader uses Node's `createRequire` so existing CommonJS
95+
> plugins (the documented format above) continue to load unchanged. ESM
96+
> plugins are also supported — name your hook entry file with a `.mjs`
97+
> extension or set `"type": "module"` in your plugin's `package.json`, and
98+
> export hook functions with `export const`. One contract change: plugins
99+
> that previously read core settings via `require('ep_etherpad-lite/node/utils/Settings').toolbar`
100+
> must now use either `import settings from 'ep_etherpad-lite/node/utils/Settings'`
101+
> (ESM) or `require('ep_etherpad-lite/node/utils/Settings').default.toolbar`
102+
> (CJS via the bridge). The accessor-property shim that exposed top-level
103+
> fields directly on the require() result is gone.
104+
93105
For the module name you can omit the `.js` suffix, and if the file is `index.js`
94106
you can use just the directory name. You can also omit the module name entirely,
95107
in which case it defaults to the plugin name (e.g., `ep_example`).

0 commit comments

Comments
 (0)