diff --git a/.envrc b/.envrc index a60b67f960..47ab5b6410 100644 --- a/.envrc +++ b/.envrc @@ -27,6 +27,10 @@ function @test-self { @meteor self-test "$@" } +function @test-in-console { + "$ROOT_DIR/packages/test-in-console/run.sh" "$@" +} + function @check-syntax { node "$ROOT_DIR/scripts/admin/check-legacy-syntax/check-syntax.js" } diff --git a/.github/workflows/meteor-selftest-windows.yml b/.github/workflows/meteor-selftest-windows.yml index d78f633ec3..2935532c1b 100644 --- a/.github/workflows/meteor-selftest-windows.yml +++ b/.github/workflows/meteor-selftest-windows.yml @@ -22,6 +22,9 @@ env: jobs: test: runs-on: windows-2019-meteor + concurrency: + group: ${{ github.head_ref }}-meteor-selftest-windows + cancel-in-progress: true steps: - name: Checkout code diff --git a/.github/workflows/test-deprecated-packages.yml b/.github/workflows/test-deprecated-packages.yml new file mode 100644 index 0000000000..e4ed12fe92 --- /dev/null +++ b/.github/workflows/test-deprecated-packages.yml @@ -0,0 +1,52 @@ +name: Test Deprecated Packages + +# Disabled until we figure out how to fix the error from puppeteer +# Runs on Travis CI for now +# +#on: +# push: +# branches: +# - main +# pull_request: + +jobs: + build: + runs-on: ubuntu-latest + concurrency: + group: ${{ github.head_ref }}-test-deprecated-packages + cancel-in-progress: true + timeout-minutes: 60 + + env: + PUPPETEER_DOWNLOAD_PATH: /home/runner/.npm/chromium + + steps: + - name: Update and install dependencies + run: sudo apt-get update && sudo apt-get install -y libnss3 g++-12 + + - name: Checkout code + uses: actions/checkout@v3 + + - name: Set up Node.js + uses: actions/setup-node@v3 + with: + node-version: 20.15.1 + + - name: Cache Node.js modules + uses: actions/cache@v3 + with: + path: | + ~/.npm + .meteor + .babel-cache + dev_bundle + /home/runner/.npm/chromium + key: ${{ runner.os }}-node-${{ hashFiles('meteor', '**/package-lock.json') }} + restore-keys: | + ${{ runner.os }}-node- + + - name: Install dependencies + run: npm install + + - name: Run tests + run: ./packages/test-in-console/run.sh \ No newline at end of file diff --git a/packages/accounts-2fa/.npm/package/npm-shrinkwrap.json b/packages/accounts-2fa/.npm/package/npm-shrinkwrap.json index ebacac28ad..64d0411523 100644 --- a/packages/accounts-2fa/.npm/package/npm-shrinkwrap.json +++ b/packages/accounts-2fa/.npm/package/npm-shrinkwrap.json @@ -2,9 +2,9 @@ "lockfileVersion": 4, "dependencies": { "@types/node": { - "version": "22.7.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", - "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==" + "version": "22.7.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.6.tgz", + "integrity": "sha512-/d7Rnj0/ExXDMcioS78/kf1lMzYk4BZV8MZGTBKzTGZ6/406ukkbYlIsZmMPhcR5KlkunDHQLrtAVmSq7r+mSw==" }, "@types/notp": { "version": "2.0.5", @@ -32,9 +32,9 @@ "integrity": "sha512-OEI0IWCe+Dw46019YLl6V10Us5bi574EvlJEOcAkB29IzQ/mYD1A6RyNHLjZPiHCmuodxvgF6U+vZO1L15lxVA==" }, "tslib": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.7.0.tgz", - "integrity": "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==" + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz", + "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==" }, "undici-types": { "version": "6.19.8", diff --git a/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/npm-shrinkwrap.json b/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/npm-shrinkwrap.json index 4bc9ce2a15..1fe92eee26 100644 --- a/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/npm-shrinkwrap.json +++ b/packages/deprecated/stylus/.npm/plugin/compileStylusBatch/npm-shrinkwrap.json @@ -32,9 +32,9 @@ "integrity": "sha512-fKSWtyNQTclfi1A+s2KU91/r1mfANG1ZibxTdCwJGfV1J9UwcV22plFOm0wkaq4WzqW87zxiAkyp2Ho1Wn1NnA==" }, "caniuse-db": { - "version": "1.0.30001640", - "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30001640.tgz", - "integrity": "sha512-K8/5iWoH/NULlqJz/iaopQJraQCHGcFGvs8dmTpAH7GyvoQu2Xq8ht3jq2c+wNck4bgQu/PHu2GN2mJfUj9qtw==" + "version": "1.0.30001669", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30001669.tgz", + "integrity": "sha512-GK+G6CnRZ7IY2J2H3bcm9kshwHcJ4ZWDC5u9WaIh7DQAAHHeuxIPtaZd15GMTmGvGbDx/u1AcQs3MYur9Tem7A==" }, "concat-map": { "version": "0.0.1", @@ -47,9 +47,9 @@ "integrity": "sha512-OI38lO4JQQX2GSisTqwiSFxiWNmLajXdW4tCCxAuiwGKjusHALQadSHBSxGlU8lrFp47IkLuU2AfSYz31qpETQ==" }, "debug": { - "version": "4.3.5", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", - "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==" + "version": "4.3.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.7.tgz", + "integrity": "sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==" }, "fs.realpath": { "version": "1.0.0", @@ -97,9 +97,9 @@ "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==" }, "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, "multi-stage-sourcemap": { "version": "0.2.1", diff --git a/packages/email/.npm/package/npm-shrinkwrap.json b/packages/email/.npm/package/npm-shrinkwrap.json index fcc8fd64c8..68404a03da 100644 --- a/packages/email/.npm/package/npm-shrinkwrap.json +++ b/packages/email/.npm/package/npm-shrinkwrap.json @@ -2,9 +2,9 @@ "lockfileVersion": 4, "dependencies": { "@types/node": { - "version": "22.7.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", - "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==" + "version": "22.7.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.6.tgz", + "integrity": "sha512-/d7Rnj0/ExXDMcioS78/kf1lMzYk4BZV8MZGTBKzTGZ6/406ukkbYlIsZmMPhcR5KlkunDHQLrtAVmSq7r+mSw==" }, "@types/nodemailer": { "version": "6.4.14", diff --git a/packages/test-helpers/async_multi.js b/packages/test-helpers/async_multi.js index 1286508fde..c9c09ac66e 100644 --- a/packages/test-helpers/async_multi.js +++ b/packages/test-helpers/async_multi.js @@ -53,31 +53,31 @@ var ExpectationManager = function (test, onComplete) { }; Object.assign(ExpectationManager.prototype, { - expect: function (...args) { + expect: function (/* arguments */) { var self = this; - if (typeof args[0] === "function") - var expected = args[0]; + if (typeof arguments[0] === "function") + var expected = arguments[0]; else - var expected = args; + var expected = Array.from(arguments); if (self.closed) throw new Error("Too late to add more expectations to the test"); self.outstanding++; - return async function (...args) { + return async function (/* arguments */) { if (self.dead) return; if (typeof expected === "function") { try { - await expected.apply({}, args); + await expected.apply({}, arguments); } catch (e) { if (self.cancel()) self.test.exception(e); } } else { - self.test.equal(args, expected); + self.test.equal(Array.from(arguments), expected); } self.outstanding--; @@ -115,12 +115,12 @@ testAsyncMulti = function (name, funcs, { isOnly = false } = {}) { const addFunction = isOnly ? Tinytest.onlyAsync : Tinytest.addAsync; addFunction(name, function (test, onComplete) { - var remaining = Object.assign({}, funcs); + var remaining = [...funcs] var context = {}; var i = 0; var runNext = function () { - var func = Object.values(remaining).shift(); + var func = remaining.shift(); if (!func) { delete test.extraDetails.asyncBlock; onComplete(); diff --git a/packages/test-helpers/callback_logger.js b/packages/test-helpers/callback_logger.js index 2f98cbe8de..0cac2c825c 100644 --- a/packages/test-helpers/callback_logger.js +++ b/packages/test-helpers/callback_logger.js @@ -1,4 +1,3 @@ -import isEmpty from 'lodash.isempty'; import isEqual from 'lodash.isequal'; // This file allows you to write tests that expect certain callbacks to be @@ -24,11 +23,9 @@ var CallbackLogger = function (test, callbackNames) { var self = this; self._log = []; self._test = test; - self._yielded = false; callbackNames.forEach(function (callbackName) { - self[callbackName] = function () { - var args = Array.from(arguments); - self._log.push({callback: callbackName, args: args}); + self[callbackName] = function (...args) { + self._log.push({ callback: callbackName, args }); }; }); }; @@ -36,7 +33,7 @@ var CallbackLogger = function (test, callbackNames) { CallbackLogger.prototype.expectResult = async function (callbackName, args) { var self = this; await self._waitForLengthOrTimeout(1); - if (isEmpty(self._log)) { + if (self._log.length === 0) { self._test.fail(["Expected callback " + callbackName + " got none"]); return; } @@ -78,8 +75,10 @@ CallbackLogger.prototype.expectResultUnordered = async function (list) { await self._waitForLengthOrTimeout(list.length); - list = [...list]; // shallow copy. + list = [...list]; + var i = list.length; + while (i > 0) { var found = false; var dequeued = self._log.shift(); @@ -114,4 +113,4 @@ CallbackLogger.prototype.expectNoResult = async function (fn) { await self._waitForLengthOrTimeout(0); self._expectNoResultImpl(); -}; \ No newline at end of file +}; diff --git a/packages/test-helpers/connection_server.js b/packages/test-helpers/connection_server.js index ffb15ad5bc..255bfed03d 100644 --- a/packages/test-helpers/connection_server.js +++ b/packages/test-helpers/connection_server.js @@ -1,5 +1,3 @@ -import isString from 'lodash.isstring'; - // Establish a connection from the server to the server, and wait // until the client side of the connection has received the session // id. On success call `succeeded` with two arguments, the client @@ -15,7 +13,7 @@ makeTestConnection = function (test, succeeded, failed) { // Add incoming connections to `serverConns`. var onConnectionHandle = Meteor.onConnection(function (serverConn) { - test.isTrue(isString(serverConn.id), "connection handle id exists and is a string"); + test.isTrue(typeof serverConn.id === 'string', "connection handle id exists and is a string"); if (serverConns[serverConn.id]) { test.fail("onConnection callback called multiple times for same session id"); failed(); diff --git a/packages/test-helpers/package.js b/packages/test-helpers/package.js index bb7f296c60..8eea18c3f9 100644 --- a/packages/test-helpers/package.js +++ b/packages/test-helpers/package.js @@ -5,9 +5,7 @@ Package.describe({ Npm.depends({ 'lodash.isequal': '4.5.0', - 'lodash.isempty': '4.4.0', - 'lodash.isstring': '4.0.1' -}); +}) Package.onUse(function (api) { api.use([ diff --git a/packages/test-helpers/try_all_permutations_test.js b/packages/test-helpers/try_all_permutations_test.js index 4c9b451fff..91378b1bf8 100644 --- a/packages/test-helpers/try_all_permutations_test.js +++ b/packages/test-helpers/try_all_permutations_test.js @@ -61,7 +61,7 @@ Tinytest.add("test-helpers - try_all_permutations", function (test) { var seen = {}; for (var i = 0; i < n; i++) - fs.push(function (x) { seq += x + "_"; }.bind(null, i)); + fs.push((function (x) { seq += x + "_"; }).bind(null, i)); try_all_permutations( function () {seq = "";}, fs, diff --git a/packages/test-in-console/package.js b/packages/test-in-console/package.js index 810f07e1f3..04a0729eb2 100644 --- a/packages/test-in-console/package.js +++ b/packages/test-in-console/package.js @@ -4,7 +4,7 @@ Package.describe({ }); Package.onUse(function(api) { - api.use(['tinytest', 'random', 'ejson', 'check']); + api.use(['tinytest', 'random', 'ejson', 'check', 'ecmascript']); api.use('fetch', 'server'); api.export('TEST_STATUS', 'client'); @@ -13,9 +13,7 @@ Package.onUse(function(api) { api.addFiles(['reporter.js'], 'server'); - // This is to be run by phantomjs, not as part of normal package code. - api.addAssets('phantomRunner.js', 'server'); - api.addAssets('puppeteerRunner.js', 'server'); + api.addAssets('puppeteer_runner.js', 'server'); api.export('runTests'); }); diff --git a/packages/test-in-console/phantomRunner.js b/packages/test-in-console/phantomRunner.js deleted file mode 100644 index 43fc0b8c47..0000000000 --- a/packages/test-in-console/phantomRunner.js +++ /dev/null @@ -1,69 +0,0 @@ -var createPage = require('webpage').create; -var system = require('system'); -var platform = system.args[1] || 'local'; -var platformUrl = system.env.URL + platform; -var testUrls = [ - // Additional application URLs can be added here to re-run tests in - // PhantomJS with different query parameter-based configurations. - platformUrl -]; - -function runNextUrl() { - var url = testUrls.shift(); - if (!url) { - phantom.exit(0); - return; - } - - console.log('Running Meteor tests in PhantomJS... ' + url); - - var page = createPage(); - - page.onConsoleMessage = function(message) { - console.log(message); - }; - - page.open(url); - - function poll() { - if (isDone(page)) { - var failCount = getFailCount(page); - if (failCount > 0) { - phantom.exit(1); - } else { - page.close(); - setTimeout(runNextUrl, 1000); - } - } else { - setTimeout(poll, 1000); - } - } - - poll(); -} - -function isDone(page) { - return page.evaluate(function() { - if (typeof TEST_STATUS !== 'undefined') { - return TEST_STATUS.DONE; - } - - return typeof DONE !== 'undefined' && DONE; - }); -} - -function getFailCount(page) { - return page.evaluate(function() { - if (typeof TEST_STATUS !== 'undefined') { - return TEST_STATUS.FAILURES; - } - - if (typeof FAILURES === 'undefined') { - return 1; - } - - return 0; - }); -} - -runNextUrl(); diff --git a/packages/test-in-console/puppeteerRunner.js b/packages/test-in-console/puppeteer_runner.js similarity index 95% rename from packages/test-in-console/puppeteerRunner.js rename to packages/test-in-console/puppeteer_runner.js index d0a59ae9c9..0ad644d070 100644 --- a/packages/test-in-console/puppeteerRunner.js +++ b/packages/test-in-console/puppeteer_runner.js @@ -5,6 +5,10 @@ let testNumber = 0; async function runNextUrl(browser) { const page = await browser.newPage(); + // page.on('console', msg => { + // console.log('PAGE LOG:', msg.text()); + // }); + page.on('console', async msg => { // this is a way to make sure the travis does not timeout // if the test is running for too long without any output to the console (10 minutes) @@ -58,7 +62,7 @@ async function runNextUrl(browser) { } } - poll(); + await poll(); } /** @@ -130,9 +134,10 @@ async function runTests() { '--disable-setuid-sandbox', '--disable-web-security', ], + headless: "new", }); console.log(`Using version: ${await browser.version()}`); - runNextUrl(browser); + await runNextUrl(browser) } runTests().catch((e) => diff --git a/packages/test-in-console/reporter.js b/packages/test-in-console/reporter.js index 099e43a81c..7fb49b28ce 100644 --- a/packages/test-in-console/reporter.js +++ b/packages/test-in-console/reporter.js @@ -1,14 +1,7 @@ -// A hacky way to extract the phantom runner script from the package. -if (process.env.WRITE_RUNNER_JS) { - Npm.require('fs').writeFileSync( - process.env.WRITE_RUNNER_JS, Buffer.from(Assets.getBinary('runner.js'))); -} +let url = null; -var url = null; -if (Meteor.settings && - Meteor.settings.public && - Meteor.settings.public.runId && - Meteor.settings.public.reportTo) { +if (Meteor.settings?.public?.runId && + Meteor.settings?.public?.reportTo) { url = Meteor.settings.public.reportTo + "/report/" + Meteor.settings.public.runId; diff --git a/packages/test-in-console/run.sh b/packages/test-in-console/run.sh index 38012a605d..9a6231d209 100755 --- a/packages/test-in-console/run.sh +++ b/packages/test-in-console/run.sh @@ -8,36 +8,21 @@ cd $(dirname $0)/../.. export METEOR_HOME=`pwd` -export phantom=$phantom - -# only install dependencies if required -if [ "$phantom" = true ] -then - # Just in case these packages haven't been installed elsewhere. - ./meteor npm install -g phantomjs-prebuilt browserstack-webdriver -else - # Installs into dev_bundle/lib/node_modules/puppeteer. - ./meteor npm install -g puppeteer@20.4.0 -fi +# Installs into dev_bundle/lib/node_modules/puppeteer. +./meteor npm install -g puppeteer@20.4.0 export PATH=$METEOR_HOME:$PATH -# synchronously get the dev bundle and NPM modules if they're not there. -./meteor --help || exit 1 export URL='http://127.0.0.1:4096/' export METEOR_PACKAGE_DIRS='packages/deprecated' -exec 3< <(meteor test-packages --driver-package test-in-console -p 4096 --exclude ${TEST_PACKAGES_EXCLUDE:-''} $1) +exec 3< <(./meteor test-packages --driver-package test-in-console -p 4096 --exclude ${TEST_PACKAGES_EXCLUDE:-''} $1) EXEC_PID=$! +trap "pkill -TERM -P $EXEC_PID; exit 1" SIGINT sed '/test-in-console listening$/q' <&3 -if [ "$phantom" = true ] -then - ./dev_bundle/bin/phantomjs "$METEOR_HOME/packages/test-in-console/phantomRunner.js" -else - node "$METEOR_HOME/packages/test-in-console/puppeteerRunner.js" -fi +node --trace-warnings "$METEOR_HOME/packages/test-in-console/puppeteer_runner.js" STATUS=$? diff --git a/packages/webapp/.npm/package/npm-shrinkwrap.json b/packages/webapp/.npm/package/npm-shrinkwrap.json index 39ebcd33bb..e904107de5 100644 --- a/packages/webapp/.npm/package/npm-shrinkwrap.json +++ b/packages/webapp/.npm/package/npm-shrinkwrap.json @@ -32,9 +32,9 @@ "integrity": "sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==" }, "@types/node": { - "version": "22.7.5", - "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.5.tgz", - "integrity": "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==" + "version": "22.7.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.7.6.tgz", + "integrity": "sha512-/d7Rnj0/ExXDMcioS78/kf1lMzYk4BZV8MZGTBKzTGZ6/406ukkbYlIsZmMPhcR5KlkunDHQLrtAVmSq7r+mSw==" }, "@types/qs": { "version": "6.9.16", @@ -514,11 +514,6 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" }, - "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" - }, "unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", diff --git a/packages/webapp/package.js b/packages/webapp/package.js index d225d066db..9d5c36a641 100644 --- a/packages/webapp/package.js +++ b/packages/webapp/package.js @@ -13,7 +13,6 @@ Npm.depends({ send: "1.1.0", "stream-to-string": "1.2.1", qs: "6.13.0", - 'lodash.has': '4.5.2', "useragent-ng": "2.4.3", "tmp": "0.2.3", }); diff --git a/packages/webapp/webapp_server.js b/packages/webapp/webapp_server.js index 5b3ef24edf..5849c90642 100644 --- a/packages/webapp/webapp_server.js +++ b/packages/webapp/webapp_server.js @@ -19,7 +19,6 @@ import { } from './socket_file.js'; import cluster from 'cluster'; import { execSync } from 'child_process'; -import has from 'lodash.has'; var SHORT_SOCKET_TIMEOUT = 5 * 1000; var LONG_SOCKET_TIMEOUT = 120 * 1000; @@ -622,7 +621,7 @@ WebAppInternals.staticFilesMiddleware = async function( }; if ( - has(additionalStaticJs, pathname) && + pathname in additionalStaticJs && !WebAppInternals.inlineScriptsAllowed() ) { serveStaticJs(additionalStaticJs[pathname]);