jest-styled-components: Match snapshot fails with "undefined:3:21: property missing ':'"

I have this test:

import 'jest-styled-components';
import React from 'react';
import { truncate } from '../style';
import styled from 'styled-components';
import { shallow } from 'enzyme';

describe('shared/utils/string/isBlank', () => {
  it('should return the css with width', () => {
    const Result = styled.div`
      color: red;
      ${truncate({ width: 100 })};
    `;
    const wrapper = shallow(<Result />);
    expect(wrapper).toMatchSnapshot();
  });
});

And this truncate function

export function truncate({ maxWidth, width }) {
  return `
    ${({ maxWidth }) => maxWidth && `max-width: ${maxWidth}px;`}
    ${({ width }) => width && `width: ${width}px;`}
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
  `;
}

However, when I try to match the snapshot I’m getting:

    undefined:3:21: property missing ':'

      at Object.it (src/shared/utils/__tests__/style.js:22:21)
          at Promise (<anonymous>)
      at Promise.resolve.then.el (node_modules/p-map/index.js:42:16)
          at <anonymous>
      at process._tickCallback (internal/process/next_tick.js:188:

Seems like jest-styled-components doesn’t like those nested functions because if I remove them it works.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 2
  • Comments: 21 (1 by maintainers)

Commits related to this issue

Most upvoted comments

I’m running into this exact issue and have narrowed down my problematic code to be background-images. An example:

background-image: url("data:image/svg+xml;utf8, <svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='10' height='10' viewBox='0 0 10 7'><polygon points='0 0 5 7 10 0' style='fill: rgb%2839, 34, 84%29' /></svg>");

UPDATE:

My solution was to URL encode the contents in the url() method.

I’ve dealt with a similar problem for the past week. Unfortunately, the property missing ':' error is so useless that we had to dig around all our code and review each styled component to look for issues.

It was strange that we couldn’t get any errors when actually running the app, and that it was only came up during tests. Moreover, the tests were passing before, so some newer version of emotion/jest/jest-emotion/react-emotion was giving us this problem.

Below is a link to our fix.

Root cause: we had a style that sometimes returned a boolean, and sometimes a string. Fix: Had to ensure we always return a string.

https://stackoverflow.com/questions/55641543/react-emotion-and-jest-snapshots-error-property-missing/55656556#55656556

I am having the same issue. What bothers me is that the stack trace does not help me at all to trace the origin of the problem. In a big project it is hard even to figure out that the issue is being caused by this serialiser.

Ran into this same issue today. My problem was some stray text in styled component template literal, like

- const Wrapper = styled.div`
-  color: ${({ theme }) => theme.specialGray};
-  fs
- `;
+ const Wrapper = styled.div`
+  color: ${({ theme }) => theme.specialGray};
+ `; 

Solved!

We apparently need to used the css template literal helper

A helper function to generate CSS from a template literal with interpolations. You need to use this if you return a template literal with interpolations inside an interpolation. (This is due to how tagged template literals work)

If you leave off the css your function will be toString()ed and you’ll not get the results you expected.

I’ve determined that using the css helper around nested string interpolation resolves the issue. Not sure why it’s only necessary for tests, when it renders fine in the browser. I’d still love to understand why this is.

encoding the contents of the url() function is not a solution, the images no longer show up in Firefox or Chrome in that case

@DevanB Thank you for the tip ! I’m facing the same issue with a very similar code (svg as background-image), and URL encode solve the parsing issue However the svg did not show up anymore in browser… I’m trying hard getting it to work. If you have any idea, I’d be pleased to hear it.

Source code

const svg = "data:image/svg+xml;utf8, <svg xmlns='http://www.w3.org/2000/svg' version='1.1' width='100' height='100' viewBox='0 0 100 100'><path fill='#fff' d=''/></svg>";
// SVG path was intentionally cut

const ButtonClose = styled.div`
  position: absolute;
  background-image: url("${encodeURIComponent(svg)}");
`

Original non-working scheme

The SVG string was not URL encoded, and the parser failed with

undefined:2:360: property missing ':'

      at error (node_modules/css/lib/parse/index.js:62:15)
      at declaration (node_modules/css/lib/parse/index.js:224:33)
      at declarations (node_modules/css/lib/parse/index.js:253:19)
      at rule (node_modules/css/lib/parse/index.js:561:21)
      at rules (node_modules/css/lib/parse/index.js:118:70)
      at stylesheet (node_modules/css/lib/parse/index.js:81:21)
      at Object.<anonymous>.module.exports [as parse] (node_modules/css/lib/parse/index.js:565:20)
      at getCSS (node_modules/jest-styled-components/src/utils.js:46:26)
      at getStyle (node_modules/jest-styled-components/src/styleSheetSerializer.js:73:15)
      at Object.print (node_modules/jest-styled-components/src/styleSheetSerializer.js:139:19)

What helped but caused the svg not to show up

Just URL encoded the SVG string.

Thanks for your tips, hope we will find out what’s wrong.

Using base 64 encoding solved the issue for me. None of the above option worked (either the URL encoding or the css utility)

@greypants Thanks for that tip. I’ll give the css helper a try 👍

But due to the poor stack trace, I can’t really know where the error is coming from. Is there any easy way to know where the error is coming from?