jest-environment-emit
v1.0.8
Published
Environment with unlimited test event handlers
Downloads
681,492
Maintainers
Readme
jest-environment-emit
Environment with unlimited test event handlers
Overview
There can be only one test environment per a project config in Jest unlike test reporters, which can be multiple.
This limitation is not convenient, so this package provides a couple of pre-defined test environments and a way to create custom ones:
jest-environment-emit
– exportsWithEmitter
, a higher-order function to create custom environment classesjest-environment-emit/node
– exportsTestEnvironment
, a wrapper overjest-environment-node
jest-environment-emit/jsdom
– exportsTestEnvironment
, a wrapper overjest-environment-jsdom
To wrap a custom environment, use WithEmitter
:
import { WithEmitter } from 'jest-environment-emit';
// ...
export default WithEmitter(MyEnvironment);
Usage
Assuming you have any test environment wrapped with jest-environment-emit
, you can add as many event listeners as you want:
/** @type {import('jest').Config} */
module.exports = {
// ...
testEnvironment: 'jest-environment-emit/node',
testEnvironmentOptions: {
eventListeners: [
'./simple-subscription-1.js',
['./parametrized-subscription-2.js', { some: 'options' }],
]
},
};
The modules specified in eventListeners
are required and should export a function with the following signature:
/** @type {import('jest-environment-emit').EnvironmentListenerFn} */
const subscription = function (context, options) {
context.testEvents
.on('test_environment_setup', async ({ env }) => {
// use like TestEnvironment#setup, e.g.:
env.global.__SOME__ = 'value';
})
.on('add_hook', ({ event, state }) => {
// use like TestEnvironment#handleTestEvent in jest-circus
})
.on('run_start', async ({ event, state }) => {
// use like TestEnvironment#handleTestEvent in jest-circus
})
.on('test_environment_teardown', async ({ env }) => {
// use like TestEnvironment#teardown
})
.on('*', ({ type }) => {
// wildcard listener
if (type === 'test_start') {
// ...
}
});
};
export default subscription; // module.exports = subscription;
For exact type definitions, see src/types.ts.
Library API
Deriving from classes
This higher-order function can also accept one subscriber function and custom class name:
import { WithEmitter } from 'jest-environment-emit';
// ...
export default WithEmitter(MyEnvironment, 'WithMyListeners', (context, options) => {
context.testEvents.on('*', ({ type }) => {
// ...
});
}); // -> class WithMyListeners(MyEnvironment) { ... }
The derived classes have a static method derive
to continue derivation, e.g.:
import { TestEnvironment } from 'jest-environment-emit/node';
export default TestEnvironment.derive((context, options) => {
context.testEvents.on('*', ({ type }) => {
// ...
});
}, 'WithMyListeners'); // -> class MyTestEnvironment(JestEnvironment) { ... }
All derived classes have also a protected property testEvents
to access the event emitter.
import { TestEnvironment } from 'jest-environment-emit/node';
export class MyTestEnvironment extends TestEnvironment {
constructor(config, context) {
super(config, context);
this.testEvents.on('*', ({ type }) => {
// ...
});
}
}
Using custom priorities
By default, all event listeners are appended to the list. If you need to guarantee the order of execution, you can specify a priority:
/** @type {import('jest-environment-emit').EnvironmentListenerFn} */
const subscription = function (context, options) {
context.testEvents
.on('test_environment_setup', async ({ env }) => {
// make sure this listener is executed first
}, -1)
.on('test_environment_teardown', async ({ env }) => {
// make sure this listener is executed last
}, 1E6)
};
Try to avoid using priorities unless you really need them.
Troubleshooting
Use JEST_BUNYAMIN_DIR=path/to/dir
to enable debug logging.
In your globalTeardown
script, you can aggregate all the logs into a single file for convenience:
// globalTeardown.js
import { aggregateLogs } from 'jest-environment-emit/debug';
module.exports = async () => {
await aggregateLogs();
};
The logs, e.g. jest-bunyamin.log
is a file viewable with Perfetto or chrome://tracing
.