Styled Components Nested components erroring - javascript

I am trying to workout why this is erroring.
Although If I do not have CardWrapper wrapping around CardImage the image is displaying.
import React from 'react'
import styled, { css } from 'styled-components'
const CardWrapper = styled.div`
background-color: yellow;
border-color: 1px solid red;
position: relative;
`
const CardImage = styled.img`
height: auto;
width: 100%;
`
const Card = props => {
return (
<CardWrapper>
<CardImage src={props.data.imageUrl}/>
</CardWrapper>
)
}
export default Card;
App.js
<Card data={{imageUrl: 'https://via.placeholder.com/630x354', logoUrl: "https://via.placeholder.com/100x100", text: "test"}}/>
Error
./src/Components/Card/Card.js
Error: Cannot find module '/Users/max/test/test/test/node_modules/babel-preset-react-app/node_modules/#babel/core/lib/index.js'. Please verify that the package.json has a valid "main" entry

Looks like you need to install a Node.js package. In your terminal, navigate to the project's root directory and run:
npm install babel-preset-react-app

Related

Can't apply GlobalStyles from styled-components when testing react app with cypress

I am developing a react app with styled-components and unit tests writen with cypress. I have a problem with global styles. My GlobalStyles style is just normalize.css. The problem is that in the browser it looks fine and works fine, but in the cypress test environment, no global styles are applied, so the fonts are wrong, the body has margins, etc. This is not very important for testing, but I prefer to know that my app looks exactly the same while I do my tests. Can you help me?
GlobalStyle.js:
import { createGlobalStyle } from "styled-components";
export const GlobalStyle = createGlobalStyle`
/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */
html {
line-height: 1.15;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
}
main {
display: block;
}
h1 {
font-size: 2em;
margin: 0.67em 0;
}
...
`;
App.test.jsx:
import React from "react";
import { mount } from "#cypress/react";
import { App } from "./App";
import { GlobalStyle } from "./globalStyles";
it("renders hello world", () => {
mount(
<App>
<GlobalStyle />
</App>
);
cy.get("h1").contains("Hello world!");
});

Gatsby not loading useEffect function in production

I'm creating a website using Gatsby.js.
In my component, I'd created animation using Gsap, inside useEffect function.
While debugging, all works. In production the useEffect function not running, what follows to not showing animations.
What I should do?
Any ideas?
Thanks for answers!
My component:
import React, { useRef, useEffect } from "react"
import styled from "styled-components"
import gsap from "gsap"
import WhatEver from "../../../static/whatever.svg"
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome'
import { faArrowDown } from '#fortawesome/free-solid-svg-icons'
import scrollTo from 'gatsby-plugin-smoothscroll';
const HeaderWrapper = styled.header`
width: 100%;
height: 100vh;
min-height: 150px;
padding: 10px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
background-color: rgb(255, 216, 41);
`
const HeaderButton = styled.button`
display: block;
margin: 40px auto;
border: 2px solid #000000;
`
const HeaderComponent = () => {
const animWrapper = useRef(null)
useEffect(() => {
const [elements] = animWrapper.current.children
const what = elements.getElementById('What')
const ever = elements.getElementById('Ever')
const button = document.getElementById('header-button')
const icon = document.getElementById('header-icon')
const whatChildrens = what.children
const everChildrens = ever.children
const allChildrens = [...whatChildrens, ...everChildrens]
gsap.set([...allChildrens, button], { autoAlpha: 0 })
const timeLine = gsap.timeline({ defaults: { ease: 'power3.inOut' } })
timeLine
.to(whatChildrens, { autoAlpha: 1, duration: 0.75 })
.to(everChildrens, { autoAlpha: 1, stagger: 0.025 })
.to(button, { autoAlpha: 1 })
}, [])
return (
<HeaderWrapper className="header" id="main-header">
<div ref={animWrapper} id="header-logo-wrapper">
<WhatEver style={{width: '100%'}}/>
<HeaderButton id="header-button" onClick={() => scrollTo('#poznaj-nas')}>
<FontAwesomeIcon icon={faArrowDown} id="header-icon"/>
</HeaderButton>
</div>
</HeaderWrapper>
)
}
export default HeaderComponent
I think what is happening is that the gsap library is getting tree shaken out of the production build. I would either try adjusting your webpack settings to make sure that it is not removed, or include it like this instead:
const gsap = require("gsap")
Which in my experience has prevented libraries from being tree shaken out.
I was facing this issue and it got resolved just by following the steps:
If you are trying to open the html directly without any web server then useEffect won't be called.
Only way to solve this issue is by running a webserver and serve the html from the server.
I am using a mac system so run the python server using the command inside the public folder:
python -m SimpleHTTPServer 8000
then open it using localhost:8000

Same code generating different snapshots on different machines

We're using git for version control, so the code is the same. But if I generate snapshots, and my coworkers run the tests, they all fail on the snapshot part. Why can this happen?
Example component
import React from 'react';
import styled from 'styled-components';
import classnames from 'classnames';
import { colors } from '../../utils/css';
const ProgressIcon = ({ className, progress, color }) => (
<div className={className}>
<div className={classnames('background', color)}>
<div className={classnames('icon', progress, color)}/>
</div>
</div>
);
export const StyledProgressIcon = styled(ProgressIcon)`
width: 12.8px;
height: 12.8px;
margin: 0;
div {
margin: 0;
}
.background.white {
border: 2px solid ${colors.LG_WHITE};
}
.background.gray {
border: 2px solid ${colors.LG_GRAY_2};
}
.background {
height: 100%;
width: 100%;
border-radius: 50%;
box-sizing: border-box;
.icon {
height: 100%;
}
.icon.white {
background: ${colors.LG_WHITE};
}
.icon.gray {
background: ${colors.LG_GRAY_2};
}
.icon.full {
width: 100%;
}
.icon.half {
width: 50%;
}
.icon.empty {
width: 0;
}
}
`;
Test
import React from 'react';
import { shallow } from 'enzyme';
import { StyledProgressIcon as ProgressIcon } from '../ProgressIcon';
describe('<ProgressIcon/>',
() => {
let wrapper;
beforeEach(() => {
wrapper = shallow(<ProgressIcon progress={'full'} color={'gray'}/>);
});
it('should match the snapshot', () => {
expect(wrapper).toMatchSnapshot();
});
});
I'm comparing the snapshots created by my coworkers (Everybody else's tests are passing with the exact same snapshots, and code. It only fails on my machine)
Here is the log
FAIL src/components/ProgressIcon/test/ProgressIcon.test.js
● <ProgressIcon/> › should match the snapshot
expect(received).toMatchSnapshot()
Snapshot name: `<ProgressIcon/> should match the snapshot 1`
- Snapshot
+ Received
## -4,11 +4,11 ##
Object {
"$$typeof": Symbol(react.forward_ref),
"attrs": Array [],
"componentStyle": ComponentStyle {
"componentId": "sc-bdVaJa",
- "isStatic": false,
+ "isStatic": true,
"rules": Array [
"
width: 12.8px;
height: 12.8px;
margin: 0;
## -69,11 +69,10 ##
"foldedComponentIds": Array [],
"render": [Function],
"styledComponentId": "sc-bdVaJa",
"target": [Function],
"toString": [Function],
- "usesTheme": false,
"warnTooManyClasses": [Function],
"withComponent": [Function],
}
}
forwardedRef={null}
10 | });
11 | it('should match the snapshot', () => {
> 12 | expect(wrapper).toMatchSnapshot();
| ^
13 | });
14 | });
15 |
at Object.toMatchSnapshot (src/components/ProgressIcon/test/ProgressIcon.test.js:12:23)
And the reverse is if I generate snapshots, and my coworkers test. Why is this happening and how can I fix this?
There is a version mismatch in your styled-components lib dependency. As explained
here
It is the styled component's shallow render that shows you that "isStatic": false value
Both of you need to sync up your dependencies. First
make sure that both have the same package.json.
Then the surefire way to do this is. In one of your computers
Remove node_modules
delete package-lock.json
Run npm install
Commit your package-lock.json! (ignore if no changes)
Go to all other PCs.
Pull in the changes to package lock json (reject all local and accept all remote changes).
Remove node_modules.
Run npm install.
Now run your tests and check, the snapshots should be equal.
I fixed it by installing https://github.com/styled-components/jest-styled-components
Although I've followed the above mentioned points as well but I think this one should also fix the issue.
yarn add --dev jest-styled-components
Usage
import React from 'react'
import styled from 'styled-components'
import renderer from 'react-test-renderer'
import 'jest-styled-components'
const Button = styled.button`
color: red;
`
test('it works', () => {
const tree = renderer.create(<Button />).toJSON()
expect(tree).toMatchSnapshot()
expect(tree).toHaveStyleRule('color', 'red')
})

Testing DOM in Enzyme

Let's say I have a tiny component like this:
Button.js
import React from 'react';
import './Button.css';
export default class Button extends React.Component {
render() {
return (
<a href={ this.props.url } className={`button button-${ this.props.type }`}>
{ this.props.content }
</a>
);
}
}
And there's some super basic styling like this:
Button.css
.button {
color: white;
padding: 1em;
border-radius: 5px;
text-decoration: none;
}
.button-primary {
background-color: red;
}
.button-primary:hover {
background-color: darkred
}
.button-secondary {
background-color: aqua;
color: black;
}
.button-secondary:hover {
background-color: darkcyan;
color: white;
}
And let's say I want to write some tests for this:
Button.test.js
import React from 'react';
import Enzyme, {shallow, mount} from 'enzyme';
import Adapter from 'enzyme-adapter-react-16';
Enzyme.configure({adapter: new Adapter()});
import Button from './Button';
import './Button.css';
// Render buttons
const primaryButton = mount(
<Button
content="Primary button"
url="http://www.amazon.co.uk"
type="primary"
/>
);
const secondaryButton = mount(
<Button
content="Secondary button"
url="http://www.ebay.co.uk"
type="secondary"
/>
);
it('should exist', () => {
expect(primaryButton).toBeDefined();
expect(secondaryButton).toBeDefined();
});
it('should display text in the button', () => {
expect(primaryButton.text()).toEqual('Primary button');
});
it('should have the correct CSS classes', () => {
expect(primaryButton.find('.button').hasClass('button-primary')).toEqual(true);
expect(secondaryButton.find('.button').hasClass('button-secondary')).toEqual(true);
});
I've set this up using react-create-app and all the above works perfectly.
My question is: how do I test that what is getting rendered looks correct? For example, in this case I would want to make sure that the buttons have the correct background colours defined in the CSS file and that they have the correct border radius. This will prevent other developers accidentally overriding critical styling for example.
I was under the impression that Enzyme did this out of the box, but I cannot understand how to interrogate the virtual DOM which I assume is happening in the background? I thought that JSDOM was automatically running and I'm executing this from the CLI which is a Node environment.
I've tried this so far:
it('should have the correct background colours', () => {
const domNode = primaryButton.find('.button').at(0).getDOMNode();
const background = getComputedStyle(domNode).getPropertyValue('background');
expect(background).toBe('red');
});
But background is returned blank, in fact if I do console.log(getComputedStyle(domNode)) I get this returned which seems to be missing the styles:
console.log src/modules/Button/Button.test.js:42
CSSStyleDeclaration {
_values: {},
_importants: {},
_length: 0,
_onChange: [Function] }
The getDOMNode of an enzyme wrapper gets you the corresponding DOM node.
You can then use getComputedStyle to get the style of that DOM:
const renderedComponent = mount(<MyComponent /);
const domNode = renderedComponent.find('div').at(0).getDOMNode();
const background = getComputedStyle(domNode).getPropertyValue('background');
expect(background).toBe('red');

Passing props from react-cosmos to styled-components

I have the following component where I have applied the css using styled-components:
import styled from 'styled-components'
// square-block css can be re-written as a styled-component(???)
const SquareBlock = styled.div`
width: 100%;
height: 100%;
background-color: ${props => props.color};
`
export default SquareBlock
I would like to use the following fixture with react-cosmos to adapt the background-color of the component based on the props:
import { COLORS } from '../../../constants/tetronimo'
export default {
color: COLORS.I
}
In the React developer tools I noticed that the component PropsProxy had a fixture prop which has the color property:
JSON.stringify($r.props.fixture, null, 2)
{
"color": "#3cc7d6"
}
How can I ensure that props are passed correctly to react-cosmos?
Props need to be placed under fixture.props in the latest version of React Cosmos, but you seem to have already figured this out. Does this solve your problem?

Categories

Resources