Closed machineghost closed 2 years ago
I understand your time is valuable, but running tests at the command line sucks :(
If there's any way I could offer to help with some other issue (where you know the problem, and just need someone to code up a solution) I'd be happy to offer to help, in exchange for some advice on fixing this issue.
Or if you can't think of any, maybe I could help modify the adapter to throw more useful error messages (more useful than "you've got something wrong with jsdom-global/register
") that actually instruct people how to fix the issue. That way we'd kill two birds with one stone: I'd learn the fix, and I can help save future people from bugging you for it.
The stacktrace suggests that you aren't using mocha's esm loader (you have either set mochaExplorer.esmLoader
to false
in your configuration or you're using an old Mocha version that doesn't have that loader). You can check in the diagnostic logs if it says Trying requireOrImport('jsdom-global/register')
(that's mocha's esm loader) or Trying require('jsdom-global/register')
. I just realized that the require option will only work for globally installed packages without mocha's esm loader, so you should try enabling that.
when I try that command on my server folder in this codebase (which clearly has no need for jsdom) it doesn't do anything: I still have the tests failing.
They're failing with the same error message? In that case I'd need more info: the mocha and VS Code config and ideally the diagnostic log output.
I understand your time is valuable, but running tests at the command line sucks :(
Yeah, sorry, I'll try to be more responsive in the future (but can't make any promises)
maybe I could help modify the adapter to throw more useful error messages
If I had foreseen that problem (that requiring doesn't work properly without mocha's esm loader) I would already have added such error messages. I'll try to come up with a proper fix for this and another issue that you've also run into (where requiring doesn't work properly if the adapter uses the bundled version of mocha).
you have either set mochaExplorer.esmLoader to false in your configuration or you're using an old Mocha version that doesn't have that loader
I just realized that the require option will only work for globally installed packages without mocha's esm loader, so you should try enabling that.
That setting is already checked, and I most definitely have the esm
package because my app uses it :) Also my mocharc.js
file has:
require: 'esm',
Unchecking that setting (and refreshing the tests) does nothing.
You can check in the diagnostic logs if it says Trying requireOrImport('jsdom-global/register') (that's mocha's esm loader) or Trying require('jsdom-global/register').
Under the "Mocha Explorer Log" output I see this, among other lines, when I refresh:
[2022-06-26 19:54:07.265] [INFO] Worker: Trying requireOrImport('jsdom-global/register')
(followed by that same error about jsdom-global/register
)
They're failing with the same error message? In that case I'd need more info: the mocha and VS Code config
Mocha Config:
process.env['NODE_ENV'] = 'test';
process.env['NODE_PATH'] = '/path/to/my/project/root';
module.exports = {
exit: true,
bail: true,
recursive: true,
require: 'esm',
file: ['./src/testMain.js'],
};
VS Code Settings (or at least all the Mocha/Test Explorer ones):
"mochaExplorer.files": "./{,!(node_modules)/**}/*.spec.js",
"mochaExplorer.ignore": "node_modules",
"mochaExplorer.require": ["jsdom-global/register", "@babel/register"],
"testExplorer.addToEditorContextMenu": true,
"testExplorer.hideEmptyLog": false,
"testExplorer.errorDecoration": false,
"mochaExplorer.logpanel": true,
"explorer.fileNesting.enabled": true,
"mochaExplorer.globImplementation": "vscode",
"mochaExplorer.envPath": ""
and ideally the diagnostic log output.
Where do I find that? In my "Test Explorer" Output I have:
Error: Cannot find module 'jsdom-global/register'
Require stack:
- /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js:5790:35
at Generator.next (<anonymous>)
at /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js:115:71
at new Promise (<anonymous>)
at __awaiter (/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js:111:12)
at execute (/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js:5727:12) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js'
]
}
In "Mocha Tests" I have nothing, and in "Mocha Explorer Log" I have:
[2022-06-26 20:48:04.109] [INFO] Worker finished with code null and signal SIGTERM
[2022-06-26 20:48:04.109] [INFO] Worker: Caught error Error: Cannot find module 'jsdom-global/register'
Require stack:
- /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/lib/nodejs/esm-utils.js
- /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/lib/mocha.js
- /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/index.js
- /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at exports.requireOrImport (/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/lib/nodejs/esm-utils.js:49:16) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/lib/nodejs/esm-utils.js',
'/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/lib/mocha.js',
'/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/index.js',
'/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js'
]
}
[2022-06-26 20:48:04.109] [INFO] Received error from worker
[2022-06-26 20:48:04.110] [ERROR] Worker (stderr): node:internal/process/promises:279
triggerUncaughtException(err, true /* fromPromise */);
^
Error: Cannot find module 'jsdom-global/register'
Require stack:
- /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/lib/nodejs/esm-utils.js
- /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/lib/mocha.js
- /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/index.js
- /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at exports.requireOrImport (/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/lib/nodejs/esm-utils.js:49:16) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/lib/nodejs/esm-utils.js',
'/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/lib/mocha.js',
'/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/node_modules/mocha/index.js',
'/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js'
]
}
[2022-06-26 20:48:04.113] [INFO] Worker finished with code 1 and signal null
Yeah, sorry, I'll try to be more responsive in the future (but can't make any promises)
I owe you an apology too, as I completely understand maintaining OSS is a PITA. I swear, while I was trying to get help, I wasn't trying to guilt trip you!
If I had foreseen that problem (that requiring doesn't work properly without mocha's esm loader) I would already have added such error messages. I'll try to come up with a proper fix for this and another issue that you've also run into (where requiring doesn't work properly if the adapter uses the bundled version of mocha).
Again, I totally understand.
I just imaged that somewhere in the code is a require('jsdom-global/register')
line (or something like it) that could be wrapped with a try
/catch
that does nothing except rethrow the error ... with a message more like "A library used by Mocha Test Explorer wouldn't load; please see https://github.com/hbenl/vscode-mocha-test-adapter/issues/215 for possible solutions."
The diagnostic log is the "Mocha Explorer Log" output. The stacktrace shown there is different from the one in the "Test Explorer" output, so my guess is that we may be looking at logs from different workspace folders (unfortunately the diagnostic doesn't say which workspace folder a message came from, I'll have to fix this).
The stacktrace in the diagnostic log indicates that it's using the bundled mocha version, which doesn't play well with mochaExplorer.require
.
You'll have to try opening each workspace folder separately in VS Code to see what's happening in that folder. Check in the diagnostic log which installation of mocha it's using, it must be installed in the same node_modules
folder as jsdom-global
so that it can find it.
The whole monorepo-and-require story is currently causing a lot of issues, I'm still trying to figure out all the ways it breaks and how I can steer users towards a configuration that works, that's why I'm holding off on adding an error message that currently could only tell users that "it's complicated".
Ah, that all makes sense. Well, except this part:
indicates that it's using the bundled mocha version
It took me awhile, but I think that meant that I didn't have:
"mochaExplorer.mochaPath": "node_modules/mocha"
in my settings? If so, I added that line, and now I get ... the same error, but with new stuff in front!
[2022-06-27 19:53:53.226] [INFO] Worker finished with code 1 and signal null [2022-06-27 19:53:53.306] [DEBUG] Found test files [] [2022-06-27 19:53:53.307] [DEBUG] Adding files ["/home/jeremy/project/admin/server/src/testMain.js"] [2022-06-27 19:53:53.308] [DEBUG] Using environment variables from config: {} [2022-06-27 19:53:53.309] [DEBUG] Spawning /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js with IPC options {} [2022-06-27 19:53:53.381] [INFO] Worker: Using the mocha package at /home/jeremy/project/admin/server/node_modules/mocha [2022-06-27 19:53:53.480] [INFO] Worker: Patching Mocha
It looks like things have progressed much farther now ... but then the next lines are:
[2022-06-27 19:53:53.480] [INFO] Worker: Trying require('jsdom-global/register') [2022-06-27 19:53:53.485] [INFO] Worker: Caught error Error: Cannot find module 'jsdom-global/register' Require stack:
- /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15) at Function.Module._load (node:internal/modules/cjs/loader:778:27) at Module.require (node:internal/modules/cjs/loader:1005:19) at require (node:internal/modules/cjs/helpers:102:18) at /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js:5790:35 at Generator.next (
) at fulfilled (/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js:112:58) { code: 'MODULE_NOT_FOUND', requireStack: [ '/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js' ] }
As an aside, shouldn't that setting be the default? I'd think it'd be far more common for a project that wants to use this extension to have mocha
in their devDependencies
... in fact, it'd be rather odd if they didn't ... no?
Anyhow, I tried installing jsdom-global
and it got me two more lines:
[2022-06-27 19:58:31.820] [INFO] Worker: Trying require('jsdom-global/register') [2022-06-27 19:58:33.086] [INFO] Worker: Trying require('@babel/register') [2022-06-27 19:58:33.090] [INFO] Worker: Caught error Error: Cannot find module '@babel/register'
I thought I might be going down the wrong rabbit hole with that approach though, so I didn't try to figure out what package(s) to install to get '@babel/register
.
As an aside, shouldn't that setting be the default?
The default is to try look if node_modules/mocha
exists and is a directory and use that if it does or fall back to the bundled mocha otherwise. If you add that setting, it will not fall back to the bundled mocha because you've clearly stated that's not what you want.
Apparently you have node_modules/mocha
and it works so I don't understand why that check fails so that it falls back to the bundled mocha. Is node_modules/mocha
perhaps symlinked?
[2022-06-27 19:58:31.820] [INFO] Worker: Trying require('jsdom-global/register')
So now it's not using the esm loader anymore (at least in your server folder)!?
Furthermore, why is it trying to require jsdom-global/register
even if that isn't needed in that folder? Do you have it in the VS Code settings for this folder?
I didn't try to figure out what package(s) to install to get '@babel/register'
That package is literally @babel/register
.
Is node_modules/mocha perhaps symlinked?
Nope, it's just a regular old npm
install.
One thing of note though: two of my folders have the same name. One is root/client
and one is root/admin/client
. I only see one "client" in the test pane, so maybe that's why ... but it seems unlikely that it's making my root/admin/server
tests not work.
So now it's not using the esm loader anymore (at least in your server folder)!?
My server output, when I rerun today, is:
[2022-06-29 18:49:19.230] [INFO] Worker finished with code 1 and signal null
[2022-06-29 18:49:19.981] [INFO] Worker: Patching Mocha
[2022-06-29 18:49:19.981] [INFO] Worker: Trying require('jsdom-global/register')
[2022-06-29 18:49:25.560] [INFO] Worker: Trying require('@babel/register')
[2022-06-29 18:49:25.579] [INFO] Worker: Caught error Error: Cannot find module '@babel/register'
Require stack:
- /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:933:15)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at /home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js:5790:35
at Generator.next (<anonymous>)
at fulfilled (/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js:112:58) {
code: 'MODULE_NOT_FOUND',
requireStack: [
'/home/jeremy/.vscode/extensions/hbenl.vscode-mocha-test-adapter-2.13.5/out/worker/bundle.js'
]
}
Furthermore, why is it trying to require jsdom-global/register even if that isn't needed in that folder?
I have no idea ... you tell me ;)
Do you have it in the VS Code settings for this folder?
Here are my (relevant) VS Code settings:
"mochaExplorer.files": "./{,!(node_modules)/**}/*.spec.js",
"mochaExplorer.ignore": "node_modules",
"mochaExplorer.require": ["jsdom-global/register", "@babel/register"],
"testExplorer.addToEditorContextMenu": true,
"testExplorer.hideEmptyLog": false,
"testExplorer.errorDecoration": false,
"mochaExplorer.logpanel": true,
"explorer.fileNesting.enabled": true,
"mochaExplorer.globImplementation": "vscode",
"mochaExplorer.envPath": "",
"mochaExplorer.mochaPath": "node_modules/mocha",
That package is literally @babel/register.
Oh, heh.
But my larger point is that I shouldn't be fixing a problem with an extension by installing new dependencies in my project. That project already works with its existing dependencies, as I can npx mocha
and run my tests fine.
So you have "mochaExplorer.require": ["jsdom-global/register", "@babel/register"]
in your config, if these aren't really needed in that folder you should remove that.
The next question is: are you using npm workspaces? I just looked into npm/yarn workspaces and realized why this extension is having problems with monorepos that use that npm feature. I'll have a fix for that in the next couple of days, hopefully this will solve your problems as well.
So you have "mochaExplorer.require": ["jsdom-global/register", "@babel/register"] in your config
No, I do not. My .mocharc
(for my server folder, ie. the one I'm trying to run test on) is:
'use strict';
process.env['NODE_ENV'] = 'test';
process.env['NODE_PATH'] = '/home/me/projectRoot/admin/server';
module.exports = {
exit: true,
bail: true,
recursive: true,
require: 'esm',
file: ['./src/testMain.js'],
};
are you using npm workspaces?
No. I have three separate folders, each with their own completely separate package.json. The only thing the folders have in common is a common parent folder ... and the fact that I've added all three folders to VS Code.
No, I do not.
I meant the VS Code settings that you posted earlier.
Your .mocharc.js
looks quite different from those settings: it tells mocha to require esm
, whereas the VS Code settings are telling the extension to require jsdom-global/register
and @babel/register
. That's why they're behaving differently. I'd recommend removing all mochaExplorer.*
settings, the extension will use the settings from .mocharc.js
. Then re-add individual settings only when you really need them.
When I do that ... well first off, it stops showing my other folders in the test pane, but that makes sense since they don't have (Mocha) tests ... but second, I do make progress! I now get:
/home/me/project/admin/server/src/graphql/mutations/login.spec.js:1
Error: Cannot find module 'src/graphql/authenticationUtil'
Require stack:
- /home/me/project/admin/server/src/graphql/mutations/login.spec.js
But that's a perfectly valid path, if this line from my .mocharc
is respected:
process.env['NODE_PATH'] = '/home/me/project/admin/server';
And again, when I run npx mocha
at the command line it does work, so it seems the plugin is somehow breaking that line of my config.
The extension only takes the exported config from .mocharc.js
, but it does this in a separate process, so any changes that .mocharc.js
makes to the process (like setting environment variables) are not used.
Most people that need environment variables for their tests put them in a .env
file and use the dotenv
package to load them, setting them in .mocharc.js
is a neat trick that simplifies this but unfortunately that's currently not supported by this extension.
So here's what you could do:
.env
file with the content:
NODE_ENV="test"
NODE_PATH="/home/me/project/admin/server"
process.env...
lines in your .mocharc.js
with require('dotenv').config()
"mochaExplorer.envPath": ".env"
to your VS Code settingsAlternatively, if you don't want to add dotenv
to your project, you could set the following VS Code setting (and keep the environment variables in .mocharc.js
so that they're used when running npx mocha
):
"mochaExplorer.env": {
"NODE_ENV": "test",
"NODE_PATH": "/home/me/project/admin/server"
}
The downside to this approach is that you're duplicating the environment variables, so if you ever change them you have to remember to make the same change in both places.
That worked, thank you! I would submit a PR, adding further info about how environmental variables are an exception to:
Put your Mocha command line options (if you have any) in a mocha configuration file (either a .mocharc.* file or a mocha property in your package.json or a mocha.opts file) or VS Code's settings (see below)
... but you still haven't accepted my last PR :( And it's just a documentation PR also, which is like the easiest PR in the world to accept.
Surely you don't want to have to keep explaining this stuff to people in issues threads, when you can just explain it in the documentation?
That worked, thank you!
:tada:
but you still haven't accepted my last PR :(
I've done that now, more PRs are welcome.
PR added; thanks again for all the help!
I have a "monorepo" project, ie. three separate workspace folders. All of them are failing to run any tests, with the following output:
In https://github.com/hbenl/vscode-mocha-test-adapter/issues/210 (also by me, but for a different codebase) someone suggested
and it worked ... in that codebase.
However, when I try that command on my server folder in this codebase (which clearly has no need for
jsdom
) it doesn't do anything: I still have the tests failing.