@tdd-buffet/react
v3.0.4
Published
React testing for tdd-buffet
Downloads
19,194
Readme
React testing tools for tdd-buffet
This package can be used independently of
tdd-buffet
.
Install
npm install @tdd-buffet/react
Usage
This package wraps the excellent @testing-library/react and adds jQuery for its powerful selection engine.
The following table illustrates the methods available in @testing-library/react
and their equivalents in this package:
@testing-library/react
| @tdd-buffet/react
-------------------------|--------------------
render
| $render
rerender
| $rerender
unmount
| $unmount
fireEvent.*
| $fireEvent.*
fireEvent.click
| $click
fireEvent.change
| $change
fireEvent.submit
| $submit
fireEvent.keyDown
| $keyDown
waitFor
| $wait
, $waitForElement
queryBy
| $find
ByText
| $*ByText
ByTestId
| $*ByTestId
prettyDOM
| $prettyDOM
Render components
import React from 'react';
import { expect } from 'tdd-buffet/suite/chai';
import { $render } from '@tdd-buffet/react';
const $container = $render(<span>foobar</span>);
expect($container.text()).to.equal('foobar');
The returned $container
is a JQuery wrapper over the container that holds the component. You can use the familiar JQuery API to query for content ($container.find('p')
), get text content ($container.text()
), assert visibility ($container.find('.class').is(':visible')
) etc.
Find elements
Since $render
returns a jQuery container you can use the $.find
method to query elements by any CSS selector (ID, class name, data-*
attribute etc.) or by jQuery's special selectors (:contains
, :checked
, :disabled
etc.).
import React from 'react';
import { $render } from '@tdd-buffet/react';
const $container = $render(<div>
<p>first paragraph</p>
<p>second paragraph</p>
</div>);
$container.find('p:second').text() === 'second paragraph';
There are also a few convenience query methods for finding elements by test ID ($getByTestId
, $getAllByTestId
, $queryByTestId
) and by text ($getByText
, $queryByText
).
import React from 'react';
import { $render, $getByText, $getByTestId } from '@tdd-buffet/react';
$render(<div>
<p>first paragraph</p>
<p data-testid="second">second paragraph</p>
</div>);
$getByText('first').text() === 'first paragraph';
$getByTestId('second').text() === 'second paragraph';
By default, all queries search throw the whole component that's currently rendered. You can override this by passing an optional selector to limit the search to e.g. a subtree of the component.
import React from 'react';
import { $render, $getByText, $getByTestId } from '@tdd-buffet/react';
$render(<div>
<div data-testid="foo">
<span>foo text</span>
</div>
<div data-testid="bar">
<span>bar text</span>
</div>
</div>);
console.log(
$getByText('text', $getByTestId('bar'))
); // 'bar text'
Fire events
The package exposes the fireEvent
object from @testing-library/react wrapped in a helper that can take a DOM element, a CSS selector or a JQuery collection:
import React from 'react';
import { $render, $fireEvent } from '@tdd-buffet/react';
$render(<button onClick={() => console.log('clicked')}>
click me
</button>);
$fireEvent.click('button'); // will log 'clicked'
Some aliases are also exported for the most common events:
$click
Simulate click events on buttons, checkboxes, radio buttons etc.
import React from 'react';
import { $render, $click } from '@tdd-buffet/react';
$render(<button onClick={() => console.log('clicked')}>
click me
</button>);
$click('button'); // will log 'clicked'
$change
Simulate change events on inputs. Receives the text value as the 2nd argument.
import React from 'react';
import { $render, $change } from '@tdd-buffet/react';
$render(<input onChange={e => console.log(e.target.value)} />);
$change('input', 'foobar'); // will log 'foobar'
$submit
Simulate form submissions. Can be triggered on a form or on a linked button (either inside the form or linked via the form
attribute).
import React from 'react';
import { $render, $submit } from '@tdd-buffet/react';
$render(<form onSubmit={() => console.log('submit')}>
<button>Submit me</button>
</form>);
$submit('button'); // will log 'submit'
$keyDown
Simulate pressing down a key. Receives the key character as the 2nd argument.
import React from 'react';
import { $render, $keyDown } from '@tdd-buffet/react';
$render(<div onKeyDown={(e) => console.log(e.which)} />);
$keyDown('div', 'A'); // will log 65
Wait for conditions
If your component contains async logic like waiting for a promise or for a timer you can use the $wait
function to wait for a condition to be satisfied such as an element becoming visible.
import React, { useState } from 'react';
import { $render, $wait, $click } from '@tdd-buffet/react';
const MyComponent = () => {
const [isLoading, setIsLoading] = useState(true);
return <button onClick={() => setIsLoading(false)}>
{isLoading ? 'loading' : 'done'}
</button>;
};
$render(<MyComponent />);
$click('button');
await $wait($container => $container.text() === 'done');
Wait for elements
The package exposes a shortcut to wait for the condition that an element is present in the container.
import React, { useState } from 'react';
import { $render, $waitForElement, $click } from '@tdd-buffet/react';
const MyComponent = () => {
const [isLoading, setIsLoading] = useState(true);
return <>
<button onClick={() => setIsLoading(false)}>Click me</button>
{!isLoading && <span className="present">I'm here</span>}
</>;
};
$render(<MyComponent />);
$click('button');
await $waitForElement($container => $container.find('.present'));
Unmount
If your component has cleanup logic e.g. clearing timers in componentWillUnmount
you can check them in your tests by manually unmounting the component.
import React from 'react';
import { $render, $unmount } from '@tdd-buffet/react';
const $container = $render(<span>foobar</span>);
$unmount();
$container.text() === '';
Rerender
Rerendering a component with new props can be useful if you want to check that it reacts to the new props e.g. getDerivedStateFromProps
.
import React from 'react';
import { $render, $rerender } from '@tdd-buffet/react';
$render(<span>foobar</span>);
$rerender(<span>potato</span>);
Print DOM
To help with debugging tests, you can use the $.html()
method to get the HTML content of an element. For large DOM trees the output could be hard to read, so you can use the $prettyDOM
helper instead to get a more readable representation. By default, it prints the currently rendered component's container, but you can pass a different element e.g. the result of $find
.
import { $render, $prettyDOM } from '@tdd-buffet/react';
import React from 'react';
$render(<div>foobar</div>);
console.log($prettyDOM());
// <div>
// foobar
// </div>