npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

jest-environment-emit

v1.0.8

Published

Environment with unlimited test event handlers

Downloads

742,405

Readme

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.