首页 > 解决方案 > How to test that a media query css applies to an element upon screen resize using jest and enzyme in reactjs

问题描述

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.

标签: reactjsunit-testingresponsive-designjestjsenzyme

解决方案


推荐阅读