Jest/Storyshots test responsive elements in my components - reactjs

I am using react material ui combined with storybook and storyshots. I am trying to understand how I can test responsive elements in material-ui with jest or storyshots via storybook
I have Hidden elements in my components like the following
<Hidden xsDown>
{displayText}
</Hidden>
and stories that look roughly like
storiesOf("Card", module)
.addDecorator(muiTheme(myTheme))
.add("options bar", () => (
<Card {...someProps}/>
));
I have tried modding the breakpoints in my theme, which has an effect when viewing through storybook. However no matter what I have tried, the Hidden element never renders in my snapshots.
I have also tried not using the Hidden element and tried className styles to set display: none if theme.breakpoints.down('xs') is true. This produces the element in my snapshot like
<h6
className="MuiTypography-root CardOptions-label-1170 MuiTypography-
subtitle2"
>
View Route
</h6>
but nothing in this block tells me that the element is being hidden on xs screens.
It seem like I should be able to somehow toggle xsDown in the Hidden element to be true or false in storybook to have storyshot render or not render the element in my snapshot, but I am having no luck figuring that out.
I guess in general I am just wondering how most people are testing responsive UIs with jest. It seems like I should be able to accomplish this with snapshots but maybe I am missing something.
Thanks for your help

At the moment Storybook does not provide a responsive UI testing library out of the box.
However, you can use an additional library such as Chroma (company behind Storybook) or React screenshot test.
Which one you choose really depends on other factors.
Read more on Chroma: https://blog.hichroma.com/responsive-ui-component-testing-6d38b7e89dd4

Related

Usage of TailwindCSS messes with styled components in react

the problem I have is simply explained. I work on a project as a front-end developer and use react with styled-components to do so. My colleague uses TailwindCSS. Now I tried to merge things together but it seems like whenever I activate Tailwind and the components of my collage it messes up my styled-components just a slight bit so they look off, even though he did not work on these files and has never done anything Tailwindy inside of them. Is there something I'm missing out on or should look for?
Thank you in advance.
I don't know how you're working together but the right way to integrate styled components with tailwind is with the attr function to add the styles
const Card = styled.div.attrs({ className: "bg-white mx-auto max-w-sm shadow-lg rounded-lg" })` ["Your styles and props"]`;
//and even extend later
<Card className="overflow-hidden">Content</Card>
Otherwise, some tailwind global styles can affect your components where you don't want it to happen (this is probably what happened to you).

React TypeScript - Optionally depend on library and import it

I am currently creating a React component library. This component needed a lightweight tooltip, and as I could not find anything as light as I wanted, I made another component library that I can use for the main or any other projects I want. This works very well.
However, what I'd like to do is offer users of my library a way to disable tooltips and not be penalized for doing so. From my tests it seem that, even if the tooltip is not used, it is still added to the bundle. Webpack apparently can't shake it out. It will also need to be installed as a dependency.
To give an idea of how it's used:
return (
<div>
{showTooltip ? (
<Tooltip>
//...children
</Tooltip>
) : (
//children
)}
</div>
);
showTooltip is just a destructured prop. I get why this doesn't work, as it's impossible for the bundler to know that showTooltip is never going to change value, but how do I do what I want here? How do I allow users to not install the tooltip lib and not be weighed down by a feature they've disabled?

What does "animated" do in react-spring?

