From 3ebba83790df0e95fb14c7e1bfc54b24411dd3c2 Mon Sep 17 00:00:00 2001 From: Per Bergland Date: Wed, 18 Feb 2026 14:25:10 +0100 Subject: [PATCH 1/2] 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/2] 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'); + }); +});