Prevent CSS modules in build from breaking Jest tests#75792
Conversation
1add8a7 to
e151dda
Compare
|
Size Change: -3 B (0%) Total Size: 6.84 MB
ℹ️ View Unchanged
|
|
The following accounts have interacted with this PR and/or linked issues. I will continue to update these lists as activity occurs. You can also manually ask me to refresh this list by adding the If you're merging code through a pull request on GitHub, copy and paste the following into the bottom of the merge commit message. To understand the WordPress project's expectations around crediting contributors, please review the Contributor Attribution page in the Core Handbook. |
jsnajdr
left a comment
There was a problem hiding this comment.
Yes, this is indeen an annoying issue that creates friction for adopters.
The proposed solution is OK. I left a comment suggesting how to simplify the syntax.
packages/wp-build/lib/build.mjs
Outdated
| } ); | ||
|
|
||
| let cssModule = `if (typeof document !== 'undefined' && !document.head.querySelector("style[data-wp-hash='${ hash }']")) { | ||
| let cssModule = `if (typeof document !== 'undefined' && !(typeof process !== 'undefined' && process.env?.NODE_ENV === 'test') && !document.head.querySelector("style[data-wp-hash='${ hash }']")) { |
There was a problem hiding this comment.
I think you can use an unguarded condition directly:
if (typeof document !== 'undefined' && process.env.NODE_ENV !== 'test')The Gutenberg code is always built with a tool (webpack, newly esbuild) that defines the process.env.NODE_ENV constant. If you search for usages across the codebase, you'll find conditions like process.env.NODE_ENV === 'production' at several places.
|
Adding a note about the future, when we move to browser-based tests like in Vitest: We're going to need to find a different way to suppress style injection only in jsdom. Maybe we can make it the consumer's job to set a designated process env in their jest config, to bypass style injection. |
|
Flaky tests detected in f76053e. 🔍 Workflow run URL: https://github.com/WordPress/gutenberg/actions/runs/22350273174
|
What?
Skip runtime CSS style injection during Jest tests to prevent
jsdomconsole errors.Why?
wp-buildcompiles CSS module imports into JavaScript that injects<style>elements into the DOM at runtime. The injected CSS uses@layerrules, whichjsdomdoesn't support — causingError: Could not parse CSS stylesheetconsole errors in any Jest test that transitively imports a package built bywp-build(including@wordpress/ui).Consumers shouldn't need to mock
@wordpress/uijust to avoid CSS parse errors in their test suite. This becomes increasingly impractical as@wordpress/uiadoption grows.How?
Adds a
NODE_ENV === 'test'guard to the generated style injection code incompileInlineStyle(). Whenprocess.env.NODE_ENVis'test', style injection is skipped entirely.Runtime behavior:
typeof processis'undefined', guard short-circuits, styles are injected normally.NODE_ENV=test) — guard matches, injection is skipped, no console errors.NODE_ENVis not'test', styles are injected normally.process.env.NODE_ENVis not replaced by esbuild'sdefinein the built output (at least for normalbuildandbuild-module), so the check is evaluated at runtime as intended.Testing Instructions
@wordpress/uias a dependency. (In the "before" test, it can come straight from npm. In the "after" test, replace it in node_modules with the new built files rebuilt from this PR branch.)@wordpress/ui.