I am currently getting to grips with the react-spring animation library.
In some of the CodeSandbox demos (e.g. https://codesandbox.io/embed/j150ykxrv) in the documentation, something is imported called "animated":
import { Transition, animated } from 'react-spring'
and then used like so:
{this.state.items.map(item => styles => <animated.li style={{ ...defaultStyles, ...styles }}>{item}</animated.li>)}
In other examples this isn't used:
import { Spring } from 'react-spring'
<Spring
from={{ opacity: 0 }}
to={{ opacity: 1 }}>
{props => <div style={props}>✌️</div>}
</Spring>
I can't find any mention in the documentation of what this does or why it is used, as it seems you can animate by just passing animated style props into a component.
Are the uses in the documentation part of a legacy version?
Native is optional, if you set it (and then you need the component to extend from animated.xxx) it won't render out the animation like normally react animation libs would do, in other words they call forceUpdate or setState on every frame, which is expensive. With native it will render the component once, then animate in the background using a requestAnimationFrame-loop which sets the styles directly. The values you pass to your target div (or whatever) are not numeric values but classes that receive update events, this is why you need to extend.
Rendering through react is not obsolete, though, it is the only way you can animate React component props. If you have a foreign control, or a D3 graph for instance, you would simply blow props into it while the spring renders them out.
Looking further into the docs, I can see it is used for "native" rendering.
This allows react-spring to bypass React for frame updates. The benefits of this method are improved performance.
It is recommended to use this approach
"Try doing this in all situations where you can"
Just be aware of the following conditions:
native only animates styles, attributes and children (as textContent)
The values you receive are opaque objects, not regular values
Receiving elements must be animated.[elementName], for instance div becomes animated.div
If you use styled-components or custom componemts do: animated(component)
If you need to interpolate styles use interpolate
Summarised benefits:
Your application will be faster, the difference really can be night
and day
You get quite powerful interpolation and keyframing tools (see
below)
You get to animate scrollTop and scrollLeft out of the box (which
React can't normally handle)
Looks like it is used for doing native rendering,take a look a the Transition component , it has a native prop

Semantic-UI-React Responsive component renders element in spite of minWidth/maxWidth prop

I have a component where I want to render different components based on screen size. If I reload the page while on mobile view, everything is ok, NavBarMobile is rendered and NavbarDesktop is not.
If I reload the page while on desktop view, then my NavbarMobile is rendered again instead of NavBarDesktop.
If I start resizing the screen to mobile and back to desktop view, NavBarDesktop is rendered correctly.
So, the problem is first page load while in Desktop view, how to fix that?
const { mainAppComponents, } = this.props
const { visible, } = this.state
return (
<Fragment>
<Responsive maxWidth={767}>
<NavBarMobile
onPusherClick={this.handlePusher}
onToggle={this.handleToggle}
rightItems={rightItems}
visible={visible}
>
{mainAppComponents.header}
{mainAppComponents.routes}
</NavBarMobile>
</Responsive>
<Responsive minWidth={768}>
<NavBarDesktop rightItems={rightItems}>{mainAppComponents.header}</NavBarDesktop>
{mainAppComponents.routes}
</Responsive>
</Fragment>
)
Igor-Vuk, I put together a quick codesandbox example just to make sure there was not a problem with how you are trying to implement the min/max width props. As you can see from this example, they do in fact work as expected. https://codesandbox.io/s/98pk46l7vr
Without seeing the rest of your component, or application, the issue may be due to something in your router. I'd recommend trying to remove some of the other components you are returning as children of the Responsive component to see if it starts working as expected (like in my codesandbox example). If it works, then you know the problem is somewhere in the children. If it does not work then there is a greater problem above in your app.
If you are using SSR, on initial load the content was rendered and served with the Responsive component having no knowledge of the viewport. So you may need to also add a CSS media query.

Rendering null in react element prevents me from using css's :empty selector

To better explain my question, I'll use an example:
Let's say I have two react elements, which contain one another. Lets call the container Box, and the child Stuff. Box just renders a div with className="box" which surrounds the children it is given. Stuff most of the time renders something, but its render function can return null when it decides there's nothing to render.
Here's the twist: if <Box> is empty, I don't want to show it at all. So I decided to use css3 selectors, and write something like
.box:empty {
display: none;
}
... which should work, except react renders a <noscript> tag, which prevents the browser from treating the parent .box element as empty...
Is there an elegant way around this? I'd like to keep the logic of determining emptiness inside of Stuff, and have Box just "look" at its contents and decide whether it wants to show anything or not.
UPDATE
This fiddle https://jsfiddle.net/69z2wepo/67543/ has an example of what I'm trying to do. Strangely, in that fiddle, it works, and react doesn't render <noscript> tags... why does it render <noscript>s in my code? In what cases does react choose to render <noscript>s?
Found the problem!
I was using an old version of react-css-modules (3.7.7). Upgrading to 4.1.0 fixed it.
Looks like this was a relatively recent fix, too:
https://github.com/gajus/react-css-modules/commit/a9c8de252d5464037090e155c431abfe9f671531

Resources