![PyPI Now Supports iOS and Android Wheels for Mobile Python Development](https://cdn.sanity.io/images/cgdhsj6q/production/96416c872705517a6a65ad9646ce3e7caef623a0-1024x1024.webp?w=400&fit=max&auto=format)
Security News
PyPI Now Supports iOS and Android Wheels for Mobile Python Development
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
react-cosmos-testing-library
Advanced tools
An integration between react-cosmos-test and react-testing-library
yarn add --dev react-cosmos-testing-library
react-cosmos-testing-library
is also required as a peerDependency
To demonstrate how to test, we're going to set up a simple component that has
some state handling, some basic content rendered into the dom, and a handler
that needs to be called. When ToggleButton
is clicked, Toggled
will appear
above the button, and onToggle
will be called.
class ToggleButton extends React.Component {
state = {
isActive: true,
}
handleClick = () => {
const {isActive} = this.state
const newIsActive = !isActive
this.props.onToggle(newIsActive)
this.setState({
isActive: newIsActive,
})
}
render() {
const {text} = this.props
return (
<div>
<span data-test-id="text-area">{this.state.isActive && 'Toggled'}</span>
<button data-test-id="button" onClick={this.handleClick}>
{text}
</button>
</div>
)
}
}
This is a very simple fixture in this case, because there aren't very many props to ToggleButton. You just need to provide everything the component needs to render. For more complicated components, you would export multiple fixtures here to represent the different possible configurations of the component.
import ToggleButton from './ToggleButton'
export default {
component: ToggleButton,
props: {
text: 'Hello World',
onToggle: () => console.log('toggling'),
},
}
Now that we have the component and the fixture, it's as simple as stepping through the component and testing it in the same way it would be used in Cosmos.
// import the fixture you want to test
import fixture from 'ToggleButton.fixture.js'
import {renderFactory} from 'react-cosmos-testing-library'
const render = renderFactory({
callbacks: ['onToggle'],
// add any new test functions that you
// want to be shared across all tests in all files
getTestFunctions: ({
functions: {clickTestId, waitForCallBack, getByTestId},
}) => {
const clickButton = () => clickTestId('button')
const getCurrentText = () => getByTestId('text-area').textContent
// Because onToggle is is provided to callbacks
// you can use waitForCallback to wait for a particular number of times onToggle is called
const waitForOnToggle = desiredCall =>
waitForCallBack('onToggle', desiredCall)
return {
clickButton,
getCurrentText,
waitForOnToggle,
}
},
})
describe('text is updated on toggle', async () => {
// call render, pass in the fixture, and get back the queries, which are ready to use
const {getCurrentText, clickButton, waitForText, waitForOnToggle} = render(
fixture,
)
// ensure the component renders correctly on load
// this will error if the text isn't found
await waitForText('Hello World')
clickButton()
// confirm the text updates after the clicking the button
expect(getCurrentText()).toEqual('Toggled')
// confirm that waitForToggle is called once with the right arguments
const argsPassedToOnToggle = await waitForOnToggle(1)
// it was initially false, it should be set to true after toggling
expect(argsPassedToOnToggle).toEqual(['true'])
})
renderFactory lets you customize how you render a cosmos fixture and abstract out any repeated test functionality that's needed
Receives any already defined test functions and allows you to add test functions that are specific to your tests. You only need to return any new functions that you want to add
getTestFunctions: {
functions: existingFunctions => ({
newFunction: // define it here
}),
}
A function that allows you to modify the props provided to the fixture
getProps: props => ({
// any modifications you want to make to props
...props,
})
A function that allows you to modify anything in the fixture
updateFixture: fixture => ({
// any modifications you want to make to the fixture
...fixture,
})
An array of strings defining all callback props provided to the component that
you would like to be automatically stubbed out with jest mock functions that can
be used in conjunction with waitForCallback
callbacks: ['onToggle', 'onClick']
In addition to all of the queries provided by react-testing-library
documented
here,
several new queries are provided
id => fireEvent.click(getByTestId(id))
element => fireEvent.click(element)
Immediately throws an error if the provided text is still in the dom
same as makeSureTextIsGone
for test ids
Useful when testing elements that render directly into body(like portals). All of the provided queries start at the component that is rendered by cosmos, this query looks at the root dom node(the equivalent of body inside of cosmos)
Requires that a correspondingly named callback was provided in the callbacks
array in the renderFactory
options. Calling this allows you to wait for
desired number of calls and then resolves with the provided arguments. If the
specified number of calls doesn't occur within 5 seconds, an error is thrown
const argsPassedToSecondOnToggleCall = await waitForCallBack('onToggle', 2)
An async function that waits for the supplied text to not be in the dom, it will error after 5 seconds if it still exists
Same as waitForTextToBeGone
but for test ids
Wait for the text to be in the dom, and then click on the element that contains it
The following functions are all just combinations of waitForElement
and a
given query like getByTestId
or getByText
. They will keep searching for the
element for five seconds, and then error if it isn't found
A central tenet of react-testing-library
is to, as much as possible, rely on
the built in queries like getByTestId
and getByText
when asserting values in
the dom. This makes it much easier to test the code similarly to how it will be
used.
For simple components, this is a great solution. For complicated compound components however, it can start to get unwieldy. In situations like that, snapshot testing is a great solution, but even this has many potential issues. This is where custom serializers come in.
Instead of serializing an entire dom object that could be hundreds or even
thousands of lines long and frequently break when nothing of relevance has
changed, you can use the same standard react-testing-library
queries to build
up a simple serializable string that is much easier to follow when it breaks.
Create a file that will contain all of your custom serializers for all of your tests.
import {serializerBuilder} from 'react-cosmos-testing-library'
const serializerMap = {
customTable: {
// the test id for the object you want to serialze
testIds: ['comparison-values'],
print: val => {
// convert the react testing library dom object
// into a string that easily serialized
const rows = queryByAllTestId(val, 'row')
return rows
.map(row => {
// As much as possible, rely on the the standard react-testing-library queries, and avoid manual dom traversal
const cells = queryAllByTestId(row, 'cell')
return cells.reduce(
(rowString, cell) => `:${rowString}:${cell.textContent}`,
'',
)
})
.join('\n')
},
},
}
const addCustomSerialzers = serializerBuilder(serializerMap)
export default addCustomSerialzers
After defining the serializer, you need to initialize it in the test
import addCustomSerializers from './addCustomSerialzers'
// this corresponds to the key defined in the serializer map
// NOTE: this needs to be defined in EVERY test file
// that is going to use that custom serializer
addCustomSerializers(['customTable'])
FAQs
An integration between react-cosmos-test and react-testing-library
We found that react-cosmos-testing-library demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
PyPI now supports iOS and Android wheels, making it easier for Python developers to distribute mobile packages.
Security News
Create React App is officially deprecated due to React 19 issues and lack of maintenance—developers should switch to Vite or other modern alternatives.
Security News
Oracle seeks to dismiss fraud claims in the JavaScript trademark dispute, delaying the case and avoiding questions about its right to the name.