Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Local scoped css #201

Closed
halvardos opened this issue Feb 17, 2016 · 8 comments
Closed

Local scoped css #201

halvardos opened this issue Feb 17, 2016 · 8 comments

Comments

@halvardos
Copy link

Hi

We use CSS modules and I'm having a hard time finding a way to select nodes that have a local scoped css className.

The actual classname that is set in the DOM is built as a combination of the JS class and the css class plus a hash that ensures the class is unique.
Something like:
JSClassName__cssclass__!"##$"$Feoij3432

I tried using the attribute contains selector but this seems to not be supported yet.
E.g:
expect(wrapper.find('div[class*="cssclass"]')).to.have.length(1);

So I'm wondering if anyone has any experience on how to do this without adding code to the component to identify the node we are trying to select.

@lencioni
Copy link
Contributor

I think that a good option is to extract the thing that you want to select in tests into its own component (preferably stateless functional component if that fits your use-case). Then you should be able to select it easily without worrying about the CSS classes at all.

However, if you would rather not do that, I think you might have a few options:

  • import your stylesheet in your tests as a dependency and reference the classes as you would in the component
  • use a global class for this

And a couple of options that don't fit your requirement of not adding code to the component to identify the node you are trying to select:

  • add an attribute to help with testing (like data-test-name) and then find based on that attribute
  • add a non-CSS className to your component, for testing purposes

@blainekasten
Copy link
Contributor

I have pulled this off by having my preprocessor not obfuscate the classnames for my unit tests. I'm not sure what your build pipeline is, but you should be able to do this. That way you can test it by the js key you define.

For example:

// component
import style from './style.css';

const div = <div className={style.foo} />

// test
const wrapper = shallow(div);
wrapper.hasClass('foo') // true;

@clouddra
Copy link

I run my tests with karma-webpack so that the spec files can also process CSS. In my tests, it looks something like this

import style from './style.css';
render.find(`.${style.foo}`);

@halvardos
Copy link
Author

@clouddra thx! this actually worked perfectly, we also use karma-webpack.

I'm not sure why i thought it would generate a different classname for my test and for my source, but when i tried testing it i forgot to concatenate it with .

@gbrassey
Copy link

When a selector is composed of another you get two class names which will throw this error: Enzyme received a complex CSS selector ('.styles__navigation___fCgdZ styles__trigger___2b9Qy') that it does not currently support

Used this to fix it:

wrapper.find(`.${styles.navigation.split(' ').join('.')}`);

@pietrofxq
Copy link

How can I make it work if I use jest? I need to find a selector with a class generated with CSS Modules. Like "search-icon--33gh78". I'm adding a fixed class like "enzyme-search-icon" as a workaround, but I'd like to import my css files in my tests.

@blainekasten
Copy link
Contributor

@pietrofxq use this https://github.com/Connormiha/jest-css-modules-transform/blob/master/src/index.js

Then in your tests your className will match the className in your .css file (not obfuscated);

// component
import style from './style.css';

const div = <div className={style.foo} />

// test
const wrapper = shallow(div);
wrapper.hasClass('foo') // true;

@drydenwilliams
Copy link

I managed to get it working by adding this: identity-obj-proxy

  "moduleNameMapper": {
    ".*\\.scss$": "identity-obj-proxy"
  }

Then when you do styles['badger'] in jest you get "badger" rather than ""

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

7 participants