Skip to content

Jest setup

The package is ESM only: its exports map has an import condition and no require or default. Bundlers and Vitest handle that. Jest, which resolves modules the CommonJS way, reports that it cannot find @beyul/sulmu-ui.

Two settings fix it. This is the configuration in the frontend’s shared preset (packages/test-utils/jest-preset.cjs).

const path = require('node:path')
// @beyul/sulmu-ui only publishes an ESM "import" entry, which Jest's CommonJS resolver
// cannot see: point at the built file.
const sulmuUi = path.resolve(__dirname, '../../node_modules/@beyul/sulmu-ui/dist/index.js')
module.exports = {
moduleNameMapper: {
'^@beyul/sulmu-ui$': sulmuUi,
},
}

The built file is an ES module, so it has to go through the same transform as the app’s code. By default Jest skips everything in node_modules; make an exception for the @beyul scope:

module.exports = {
transform: {
'^.+\\.(js|jsx|ts|tsx)$': [require.resolve('@swc/jest')],
},
transformIgnorePatterns: ['/node_modules/(?!(@beyul))'],
}

Add @beyul to the existing list if the pattern already has exceptions.

If a file under test imports @beyul/sulmu-ui/styles.css, map CSS files to an empty module, as most Jest setups already do:

moduleNameMapper: {
'\\.css$': '<rootDir>/test/fileMock.js',
}
  • Components render real markup. Query them the way a user would: getByRole('button', { name: 'Log In' }), getByLabelText('Email').

  • No styles are applied, so do not assert on computed styles. Variant classes are on the elements if a test really needs them (su-button--variant_secondary).

  • Popups (Select, Menu, Dialog) render in a portal in document.body; screen queries find them.

  • jsdom lacks a few browser APIs that the floating components use. If a test that opens a popup fails on one, add these to the Jest setup file, as the library’s own test setup does:

    class ResizeObserverStub {
    observe() {}
    unobserve() {}
    disconnect() {}
    }
    globalThis.ResizeObserver ??= ResizeObserverStub
    Element.prototype.scrollIntoView ??= () => {}
    Element.prototype.scrollTo ??= () => {}

Vitest resolves ES modules natively and needs none of this.