CSS Injection in JSDOM
Tailwind CSS is a popular CSS framework that provides utility classes to style web applications. However, when it comes to unit testing with JSDOM, injecting the stylesheet can be a tricky task. In this blog post, we will explore a common issue that developers face when trying to inject Tailwind CSS stylesheets into JSDOM for unit testing purposes and how to solve it.
Introduction
When unit testing React components with React Testing Library, developers need to make sure that the component is visible in certain scenarios. This visibility is often controlled by the "hidden" class from Tailwind CSS. However, without injecting the stylesheet into the DOM, class names are meaningless. In this blog post, we will explore a solution to a problem encountered unexpectedly.
Stylesheet Injection to JSDom
Here is a piece of code that's commonly introduced to the customRender function when using React Testing Library
// inject the style sheet generated by tailwind into document before rendering
const style = document.createElement("style");
const cssText = fs.readFileSync("./lib/src/index.css", "utf8");
style.innerHTML = cssText;
document.head.appendChild(style);
Problem
When trying to append a "style" element to the "head" of the document and add the styles as its content, JSDOM throws an error that says "Error: Could not parse CSS stylesheet." After some research, we figured out that JSDOM uses CSSOM as its underlying CSS parser. So, we tried to parse it ourselves by installing the CSSOM as a dependency and running cssom.parse([loadedFile])
. However, we encountered an error that pointed to a chunk of CSS generated by Tailwind:
.after\:content-\[\"\"\]::after {
--tw-content: "";
content: var(--tw-content);
}
The error message complained about an unmatched "
in the classname .after\:content-\[\"\"\]::after
. This classname came from a Tailwind utility after:content-[""]
.
Root Cause
The classname .after\:content-\[\"\"\]::after
contains \"
, which cannot be parsed by CSSOM. As a result, the stylesheet injection fails.
Solution
The solution is to omit the after:content-[""]
utility. This utility is not needed because Tailwind will automatically add content: ''
by default when using ::before
and ::after
modifiers. Developers only need to specify a different value if they want to. This information can be found in the official Tailwind documentation (open with chrome).
Conclusion
Unit testing with JSDOM and Tailwind CSS can be challenging, but with the right knowledge, developers can overcome common issues. In this blog post, we explored a solution to a common problem that developers face when injecting Tailwind CSS stylesheets into JSDOM for unit testing purposes. Remember to always refer to official documentation and stay up-to-date with the latest best practices.
This article is co-authored with ChatGPT
Cover image generated by Midjourney