Comments (24)
Alright, it worked! I changed my files
config to this:
files: [
// include the augment-node-path.js file first
path.resolve(__dirname, 'augment-node-path.js'),
// include all the test files after augment-node-path.js (order matters)
{pattern: 'dist/**/*.test.js', watched: false},
],
And augment-node-path.j
contains:
// Most of the time, this doesn't do anything. But when karma-electron is
// symlinked into the project's node_modules, the regular upward lookup for
// node_modules will not find the project's node_modules, so this explicitly
// adds that to NODE_PATH. The karma.config.js file ensures this is loaded
// before all test files.
const path = require('path')
process.env.NODE_PATH = path.resolve(process.cwd(), 'node_modules') + ':' + process.env.NODE_PATH
require('module').Module._initPaths()
from karma-electron.
Thank you for your responsiveness on this by the way! You are more responsive than most any other project maintainer.
from karma-electron.
Aha!! So, I couldn't get the above module.paths
trick to work, but I got the test to pass by doing the following
const path = require('path')
process.env.NODE_PATH = path.resolve(process.cwd(), 'node_modules') + ':' + process.env.NODE_PATH
require('module').Module._initPaths()
const mkdirp = require('mkdirp')
describe('TODO, tests', () => {
it('needs to be done', () => {
expect(mkdirp).toBeInstanceOf(Function)
})
})
thanks to this hint on StackOverflow: https://stackoverflow.com/a/33976627/454780.
from karma-electron.
I'm quite busy the next 2 nights so I don't have time to parse/dig into all of this. I'll give it a read by the end of the weekend =)
No rush, it took me more than a year to circle back with a reply. :)
I'll try to make a repo (I'll take my repo and strip everything out except one file, and hopefully that'll work). No guarantees on a timeline though. :)
from karma-electron.
Seems like this is the same issue (but not solution): electron/electron#11 EDIT: well even if that require('module').globalPaths
trick works, I don't want to have to write that in every test file.
from karma-electron.
To paraphrase your issue: You'd like to load a file for each test file execution, is that right? (e.g. auto-insert require
/similar at the start of each test file)
If that's the case, then we need to reframe your understanding a bit =/
Karma is a browser test runner, not a Node.js one. We need to look at everything through the lens of "what if this was executing in Chrome or Firefox"? (where we don't have sweet features like NODE_PATH
)
Once we reframe it, then we realize we need to find support for this either in karma
itself or your chosen test runner (e.g. mocha
, jasmine
)
karma
easily supports this feature (I use it all the time for loading CSS files for visual testing/debugging)
Documentation:
included
boolean infiles
config, https://karma-runner.github.io/4.0/config/files.html
Example:
- Including a CSS file in all test cases https://github.com/twolfson/multi-image-mergetool/blob/1.32.1/karma.conf.js#L17
- Note: JS will be loaded via
<script
but will behave identical to test files (i.e. share same global context)
If you'd like something even more custom, karma
also supports custom HTML pages where scripts can be loaded as you wish:
Documentation:
customContextFile
andcustomDebugFile
in https://karma-runner.github.io/4.0/config/configuration-file.html
Example:
- https://github.com/twolfson/karma-electron/blob/6.3.0/test/integration-test/karma.conf.js#L83-L86
- https://github.com/twolfson/karma-electron/blob/6.3.0/test/integration-test/test-files/custom-context.html
from karma-electron.
To paraphrase your issue: You'd like to load a file for each test file execution, is that right? (e.g. auto-insert require/similar at the start of each test file)
That's not exactly my issue (but that is one way I thought I could possibly solve my issue).
The issue is that when a meta-package of mine (which contains karma and karma-electron, and this meta package has other things like TypeScript build steps, Webpack bundling steps, etc) is not installed normally in my project, but symlinked, then Node which is running in karma-electron's Electron instance will no longer find my project's node_modules.
To make it more clear, if I run console.log(module)
in a test file, I see this:
Module {
...
paths: [
'/home/trusktr/src/lume+umbrella/packages/builder-js-package/node_modules/electron/dist/resources/default_app.asar/node_modules',
'/home/trusktr/src/lume+umbrella/packages/builder-js-package/node_modules/electron/dist/resources/node_modules'
],
...
}
But the thing is, my project is actually located at
/home/trusktr/src/lume+umbrella/packages/my-project
So Node will not find /home/trusktr/src/lume+umbrella/packages/my-project/node_modules
where all my project dependencies are.
This is happening, because I tried to switch to Lerna for multi-project management, which symlinks projects together. Now karma and karme-electron are not directly inside of /home/trusktr/src/lume+umbrella/packages/my-project/node_modules
like they are when nothing is symlinked.
/home/trusktr/src/lume+umbrella/packages/my-project/node_modules/builder-js-package
is symlinked to /home/trusktr/src/lume+umbrella/packages/builder-js-package
, where builder-js-package
is my "meta package" that contains all my build scripts, test tools, etc.
Karma is a browser test runner, not a Node.js one
This I know, which is exactly why I'm using karma+karma-electron (because with Jest I can only get fake browser APIs which have bugs or missing features).
As for the rest of your previous comment, I think we can ignore it because it was misunderstanding.
I just want require
calls in karma-electron's Electron instance to find my modules. (And this problem only happens when karma-electron is not located under my project node_modules like normal because it in another symlinked location)
EDIT: Or, wait, maybe I misunderstood: Are you saying, that if I add the files to karma includes
that then this allows them to be require
d in Electron (effectively adding them to module.paths
)?
from karma-electron.
Alrighty! I think there might be an easy fix for this in karma-electron. I found this line:
Maybe, we can add an option for karma-electron called path
, which allows us to specify additional paths that can be pushed onto that array.
Let me see about a pull request.
from karma-electron.
In case I can make it more clear, in my project, I install some NPM packages:
npm install mkdirp
Now in my test code, this normally works fine:
const mkdirp = require('mkdirp')
describe('foo', () => {
it('bar', () => { /* ... use mkdirp ...*/ })
})
But the problem happens only when karma-electron is no longer in my project node_modules (because it is in a symlinked location), and in this case I get an error
Electron 2.0.18 (Node 8.9.3) ERROR
Uncaught Error: Cannot find module 'mkdirp'
at module.js:545:5
from karma-electron.
Ah, I see. Thanks for explaining the issue in more detail =)
A PR won't be necessary, more detailed options coming up in next comment
from karma-electron.
Great find! The mustache
template you linked to is indeed how we correct electron
dropping node_modules
paths due to a similar problem
This template is loaded via a karma
preprocessor to wrap our files
listed in karma
. Thus, it has the same browser
context as any other JS in our tests =) This means any tricks used there, can be used more broadly
https://github.com/twolfson/karma-electron/blob/6.3.0/lib/karma-electron-preprocessor.js#L23-L91
To reiterate, module.paths
was the solution you were looking for, not NODE_PATH
, for adjusting node_modules
path resolution inside of the JS runtime (e.g. Electron main
, Electron renderer
)
First off, I recommend giving it a try with a specific test file. To reuse your mkdirp
example:
// I prefer to use `concat` to avoid contaminating the original array
module.paths = module.paths.concat(['path/to/custom/node_modules']);
// Normal `mkdirp` execution
const mkdirp = require('mkdirp')
describe('foo', () => {
it('bar', () => { /* ... use mkdirp ...*/ })
})
If that works fine, then we've got 2 options for you:
- Use Electron's
preload
feature, https://github.com/twolfson/karma-electron/tree/6.3.0#using-preload-with-browserwindowpreload
file should be as simple as contentsmodule.paths = module.paths.concat(['path/to/custom/node_modules']);
- I'm iffy if this will propagate properly to child windows/iframes (how
karma
launches fresh contexts for test runs)- In fact, it might not since I'd prob have avoided the
mustache
template in that case
- In fact, it might not since I'd prob have avoided the
- Use previously described options in #44 (comment)
- File should be loaded at start of
files
and useincluded: true
flag - Same contents:
module.paths = module.paths.concat(['path/to/custom/node_modules']);
- If this doesn't work (pretty sure if should, otherwise CSS wouldn't be in same context as other test files), then there's probably a
karma
plugin which allows for appending content to each test file
- File should be loaded at start of
from karma-electron.
Great! Glad to hear it all worked out =)
from karma-electron.
Well so far that sample works, but I still want to avoid writing that inside every test file. Let me try your files
/included
suggestion.
Would that trick with NODE_PATH be worth putting in the mustache template to ensure that path.resolve(process.cwd(), 'node_modules')
is always available, even when symlinked?
from karma-electron.
from karma-electron.
from karma-electron.
I don't believe using cwd in that resolution is a common setup so I'd
prefer to leave it as a one off setup
I agree with that sentiment, but maybe we should consider the following:
With normal Node usage, the user runs node
in their project, and it always resolves things in project/node_modules
by default.
But for whatever reason, with karma-electron existing in a folder symlinked into the project node_modules it caused node
(the one inside Electron) not to look at project/node_modules
as expected, which seems like behavior that doesn't match regular node
usage.
As an example, while karma-electron's Electron was failing to find anything in project/node_modules
, I could still run the node
repl in my terminal and successfully execute require('mkdirp')
. So the behavior of Electron wasn't matching my regular expectations.
I wasn't trying to add a specific non-standard location to my NODE_PATH
, which I agree would be a one-off setup; I was trying make something work in karma-electron that otherwise normally works with node
.
from karma-electron.
from karma-electron.
if I open a terminal on my desktop and run ~/github/my-project/test.sh, I would expect
it to load files in said folder, not from my desktop (cwd)
That may depend on expectations, but I see what you mean.
One thing is for sure though:
- when I run
node
in my folder, it resolves modules fine. - when I run
karma
withkarma-electron
, it doesn't resolve modules the same way
So there definitely is some problem that the end user shouldn't have to worry about.
The question is, what's the solution?
from karma-electron.
I think there's a false dichotomy that you seem to be looping on =/
I've got 2 immediate thoughts on hopefully resolving this:
karma
should be considered equivalent to runningnode path/to/test.js
, notnode
. This changes the path resolution location- If there's a discrepancy in this context, then I'd be happy to look into fixing it
- Iteration for
karma
tests should be done via thedebug
window or via rerunning tests (e.g. via the continuous run function)- This will keep path resolution 1:1 with what we expect to load
- This would be akin to use a
debugger
line or updating/rerunning a file, anode
REPL won't have a 1:1 behavior if we're using a different path resolution location
from karma-electron.
karma
should be considered equivalent to runningnode path/to/test.js
, notnode
. This changes the path resolution location
Well I am running both node
and karma
on files that are in my project, and ultimately my project contains a node_modules
folder that has the desired dependencies. So I think in both cases, the dependency should be resolvable, but it isn't.
Or in other words, if I run node
in my project, or node project/foo/file.js
which runs a file inside my project, and similarly with karm
and it running any test files inside my project, then I expect that it should traverse up and eventually find the dependencies in my project node_modules
folder, but this isn't the case.
Just to clarify that a little more, I am not running node
or karma
on any files outside of my project, only on files inside my project. So I think the node resolution algorithm should therefore always end up in my project's node_modules folder and resolve the dependency as expected.
What I can do is provide a more clear example of my folder structure, and how things are symlinked, so that I can show that where karma is located shouldn't matter, but that rather the module resolution should happen relative to the files being executed (test files for example), which doesn't seem to be the case, and instead it seems to depend on the location of karma
and karma-electron
in the overall file system (karma and karma-electron may be located entirely outside of my project).
I need to find some time to show more clearly how my filesystem is laid out...
from karma-electron.
Ah, I see. Maybe I'm misinformed of how module.paths
works then. Yea, if you could provide an example gist, then that'd be great =D
from karma-electron.
I haven't had the time to make an example, but to try and describe it simply, suppose we have this folder structure:
user-home/
project/
path/
test.js
node_modules/
karma -> ../../libs/karma (symlink)
karma-electron -> ../../libs/karma-electron (symlink)
some-lib/
index.js
libs/
karma/
...
karma-electron/
...
where test.js
has this:
const someLib = require('some-lib/index.js')
console.log(someLib)
and assuming that the current working directory is user-home/project/
.
If I run node path/test.js
it will correctly log the export of some-lib/index.js
because Node finds the dependency in my project
's node_modules
folder.
If I run karma
(we're still inside of project/
), then the dependency resolution will fail to find some-lib
.
This problem only happens if karma
and karma-electron
are symlinked (therefore they are not actually inside of the project/node_modules/
folder).
When dependencies are not linked, module resolution works as expected (which seems to indicate that module resolution happens based on the actual location of karma
and karma-electron
, not based on the project location (unlike node
).
When karma dependencies are linked and live somewhere outside of project/
, the node_modules
folder inside of project/
seems to be ignored during module resolution.
The workaround that I used is to add to ~/user-home/project/node_modules/
to NODE_PATH
before executing the test bundles, which makes the module lookup work.
It seems that Electron running via karma-electron is not performing module resolution the same as when running node
. Note that node
is also not located inside project/
, it is external, but it still takes into consideration the current working directory for module lookup based on where node
is being executed, which is what doesn't happen when I execute a symlinked karma
/karma-electron
.
from karma-electron.
I'm quite busy the next 2 nights so I don't have time to parse/dig into all of this. I'll give it a read by the end of the weekend =)
from karma-electron.
Alright, so that explanation is great and well laid out. That being said, trying to reproduce that can either be very quick or very slow/painful by trying to guess what went went (and even if it's quick, it might not be the issue you're describing).
I definitely need a demonstration repo/similar to have a version of "here's it working in Node", "here's it not working in Electron"
I'll re-open the issue for now but that demo repo is needed to move forward =/
from karma-electron.
Related Issues (20)
- `electron` did show not nothing happen then HOT 1
- Can't import nodejs modules in an angular-cli project (Typescript) HOT 1
- Errors without stack traces coming from karma-electron? HOT 5
- running with ndb for debugging? HOT 2
- Unable to open Electron window using --show HOT 3
- Electron 5 nodeIntegration HOT 12
- Custom launcher `require` mechanism doesn't work HOT 4
- Module paths are messed up HOT 5
- Error: Karma plugin is meant to be used from within Angular CLI and will not work correctly outside of it HOT 1
- [feature] option like 'require', but for renderer processes. HOT 1
- Karma times out when using Electron 9 and client.useIframe = false HOT 20
- Non-context aware native modules in renderer will cause specs to error HOT 3
- [questions] Is Electron 12 supported? HOT 16
- electron V12.0.4---------require is not defined HOT 3
- ES Modules HOT 2
- "require is not defined" after update to karma-electron 7 / electron 12 HOT 12
- Regardless of the `browserWindowOptions.show` value, a window always opens. HOT 12
- sqlite3 stalls with nodeIntegration true contextIsolation false HOT 12
- Consider migrating this great work to @web/test-runner. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from karma-electron.