I'm trying to test a responsive design where I hide some text (in spans) when the screen size is too narrow.
import React from 'react'
import './index.css'
function Welcome(props) {
return (
<div className="container" data-testid="welcome-component">
<span
className="search-detective-emoji"
role="img"
aria-label="search emoji"
>
🕵️♀️
</span>
<span className="title">
<span className="verb">Search</span>{' '}
<span className="adjectives">Good Old</span> Flickr
</span>
<span
className="search-detective-emoji"
role="img"
aria-label="search emoji"
>
🕵️♂️
</span>
</div>
)
}
export default Welcome
.container {
display: flex;
justify-content: center;
align-items: center;
}
.search-detective-emoji {
font-size: 10vw;
}
.title {
text-align: center;
font-size: calc(1rem + 3vw);
font-family: Abril Fatface, Cambria, Cochin, Georgia, Times, 'Times New Roman',
serif;
margin: 0 10px;
}
@media screen and (max-width: 500px) {
.title .adjectives {
display: none;
}
}
@media screen and (max-width: 200px) {
.title .verb {
display: none;
}
}
import React from 'react'
import { render, screen, act, fireEvent } from '@testing-library/react'
import Welcome from '.'
test('renders a title', () => {
const { getByText } = render(<Welcome />)
const title = /flickr/i
expect(getByText(title)).toBeInTheDocument()
})
test('renders a responsive title', () => {
const { rerender, container } = render(<Welcome />)
let title = /search good old flickr/i
expect(container).toHaveTextContent(title)
act(() => {
window.innerWidth = 199
fireEvent(window, new Event('resize'))
})
rerender(<Welcome />)
expect(screen.getByText('Good Old')).not.toBeVisible()
})
src/components/Welcome/index.test.js
● renders a responsive title
expect(element).not.toBeVisible()
Received element is visible:
<span class="adjectives" />
22 | rerender(<Welcome />)
23 |
> 24 | expect(screen.getByText('Good Old')).not.toBeVisible()
| ^
25 | })
26 |
at Object.<anonymous> (src/components/Welcome/index.test.js:24:44)
PASS src/App.test.js
Test Suites: 1 failed, 1 passed, 2 total
Tests: 1 failed, 2 passed, 3 total
Snapshots: 0 total
Time: 2.717s, estimated 3s
if it's easier then I got this github branch https://github.com/Norfeldt/flickr-code-challenge/blob/implement-css/src/components/Welcome/index.test.js
be aware that I have commented out my attempt and that it's not possible to see if the results is a false positive (since removing the .not
will also make the test pass)
TLDR; You will not be able to test media-queries with current setup (jest-dom).
After debugging and going through github repository of jest-dom, it seems it will be pretty hard to test what responsive design.
There are couple of issue with the way, jest-dom (which uses jsdom) library renders component and calculates style.
To begin with, it doesn't attach/compute styles from attached stylesheet. This came with surprise to me as I am used to test UI with Angular setup. As mentioned in the attached link, you can try to overcome this issue by manually creating style element
const style = document.createElement('style')
style.innerHTML = `
@media screen and (min-width: 500px) {
.title .adjectives {
display: none;
color: red;
}
}
`;
document.body.appendChild(style)
or use helper function to do that as suggested in this bug.
After this change, I assumed it would work but to my surprise, it FAILED!, I checked with non-media query style and it was attaching style perfectly and that's when I discovered this TODO comment in jsdom, which makes sense as media-query styles are not working.
To conclude, it will not be possible to test media-query at the moment with react-testing-library. I haven't checked if it is working with enzyme setup, but it might who knows!
on you can use end to end testing framework such as Cypress.