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.
Thank you very much @topicus, this looks similar to #93.
The code doesn't seem to work in the browser as well, can you please check?
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.
Also having this issue. What's weird is that the test runs fine locally, but fails in our CI pipeline (Jenkins). So what's the specific issue? Nesting string interpolation?
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.
@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?
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.
@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.
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)}");
`
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)
Just URL encoded the SVG string.
Thanks for your tips, hope we will find out what's wrong.
encoding the contents of the url() function is _not_ a solution, the images no longer show up in Firefox or Chrome in that case
this issue still exists
export const StyledDiv = styled.div`
width: 400px;
height: 100%;
border-top: 7px solid #e3e7ea;
border-radius: 5px;
margin-right: 40px;
background: #fff;
display: flex;
flex-direction: column;
`;
if run only one case - it's okay
it("StyledDiv", () => {
const component = renderer.create(<StyledDiv />).toJSON();
expect(component).toMatchSnapshot();
});
but if run "describe" section it fails with error
Error: undefined:2:6176: property missing ':'
at error (.../node_modules/css/lib/parse/index.js:62:15)
Same problem, it happens only with @storybook/addon-storyshots with arg --coverage
I'm using jest-dom 6.3.1 and have the same problem with a SVG background image and like @abejfehr said, encoding the image is not gonna work on Chrome or FIrefox.
// MyComponent.js
const MyComponent = styled.span`
background: url('data:image/svg+xml;utf8,<svg width="9" height="6" xmlns="http://www.w3.org/2000/svg"><path d="M1.28.24a.712.712 0 0 0-1.06 0 .855.855 0 0 0 0 1.144L4.499 6 8.78 1.382a.855.855 0 0 0 0-1.145.712.712 0 0 0-1.06 0L4.499 3.71 1.28.24z" fill="%230E242F" fill-rule="nonzero" fill-opacity=".369"/></svg>');
`
// MyComponent.spec.js
it('should match snapshot', () => {
const { container } = render(<MyComponent />);
expect(container).toMatchSnapshot();
});
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: we had a style that sometimes returned a boolean, and sometimes a string.
Had to ensure we always return a string.
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};
+ `;
This worked for me
https://css-tricks.com/probably-dont-base64-svg/#article-header-id-2
and
https://codepen.io/tigt/post/optimizing-svgs-in-data-uris
Using base 64 encoding solved the issue for me. None of the above option worked (either the URL encoding or the css utility)

we found this error compiling from TS, this is our solution hope helps someone
I submitted a new issue for the still open svg bug: #293
@jaimefps thanks returning string instead of boolean worked for me
Had the same issue. Was using a variable inside of styled components that returned an object when I was under the impression that it was returning a number. My font size was being set to {}px instead of 16px 馃榿
Most helpful comment
I'm running into this exact issue and have narrowed down my problematic code to be background-images. An example:
UPDATE:
My solution was to URL encode the contents in the
url()method.