Skip to content

fix(run-multiple): restore plugin loading and per-child reportDir (#5577)#5578

Merged
DavertMik merged 1 commit into
codeceptjs:4.xfrom
mirao:fix/run-multiple-plugins-5577
May 24, 2026
Merged

fix(run-multiple): restore plugin loading and per-child reportDir (#5577)#5578
DavertMik merged 1 commit into
codeceptjs:4.xfrom
mirao:fix/run-multiple-plugins-5577

Conversation

@mirao
Copy link
Copy Markdown
Contributor

@mirao mirao commented May 24, 2026

Fixes #5577

Two regressions introduced during the 3.x → 4.x ESM migration caused the testomatio HTML reporter (and any plugin with runInWorker: false) to produce no output when using run-multiple.


Bug 1 – plugins with runInWorker:false silently skipped in child processes

File: lib/container.js

options.child was used to detect "running inside a worker thread" and skipped plugins whose runInWorker is false (testomatio defaults to false). But run-multiple also sets --child on every forked child process, so those plugins were silently skipped there too — no error, no report.

Fix: replace options.child with !isMainThread (from Node's worker_threads). A run-multiple child is a freshly-forked OS process whose isMainThread is true, so the gate no longer fires. An actual run-workers worker thread has isMainThread === false, so the gate still fires as intended.

Context options.child isMainThread Before (skipped?) After
run-workers worker thread truthy (index) false skipped ✓ skipped ✓
run-multiple child process truthy (string) true skipped ✗ (bug) loads ✓
normal run / parent process falsy true loads ✓ loads ✓

Bug 2 – all children write to the same reportDir, last one wins

File: lib/command/run-multiple.js

3.x run-multiple.js replaced three per-child directory keys before forking each child:

overriddenConfig = replaceValueDeep(overriddenConfig, 'output',    path.join(config.output, outputDir))
overriddenConfig = replaceValueDeep(overriddenConfig, 'reportDir', path.join(config.output, outputDir))  // ← dropped in 4.x
overriddenConfig = replaceValueDeep(overriddenConfig, 'mochaFile', path.join(config.output, outputDir, `${browserName}_report.xml`))

The 4.x port dropped the reportDir line, so every child kept the same shared reportDir value from the config (e.g. output/report) and each child's run overwrote the previous one's HTML file.

Fix: restore the missing replaceValueDeep('reportDir', ...) call so each child receives its own directory — matching 3.x behaviour.


Result

Before:

output/report/testomatio-report.html   ← only webkit's data (chromium overwritten)

After:

output/dev_chromium_1/testomatio-report.html
output/dev_webkit_2/testomatio-report.html

Tests

A regression test is added to test/runner/run_multiple_test.js backed by a minimal fixture plugin and config. It verifies both bugs together:

  1. A plugin with runInWorker: false is initialised once per child (not zero times).
  2. Each child receives a distinct reportDir (not the same shared path).

The test fails against the unfixed code and passes with the fix applied.

🤖 Generated with Claude Code

…deceptjs#5577)

Two regressions introduced during the 3.x → 4.x ESM migration:

## Bug 1 – plugins with runInWorker:false silently skipped in child processes

lib/container.js used options.child to detect "running inside a worker thread"
and skipped plugins whose runInWorker is false (testomatio defaults to false).
But run-multiple also sets --child on every forked child process, so those
plugins were incorrectly skipped there too.

Fix: replace options.child with !isMainThread (worker_threads).
A run-multiple child is a freshly-forked OS process whose isMainThread is true,
so the gate no longer fires. An actual run-workers worker thread has
isMainThread === false, so the gate still fires as intended.

| Context                   | options.child | isMainThread | before (skipped?) | after  |
|---------------------------|---------------|--------------|-------------------|--------|
| run-workers worker thread | truthy (idx)  | false        | skipped ✓         | skipped ✓ |
| run-multiple child proc   | truthy (str)  | true         | skipped ✗ (bug)   | loads ✓ |
| normal run / parent proc  | falsy         | true         | loads ✓           | loads ✓ |

## Bug 2 – all children write to the same reportDir, last one wins

3.x run-multiple.js replaced three per-child directory keys before forking:
  output, reportDir, mochaFile
The 4.x port dropped the reportDir line, so every child kept the shared
reportDir value from the config (e.g. "output/report") and overwrote each
other's HTML file.

Fix: restore the missing replaceValueDeep('reportDir', ...) call so each child
receives its own directory, matching 3.x behaviour.

Regression test added: verifies that a plugin with runInWorker:false is
initialised once per child and that each child receives a distinct reportDir.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@DavertMik DavertMik merged commit 16b2f32 into codeceptjs:4.x May 24, 2026
10 checks passed
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.

[4.0] run-multiple: Testomatio HTML report isn't created

2 participants