Karma launcher and preprocessor for Electron
This was written to allow for directly testing in Electron where we might want require
to work automatically
Features:
- Tested via CI on Linux and Windows
- Support for Node.js integration in the renderer process (e.g.
node_modules
,__filename
, relative paths forrequire
) - Support for hidden browser windows
- Support for isolated test runs to prevent cookie/localStorage pollution
Requirements:
karma>=1.1.0
to work withinelectron's
security policy for shared context between parent/child windows- See karma-runner/karma#1984 for more information
Notices:
- This plugin has been tested against
[email protected]
and[email protected]
but should support the latest version - This plugin is best suited for testing the renderer portion of an
electron
application- For testing a full application, see
electron's
documentation on Selenium and WebDriver - https://github.com/electron/electron/blob/v1.3.6/docs/tutorial/using-selenium-and-webdriver.md
- For testing a full application, see
We have corrected inaccuracies with file://
behavior from Electron. For example:
__filename
is now Karma'scontext.html
- Relative paths for
require
resolve from Karma'scontext.html
directory
We have transferred support for this to the option client.loadScriptsViaRequire
which loads scripts via require
and has the original expected Node.js behavior
For more information, see twolfson#11
On a project that has been set up with karma init
already, install the module via:
# Install our module and `electron`
npm install karma-electron electron
Then, configure the module:
// Inside `karma.conf.js`
browsers: ['Electron']
// If you would like Node.js integration support (e.g. `require`)
// then, you must include this in `preprocessors` and `client`
// DEV: preprocessors is for backfilling `__filename` and local `require` paths
preprocessors: {
'**/*.js': ['electron']
},
// DEV: `useIframe: false` is for launching a new window instead of using an iframe
// In Electron, iframes don't get `nodeIntegration` priveleges yet windows do
client: {
useIframe: false
}
Then, we can run Karma:
karma start
- ELECTRON_BIN - Override path to use for
electron
- By default, we will use path given by
electron
- By default, we will use path given by
Example:
ELECTRON_BIN=/usr/bin/electron karma start
We support the following configurations:
- client
Object
- Container for configuring child windows loaded from Karma- __filenameOverride
String
- Override__filename
to be another path (e.g./path/to/my-index.html
)- This will also affect
__dirname
andmodule.filename
as those are derived from__filename
- By default,
__filename
will point to Karma'scontext.html
- This will also affect
- loadScriptsViaRequire
Boolean
- Load scripts viarequire
instead of<script src=
- This sets
__filename
,__dirname
, andmodule
to match the script instead of Karma'scontext.html
- By default, this is
false
and we directly load the original scripts content
- This sets
- __filenameOverride
Example:
module.exports = function (config) {
config.set({
client: {
// DEV: These 2 options aren't typically used together
// This is for demonstration purposes
// Override top level `__filename` to be `/home/.../my-electron-app/index.html`
// where `__dirname` is `/home/.../my-electron-app`
__filenameOverride: __dirname + '/index.html',
// Use `require` instead of `<script src=` to load scripts
loadScriptsViaRequire: true
}
});
};
We support configuration via Karma's custom launcher inheritance:
- flags
Array
- List of Chromium flags to alter Electron's behavior - userDataDir
String
- Directory to store cookies/localStorage information- By default, this is a random directory generated by Karma (e.g.
/tmp/karma-5355024
)
- By default, this is a random directory generated by Karma (e.g.
- require
String
- Path to a main Electron process file to require before callingapp.on('ready')
- browserWindowOptions
Object
- Parameters to pass tonew BrowserWindow
- This will be serialized to JSON so any functions or other live data will be lost
- loadURLOptions
Object
- Parameters to pass toBrowserWindow.loadURL
- This will be serialized to JSON so any functions or other live data will be lost
Example:
module.exports = function (config) {
config.set({
// Specify usage of our custom launcher
browsers: ['CustomElectron'],
// Define a custom launcher which inherits from `Electron`
customLaunchers: {
CustomElectron: {
base: 'Electron',
userDataDir: __dirname + '/.electron',
browserWindowOptions: {
show: true
},
require: __dirname + '/main-fixtures.js'
}
}
});
};
We can add our preload
location via a custom launcher:
module.exports = function (config) {
config.set({
// Specify usage of our custom launcher
browsers: ['CustomElectron'],
// Define a custom launcher which inherits from `Electron`
customLaunchers: {
CustomElectron: {
base: 'Electron',
browserWindowOptions: {
webPreferences: {
preload: __dirname + '/path/to/preload.js'
}
}
}
}
});
};
If we're upgrading to Electron@5 or later, then we might run into missing nodeIntegration
support. While it's advised to use preload
, here's a workaround until the transition to preload
is complete
module.exports = function (config) {
config.set({
// Specify usage of our custom launcher
browsers: ['CustomElectron'],
// Define a custom launcher which inherits from `Electron`
customLaunchers: {
CustomElectron: {
base: 'Electron',
browserWindowOptions: {
webPreferences: {
nodeIntegration: true
}
}
}
}
});
};
In lieu of a formal styleguide, take care to maintain the existing coding style. Add unit tests for any new or changed functionality. Lint via npm run lint
and test via npm test
.
Support this project and others by twolfson via donations.
http://twolfson.com/support-me
As of Mar 03 2016, Todd Wolfson has released this repository and its contents to the public domain.
It has been released under the UNLICENSE.