From 3ebba83790df0e95fb14c7e1bfc54b24411dd3c2 Mon Sep 17 00:00:00 2001 From: Per Bergland Date: Wed, 18 Feb 2026 14:25:10 +0100 Subject: [PATCH 1/7] fix: await Meteor.startup() queue before running tests In Meteor 3.x, async startup callbacks and top-level await can cause mocha.run() to fire before all Meteor.startup() callbacks have completed. This leads to flaky tests when server initialization depends on async startup work (e.g. ensuring MongoDB indices). Await a promise resolved by a Meteor.startup() callback at the end of the queue, ensuring all prior callbacks (including async ones) have finished before tests begin. Fixes #176 Co-Authored-By: Claude Opus 4.6 --- package/server.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/package/server.js b/package/server.js index 8439af4..d709daa 100644 --- a/package/server.js +++ b/package/server.js @@ -204,7 +204,14 @@ function clientTests() { } // Before Meteor calls the `start` function, app tests will be parsed and loaded by Mocha -function start() { +async function start() { + // Wait for all Meteor.startup() callbacks (including async ones) to complete. + // In Meteor 3.x, async startup callbacks and top-level await can cause the + // startup queue to still be draining when the test driver's start() is called. + // Adding a callback at the end of the queue ensures it runs after all prior + // callbacks have finished. See: https://github.com/Meteor-Community-Packages/meteor-mocha/issues/176 + await new Promise(resolve => Meteor.startup(resolve)); + const args = setArgs(); runnerOptions = args.runnerOptions; coverageOptions = args.coverageOptions; From 9c93ccec998028e1fa0518c7bdaa8c87f67ec6ce Mon Sep 17 00:00:00 2001 From: Per Bergland Date: Wed, 18 Feb 2026 14:27:24 +0100 Subject: [PATCH 2/7] test: add regression test for async Meteor.startup() timing Adds a server test that registers an async Meteor.startup() callback with a short delay and asserts it completed before tests run. Without the fix in server.js, mocha.run() fires before the callback finishes, causing this test to fail. Co-Authored-By: Claude Opus 4.6 --- tests/dummy_app/server/async-startup.tests.js | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 tests/dummy_app/server/async-startup.tests.js diff --git a/tests/dummy_app/server/async-startup.tests.js b/tests/dummy_app/server/async-startup.tests.js new file mode 100644 index 0000000..04fee7b --- /dev/null +++ b/tests/dummy_app/server/async-startup.tests.js @@ -0,0 +1,21 @@ +/* eslint-env mocha */ +import { Meteor } from 'meteor/meteor'; +import assert from 'assert'; + +// Simulate async startup work (e.g. ensuring MongoDB indices, initializing +// collections). Without the fix in server.js, mocha.run() can fire before +// this callback completes, causing the test below to fail. +let startupCompleted = false; + +Meteor.startup(async () => { + await new Promise(resolve => setTimeout(resolve, 50)); + startupCompleted = true; +}); + +describe('async Meteor.startup()', function () { + it('should complete before tests run', function () { + assert.strictEqual(startupCompleted, true, + 'Async Meteor.startup() callback did not complete before tests ran. ' + + 'See https://github.com/Meteor-Community-Packages/meteor-mocha/issues/176'); + }); +}); From 35b8f20e673720e2bfc8e4e640a91f7968fa87e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Mon, 11 May 2026 16:27:27 +0200 Subject: [PATCH 3/7] bump to version 3.4.0, ensure `Meteor.startup()` callbacks complete before tests run --- CHANGELOG.md | 4 ++++ package/package.js | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2fcd611..eed6d24 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # CHANGELOG +## 3.4.0 + +- Await pending `Meteor.startup()` callbacks before running tests, so async startup work (e.g. ensuring MongoDB indices) finishes before `mocha.run()` fires on Meteor 3.x. [PR #177](https://github.com/Meteor-Community-Packages/meteor-mocha/pull/177) + ## 3.0.0 - Meteor 3.0 compatibility; drop Fibers diff --git a/package/package.js b/package/package.js index be24c34..6e36576 100644 --- a/package/package.js +++ b/package/package.js @@ -3,7 +3,7 @@ Package.describe({ summary: 'Run Meteor package or app tests with Mocha', git: 'https://github.com/meteortesting/meteor-mocha.git', documentation: '../README.md', - version: '3.3.0', + version: '3.4.0', testOnly: true, }); From 480b0b98a418f3340f29fdee5deb2bc28dd2254d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Mon, 11 May 2026 16:41:05 +0200 Subject: [PATCH 4/7] style: add parentheses for consistency in promise callback function --- package/server.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package/server.js b/package/server.js index d709daa..ecad45c 100644 --- a/package/server.js +++ b/package/server.js @@ -210,7 +210,7 @@ async function start() { // startup queue to still be draining when the test driver's start() is called. // Adding a callback at the end of the queue ensures it runs after all prior // callbacks have finished. See: https://github.com/Meteor-Community-Packages/meteor-mocha/issues/176 - await new Promise(resolve => Meteor.startup(resolve)); + await new Promise((resolve) => Meteor.startup(resolve)); const args = setArgs(); runnerOptions = args.runnerOptions; From bf7d8e17c09ef0bb8070d0efeb946131715c15e0 Mon Sep 17 00:00:00 2001 From: jankapunkt Date: Tue, 12 May 2026 09:40:25 +0200 Subject: [PATCH 5/7] publish 3.4.0-rc.0 --- package/.versions | 14 +++++++------- package/package.js | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/package/.versions b/package/.versions index b456b30..2716bdf 100644 --- a/package/.versions +++ b/package/.versions @@ -1,19 +1,19 @@ -babel-compiler@7.11.3 +babel-compiler@7.14.0 babel-runtime@1.5.2 core-runtime@1.0.0 dynamic-import@0.7.4 -ecmascript@0.16.10 +ecmascript@0.18.0 ecmascript-runtime@0.8.3 -ecmascript-runtime-client@0.12.3 +ecmascript-runtime-client@0.13.0 ecmascript-runtime-server@0.11.1 fetch@0.1.6 inter-process-messaging@0.1.2 -meteor@2.1.0 +meteor@2.3.0 meteortesting:browser-tests@1.8.0 -meteortesting:mocha@3.3.0 +meteortesting:mocha@3.4.0-rc.0 meteortesting:mocha-core@8.3.1-rc300.1 -modern-browsers@0.2.1 +modern-browsers@0.2.3 modules@0.20.3 modules-runtime@0.13.2 promise@1.0.0 -react-fast-refresh@0.2.9 +react-fast-refresh@0.3.0 diff --git a/package/package.js b/package/package.js index 6e36576..4307534 100644 --- a/package/package.js +++ b/package/package.js @@ -3,7 +3,7 @@ Package.describe({ summary: 'Run Meteor package or app tests with Mocha', git: 'https://github.com/meteortesting/meteor-mocha.git', documentation: '../README.md', - version: '3.4.0', + version: '3.4.0-rc.0', testOnly: true, }); From d847a154397af632646afe0b1f04181dc7a48ced Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 28 Jul 2026 11:45:00 +0200 Subject: [PATCH 6/7] refactor: revise startup test logic to avoid deadlock and ensure hooks complete --- package/server.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/package/server.js b/package/server.js index ecad45c..4b100c8 100644 --- a/package/server.js +++ b/package/server.js @@ -203,15 +203,14 @@ function clientTests() { }); } -// Before Meteor calls the `start` function, app tests will be parsed and loaded by Mocha -async function start() { - // Wait for all Meteor.startup() callbacks (including async ones) to complete. - // In Meteor 3.x, async startup callbacks and top-level await can cause the - // startup queue to still be draining when the test driver's start() is called. - // Adding a callback at the end of the queue ensures it runs after all prior - // callbacks have finished. See: https://github.com/Meteor-Community-Packages/meteor-mocha/issues/176 - await new Promise((resolve) => Meteor.startup(resolve)); +// Run tests from a new startup hook so every hook already queued, including +// async ones, completes first. Awaiting a callback added to the startup queue +// here would deadlock: this function itself is run by that queue. +function start() { + Meteor.startup(runTests); +} +function runTests() { const args = setArgs(); runnerOptions = args.runnerOptions; coverageOptions = args.coverageOptions; From d7cd9221c5cb247f7d47b5091a0d973a36c11635 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nacho=20Codo=C3=B1er?= Date: Tue, 28 Jul 2026 11:52:09 +0200 Subject: [PATCH 7/7] bump to version 3.4.0-rc.1, update dependencies for compatibility --- package/.versions | 10 +++++----- package/package.js | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/package/.versions b/package/.versions index 2716bdf..0e35f0b 100644 --- a/package/.versions +++ b/package/.versions @@ -1,16 +1,16 @@ -babel-compiler@7.14.0 +babel-compiler@7.14.1 babel-runtime@1.5.2 core-runtime@1.0.0 dynamic-import@0.7.4 -ecmascript@0.18.0 +ecmascript@0.18.1 ecmascript-runtime@0.8.3 ecmascript-runtime-client@0.13.0 ecmascript-runtime-server@0.11.1 -fetch@0.1.6 +fetch@0.2.0 inter-process-messaging@0.1.2 -meteor@2.3.0 +meteor@2.3.1 meteortesting:browser-tests@1.8.0 -meteortesting:mocha@3.4.0-rc.0 +meteortesting:mocha@3.4.0-rc.1 meteortesting:mocha-core@8.3.1-rc300.1 modern-browsers@0.2.3 modules@0.20.3 diff --git a/package/package.js b/package/package.js index 4307534..57f1455 100644 --- a/package/package.js +++ b/package/package.js @@ -3,7 +3,7 @@ Package.describe({ summary: 'Run Meteor package or app tests with Mocha', git: 'https://github.com/meteortesting/meteor-mocha.git', documentation: '../README.md', - version: '3.4.0-rc.0', + version: '3.4.0-rc.1', testOnly: true, });