1.0.7 • Published 3 months ago

jest-environment-emit v1.0.7

Weekly downloads
-
License
MIT
Repository
github
Last release
3 months ago

logo

jest-environment-emit

Environment with unlimited test event handlers

npm version

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 – exports WithEmitter, a higher-order function to create custom environment classes
  • jest-environment-emit/node – exports TestEnvironment, a wrapper over jest-environment-node
  • jest-environment-emit/jsdom – exports TestEnvironment, a wrapper over jest-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.

1.0.7

3 months ago

1.0.6

3 months ago

1.0.5

4 months ago

1.0.4

5 months ago

1.0.2

5 months ago

1.0.3

5 months ago

1.0.1

5 months ago

1.0.0

5 months ago

1.0.0-alpha.10

5 months ago

1.0.0-alpha.9

5 months ago

1.0.0-alpha.8

5 months ago

1.0.0-alpha.7

5 months ago

1.0.0-alpha.6

5 months ago

1.0.0-alpha.5

5 months ago

1.0.0-alpha.4

5 months ago

1.0.0-alpha.3

6 months ago

1.0.0-alpha.2

6 months ago

1.0.0-alpha.1

6 months ago