web-dev-qa-db-fra.com

Pourquoi getComputedStyle () dans un test JEST renvoie des résultats différents aux styles calculés dans Chrome / Firefox DevTools

J'ai écrit un bouton personnalisé (MyStyledButton) basé sur material-ui Button.

import React from "react";
import { Button } from "@material-ui/core";
import { makeStyles } from "@material-ui/styles";

const useStyles = makeStyles({
  root: {
    minWidth: 100
  }
});

function MyStyledButton(props) {
  const buttonStyle = useStyles(props);
  const { children, width, ...others } = props;

  return (

      <Button classes={{ root: buttonStyle.root }} {...others}>
        {children}
      </Button>
     );
}

export default MyStyledButton;

Il est stylisé en utilisant un thème et cela spécifie que le backgroundColor doit être une nuance de jaune (spécialement #fbb900)

import { createMuiTheme } from "@material-ui/core/styles";

export const myYellow = "#FBB900";

export const theme = createMuiTheme({
  overrides: {
    MuiButton: {
      containedPrimary: {
        color: "black",
        backgroundColor: myYellow
      }
    }
  }
});

Le composant est instancié dans mon index.js Principal et enveloppé dans le theme.

  <MuiThemeProvider theme={theme}>
     <MyStyledButton variant="contained" color="primary">
       Primary Click Me
     </MyStyledButton>
  </MuiThemeProvider>

Si j'examine le bouton dans Chrome DevTools, le background-color Est "calculé" comme prévu. C'est également le cas dans Firefox DevTools.

Screenshot from Chrome

Cependant, lorsque j'écris un test JEST pour vérifier le background-color Et que j'interroge le style de nœud DOM du bouton à l'aide de getComputedStyles() j'obtiens transparent et le test échoue.

const wrapper = mount(
    <MyStyledButton variant="contained" color="primary">
      Primary
    </MyStyledButton>
  );
  const foundButton = wrapper.find("button");
  expect(foundButton).toHaveLength(1);
  //I want to check the background colour of the button here
  //I've tried getComputedStyle() but it returns 'transparent' instead of #FBB900
  expect(
    window
      .getComputedStyle(foundButton.getDOMNode())
      .getPropertyValue("background-color")
  ).toEqual(myYellow);

J'ai inclus un CodeSandbox avec le problème exact, le code minimum à reproduire et l'échec du test JEST.

Edit headless-snow-nyofd

16
Simon Long

Je me suis rapproché, mais je n'ai pas encore trouvé de solution.

Le problème principal est que MUIButton injecte une balise à l'élément pour alimenter les styles. Cela ne se produit pas dans votre test unitaire. J'ai pu faire fonctionner cela en utilisant createMount que les tests de matériaux utilisent.

Après ce correctif, le style s'affiche correctement. Cependant, le style calculé ne fonctionne toujours pas. Il semble que d'autres ont rencontré des problèmes avec la gestion correcte des enzymes - donc je ne sais pas si c'est possible.

Pour arriver là où j'étais, prenez votre extrait de test, copiez-le en haut, puis changez votre code de test en:

const myMount = createMount({ strict: true });
  const wrapper = myMount(
    <MuiThemeProvider theme={theme}>
      <MyStyledButton variant="contained" color="primary">
        Primary
      </MyStyledButton>
    </MuiThemeProvider>
  );
class Mode extends React.Component {
  static propTypes = {
    /**
     * this is essentially children. However we can't use children because then
     * using `wrapper.setProps({ children })` would work differently if this component
     * would be the root.
     */
    __element: PropTypes.element.isRequired,
    __strict: PropTypes.bool.isRequired,
  };

  render() {
    // Excess props will come from e.g. enzyme setProps
    const { __element, __strict, ...other } = this.props;
    const Component = __strict ? React.StrictMode : React.Fragment;

    return <Component>{React.cloneElement(__element, other)}</Component>;
  }
}

// Generate an enhanced mount function.
function createMount(options = {}) {

  const attachTo = document.createElement('div');
  attachTo.className = 'app';
  attachTo.setAttribute('id', 'app');
  document.body.insertBefore(attachTo, document.body.firstChild);

  const mountWithContext = function mountWithContext(node, localOptions = {}) {
    const strict = true;
    const disableUnnmount = false;
    const localEnzymeOptions = {};
    const globalEnzymeOptions = {};

    if (!disableUnnmount) {
      ReactDOM.unmountComponentAtNode(attachTo);
    }

    // some tests require that no other components are in the tree
    // e.g. when doing .instance(), .state() etc.
    return mount(strict == null ? node : <Mode __element={node} __strict={Boolean(strict)} />, {
      attachTo,
      ...globalEnzymeOptions,
      ...localEnzymeOptions,
    });
  };

  mountWithContext.attachTo = attachTo;
  mountWithContext.cleanUp = () => {
    ReactDOM.unmountComponentAtNode(attachTo);
    attachTo.parentElement.removeChild(attachTo);
  };

  return mountWithContext;
}
1
AnilRedshift