Skip to content

test(flake): scoped per-test event-loop yield in the 6 dying spec files#7854

Closed
JohnMcLear wants to merge 1 commit into
developfrom
test-flake-dying-describe-drain
Closed

test(flake): scoped per-test event-loop yield in the 6 dying spec files#7854
JohnMcLear wants to merge 1 commit into
developfrom
test-flake-dying-describe-drain

Conversation

@JohnMcLear
Copy link
Copy Markdown
Member

Summary

Adds beforeEach(async () => await new Promise(r => setImmediate(r))) at the top-level describe of the six spec files that cluster in the silent-ELIFECYCLE captures. Pattern-wide intervention against rapid-sequential test cadence as the suspected trigger.

Why

12 captured silent-ELIFECYCLE deaths (#7838, #7842, #7846 diagnostics) all hit the same six files:

File Deaths
importexportGetPost.ts 4
socketio.ts 3
messages.ts 3
pad.ts > Tests 2
import.ts 1
clientvar_rev_consistency.ts 1

All six share a shape: 50–100 short tests per top-level describe, each test making rapid loopback HTTP (supertest) or socket.io connect/disconnect calls. Pre-kill node-reports show V8 main isolate going event-loop-starved for 200–400 ms before each kill (5 Hz heartbeat falls silent), then external termination.

The TIME_WAIT smoking gun captured by #7846 was ruled out as causal by #7852 (closed): keepAlive collapsed TIME_WAIT churn to zero, kill survived anyway. The remaining shared substrate is just cadence.

What this changes

One beforeEach per file, inserted at the top-level describe(__filename, ...). The yield forces a timer-queue drain between every test in those files, breaking the tight microtask chain that may be the trigger.

Critical scope note: per-file beforeEach, NOT root mochaHooks.beforeEach. PR #7844 tried the root-level variant and broke ep_subscript_and_superscript's returns HTML with Subscript HTML tags tests, which share state across describe-block boundaries. Per-file scope contains any timing perturbation to the affected files — plugin tests loaded from ../node_modules/ep_*/static/tests/backend/specs are completely untouched.

Expected outcomes

  • Linux ± plugins must pass. If they regress, the yield is breaking the affected tests' own state-sharing assumptions — we'd revert.
  • Windows ± plugins flake rate:

Either result is data we don't currently have.

Locally verified

Not feasible — local mocha against this project needs full bootstrap. Relying on CI.

🤖 Generated with Claude Code

@qodo-code-review
Copy link
Copy Markdown

Qodo reviews are paused for this user.

Troubleshooting steps vary by plan Learn more →

On a Teams plan?
Reviews resume once this user has a paid seat and their Git account is linked in Qodo.
Link Git account →

Using GitHub Enterprise Server, GitLab Self-Managed, or Bitbucket Data Center?
These require an Enterprise plan - Contact us
Contact us →

@qodo-free-for-open-source-projects
Copy link
Copy Markdown

Review Summary by Qodo

Add per-test event-loop yield to six flaky spec files

🧪 Tests

Grey Divider

Walkthroughs

Description
• Add per-test event-loop yield via setImmediate in beforeEach
• Target six spec files with Windows silent-ELIFECYCLE flake
• Break tight microtask chains causing event-loop starvation
• Scoped per-file to avoid breaking plugin state-sharing
Diagram
flowchart LR
  A["Six spec files<br/>with ELIFECYCLE flake"] -->|"Add beforeEach<br/>with setImmediate yield"| B["Event loop<br/>drains timer queue<br/>between tests"]
  B -->|"Breaks microtask<br/>chains"| C["Reduces event-loop<br/>starvation on Windows"]

Loading

Grey Divider

File Changes

1. src/tests/backend/specs/api/importexportGetPost.ts 🧪 Tests +5/-0

Add event-loop yield to importexportGetPost tests

• Add beforeEach hook with setImmediate yield at top-level describe
• Include comment referencing rationale in api/pad.ts
• Force event loop drain between each test in file

src/tests/backend/specs/api/importexportGetPost.ts


2. src/tests/backend/specs/api/pad.ts 🧪 Tests +13/-0

Add event-loop yield with detailed flake rationale

• Add beforeEach hook with setImmediate yield at top-level describe
• Include detailed comment explaining Windows ELIFECYCLE flake diagnosis
• Document why per-file scope is critical vs root-level mocha hook
• Reference PR #7844 and #7838/#7842/#7846 diagnostics

src/tests/backend/specs/api/pad.ts


3. src/tests/backend/specs/clientvar_rev_consistency.ts 🧪 Tests +5/-0

Add event-loop yield to clientvar_rev_consistency tests

• Add beforeEach hook with setImmediate yield at top-level describe
• Include comment referencing rationale in api/pad.ts
• Force event loop drain between each test in file

src/tests/backend/specs/clientvar_rev_consistency.ts


View more (3)
4. src/tests/backend/specs/import.ts 🧪 Tests +5/-0

Add event-loop yield to import tests

• Add beforeEach hook with setImmediate yield at top-level describe
• Include comment referencing rationale in api/pad.ts
• Force event loop drain between each test in file

src/tests/backend/specs/import.ts


5. src/tests/backend/specs/messages.ts 🧪 Tests +5/-0

Add event-loop yield to messages tests

• Add beforeEach hook with setImmediate yield at top-level describe
• Include comment referencing rationale in api/pad.ts
• Force event loop drain between each test in file

src/tests/backend/specs/messages.ts


6. src/tests/backend/specs/socketio.ts 🧪 Tests +5/-0

Add event-loop yield to socketio tests

• Add beforeEach hook with setImmediate yield at top-level describe
• Include comment referencing rationale in api/pad.ts
• Force event loop drain between each test in file
• Positioned after timeout configuration

src/tests/backend/specs/socketio.ts


Grey Divider

Qodo Logo

@qodo-free-for-open-source-projects
Copy link
Copy Markdown

qodo-free-for-open-source-projects Bot commented May 26, 2026

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (0)

Grey Divider


Remediation recommended

1. Duplicated yield hook 🐞 Bug ⚙ Maintainability
Description
The same per-test setImmediate yield hook is duplicated across six spec files, making future
tuning/error-handling updates easy to miss in one file and creating divergence risk. The PR already
documents why the workaround must stay per-file scoped, so extracting the yield into a shared helper
(still called per-file) would reduce duplication without reintroducing the root-hook problem.
Code

src/tests/backend/specs/api/pad.ts[R52-63]

Evidence
The PR introduces identical beforeEach(async () => await new Promise((r) => setImmediate(r)))
blocks in multiple spec files. api/pad.ts explicitly states the constraint that prevents using a
root mocha hook, which supports the recommendation to deduplicate via a helper while preserving
per-file scoping.

src/tests/backend/specs/api/pad.ts[51-63]
src/tests/backend/specs/api/importexportGetPost.ts[38-45]
src/tests/backend/specs/clientvar_rev_consistency.ts[23-28]
src/tests/backend/specs/import.ts[13-18]
src/tests/backend/specs/messages.ts[12-17]
src/tests/backend/specs/socketio.ts[13-19]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The same async `beforeEach` hook (`await new Promise((r) => setImmediate(r))`) is duplicated across six spec files. This increases the chance that future adjustments (changing the yield mechanism, adding diagnostics, gating to Windows, etc.) are applied inconsistently.

The workaround needs to remain **per-file scoped** (as documented) rather than moved to a root mocha hook; the goal is to remove duplication while keeping the same scope.

### Issue Context
`src/tests/backend/specs/api/pad.ts` already explains why a root-level hook is not acceptable (it previously broke plugin tests due to cross-describe state sharing). The code can still be deduplicated by extracting a helper function and calling it from each of the six files.

### Fix Focus Areas
- src/tests/backend/specs/api/pad.ts[52-63]
- src/tests/backend/specs/api/importexportGetPost.ts[40-44]
- src/tests/backend/specs/clientvar_rev_consistency.ts[24-28]
- src/tests/backend/specs/import.ts[14-18]
- src/tests/backend/specs/messages.ts[13-17]
- src/tests/backend/specs/socketio.ts[15-19]

### Suggested approach
1. Add a small helper in an appropriate shared test location (for example `src/tests/backend/specs/helpers/eventLoopYield.ts` or `src/tests/backend/common.ts`) such as:
  - `export const perTestEventLoopYield = () => beforeEach(async () => await new Promise<void>(setImmediate));`
2. Replace each duplicated block with a call to that helper inside the file's top-level `describe()`.
3. Keep the existing per-file comments (or make them a single shared comment in the helper and a short per-file reference) so the rationale remains discoverable.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

… to etherpad's own backend specs

PR #7854's first iteration added the yield to 6 known-dying spec files
(pad.ts, importexportGetPost.ts, socketio.ts, messages.ts, import.ts,
clientvar_rev_consistency.ts). Linux backend matrix passed, proving
the yield doesn't break the affected tests' own state-sharing
assumptions. But the very next Win+plugins run captured **death #13
in sessionsAndGroups.ts**, a 7th file outside the scoped fix. The
flake migrated rather than being suppressed.

That's strong evidence the trigger is the rapid-sequential-test
pattern in general, not specific files. Replace the per-file scope
with a root-level `mochaHooks.beforeEach` yield in diagnostics.ts,
gated on a file-path check: yield for ether/etherpad's own specs in
`tests/backend/specs/`, SKIP for plugin tests loaded from
`../node_modules/ep_*/static/tests/backend/specs/`.

The plugin-test skip exists because PR #7844 demonstrated that an
unconditional global yield breaks `ep_subscript_and_superscript`'s
`returns HTML with Subscript HTML tags` series — those plugin tests
share state across describe-block boundaries and don't tolerate any
microtask reordering. The file-path check preserves PR #7844's
finding without re-breaking those tests.

Files modified:
  - src/tests/backend/diagnostics.ts: root beforeEach yield, scoped

Per-file changes from the previous commit are reverted — root scope
supersedes them and there's no point yielding twice per test.

Test plan unchanged from the original PR:
  - Linux ± plugins must pass.
  - Windows ± plugins flake rate: ~22% pre-fix. Post-fix, run the CI
    5-10x and compare. If unchanged, cadence is ruled out as the
    trigger and we look at per-test pathologies (jose CNG on
    Windows, libuv IOCP edge cases unrelated to load).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@JohnMcLear JohnMcLear force-pushed the test-flake-dying-describe-drain branch from 1bf8a75 to 83e1d37 Compare May 26, 2026 13:48
@qodo-free-for-open-source-projects
Copy link
Copy Markdown

CI Feedback 🧐

A test triggered by this PR failed. Here is an AI-generated analysis of the failure:

Action: Windows without plugins (24)

Failed stage: Run the backend tests [❌]

Failed test name: Pad-wide settings creator gate different browsers (separate cookie jars): only the creator gets canEditPadSettings

Failure summary:

The GitHub Action failed because the test run (pnpm test -- --exit) exited with a non-zero status
(##[error]Process completed with exit code 255), reported as [ELIFECYCLE] Test failed.
The log
excerpt does not include the actual assertion/stack trace for the failing expectation, but the run
stops immediately after starting the test:

D:\a\etherpad\etherpad\src\tests\backend\specs\socketio.ts Pad-wide settings creator gate different
browsers (separate cookie jars): only the creator gets canEditPadSettings
indicating that this is
the most likely test that failed right before the runner aborted.

Relevant error logs:
1:  ##[group]Runner Image Provisioner
2:  Hosted Compute Agent
...

355:  ##[group]Run powershell -Command "(gc settings.json.template) -replace '\"max\": 10', '\"max\": 10000' | Out-File -encoding ASCII settings.json.holder"
356:  �[36;1mpowershell -Command "(gc settings.json.template) -replace '\"max\": 10', '\"max\": 10000' | Out-File -encoding ASCII settings.json.holder"�[0m
357:  �[36;1mpowershell -Command "(gc settings.json.holder) -replace '\"points\": 10', '\"points\": 1000' | Out-File -encoding ASCII settings.json"�[0m
358:  shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'"
359:  env:
360:  PNPM_HOME: C:\Users\runneradmin\setup-pnpm\node_modules\.bin
361:  ##[endgroup]
362:  ##[group]Run mkdir -p "D:\a\etherpad\etherpad/node-report"
363:  �[36;1mmkdir -p "D:\a\etherpad\etherpad/node-report"�[0m
364:  �[36;1mOUT="D:\a\etherpad\etherpad/node-report"�[0m
365:  �[36;1m# Out-of-process OS-level watcher for the silent-ELIFECYCLE flake.�[0m
366:  �[36;1m# In-process diagnostics (diagnostics.ts heartbeat + node-report�[0m
367:  �[36;1m# snapshots) showed that during the death window the V8 main�[0m
368:  �[36;1m# isolate is starved — heartbeat stops firing entirely, then the�[0m
369:  �[36;1m# process is externally terminated, bypassing all JS handlers and�[0m
370:  �[36;1m# Node's --report-on-fatalerror. To capture state during that�[0m
371:  �[36;1m# starvation we need a process that doesn't depend on the dying�[0m
372:  �[36;1m# process's event loop. A bash background loop polling Windows�[0m
373:  �[36;1m# OS state every 500 ms gives us that:�[0m
374:  �[36;1m#   - netstat.log: localhost TCP socket states over time�[0m
375:  �[36;1m#     (TIME_WAIT/CLOSE_WAIT accumulation, handle exhaustion)�[0m
376:  �[36;1m#   - tasklist.log: node.exe process handle count, working set,�[0m
377:  �[36;1m#     CPU time — captured by the OS independent of V8.�[0m
378:  �[36;1m# Both logs are appended to node-report/ which already gets�[0m
379:  �[36;1m# uploaded as an artifact on failure.�[0m
380:  �[36;1m(�[0m
...

394:  �[36;1mWATCHER_PID=$!�[0m
395:  �[36;1m# --exit forces process.exit(failures) after the suite completes,�[0m
396:  �[36;1m# closing the post-suite event-loop drain window where Windows +�[0m
397:  �[36;1m# Node 24 hard-kills the process. Scoped to Windows so Linux/local�[0m
398:  �[36;1m# runs still surface real handle leaks via natural drain.�[0m
399:  �[36;1mset +e�[0m
400:  �[36;1mpnpm test -- --exit�[0m
401:  �[36;1mEXIT=$?�[0m
402:  �[36;1mset -e�[0m
403:  �[36;1mkill "$WATCHER_PID" 2>/dev/null || true�[0m
404:  �[36;1mwait "$WATCHER_PID" 2>/dev/null || true�[0m
405:  �[36;1mexit $EXIT�[0m
406:  shell: C:\Program Files\Git\bin\bash.EXE --noprofile --norc -e -o pipefail {0}
407:  env:
408:  PNPM_HOME: C:\Users\runneradmin\setup-pnpm\node_modules\.bin
409:  NODE_OPTIONS: --report-on-fatalerror --report-uncaught-exception --report-on-signal --report-compact --report-directory=D:\a\etherpad\etherpad/node-report
410:  ##[endgroup]
...

445:  �[32m[2026-05-26T13:50:07.083] [INFO] plugins - �[39mLoaded 1 plugins
446:  �[32m[2026-05-26T13:50:07.436] [INFO] server - �[39mInstalled plugins: 
447:  �[32m[2026-05-26T13:50:07.438] [INFO] settings - �[39mReport bugs at https://github.com/ether/etherpad/issues
448:  �[32m[2026-05-26T13:50:07.439] [INFO] settings - �[39mYour Etherpad version is 3.2.0 (83e1d37)
449:  [diag +4481ms] hb running="<no test running>" lastFinished="<no test finished yet>" rss=349M heap=126M handles=3 requests=39
450:  Writing Node.js report to file: hb-0007-_no_test_running_.json
451:  Node.js report completed
452:  [diag +5361ms] hb running="<no test running>" lastFinished="<no test finished yet>" rss=383M heap=173M handles=3 requests=6
453:  Writing Node.js report to file: hb-0008-_no_test_running_.json
454:  Node.js report completed
455:  �[32m[2026-05-26T13:50:08.422] [INFO] updater - �[39mupdater: install method = git, tier = notify
456:  �[32m[2026-05-26T13:50:08.425] [INFO] http - �[39mHTTP server listening for connections
457:  �[32m[2026-05-26T13:50:08.425] [INFO] settings - �[39mYou can access your Etherpad instance at http://localhost:0/
458:  �[33m[2026-05-26T13:50:08.425] [WARN] settings - �[39mAdmin username and password not set in settings.json. To access admin please uncomment and edit "users" in settings.json
459:  �[32m[2026-05-26T13:50:08.425] [INFO] server - �[39mEtherpad is running
460:  D:\a\etherpad\etherpad\src\tests\backend\specs\admin\adminSettingsAuthError.ts
461:  [diag +5465ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\admin\adminSettingsAuthError.ts emits admin_auth_error and disconnects when not authenticated as admin
462:  Writing Node.js report to file: be-0009-D_a_etherpad_etherpad_src_tests_backend_specs_admin_adminSettingsAuthError.ts_em.json
463:  Node.js report completed
464:  [diag +5561ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\admin\adminSettingsAuthError.ts emits admin_auth_error and disconnects when not authenticated as admin" lastFinished="<no test finished yet>" rss=384M heap=175M handles=6 requests=0
465:  Writing Node.js report to file: hb-0010-D_a_etherpad_etherpad_src_tests_backend_specs_admin_adminSettingsAuthError.ts_em.json
466:  Node.js report completed
467:  ✔ emits admin_auth_error and disconnects when not authenticated as admin (104ms)
468:  AdminSettingsRedact
...

526:  ✔ preserves /* */ comments in the written file
527:  D:\a\etherpad\etherpad\src\tests\backend\specs\admin\anonymizeAuthorSocket.ts
528:  �[32m[2026-05-26T13:50:09.336] [INFO] http - �[39mSuccessful authentication from IP ANONYMOUS for user test-admin
529:  [diag +6397ms] hb running="<no test running>" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\admin\adminSettingsSave.ts preserves /* */ comments in the written file" rss=386M heap=182M handles=6 requests=0
530:  Writing Node.js report to file: hb-0018-_no_test_running_.json
531:  Node.js report completed
532:  [diag +6486ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\admin\anonymizeAuthorSocket.ts authorLoad returns paginated rows
533:  Writing Node.js report to file: be-0019-D_a_etherpad_etherpad_src_tests_backend_specs_admin_anonymizeAuthorSocket.ts_aut.json
534:  Node.js report completed
535:  ✔ authorLoad returns paginated rows
536:  [diag +6571ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\admin\anonymizeAuthorSocket.ts anonymizeAuthorPreview returns counters without flipping erased
537:  ✔ anonymizeAuthorPreview returns counters without flipping erased
538:  [diag +6573ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\admin\anonymizeAuthorSocket.ts anonymizeAuthor commits when the flag is enabled
539:  �[32m[2026-05-26T13:50:09.537] [INFO] adminSettings - �[39manonymizeAuthor (admin socket): a.WWlADiMnfS7BDio7
540:  ✔ anonymizeAuthor commits when the flag is enabled
541:  [diag +6575ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\admin\anonymizeAuthorSocket.ts anonymizeAuthor returns {error: "disabled"} when flag is off
542:  ✔ anonymizeAuthor returns {error: "disabled"} when flag is off
543:  [diag +6576ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\admin\anonymizeAuthorSocket.ts anonymizeAuthorPreview returns {error: "disabled"} when flag is off
544:  ✔ anonymizeAuthorPreview returns {error: "disabled"} when flag is off
545:  [diag +6577ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\admin\anonymizeAuthorSocket.ts authorLoad returns {error: "disabled"} when flag is off
546:  ✔ authorLoad returns {error: "disabled"} when flag is off
547:  [diag +6578ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\admin\anonymizeAuthorSocket.ts handlers do not crash on payload-less emits
...

588:  [diag +7375ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\admin\padLoadFilter.ts filter omitted (older client) falls back to "all"
589:  ✔ filter omitted (older client) falls back to "all"
590:  [diag +7376ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\admin\padLoadFilter.ts filter:"all" matches the no-filter behaviour
591:  ✔ filter:"all" matches the no-filter behaviour
592:  [diag +7377ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\admin\padLoadFilter.ts filter:"active" excludes pads with no active users
593:  ✔ filter:"active" excludes pads with no active users
594:  D:\a\etherpad\etherpad\src\tests\backend\specs\anonymizeAuthor.ts
595:  [diag +7383ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\anonymizeAuthor.ts zeroes the display identity on globalAuthor:<id>
596:  ✔ zeroes the display identity on globalAuthor:<id>
597:  [diag +7384ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\anonymizeAuthor.ts drops token2author and mapper2author mappings pointing at the author
598:  ✔ drops token2author and mapper2author mappings pointing at the author
599:  [diag +7386ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\anonymizeAuthor.ts is idempotent — second call returns zero counters
600:  ✔ is idempotent — second call returns zero counters
601:  [diag +7387ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\anonymizeAuthor.ts returns zero counters for an unknown authorID
602:  ✔ returns zero counters for an unknown authorID
603:  [diag +7388ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\anonymizeAuthor.ts re-runs the sweep when a prior call errored before setting erased=true
604:  ✔ re-runs the sweep when a prior call errored before setting erased=true
605:  [diag +7389ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\anonymizeAuthor.ts dryRun returns the same counter shape but does not mutate the record
...

646:  [diag +7665ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\anonymizeIp.ts empty / null input returns ANONYMOUS for '' in truncated mode
647:  ✔ returns ANONYMOUS for null in truncated mode
648:  ✔ returns ANONYMOUS for '' in truncated mode
649:  [diag +7665ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\anonymizeIp.ts empty / null input returns ANONYMOUS for null in anonymous mode
650:  [diag +7665ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\anonymizeIp.ts empty / null input returns ANONYMOUS for '' in anonymous mode
651:  ✔ returns ANONYMOUS for null in anonymous mode
652:  ✔ returns ANONYMOUS for '' in anonymous mode
653:  D:\a\etherpad\etherpad\src\tests\backend\specs\api\anonymizeAuthor.ts
654:  [diag +7670ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\anonymizeAuthor.ts anonymizeAuthor zeroes the author and returns counters
655:  Writing Node.js report to file: be-0031-D_a_etherpad_etherpad_src_tests_backend_specs_api_anonymizeAuthor.ts_anonymizeAu.json
656:  Node.js report completed
657:  [diag +7753ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\anonymizeAuthor.ts anonymizeAuthor zeroes the author and returns counters" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\anonymizeIp.ts empty / null input returns ANONYMOUS for '' in anonymous mode" rss=389M heap=164M handles=4 requests=0
658:  Writing Node.js report to file: hb-0032-D_a_etherpad_etherpad_src_tests_backend_specs_api_anonymizeAuthor.ts_anonymizeAu.json
659:  Node.js report completed
660:  ✔ anonymizeAuthor zeroes the author and returns counters
661:  [diag +7864ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\anonymizeAuthor.ts anonymizeAuthor with missing authorID returns an error
662:  Writing Node.js report to file: be-0033-D_a_etherpad_etherpad_src_tests_backend_specs_api_anonymizeAuthor.ts_anonymizeAu.json
663:  Node.js report completed
664:  ✔ anonymizeAuthor with missing authorID returns an error
665:  [diag +7953ms] hb running="<no test running>" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\anonymizeAuthor.ts anonymizeAuthor with missing authorID returns an error" rss=404M heap=166M handles=4 requests=0
666:  Writing Node.js report to file: hb-0034-_no_test_running_.json
667:  Node.js report completed
668:  [diag +8030ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\anonymizeAuthor.ts anonymizeAuthor returns an apierror when gdprAuthorErasure is disabled
669:  Writing Node.js report to file: be-0035-D_a_etherpad_etherpad_src_tests_backend_specs_api_anonymizeAuthor.ts_anonymizeAu.json
670:  Node.js report completed
671:  ✔ anonymizeAuthor returns an apierror when gdprAuthorErasure is disabled
672:  D:\a\etherpad\etherpad\src\tests\backend\specs\api\api.ts
...

726:  ✔ appendText with authorId attributes the text to that author (106ms)
727:  [diag +10989ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\appendTextAuthor.ts appendText without authorId does not attribute to any author
728:  Writing Node.js report to file: be-0045-D_a_etherpad_etherpad_src_tests_backend_specs_api_appendTextAuthor.ts_appendText.json
729:  Node.js report completed
730:  ✔ appendText without authorId does not attribute to any author
731:  D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts
732:  Sanity checks
733:  [diag +11085ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Sanity checks can connect
734:  ✔ can connect
735:  [diag +11089ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Sanity checks finds the version tag
736:  Writing Node.js report to file: be-0046-D_a_etherpad_etherpad_src_tests_backend_specs_api_characterEncoding.ts_Sanity_ch.json
737:  Node.js report completed
738:  [diag +11162ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Sanity checks finds the version tag" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Sanity checks can connect" rss=399M heap=165M handles=4 requests=0
739:  Writing Node.js report to file: hb-0047-D_a_etherpad_etherpad_src_tests_backend_specs_api_characterEncoding.ts_Sanity_ch.json
740:  Node.js report completed
741:  [diag +11273ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Sanity checks errors with invalid OAuth token
742:  ✔ finds the version tag
743:  Writing Node.js report to file: be-0048-D_a_etherpad_etherpad_src_tests_backend_specs_api_characterEncoding.ts_Sanity_ch.json
744:  Node.js report completed
745:  [diag +11372ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Sanity checks errors with invalid OAuth token" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Sanity checks finds the version tag" rss=399M heap=165M handles=4 requests=0
746:  Writing Node.js report to file: hb-0049-D_a_etherpad_etherpad_src_tests_backend_specs_api_characterEncoding.ts_Sanity_ch.json
747:  Node.js report completed
748:  ✔ errors with invalid OAuth token
749:  [diag +11493ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Sanity checks errors with unprivileged OAuth token
750:  Writing Node.js report to file: be-0050-D_a_etherpad_etherpad_src_tests_backend_specs_api_characterEncoding.ts_Sanity_ch.json
751:  Node.js report completed
752:  [diag +11574ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Sanity checks errors with unprivileged OAuth token" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Sanity checks errors with invalid OAuth token" rss=264M heap=122M handles=4 requests=0
753:  Writing Node.js report to file: hb-0051-D_a_etherpad_etherpad_src_tests_backend_specs_api_characterEncoding.ts_Sanity_ch.json
754:  Node.js report completed
755:  ✔ errors with unprivileged OAuth token
756:  Tests
...

762:  [diag +12049ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Tests Sets the HTML of a Pad attempting to weird utf8 encoded content" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Tests creates a new Pad" rss=283M heap=133M handles=6 requests=1
763:  Writing Node.js report to file: hb-0053-D_a_etherpad_etherpad_src_tests_backend_specs_api_characterEncoding.ts_Tests_Set.json
764:  Node.js report completed
765:  Writing Node.js report to file: mt-0054-D_a_etherpad_etherpad_src_tests_backend_specs_api_characterEncoding.ts_Tests_Set.json
766:  Node.js report completed
767:  ✔ Sets the HTML of a Pad attempting to weird utf8 encoded content (505ms)
768:  [diag +12252ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Tests Sets the HTML of a Pad attempting to weird utf8 encoded content" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Tests creates a new Pad" rss=277M heap=127M handles=4 requests=0
769:  Writing Node.js report to file: hb-0055-D_a_etherpad_etherpad_src_tests_backend_specs_api_characterEncoding.ts_Tests_Set.json
770:  Node.js report completed
771:  [diag +12332ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\characterEncoding.ts Tests get the HTML of Pad with emojis
772:  Writing Node.js report to file: be-0056-D_a_etherpad_etherpad_src_tests_backend_specs_api_characterEncoding.ts_Tests_get.json
773:  Node.js report completed
774:  ✔ get the HTML of Pad with emojis
775:  D:\a\etherpad\etherpad\src\tests\backend\specs\api\chat.ts
776:  API Versioning
777:  [diag +12425ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\chat.ts API Versioning errors if can not connect
778:  ✔ errors if can not connect
779:  Chat functionality
...

1518:  [diag +25913ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports revisions are supported in txt and html export txt request rev 2
1519:  �[32m[2026-05-26T13:50:28.875] [INFO] settings - �[39mExporting pad "ChzBh" in txt format
1520:  ✔ txt request rev 1
1521:  Writing Node.js report to file: be-0194-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1522:  Node.js report completed
1523:  [diag +26008ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports revisions are supported in txt and html export txt request rev 2" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports revisions are supported in txt and html export txt request rev 1" rss=333M heap=139M handles=4 requests=0
1524:  Writing Node.js report to file: hb-0195-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1525:  Node.js report completed
1526:  �[32m[2026-05-26T13:50:29.046] [INFO] settings - �[39mExporting pad "ChzBh" in txt format
1527:  ✔ txt request rev 2
1528:  [diag +26084ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports revisions are supported in txt and html export txt request rev 1test returns rev 1
1529:  Writing Node.js report to file: be-0196-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1530:  Node.js report completed
1531:  �[32m[2026-05-26T13:50:29.135] [INFO] settings - �[39mExporting pad "ChzBh" in txt format
1532:  ✔ txt request rev 1test returns rev 1
1533:  [diag +26174ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports revisions are supported in txt and html export txt request rev test1 returns 500 with error message
1534:  �[32m[2026-05-26T13:50:29.141] [INFO] settings - �[39mExporting pad "ChzBh" in txt format
1535:  ✔ txt request rev test1 returns 500 with error message
1536:  [diag +26179ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports revisions are supported in txt and html export txt request rev 5 returns head rev
...

1564:  Writing Node.js report to file: hb-0200-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1565:  Node.js report completed
1566:  ✔ !authn !exist -> create (136ms)
1567:  [diag +26576ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks !authn exist -> replace
1568:  Writing Node.js report to file: be-0201-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1569:  Node.js report completed
1570:  [diag +26677ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks !authn exist -> replace" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks !authn !exist -> create" rss=333M heap=143M handles=5 requests=1
1571:  Writing Node.js report to file: hb-0202-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1572:  Node.js report completed
1573:  Writing Node.js report to file: mt-0203-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1574:  Node.js report completed
1575:  [diag +26899ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks !authn exist -> replace" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks !authn !exist -> create" rss=332M heap=143M handles=6 requests=1
1576:  Writing Node.js report to file: hb-0204-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1577:  Node.js report completed
1578:  ✔ !authn exist -> replace (299ms)
1579:  [diag +26973ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn anonymous !exist -> fail
1580:  Writing Node.js report to file: be-0205-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1581:  Node.js report completed
1582:  �[32m[2026-05-26T13:50:30.009] [INFO] http - �[39mFailed authentication from IP ANONYMOUS
1583:  ✔ authn anonymous !exist -> fail
1584:  [diag +27048ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn anonymous exist -> fail
1585:  �[32m[2026-05-26T13:50:30.015] [INFO] http - �[39mFailed authentication from IP ANONYMOUS
1586:  ✔ authn anonymous exist -> fail
1587:  [diag +27055ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user create !exist -> create
1588:  �[32m[2026-05-26T13:50:30.021] [INFO] http - �[39mSuccessful authentication from IP ANONYMOUS for user user
1589:  [diag +27113ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user create !exist -> create" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn anonymous exist -> fail" rss=332M heap=145M handles=6 requests=0
1590:  Writing Node.js report to file: hb-0206-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1591:  Node.js report completed
1592:  Writing Node.js report to file: mt-0207-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1593:  Node.js report completed
1594:  ✔ authn user create !exist -> create (246ms)
1595:  [diag +27302ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user modify !exist -> fail
1596:  Writing Node.js report to file: be-0208-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1597:  Node.js report completed
1598:  [diag +27378ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user modify !exist -> fail" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user create !exist -> create" rss=332M heap=145M handles=4 requests=0
1599:  Writing Node.js report to file: hb-0209-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1600:  Node.js report completed
1601:  �[32m[2026-05-26T13:50:30.416] [INFO] http - �[39mSuccessful authentication from IP ANONYMOUS for user user
1602:  ✔ authn user modify !exist -> fail
1603:  [diag +27455ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user readonly !exist -> fail
1604:  Writing Node.js report to file: be-0210-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1605:  Node.js report completed
1606:  �[32m[2026-05-26T13:50:30.492] [INFO] http - �[39mSuccessful authentication from IP ANONYMOUS for user user
1607:  ✔ authn user readonly !exist -> fail
1608:  [diag +27530ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user create exist -> replace
1609:  �[32m[2026-05-26T13:50:30.497] [INFO] http - �[39mSuccessful authentication from IP ANONYMOUS for user user
1610:  [diag +27589ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user create exist -> replace" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user readonly !exist -> fail" rss=332M heap=146M handles=6 requests=0
1611:  Writing Node.js report to file: hb-0211-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1612:  Node.js report completed
1613:  ✔ authn user create exist -> replace (138ms)
1614:  [diag +27670ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user modify exist -> replace
1615:  Writing Node.js report to file: be-0212-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1616:  Node.js report completed
1617:  �[32m[2026-05-26T13:50:30.708] [INFO] http - �[39mSuccessful authentication from IP ANONYMOUS for user user
1618:  [diag +27789ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user modify exist -> replace" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user create exist -> replace" rss=332M heap=147M handles=6 requests=0
1619:  Writing Node.js report to file: hb-0213-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1620:  Node.js report completed
1621:  Writing Node.js report to file: mt-0214-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1622:  Node.js report completed
1623:  ✔ authn user modify exist -> replace (233ms)
1624:  [diag +27974ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user readonly exist -> fail
1625:  Writing Node.js report to file: be-0215-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1626:  Node.js report completed
1627:  [diag +28047ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user readonly exist -> fail" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\importexportGetPost.ts Imports and Exports Import authorization checks authn user modify exist -> replace" rss=332M heap=148M handles=4 requests=0
1628:  Writing Node.js report to file: hb-0216-D_a_etherpad_etherpad_src_tests_backend_specs_api_importexportGetPost.ts_Imports.json
1629:  Node.js report completed
1630:  �[32m[2026-05-26T13:50:31.085] [INFO] http - �[39mSuccessful authentication from IP ANONYMOUS for user user
1631:  ✔ authn user readonly exist -> fail
1632:  D:\a\etherpad\etherpad\src\tests\backend\specs\api\instance.ts
...

1644:  ✔ rejects a token with admin=false
1645:  [diag +28217ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\jwtAdminClaim.ts JWT admin claim enforcement (authorization_code grant) rejects a token with no admin claim
1646:  ✔ rejects a token with no admin claim
1647:  [diag +28220ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\jwtAdminClaim.ts JWT admin claim enforcement (authorization_code grant) accepts a token with admin=true (happy path)
1648:  ✔ accepts a token with admin=true (happy path)
1649:  [diag +28225ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\jwtAdminClaim.ts JWT admin claim enforcement (authorization_code grant) rejects an unsigned / tampered token
1650:  Writing Node.js report to file: be-0218-D_a_etherpad_etherpad_src_tests_backend_specs_api_jwtAdminClaim.ts_JWT_admin_cla.json
1651:  Node.js report completed
1652:  [diag +28297ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\jwtAdminClaim.ts JWT admin claim enforcement (authorization_code grant) rejects an unsigned / tampered token" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\jwtAdminClaim.ts JWT admin claim enforcement (authorization_code grant) accepts a token with admin=true (happy path)" rss=311M heap=150M handles=4 requests=0
1653:  Writing Node.js report to file: hb-0219-D_a_etherpad_etherpad_src_tests_backend_specs_api_jwtAdminClaim.ts_JWT_admin_cla.json
1654:  Node.js report completed
1655:  ✔ rejects an unsigned / tampered token
1656:  [diag +28386ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\jwtAdminClaim.ts JWT admin claim enforcement (authorization_code grant) rejects a request with no Authorization header
1657:  Writing Node.js report to file: be-0220-D_a_etherpad_etherpad_src_tests_backend_specs_api_jwtAdminClaim.ts_JWT_admin_cla.json
1658:  Node.js report completed
1659:  [diag +28488ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Sanity checks errors with invalid oauth token
1660:  ✔ rejects a request with no Authorization header
1661:  D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts
1662:  Sanity checks
1663:  Writing Node.js report to file: be-0221-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_Sanity_checks_errors_wi.json
1664:  Node.js report completed
1665:  [diag +28571ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Sanity checks errors with invalid oauth token" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\jwtAdminClaim.ts JWT admin claim enforcement (authorization_code grant) rejects a request with no Authorization header" rss=331M heap=151M handles=4 requests=0
1666:  Writing Node.js report to file: hb-0222-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_Sanity_checks_errors_wi.json
1667:  Node.js report completed
1668:  ✔ errors with invalid oauth token
1669:  Tests
...

1682:  [diag +28743ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests get the HTML of Pad
1683:  [diag +28748ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests list all pads
1684:  ✔ get the HTML of Pad
1685:  Writing Node.js report to file: be-0224-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_Tests_list_all_pads.json
1686:  Node.js report completed
1687:  [diag +28829ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests list all pads" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests get the HTML of Pad" rss=331M heap=154M handles=4 requests=0
1688:  Writing Node.js report to file: hb-0225-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_Tests_list_all_pads.json
1689:  Node.js report completed
1690:  ✔ list all pads
1691:  [diag +28906ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests deletes the Pad
1692:  Writing Node.js report to file: be-0226-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_Tests_deletes_the_Pad.json
1693:  Node.js report completed
1694:  ✔ deletes the Pad
1695:  [diag +28982ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests list all pads again
1696:  ✔ list all pads again
1697:  [diag +28986ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests get the HTML of a Pad -- Should return a failure
1698:  ✔ get the HTML of a Pad -- Should return a failure
1699:  [diag +28990ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests creates a new Pad with text
...

1790:  [diag +30265ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests Sets the HTML of a Pad attempting to pass ugly HTML
1791:  Writing Node.js report to file: be-0241-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_Tests_Sets_the_HTML_of_.json
1792:  Node.js report completed
1793:  [diag +30363ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests Sets the HTML of a Pad attempting to pass ugly HTML" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests getText of old revision" rss=335M heap=150M handles=4 requests=0
1794:  Writing Node.js report to file: hb-0242-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_Tests_Sets_the_HTML_of_.json
1795:  Node.js report completed
1796:  ✔ Sets the HTML of a Pad attempting to pass ugly HTML
1797:  [diag +30462ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests Pad with complex nested lists of different types
1798:  Writing Node.js report to file: be-0243-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_Tests_Pad_with_complex_.json
1799:  Node.js report completed
1800:  ✔ Pad with complex nested lists of different types
1801:  [diag +30561ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests Pad with white space between list items
1802:  [diag +30562ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests Pad with white space between list items" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests Pad with complex nested lists of different types" rss=336M heap=158M handles=5 requests=1
1803:  Writing Node.js report to file: hb-0244-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_Tests_Pad_with_white_sp.json
1804:  Node.js report completed
1805:  [diag +30655ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests errors if pad can be created
1806:  ✔ Pad with white space between list items (93ms)
1807:  Writing Node.js report to file: be-0245-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_Tests_errors_if_pad_can.json
1808:  Node.js report completed
1809:  [diag +30743ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests copies the content of a existent pad
1810:  ✔ errors if pad can be created
1811:  ✔ copies the content of a existent pad
...

1818:  Writing Node.js report to file: be-0247-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_Tests_creates_a_new_Pad.json
1819:  Node.js report completed
1820:  [diag +30937ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests deletes with empty text
1821:  ✔ creates a new Pad with empty text
1822:  ✔ deletes with empty text
1823:  copyPadWithoutHistory
1824:  [diag +30967ms] hb running="<no test running>" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts Tests deletes with empty text" rss=343M heap=170M handles=6 requests=1
1825:  Writing Node.js report to file: hb-0248-_no_test_running_.json
1826:  Node.js report completed
1827:  [diag +31064ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory returns a successful response
1828:  Writing Node.js report to file: be-0249-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_copyPadWithoutHistory_r.json
1829:  Node.js report completed
1830:  ✔ returns a successful response
1831:  [diag +31140ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory creates a new pad with the same content as the source pad
1832:  ✔ creates a new pad with the same content as the source pad
1833:  [diag +31151ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory copying to a non-existent group throws an error
1834:  ✔ copying to a non-existent group throws an error
1835:  [diag +31155ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory source and destination attribute pools are independent
1836:  [diag +31167ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory source and destination attribute pools are independent" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory copying to a non-existent group throws an error" rss=348M heap=175M handles=5 requests=1
1837:  Writing Node.js report to file: hb-0250-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_copyPadWithoutHistory_s.json
1838:  Node.js report completed
1839:  ✔ source and destination attribute pools are independent (132ms)
1840:  copying to an existing pad
1841:  [diag +31288ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory copying to an existing pad force=false fails
1842:  Writing Node.js report to file: be-0251-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_copyPadWithoutHistory_c.json
1843:  Node.js report completed
1844:  [diag +31367ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory copying to an existing pad force=false fails" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory source and destination attribute pools are independent" rss=358M heap=185M handles=6 requests=0
1845:  Writing Node.js report to file: hb-0252-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_copyPadWithoutHistory_c.json
1846:  Node.js report completed
1847:  �[91m[2026-05-26T13:50:34.434] [ERROR] settings - �[39merroring out without force
1848:  ✔ force=false fails
1849:  [diag +31473ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory copying to an existing pad force=true succeeds
1850:  Writing Node.js report to file: be-0253-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_copyPadWithoutHistory_c.json
1851:  Node.js report completed
1852:  [diag +31576ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory copying to an existing pad force=true succeeds" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory copying to an existing pad force=false fails" rss=359M heap=152M handles=6 requests=1
1853:  Writing Node.js report to file: hb-0254-D_a_etherpad_etherpad_src_tests_backend_specs_api_pad.ts_copyPadWithoutHistory_c.json
...

1863:  Writing Node.js report to file: be-0255-D_a_etherpad_etherpad_src_tests_backend_specs_api_restoreRevision.ts_v1.2.11_aut.json
1864:  Node.js report completed
1865:  [diag +31777ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\api\restoreRevision.ts v1.2.11 authorId ignored" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\api\pad.ts copyPadWithoutHistory copying to an existing pad force=true succeeds" rss=359M heap=154M handles=4 requests=1
1866:  Writing Node.js report to file: hb-0256-D_a_etherpad_etherpad_src_tests_backend_specs_api_restoreRevision.ts_v1.2.11_aut.json
1867:  Node.js report completed
1868:  ✔ authorId ignored
1869:  v1.3.0
1870:  [diag +31864ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\restoreRevision.ts v1.3.0 change is attributed to given authorId
1871:  Writing Node.js report to file: be-0257-D_a_etherpad_etherpad_src_tests_backend_specs_api_restoreRevision.ts_v1.3.0_chan.json
1872:  Node.js report completed
1873:  ✔ change is attributed to given authorId
1874:  [diag +31942ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\restoreRevision.ts v1.3.0 authorId can be omitted
1875:  ✔ authorId can be omitted
1876:  D:\a\etherpad\etherpad\src\tests\backend\specs\api\sessionsAndGroups.ts
1877:  API Versioning
1878:  [diag +31948ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\api\sessionsAndGroups.ts API Versioning errors if can not connect
1879:  ✔ errors if can not connect
1880:  API: Group creation and deletion
...

2044:  ✔ padId
2045:  �[32m[2026-05-26T13:50:37.515] [INFO] access - �[39m[LEAVE] pad:testChatPad socket:u7GMnWRaJDE8AiqpAAAP IP:ANONYMOUS authorID:a.6Vq2ikn1lyTSgM9A
2046:  [diag +34553ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\chat.ts chatNewMessage hook mutations propagate
2047:  �[33m[2026-05-26T13:50:37.527] [WARN] message - �[39mclient sent author token via CLIENT_READY message; cookie migration will take effect on next HTTP response. See docs/superpowers/specs/2026-04-19-gdpr-pr3-anon-identity-design.md
2048:  �[32m[2026-05-26T13:50:37.528] [INFO] access - �[39m[CREATE] pad:testChatPad socket:0algROWqFB3zCGEAAAAR IP:ANONYMOUS authorID:a.ccH8rLZdmYHoK0BH
2049:  ✔ mutations propagate
2050:  �[32m[2026-05-26T13:50:37.532] [INFO] access - �[39m[LEAVE] pad:testChatPad socket:0algROWqFB3zCGEAAAAR IP:ANONYMOUS authorID:a.ccH8rLZdmYHoK0BH
2051:  D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts
2052:  [diag +34570ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts CLIENT_VARS rev matches initialAttributedText state at that exact rev
2053:  Writing Node.js report to file: be-0286-D_a_etherpad_etherpad_src_tests_backend_specs_clientvar_rev_consistency.ts_CLIEN.json
2054:  Node.js report completed
2055:  [diag +34642ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts CLIENT_VARS rev matches initialAttributedText state at that exact rev" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\chat.ts chatNewMessage hook mutations propagate" rss=371M heap=179M handles=4 requests=0
2056:  Writing Node.js report to file: hb-0287-D_a_etherpad_etherpad_src_tests_backend_specs_clientvar_rev_consistency.ts_CLIEN.json
2057:  Node.js report completed
2058:  �[33m[2026-05-26T13:50:37.702] [WARN] settings - �[39mbypassing socket.io authentication and authorization checks due to settings.loadTest
2059:  �[91m[2026-05-26T13:50:37.702] [ERROR] message - �[39mThere is no author for authorId: a.etherpad-system. This is possibly related to https://github.com/ether/etherpad-lite/issues/2802
2060:  �[32m[2026-05-26T13:50:37.703] [INFO] access - �[39m[ENTER] pad:KVRDzvUvhU socket:ak2BJuDtXJ2sOFgbAAAT IP:ANONYMOUS authorID:a.ORVkYd9JGWWdXTk1
2061:  �[32m[2026-05-26T13:50:37.704] [INFO] access - �[39m[LEAVE] pad:KVRDzvUvhU socket:ak2BJuDtXJ2sOFgbAAAT IP:ANONYMOUS authorID:a.ORVkYd9JGWWdXTk1
2062:  ✔ CLIENT_VARS rev matches initialAttributedText state at that exact rev
2063:  [diag +34743ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts CLIENT_VARS stays consistent under concurrent edits during handshake (delay race)
2064:  Writing Node.js report to file: be-0288-D_a_etherpad_etherpad_src_tests_backend_specs_clientvar_rev_consistency.ts_CLIEN.json
2065:  Node.js report completed
2066:  [diag +34842ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts CLIENT_VARS stays consistent under concurrent edits during handshake (delay race)" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts CLIENT_VARS rev matches initialAttributedText state at that exact rev" rss=374M heap=182M handles=4 requests=1
2067:  Writing Node.js report to file: hb-0289-D_a_etherpad_etherpad_src_tests_backend_specs_clientvar_rev_consistency.ts_CLIEN.json
2068:  Node.js report completed
2069:  �[33m[2026-05-26T13:50:37.939] [WARN] settings - �[39mbypassing socket.io authentication and authorization checks due to settings.loadTest
2070:  �[91m[2026-05-26T13:50:37.940] [ERROR] message - �[39mThere is no author for authorId: a.etherpad-system. This is possibly related to https://github.com/ether/etherpad-lite/issues/2802
2071:  �[32m[2026-05-26T13:50:37.940] [INFO] access - �[39m[ENTER] pad:brK5Us9Dpn socket:H2dKoyf3EhrCP23rAAAV IP:ANONYMOUS authorID:a.azbGlZ4h81zZ2LPb
...

2080:  [diag +35467ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts CLIENT_VARS stays consistent under concurrent edits during handshake (delay race)" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts CLIENT_VARS rev matches initialAttributedText state at that exact rev" rss=378M heap=186M handles=6 requests=0
2081:  Writing Node.js report to file: hb-0293-D_a_etherpad_etherpad_src_tests_backend_specs_clientvar_rev_consistency.ts_CLIEN.json
2082:  Node.js report completed
2083:  [diag +35674ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts CLIENT_VARS stays consistent under concurrent edits during handshake (delay race)" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts CLIENT_VARS rev matches initialAttributedText state at that exact rev" rss=378M heap=186M handles=6 requests=0
2084:  Writing Node.js report to file: hb-0294-D_a_etherpad_etherpad_src_tests_backend_specs_clientvar_rev_consistency.ts_CLIEN.json
2085:  Node.js report completed
2086:  [diag +35874ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts CLIENT_VARS stays consistent under concurrent edits during handshake (delay race)" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts CLIENT_VARS rev matches initialAttributedText state at that exact rev" rss=378M heap=186M handles=6 requests=0
2087:  Writing Node.js report to file: hb-0295-D_a_etherpad_etherpad_src_tests_backend_specs_clientvar_rev_consistency.ts_CLIEN.json
2088:  Node.js report completed
2089:  �[32m[2026-05-26T13:50:38.922] [INFO] access - �[39m[LEAVE] pad:brK5Us9Dpn socket:H2dKoyf3EhrCP23rAAAV IP:ANONYMOUS authorID:a.azbGlZ4h81zZ2LPb
2090:  ✔ CLIENT_VARS stays consistent under concurrent edits during handshake (delay race) (1123ms)
2091:  [diag +35961ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\clientvar_rev_consistency.ts client receives revisions created during clientVars hook await window
2092:  Writing Node.js report to file: be-0296-D_a_etherpad_etherpad_src_tests_backend_specs_clientvar_rev_consistency.ts_clien.json
2093:  Node.js report completed
2094:  �[33m[2026-05-26T13:50:39.010] [WARN] settings - �[39mbypassing socket.io authentication and authorization checks due to settings.loadTest
2095:  �[91m[2026-05-26T13:50:39.011] [ERROR] message - �[39mThere is no author for authorId: a.etherpad-system. This is possibly related to https://github.com/ether/etherpad-lite/issues/2802
2096:  �[32m[2026-05-26T13:50:39.011] [INFO] access - �[39m[CREATE] pad:Ilz6ik8Sjl socket:80PI5NGj8BNf3AMXAAAX IP:ANONYMOUS authorID:a.GUalDYlGm7P52tLg
...

2183:  Node.js report completed
2184:  Writing Node.js report to file: mt-0306-D_a_etherpad_etherpad_src_tests_backend_specs_compactPad.ts_HTTP_API_dispatch_1..json
2185:  Node.js report completed
2186:  [diag +37182ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts HTTP API dispatch (1.3.1) passes keepRevisions from query string into compactPad" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts API.compactPad() refuses to run when cleanup.enabled is false" rss=382M heap=132M handles=4 requests=1
2187:  Writing Node.js report to file: hb-0307-D_a_etherpad_etherpad_src_tests_backend_specs_compactPad.ts_HTTP_API_dispatch_1..json
2188:  Node.js report completed
2189:  ✔ passes keepRevisions from query string into compactPad (310ms)
2190:  [diag +37262ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts HTTP API dispatch (1.3.1) collapses all history when keepRevisions is absent from URL
2191:  Writing Node.js report to file: be-0308-D_a_etherpad_etherpad_src_tests_backend_specs_compactPad.ts_HTTP_API_dispatch_1..json
2192:  Node.js report completed
2193:  ✔ collapses all history when keepRevisions is absent from URL
2194:  runCompactAll (bin/compactAllPads loop)
2195:  [diag +37349ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactAll (bin/compactAllPads loop) parses --keep / --dry-run / no args
2196:  ✔ parses --keep / --dry-run / no args
2197:  [diag +37349ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactAll (bin/compactAllPads loop) rejects --keep with non-integer / negative / unknown args
2198:  �[91m[2026-05-26T13:50:40.313] [ERROR] settings - �[39m--keep expects a non-negative integer; got abc
2199:  [diag +37350ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactAll (bin/compactAllPads loop) compacts every pad and tallies before/after revisions
2200:  �[91m[2026-05-26T13:50:40.313] [ERROR] settings - �[39m--keep expects a non-negative integer; got -1
2201:  ✔ rejects --keep with non-integer / negative / unknown args
2202:  ✔ compacts every pad and tallies before/after revisions
2203:  [diag +37351ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactAll (bin/compactAllPads loop) honours --keep N by passing it through to compactPad
2204:  ✔ honours --keep N by passing it through to compactPad
2205:  [diag +37351ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactAll (bin/compactAllPads loop) --dry-run does not call compactPad
2206:  ✔ --dry-run does not call compactPad
2207:  [diag +37351ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactAll (bin/compactAllPads loop) keeps going when one pad fails to compact
2208:  ✔ keeps going when one pad fails to compact
2209:  [diag +37352ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactAll (bin/compactAllPads loop) keeps going when one pad fails the pre-flight count
2210:  ✔ keeps going when one pad fails the pre-flight count
2211:  [diag +37352ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactAll (bin/compactAllPads loop) reports listAllPads failure without iterating
2212:  [diag +37353ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactAll (bin/compactAllPads loop) handles an empty instance
2213:  ✔ reports listAllPads failure without iterating
2214:  [diag +37353ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactAll (bin/compactAllPads loop) end-to-end against the real HTTP handler
2215:  ✔ handles an empty instance
2216:  [diag +37382ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactAll (bin/compactAllPads loop) end-to-end against the real HTTP handler" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactAll (bin/compactAllPads loop) handles an empty instance" rss=382M heap=140M handles=6 requests=1
2217:  Writing Node.js report to file: hb-0309-D_a_etherpad_etherpad_src_tests_backend_specs_compactPad.ts_runCompactAll_bin_co.json
2218:  Node.js report completed
2219:  ✔ end-to-end against the real HTTP handler (138ms)
2220:  runCompactStale (bin/compactStalePads loop)
2221:  [diag +37492ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) parses --older-than / --keep / --dry-run
2222:  Writing Node.js report to file: be-0310-D_a_etherpad_etherpad_src_tests_backend_specs_compactPad.ts_runCompactStale_bin_.json
2223:  Node.js report completed
2224:  ✔ parses --older-than / --keep / --dry-run
2225:  [diag +37569ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) rejects missing / invalid --older-than and unknown args
2226:  �[91m[2026-05-26T13:50:40.532] [ERROR] settings - �[39m--older-than is required
2227:  [diag +37569ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) only compacts pads older than the cutoff
2228:  �[91m[2026-05-26T13:50:40.532] [ERROR] settings - �[39m--older-than is required
2229:  �[91m[2026-05-26T13:50:40.532] [ERROR] settings - �[39m--older-than expects a non-negative integer; got abc
2230:  �[91m[2026-05-26T13:50:40.532] [ERROR] settings - �[39m--older-than expects a non-negative integer; got -1
2231:  ✔ rejects missing / invalid --older-than and unknown args
2232:  [diag +37570ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) honours --keep N for stale pads
2233:  ✔ only compacts pads older than the cutoff
2234:  ✔ honours --keep N for stale pads
2235:  [diag +37571ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) --dry-run does not call compactPad on stale pads
2236:  ✔ --dry-run does not call compactPad on stale pads
2237:  [diag +37571ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) keeps going when one stale pad fails to compact
2238:  ✔ keeps going when one stale pad fails to compact
2239:  [diag +37572ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) counts a getLastEdited failure as a failure but keeps going
2240:  ✔ counts a getLastEdited failure as a failure but keeps going
2241:  [diag +37572ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) reports listAllPads failure without iterating
2242:  ✔ reports listAllPads failure without iterating
2243:  [diag +37573ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) handles an empty instance
2244:  ✔ handles an empty instance
2245:  [diag +37573ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) handles an instance where every pad is fresh
2246:  ✔ handles an instance where every pad is fresh
2247:  [diag +37573ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) skips a pad that gets edited between selection and compaction
2248:  ✔ skips a pad that gets edited between selection and compaction
2249:  [diag +37574ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) counts a getLastEdited recheck failure as a failure
2250:  ✔ counts a getLastEdited recheck failure as a failure
2251:  [diag +37574ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\compactPad.ts runCompactStale (bin/compactStalePads loop) --older-than 0 treats every pad as stale
...

2342:  Node.js report completed
2343:  ✔ text matches
2344:  [diag +38721ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\contentcollector.ts A single <p></p> should create a new line alines match
2345:  Writing Node.js report to file: be-0323-D_a_etherpad_etherpad_src_tests_backend_specs_contentcollector.ts_A_single_p_p_s.json
2346:  Node.js report completed
2347:  ✔ alines match
2348:  [diag +38809ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\contentcollector.ts A single <p></p> should create a new line attributes are sorted in canonical order
2349:  ✔ attributes are sorted in canonical order
2350:  Tests if ols properly get line numbers when in a normal OL #2
2351:  [diag +38817ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\contentcollector.ts Tests if ols properly get line numbers when in a normal OL #2 text matches
2352:  ✔ text matches
2353:  [diag +38817ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\contentcollector.ts Tests if ols properly get line numbers when in a normal OL #2 alines match
2354:  ✔ alines match
2355:  [diag +38818ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\contentcollector.ts Tests if ols properly get line numbers when in a normal OL #2 attributes are sorted in canonical order
2356:  ✔ attributes are sorted in canonical order
2357:  First item being an UL then subsequent being OL will fail
2358:  - text matches
...

2672:  Writing Node.js report to file: be-0374-D_a_etherpad_etherpad_src_tests_backend_specs_contentcollector.ts_nbsp_preserved.json
2673:  Node.js report completed
2674:  ✔ alines match
2675:  [diag +43973ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\contentcollector.ts nbsp preserved across span boundary attributes are sorted in canonical order
2676:  ✔ attributes are sorted in canonical order
2677:  [diag +43973ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\ensureAuthorTokenCookie.ts mints a fresh t.* token when the cookie is absent
2678:  D:\a\etherpad\etherpad\src\tests\backend\specs\ensureAuthorTokenCookie.ts
2679:  [diag +43974ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\ensureAuthorTokenCookie.ts reuses the cookie value and does not emit Set-Cookie when already set
2680:  ✔ mints a fresh t.* token when the cookie is absent
2681:  [diag +43974ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\ensureAuthorTokenCookie.ts sets Secure when the request is HTTPS
2682:  ✔ reuses the cookie value and does not emit Set-Cookie when already set
2683:  [diag +43975ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\ensureAuthorTokenCookie.ts uses SameSite=None when embedded cross-site (Sec-Fetch-Site: cross-site)
2684:  ✔ sets Secure when the request is HTTPS
2685:  [diag +43975ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\ensureAuthorTokenCookie.ts ignores an invalid existing cookie and mints a fresh one
2686:  ✔ uses SameSite=None when embedded cross-site (Sec-Fetch-Site: cross-site)
2687:  [diag +43976ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\export.ts returns 500 on export error
2688:  ✔ ignores an invalid existing cookie and mints a fresh one
2689:  D:\a\etherpad\etherpad\src\tests\backend\specs\export.ts
2690:  �[32m[2026-05-26T13:50:46.943] [INFO] settings - �[39mExporting pad "testExportPad" in doc format
2691:  [diag +43982ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\export.ts returns 500 on export error" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\ensureAuthorTokenCookie.ts ignores an invalid existing cookie and mints a fresh one" rss=393M heap=195M handles=6 requests=1
2692:  Writing Node.js report to file: hb-0375-D_a_etherpad_etherpad_src_tests_backend_specs_export.ts_returns_500_on_export_er.json
2693:  Node.js report completed
2694:  �[32m[2026-05-26T13:50:47.075] [INFO] LibreOffice - �[39m[2672] Converting C:\Users\RUNNER~1\AppData\Local\Temp/etherpad_export_03871ea5f66d1d641467db8343d98563.html to odt in C:\Users\RUNNER~1\AppData\Local\Temp
2695:  �[91m[2026-05-26T13:50:47.080] [ERROR] LibreOffice - �[39m[2672] stderr: The system cannot find the path specified.
2696:  �[91m[2026-05-26T13:50:47.083] [ERROR] LibreOffice - �[39m[2672] Conversion failed: Error: Failed to spawn /bin/false: spawn /bin/false ENOENT
2697:  at exports (D:\a\etherpad\etherpad\src\node\utils\run_cmd.ts:124:48)
2698:  at doConvertTask (D:\a\etherpad\etherpad\src\node\utils\LibreOffice.ts:38:13)
2699:  at D:\a\etherpad\etherpad\node_modules\.pnpm\async@3.2.6\node_modules\async\dist\async.js:151:38
2700:  at D:\a\etherpad\etherpad\node_modules\.pnpm\async@3.2.6\node_modules\async\dist\async.js:4017:13
2701:  at Object.process (D:\a\etherpad\etherpad\node_modules\.pnpm\async@3.2.6\node_modules\async\dist\async.js:1680:21)
2702:  [diag +44124ms] test start: D:\a\etherpad\etherpad\src\tests\backend\specs\export.ts native DOCX export (#7538) returns a valid DOCX archive (PK zip signature)
2703:  at D:\a\etherpad\etherpad\node_modules\.pnpm\async@3.2.6\node_modules\async\dist\async.js:1532:23
2704:  at D:\a\etherpad\etherpad\node_modules\.pnpm\async@3.2.6\node_modules\async\dist\async.js:74:45
2705:  �[91m[2026-05-26T13:50:47.083] [ERROR] settings - �[39mExport error: Error: Failed to spawn /bin/false: spawn /bin/false ENOENT
2706:  at exports (D:\a\etherpad\etherpad\src\node\utils\run_cmd.ts:124:48)
2707:  at doConvertTask (D:\a\etherpad\etherpad\src\node\utils\LibreOffice.ts:38:13)
2708:  at D:\a\etherpad\etherpad\node_modules\.pnpm\async@3.2.6\node_modules\async\dist\async.js:151:38
2709:  at D:\a\etherpad\etherpad\node_modules\.pnpm\async@3.2.6\node_modules\async\dist\async.js:4017:13
2710:  at Object.process (D:\a\etherpad\etherpad\node_modules\.pnpm\async@3.2.6\node_modules\async\dist\async.js:1680:21)
2711:  at D:\a\etherpad\etherpad\node_modules\.pnpm\async@3.2.6\node_modules\async\dist\async.js:1532:23
2712:  at D:\a\etherpad\etherpad\node_modules\.pnpm\async@3.2.6\node_modules\async\dist\async.js:74:45 {
2713:  code: 'ENOENT'
2714:  }
2715:  ✔ returns 500 on export error (147ms)
2716:  native DOCX export (#7538)
2717:  Writing Node.js report to file: be-0376-D_a_etherpad_etherpad_src_tests_backend_specs_export.ts_native_DOCX_export_7538_.json
2718:  Node.js report completed
2719:  [diag +44225ms] hb running="D:\a\etherpad\etherpad\src\tests\backend\specs\export.ts native DOCX export (#7538) returns a valid DOCX archive (PK zip signature)" lastFinished="D:\a\etherpad\etherpad\src\tests\backend\specs\export.ts returns 500 on export error" rss=395M heap=196M handles=4 requests=0
2720:  Writing Node.js report to file: hb-0377-D_a_etherpad_etherpad_src_tests_backend_specs_export.ts_native_DOCX_export_7538_.json
2721:  Node.js report completed
2722:  �[32m[2026-05-26T13:50:47.284] [INFO] settings - �[39mExporting pad "testExportPad" in docx format
2723:  Writing Node.js report to file: mt-0378-D_a_etherpad_etherpad_src_tests_backend_specs_export.ts_native_DOCX_export_7538_.json
2724:  Node.js report completed
2725:  [diag +448...

@JohnMcLear
Copy link
Copy Markdown
Member Author

Closing — the broader-scope yield (root mochaHooks.beforeEach, scoped to etherpad's own specs via file-path check) still didn't prevent the silent ELIFECYCLE. Captured death #14 on this run:

```
clientvar_rev_consistency.ts > CLIENT_VARS stays consistent under concurrent edits during handshake (delay race)
kill at +46368ms, 467ms after test start, exit 255, same fingerprint
```

That file IS covered by the root yield. So cadence / rapid-sequential test pattern is NOT the trigger.

Combined with PR #7852's result, this rules out two of the most plausible causal hypotheses (TIME_WAIT, cadence). Remaining candidates need either local Windows repro or out-of-process probing beyond what we've already added (#7846's netstat sidecar). In-CI diagnosis has reached diminishing returns.

Linux ± plugins did pass cleanly — the file-path-scoped yield is safe even though it doesn't fix anything. Could be revived as a chore PR if the test-infra value alone is worth it, but I'm not going to ship "scoped yield with no measurable benefit" as a fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant