Closed michelwilson closed 6 years ago
It seems that remote.require
is looking in node_modules/karma-electron/lib
for ./main.js
, so apparently it is using the cwd of the launcher to look for modules. __filenameOverride
seems to refer to the normal require
, it isn't picked up by the remote.require
.
I've got a few questions:
require
? (e.g. browserify
, webpack
)I've tried to create an example which is as minimal as possible (not easy), I've uploaded it to https://github.com/michelwilson/karma-electron-minimal-example. The uploaded version works in karma-electron
, do a npm install; bower install; karma start
to make it go. Comment out src/script.js:4
and comment src/script.js:6
to break it. The working version doesn't work when you do a electron .
.
The error I get is:
Electron 1.7.10 (Node 7.9.0) ERROR
Uncaught Error: Cannot find module './main.js'
Error: Cannot find module './main.js'
at Module._resolveFilename (module.js:470:15)
at Function.Module._resolveFilename (/XXX/minimal/node_modules/electron/dist/resources/electron.asar/common/reset-search-paths.js:35:12)
at Function.Module._load (module.js:418:25)
at Module.require (module.js:498:17)
at EventEmitter.<anonymous> (/XXX/minimal/node_modules/electron/dist/resources/electron.asar/browser/rpc-server.js:263:70)
at emitTwo (events.js:106:13)
at EventEmitter.emit (events.js:194:7)
at WebContents.<anonymous> (/XXX/minimal/node_modules/electron/dist/resources/electron.asar/browser/api/web-contents.js:256:13)
at emitTwo (events.js:106:13)
at WebContents.emit (events.js:194:7)
at /XXX/minimal/node_modules/electron/dist/resources/electron.asar/renderer/api/remote.js:234
Great, that helped a bunch! Here's what the issues I found:
src/*.js
which is causing __filename
and __dirname
to be set as the Electron index.html
client.loadScriptsViaRequire
was set back to true
, require('../main.js')
started working from the renderer (i.e. require
, not electron.remote.require
)renderer
only testing. As a result, the require('electron').remote
path issue was unexpectedelectron.remote.require
is resolving from the remote context, meaning it's resolving from the main file of karma-electron
(i.e. node_modules/karma-electron/lib/electron-launcher.js
)
require(__dirname + '/../main.js')
require
option. Documented here:
To summarize, the following fixes should resolve everything but we recommend the launcher require
option instead of electron.remote.require
:
karma.conf.js:
// ...
preprocessors: {
'src/**/*.js': ['electron'],
'test/**/*.js': ['electron']
},
client: {
useIframe: false,
loadScriptsViaRequire: true
},
// ...
script.js:
// ...
node_script = require('electron').remote.require(__dirname + '/../main.js');
// ...
Ah that gives some insight. I've got the minimal example working, now. To get the actual application to work, a bit more is required, as the __dirname
trick doesn't seem to work there ... in karma-electron
, __dirname
refers to the directory of script.js
, in electron
itself it points to the directory of index.html
.
I am not sure what use the launcher require
option has. If I use it to require
the main Electron script, this seems to start the application, in parallel with the test. Certainly not what I wanted to achieve ;)
Well, I don't fully understand why, but I got things working. For anyone encountering similar problems (you never know, and I hate finding problems without solutions ;)):
loadScriptsViaRequire
__filenameOverride
is set to the correct location of index.html
(the one in the dev output directory, in my case__dirname
from the script in which you want to remote.require
something, very useful!remote.require(__dirname + '/something.js')
.No idea if this is the 'right' way, but it makes it work for me :) Thanks for the assistance!
Glad to hear we got it working. If you'd like, I can help direct you in the direction with respect to main.js
. Could you provide more context on why you need to load main.js
?
In case of the real application, main.js
exposes certain functionality that can only be handled outside of the renderer process: sending a UDP broadcast for server discovery. The reason for using karma-electron
is to build midway tests at the frontend level of the stack, which talk to an actual backend. This gets us three things: midway tests of the frontend code, tests of the protocol between frontend and backend, and integration tests for the backend. Downside is of course that any test failures pose an interesting puzzle ;)
Anyway: it seems to be working, I can call frontend service layer functions, that call all the way into the backend, so I'm happy.
Cool, thanks for the info. Here's a few options:
main.js
and in testing, load only that file (or maybe a test/karma-require.js
which loads it)fs.writeFileSync
or an assertion that the request/response are 1:1 with whatever is on disk. Then, I'd set up a mock using those fixtures in the renderer
testsspectron
which is better equipped for full application testing
Interesting reading, thanks! I particularly like the idea of contract-based fixtures, as this circumvents the problem of not really testing the API by explicitly defining it. Even gives you a form of documentation for the API :) Thanks! I believe that I'll continue to use the current approach, due to time/budget constraints, unfortuntely. However, there'll always be future projects :)
I'm trying to get an angularjs-app, which I package with electron, to play together with karma-electron. Previously we used PhantomJS, but I would like to move away from this. The problem is that in a couple of places I have a
require('electron').remote.require('./main.js')
to get access to some Node stuff from within the renderer process. I cannot seem to get this to work. Using the full path ofmain.js
makes it work, but that is (obviously) undesirable. I have set__filenameOverride
to the location ofindex.html
andloadScriptsViaRequire
is set totrue
. Doesn't seem to make a difference. Clearly, therequire
is looking in the wrong place for my script (it's in the same directory asindex.html
). What magic is required to get it working? Issue #11 seems to suggest that it should just work, but doesn't provide me with the detail to get it working in my case...