Styled-jsx: global attribute with styled-jsx/css import does not work with Jest

Created on 23 Jul 2018  ·  9Comments  ·  Source: vercel/styled-jsx

Do you want to request a feature or report a bug?

Report a bug.

What is the current behavior?

Running tests with jest on a component that imports its global styles from an external css template literal fails with the following:

    ReferenceError: styles is not defined

styles refers to import name of the external module than exports a css template.

If the current behavior is a bug, please provide the steps to reproduce and possibly a minimal demo or testcase in the form of a Next.js app, CodeSandbox URL or similar

  1. Create a brand new React application with latest create-react-app and eject it.
npx create-react-app@next --scripts-version=2.0.0-next.3e165448 styled-jsx-jest
cd styled-jsx-jest
npm run eject
  1. Install styled-jsx.
npm i styled-jsx
  1. Configure Babel to use styled-jsx/babel by adding the following to package.json
  "babel": {
    "presets": [
      "react-app"
    ],
    "plugins": [
      "styled-jsx/babel"
    ]
  }
  1. Delete src/App.css and create a new src/App.styles.js file with the following contents:
import css from 'styled-jsx/css';

export default css`
  .App {
    text-align: center;
  }

  .App-logo {
    animation: App-logo-spin infinite 20s linear;
    height: 40vmin;
  }

  .App-header {
    background-color: #282c34;
    min-height: 100vh;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    font-size: calc(10px + 2vmin);
    color: white;
  }

  .App-link {
    color: #61dafb;
  }

  @keyframes App-logo-spin {
    from {
      transform: rotate(0deg);
    }
    to {
      transform: rotate(360deg);
    }
  }
`
  1. Make src/App.js use the recently created styles by importing App.styles.js and using <styles jsx> tag. Contents should look like this:
import React, { Component } from 'react';
import logo from './logo.svg';
import styles from './App.styles';

class App extends Component {
  render() {
    return (
      <div className="App">
        <header className="App-header">
          <img src={logo} className="App-logo" alt="logo" />
          <p>
            Edit <code>src/App.js</code> and save to reload.
          </p>
          <a
            className="App-link"
            href="https://reactjs.org"
            target="_blank"
            rel="noopener noreferrer"
          >
            Learn React
          </a>
        </header>
        <style jsx>{styles}</style>
      </div>
    );
  }
}

export default App;
  1. Run the application and its tests and verify that everything works ok.
# Start app
npm start

# ...run tests
npm test
  1. This is the crucial step. Add the global attribute to <style> tag in src/App.js
<style global jsx>{styles}</style>
  1. Run tests again. They will fail.
 FAIL  src/App.test.js
  ✕ renders without crashing (10ms)

  ● renders without crashing

    ReferenceError: styles is not defined

       6 |   render() {
       7 |     return (
    >  8 |       <div className="App">
       9 |         <header className="App-header">
      10 |           <img src={logo} className="App-logo" alt="logo" />
      11 |           <p>

      at App.render (src/App.js:8:7)

What is the expected behavior?

Tests run normally and pass.

Environment (include versions)

  • OS: macOS High Sierra 10.13.5
  • Browser: N/A
  • styled-jsx (version): 2.2.7

Did this work in previous versions?

Unsure. Tried it with 2.2.7 and 2.2.5 (same result).

All 9 comments

I am having this same issue with 2.2.6.

hey folks can you try with styled-jsx@^3.0.0 this issue might be solved in the new version

@giuseppeg after upgrade to [email protected], I got this error

image

next and styled-jsx version:

❯ npm ls styled-jsx
[email protected] /Users/keithyao/Projects/civey/www
└─┬ [email protected]
  └── [email protected]

@giuseppeg Yep, having the same issue when using [email protected] with babel-jest.

Any import from styled-jsx/css is undefined.

Actually I have an update. When I import using the following syntax:

import {resolve} from 'styled-jsx/css';

...

const { className, styles } = resolve`{styles}`,

I get the following error with jest test running with babel-jest:

    ReferenceError: resolve is not defined

      67 |   }
      68 |
    > 69 |   private renderTabBar = () => {
         |                                ^
      70 |     const overridingClassName = 'overriding-from-tab-panel-group';
      71 |     const { className, styles } = resolve`
      72 |       .${overridingClassName} {

However, tests work if I change the import to css:

import css from 'styled-jsx/css';

...

const { className, styles } = css.resolve`{styles}`,

Using: [email protected]

I tried css.global with the latest next.js and it works, but I got a new error:

image

I fix our tests by mocking the styled-jsx/style module:

jest.mock('styled-jsx/style', () => {
  const JSXStyle = ({ styleId, css }) => {
    return <style id={styleId} />
  }

  JSXStyle.dynamic = () => {
    return 'dynamic'
  }

  return JSXStyle
})

You folks should mock styled-jsx/css. It is not necessary to compile styles with styled-jsx and test them.

since v3.1.0 we also support this https://github.com/zeit/styled-jsx#rendering-in-tests

Was this page helpful?
0 / 5 - 0 ratings

Related issues

timsuchanek picture timsuchanek  ·  29Comments

rauchg picture rauchg  ·  24Comments

thisbejim picture thisbejim  ·  18Comments

jdolinski1 picture jdolinski1  ·  16Comments

rauchg picture rauchg  ·  18Comments