Чому getComputedStyle () у тесті JEST повертає різні результати до обчислюваних стилів у Chrome / Firefox DevTools


16

Я написав спеціальну кнопку ( MyStyledButton) на основі матеріалу-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;

Він стилізований за допомогою теми, і це визначає backgroundColorвідтінок жовтого (Особливо #fbb900)

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

export const myYellow = "#FBB900";

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

Компонент інстанціонований в моєму головному index.jsі загорнутий у theme.

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

Якщо я вивчу кнопку в Chrome DevTools, то background-color"обчислюється", як очікувалося. Це також у Firefox DevTools.

Знімок екрана з Chrome

Однак, коли я пишу тест JEST, щоб перевірити, background-colorі я запитую стиль вузла DOM кнопки за допомогою, getComputedStyles()я transparentповертаюсь назад, і тест закінчується.

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);

Я включив CodeSandbox з точною проблемою, мінімальним кодом для відтворення та невдалим тестом JEST.

Редагувати безголовий-сніговий


.MuiButtonBase-root-33 фоновий колір прозорий, тоді як .MuiButton-міститьсяPrimary-13 не є - тому проблема полягає в тому, що класи в CSS мають однакове значення, тому розрізняють їх лише порядок завантаження -> у тестових стилях завантажуються в неправильному порядку.
Зиднар

1
@Andreas - Оновлені за запитом
Саймон Лонг

@Zyndar - Так, я це знаю. Чи є спосіб пройти цей тест?
Саймон Лонг

Чи не themeпотрібно було б використовуватись у тесті? Як в, загорнути <MyStyledButton>в <MuiThemeProvider theme={theme}>? Або використовувати якусь функцію обгортки, щоб додати тему до всіх компонентів?
Brett DeWoody

Ні, це не має ніякого значення.
Саймон Лонг

Відповіді:


1

Я наблизився, але поки не зовсім у вирішенні.

Основне питання полягає в тому, що MUIButton вводить тег в елемент для живлення стилів. Це не відбувається у вашому тесті на одиницю. Мені вдалося змусити це працювати, використовуючи createMount, який використовуються матеріальні тести.

Після цього виправлення стиль відображається правильно. Однак обчислюваний стиль все ще не працює. Схоже, що інші зіткнулися з проблемами щодо ферментативного поводження з цим правильно, тому я не впевнений, чи це можливо.

Щоб потрапити туди, де я був, візьміть тестовий фрагмент, скопіюйте його вгорі, а потім змініть код тесту на:

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;
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.