Hook into CSS Module creation to export a class-name-map for easier E2E Cypress testing #23949
Replies: 4 comments
-
By design, css modules are provided unique strings to ensure there won't be naming collisions when multiple stylized components are loaded within the same page. Overriding this feature with static strings goes against its purpose. Instead, a simple work-around for E2E testing, without having to reconfigure the localIdentName during build-time, would be to use static data-testid attributes. Then you can use this plugin to remove them in production. I've used this pattern in multiple projects and I find it the easiest solution to implement without having to override Next's webpack configuration. Ultimately, it's a DX friendly way to ensure UI consistency across multiple builds, test runs, and test environments. pages/example.js import { exampleClass } from "../Example.module.css;
const Example = () => <h1 data-testid="header" className={exampleClass}>Testing</h1>;
export default Example; integration/example.spec.js context("Example Page", () => {
before(() => {
cy.visit("/example");
});
it("displays the 'Testing' header", () => {
cy.get("[data-testid='header']").should("have.text", "Testing");
});
}); |
Beta Was this translation helpful? Give feedback.
-
Thank you for giving an alternative. I guess I'll use that for the time
being.
Overriding this feature with static strings goes against its purpose.
I don't understand this. What you're saying is that it's impossible to act
as a middleware and only intercept and save the generated class names?
Because I don't want to overwrite anything and use static strings, I only
want to get information about which class names get which random names and
save that information for use inside e2e tests.
|
Beta Was this translation helpful? Give feedback.
-
Misunderstood your original intentions. That said, you'll still need consistency within the DOM to select distinct elements, which the data attribute would accomplish with much less work/configuration. Imagine someone who has no idea how your DOM is structured... what would be easier for them to read and understand? A statically created data attribute string that was developer defined ( |
Beta Was this translation helpful? Give feedback.
-
You're right about identifying elements and I think I'll use this method. Although there is still a valid use case when you want to make sure a particular class name has been applied and you want to verify that in your tests. |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Feature request
Is your feature request related to a problem? Please describe.
It'd be easy in cypress to select elements based on the class name inside the
.module.css
class names.Describe the solution you'd like
During webpack
module.css
compilation one could create an object mapping from original.module.css
class names to the class names that will appear in the HTML file allowing later, inside the tests to access that data. In development a.next/cssModuleMap.js
or.next/cssModuleMap.ts
file could be created while the server is running, or maybe it should reside inside theout
directory.Describe alternatives you've considered
I guess I could somehow access the HTML elements differently, but it's probably gonna be ugly.
Additional context
Beta Was this translation helpful? Give feedback.
All reactions