Open HenriBeck opened 5 years ago
From @kof on June 29, 2017 15:36
Right now one can obtain all sheets by using SheetsRegistryProvider or JssProvider if you are on the next branch/pre release version.
import {SheetsRegistryProvider, SheetsRegistry} from 'react-jss'
it('should match the css snapshot', () => {
const sheets = new SheetsRegistry()
render(
<SheetsRegistryProvider registry={sheets}>
<Component />
</SheetsRegistryProvider>
)
const snapshot = 'some css'
expect(sheets.toString()).to.be(snapshot)
})
From @kserjey on June 29, 2017 15:40
But what if i use enzyme
for testing instead of jest
snapshot?
From @kof on June 29, 2017 15:41
Thats fine, the example above is not using jest. This issue is basically about simplifying it in the future. It is already possible now.
From @kserjey on July 4, 2017 12:1
I often use selectors to find component in Enzyme testing and for that i map classes to new object with next function:
ruleName => sheet.getRule(ruleName).selectorText
Is there more reliable method?
From @kof on July 4, 2017 13:5
From @kof on July 4, 2017 13:18
Also what about classes
object?
any news on this ? i can not get the way that @kof gives as an example to work..
Got it working with a helper
import React from 'react';
import { JssProvider, SheetsRegistry, ThemeProvider } from 'react-jss';
import { mount } from 'enzyme';
import mockTheme from './defaultTheme';
/**
* JSS helper mount
* Wrapps the passed in component in Themeprovider and captures the styles generated
* @param {React component} Component
* @returns {Array} First item in array is the stylesheet generated by jss, the second is the rendered component for further expects
*/
export const themeMount = Component => {
const sheets = new SheetsRegistry();
const ClonedComponent = React.cloneElement(Component, { _renderid: 'rendered-component' });
const tree = mount(
<JssProvider registry={sheets}>
<ThemeProvider theme={{ theme: mockTheme }}>{ClonedComponent}</ThemeProvider>
</JssProvider>
);
return [sheets.toString(), tree.findWhere(node => node.props()._renderid === 'rendered-component')];
};
then in the tests
import React from 'react';
import Button from 'components/Button';
describe('Button', () => {
test('should render a default button', () => {
const [styleSheets, component] = themeMount(<Button>Test</Button>);
expect(styleSheets.toString()).toMatchSnapshot();
expect(component).toMatchSnapshot();
});
});
Thanks for the code @jb-san, we've run into issues where the order of the attributes was not guaranteed with that approach thus the snapshots would fail at random. We're now transitioning to making visual snapshots with storybook, I feel that this might be a better path going forward.
If you're interested hit me up!
Another solution could be to render the generated styles next to the component so they would be included in the component snapshot and someone wouldn't need to wrap every component around a JssProvider
and collect the sheets manually.
What if, when passing a custom theming context to the react-jss HOC, it is able to use the React Context's default value?
// themes.js
const defaultTheme = {
color: 'red'
}
const ThemeContext = React.createContext(defaultTheme)
export const theming = createTheming(ThemeContext)
// component.jsx
import {theming} from './themes
/* ... */
export default withStyles(styles, {theming})(Component)
Then unit tests which depend on a ThemeProvider can just fallback on the default theme.
EDIT - though on a closer look at the source code, maybe this should be handled by the theming
library.
@kilrain This should already be the case.
For the default theming context this is sadly not possible.
From @kof on June 5, 2017 20:35
Motivation: when you snapshot components with jest, you can also snapshot css generated by the component. Ideally this should also work with styled-jss. Also we should support testing generated CSS without jest.
See for e.g. https://github.com/styled-components/jest-styled-components/
Copied from original issue: cssinjs/react-jss#93