I am trying to test the responsiveness of the application I am building in reactjs using jest and enzyme. How can I do that?
I have a sidebar which transitions left and disappears when the screen size is less than or equal to 1024px. I went through this - Figuring out how to mock the window size changing for a react component test stackoverflow question to simulate/mock a screen resize. Then I tried using DOM functions like getComputedStyle to see if the css rule for transition is applied to the side bar. But I can't find the transform rule I applied. When I selected the side bar, stored it as a global element and did getComputedStyle over it in the browser console, it worked. What am I doing wrong?
test.ts
describe('App', () => {
let mountedApp: any;
const props: RouteComponentProps = {
...
} as RouteComponentProps;
const initialState = {
...
};
// Function that returns a new App mounted
const newApp = ((route: string) => {
if (!mountedApp) {
props.location.pathname = route;
mountedApp = mount(
<MemoryRouter initialEntries={[route]}>
<Provider store={configureStore([thunk])(initialState)}>
<App {...props} />
</Provider>
</MemoryRouter>,
{ attachTo: document.body }
);
}
return mountedApp;
});
it('Expect the side bar to disappear and menu icon to appear for smaller screen size', () => {
const wrapper = newApp('/');
let container = wrapper.find(NavDrawer).find(Drawer);
expect(container.props().classes.paper).toEqual('nav-drawer-paper drawer-close');
Object.defineProperty(window, 'innerWidth', {writable: true, configurable: true, value: 1024});
window.dispatchEvent(new Event('resize'));
// expect(container.find(Drawer)).toHaveStyleRule('transform', 'translate3d(-240px, 0, 0)');
let element = container.getDOMNode().children[0];
let HTMLElement = document.getElementsByClassName('drawer-close')[0];
console.log('dom element', window.getComputedStyle(HTMLElement));
console.log('element style', window.getComputedStyle(element));
});
});
NavDrawer is the Component I wrote inside which I used the material ui Drawer component. To that component I applied the styles.
NavDrawer.ts
class NavDrawer extends React.Component {
render() {
return (
<Drawer
className='nav-drawer'
variant='permanent'
anchor='left'
classes={{paper: `nav-drawer-paper${this.props.isDrawerClose ? ' drawer-close' : ''}`}}
>
...
...
</Drawer>
);
}
}
When the side bar disappears, I show the menu icon on the top bar. By clicking on it the user can open or close the side bar in smaller screens. this.props.isDrawerClose
says if the drawer is opened by the user or not. It is true
by default.
style.less
.nav-drawer {
width: 240px;
z-index: 1295;
flex-shrink: 0;
.nav-drawer-paper {
border-right-width: 0;
box-shadow: 0 1px 1px rgba(0, 0, 0, 0.15);
padding-top: 68px;
width: 240px;
transition: all 300ms ease;
transform: translate3d(0, 0, 0);
}
}
@media screen and (max-width: 1024px){
.nav-drawer {
.nav-drawer-paper {
box-shadow: 0 0 10px rgba(51, 51, 51, 0.38);
}
.drawer-close {
transition: all 300ms ease;
transform: translate3d(-240px, 0, 0);
}
}
}
I found something called toHaveStyleRule
but I'm not able to use it(you can see it commented in the test.ts file) because it gives tslint error Property 'toHaveStyleRule' does not exist on type 'Matchers<any>'
I also tried using the web dom api to get the element and check styles as I did in the browser console but still not working. Initially the document.getElementsByClassName
was returning an empty array. So I referred to this stackoverflow question and added { attachTo: document.body }
option in the mount. I could retrieve the DOM element but not able to get the same results as in browser.
In browser, following is what I did and got.
I did
ele = document.getElementsByClassName('drawer-close')[0]
window.getComputedStyle(ele).transform
which gave
"matrix(1, 0, 0, 1, 0, 0)"
After resizing the screen to less than 1024px, it gave
"matrix(1, 0, 0, 1, -240, 0)"
I expected the same to happen in the browser but when I consoled computerStyle.transform, it gave an empty string.