testing-library / jest-dom

:owl: Custom jest matchers to test the state of the DOM

Home Page:https://testing-library.com/docs/ecosystem-jest-dom

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Work out of the box with explicit imports from '@jest/globals'

MattyBalaam opened this issue ยท comments

We are moving away from using global imports for our tests. Partly because we use Cypress and Jest in the same packages which causes type collisions, but also just because it is much easier to reason about.

Out of the box trying to use import '@testing-library/jest-dom' when using the explicit imports import { expect } from '@jest/globals' does not work.

I have spent a while and the best solution I have cobbled together in our local packages is to paste out parts of the types and augment, but I am sure there must be a better way!

import type { BaseExpect } from 'expect';
import type { addSerializer, SnapshotMatchers } from 'jest-snapshot';
import type { AsymmetricMatchers, Matchers } from '@jest/expect';
import { expect as jestGlobalExpect } from '@jest/globals';
import * as matchers from '@testing-library/jest-dom/matchers.js';

// BE AWARE this file may need updating from time to time as @testing-library/jest-dom package or @jest/globals is updated.

declare type PromiseMatchers<T = unknown> = {
  /**
   * Unwraps the reason of a rejected promise so any other matcher can be chained.
   * If the promise is fulfilled the assertion fails.
   */
  rejects: JestMatchers<Promise<void>, T> &
    Inverse<JestMatchers<Promise<void>, T>>;
  /**
   * Unwraps the value of a fulfilled promise so any other matcher can be chained.
   * If the promise is rejected the assertion fails.
   */
  resolves: JestMatchers<Promise<void>, T> &
    Inverse<JestMatchers<Promise<void>, T>>;
};

type JestMatchers<R extends void | Promise<void>, T> = Matchers<R, T> &
  SnapshotMatchers<R, T>;

declare type Inverse<Matchers> = {
  /**
   * Inverse next matcher. If you know how to test something, `.not` lets you test its opposite.
   */
  not: Matchers;
};

type JestExpect = {
  <T = unknown>(
    actual: T,
  ): JestMatchers<void, T> &
    Inverse<JestMatchers<void, T>> &
    PromiseMatchers<T> &
    matchers.TestingLibraryMatchers<unknown, T> &
    Inverse<matchers.TestingLibraryMatchers<unknown, T>>;
  addSnapshotSerializer: typeof addSerializer;
} & BaseExpect &
  AsymmetricMatchers &
  Inverse<Omit<AsymmetricMatchers, 'any' | 'anything'>>;

jestGlobalExpect.extend(matchers);

const expect = jestGlobalExpect as unknown as JestExpect;

export { expect };

๐ŸŽ‰ This issue has been resolved in version 6.0.0 ๐ŸŽ‰

The release is available on:

Your semantic-release bot ๐Ÿ“ฆ๐Ÿš€