10

Basic scenario is such: I have a component which has width: 100% as defined in a stylesheet. Therefore it should retain the width of its parent component. I want to calculate the width of my component and apply it to my child component because I am rendering it via createPortal and I would like them to be the same width. This works in the browser. However, in my test, I am finding that window.getComputedStyle(component) is not returning any of the styles applied from the stylesheet.

As suggested, I could mock the javascript window, but that's actually counter to what I'm hoping to do, I think. I want to verify the behavior that is present in the browser, that window.getComputedStyle() returns all styles applied, not just the inline styles.

I have put a simple example into a codesandbox: https://codesandbox.io/s/goofy-wilson-6v4dp

Also here:

function App() {
  return (
    <div className="App">
      <WidthComponent />
    </div>
  ) 
}

function WidthComponent() {
  const myInput = useRef();
  const [inputWidth, setInputWidth] = useState(0);

  useEffect(() => {
    console.log("in handleLoad");
    const width = myInput.current ? myInput.current.offsetWidth : 0;
    setInputWidth(width);
  }, [myInput]);

  return (
    <div className="inherited-width" ref={myInput}>
      <div style={{ width: inputWidth }} className="child-element">
        Hello
      </div>
    </div>
  );
}

// test
test("width is inherited", () => {
  const { rerender } = render(
    <div style={{ width: "452px" }}>
      <WidthComponent />
    </div>
  );
  const element = document.getElementsByClassName("child-element").item(0);
  rerender(
    <div style={{ width: "452px" }}>
      <WidthComponent />
    </div>
  );
  expect(window.getComputedStyle(element).width).toBe("452px");
});
.App {
  font-family: sans-serif;
  text-align: center;
  width: 500px;
}

.inherited-width {
  width: inherit;
}

Any help is appreciated.

graffic
  • 111
  • 1
  • 5
  • The code sandbox is a nice extra, but you need to add a MVCE to your question so that your question can help others in the future. – jmargolisvt Jan 05 '20 at 17:15
  • Does this answer your question? [How to mock the JavaScript window object using Jest?](https://stackoverflow.com/questions/41885841/how-to-mock-the-javascript-window-object-using-jest) – jmargolisvt Jan 05 '20 at 18:38
  • I don't think so... I don't want to mock the window, I want it to behave as it does in the browser, which it doesn't seem to be doing. In the browser, `window.getComputedStyle()` returns all the styles, including those defined in a stylesheet, but it doesn't appear to be doing so in jest. Is this just a known limitation? – graffic Jan 05 '20 at 21:11
  • The point here being that you probably need to mock the window. If you log it out, it's probably `undefined`. – jmargolisvt Jan 05 '20 at 21:33
  • 1
    Did you ever figure this out? – jorisw Aug 18 '20 at 07:43
  • May have a look at [this question](https://stackoverflow.com/questions/59396539/why-does-getcomputedstyle-in-a-jest-test-return-different-results-to-computed) and [jest issue](https://github.com/facebook/jest/issues/8464) – User Rebo Mar 07 '21 at 18:44

1 Answers1

3

However, in my test, I am finding that window.getComputedStyle(component) is not returning any of the styles applied from the stylesheet.

Note that if you're running your tests in JSDOM (i.e. every Jest test) then CSS isn't fully implemented. Specifically, the cascade part of CSS is not implemented (https://github.com/jsdom/jsdom/pull/2690). Inheritance is only partially implemented (display and visibility) (https://github.com/jsdom/jsdom/issues/2160).

I would suggest running tests that assert on computed styles only in browsers, not JSDOM. A codesandbox test is not running in an actual browser environment.

Sebastian
  • 3,322
  • 22
  • 34