What is resq?
The resq npm package is a utility for querying React components in the DOM. It is particularly useful for testing and debugging React applications by allowing developers to locate and interact with React components directly.
What are resq's main functionalities?
Querying React Components
This feature allows you to query a React component by its name. The code sample demonstrates how to use the `resq$` function to find a component named 'MyComponent' and log it to the console.
const resq = require('resq');
(async () => {
const component = await resq.resq$('MyComponent');
console.log(component);
})();
Querying Multiple React Components
This feature allows you to query multiple React components by their name. The code sample demonstrates how to use the `resq$$` function to find all components named 'MyComponent' and log them to the console.
const resq = require('resq');
(async () => {
const components = await resq.resq$$('MyComponent');
console.log(components);
})();
Querying Components by Props
This feature allows you to query a React component by its props. The code sample demonstrates how to use the `resq$` function to find a component named 'MyComponent' with a specific prop `id` and log it to the console.
const resq = require('resq');
(async () => {
const component = await resq.resq$('MyComponent', { props: { id: 'unique-id' } });
console.log(component);
})();
Other packages similar to resq
react-testing-library
The react-testing-library is a popular library for testing React components. It provides utilities to query and interact with components in a way that simulates user interactions. Compared to resq, react-testing-library focuses more on testing user interactions and behavior rather than just querying components.
enzyme
Enzyme is another popular testing utility for React that allows for shallow rendering, full DOM rendering, and static rendering of components. It provides a rich API for traversing and manipulating the React component tree. While resq is focused on querying components, Enzyme offers more comprehensive testing capabilities.
cypress
Cypress is an end-to-end testing framework that supports testing of web applications, including those built with React. It provides powerful tools for interacting with the DOM and simulating user actions. Unlike resq, which is focused on querying React components, Cypress is designed for full end-to-end testing.
resq (React Element Selector Query)
Requirements
- React v16 or higher
- Node 8 or higher
- React DevTools (optional)
This library tries to implement something similar to querySelector
and querySelectorAll
, but through the React VirtualDOM. You can query for React composite elements or HTML elements. It provides two functions resq$
and resq$$
for selecting one or multiple components, respectively.
Installation
$ npm install --save resq
$ yarn add resq
Usage
To get the most out of the library, we recommend you use React Dev Tools to verify the component names you want to select. Granted for basic usage you don't need this as long as you know the component name beforehand, but for Styled components and MaterialUI components it will be of great help.
Type definition
interface RESQNode {
name: 'MyComponent',
node: HTMLElement | null,
isFragment: boolean,
state: string | boolean | any[] | {},
props: {},
children: RESQNode[]
}
resq$(selector: string, element?: HTMLElement): RESQNode
resq$$(selector: string, element?: HTMLElement): Array<RESQNode>
Basic Usage
Take this React App:
const MyComponent = () => (
<div>My Component</div>
)
const App = () => (
<div><MyComponent /></div>
)
ReactDOM.render(<App />, document.getElementById('root'))
Selecting MyComponent
:
import { resq$ } from 'resq'
const root = document.getElementById('root');
resq$('MyComponent', root);
Wildcard selection
You can select your components by partial name use a wildcard selectors:
const MyComponent = () => (
<div>My Component</div>
)
const MyAnotherComponent = () => (
<div>My Another Component</div>
)
const App = () => (
<div>
<MyComponent />
<MyAnotherComponent />
</div>
)
ReactDOM.render(<App />, document.getElementById('root'))
Selecting both components by wildcard:
import { resq$$ } from 'resq'
const root = document.getElementById('root');
resq$$('My*', root);
Selecting MyAnotherComponent
by wildcard:
import { resq$ } from 'resq'
const root = document.getElementById('root');
resq$('My*Component', root);
Async selection
Going by the same example as in basic usage, if you don't want to pass the root element to the function, you can do it this way:
import { resq$, waitToLoadReact } from 'resq'
async function getReactElement(name) {
try {
await waitToLoadReact(2000)
return resq$(name)
} catch (error) {
console.warn('resq error', error)
}
}
getReactElement('MyComponent')
Filtering selection
You can filter your selections byState
or byProps
. These are methods attached to the RESQNode return objects.
Example app:
const MyComponent = ({ someBooleanProp }) => (
<div>My Component {someBooleanProp ? 'show this' : ''} </div>
)
const App = () => (
<div>
<MyComponent />
<MyComponent someBooleanProp={true} />
</div>
)
ReactDOM.render(<App />, document.getElementById('root'))
To select the first instance of MyComponent
where someBooleanProp
is true:
import { resq$ } from 'resq'
const root = document.getElementById('root')
const myComponent = resq$('MyComponent', root)
const filtered = myComponent.byProps({ someBooleanProp: true })
console.log(filtered)
Deep Matching with exact
flag
If you are in need of filtering byProps
or byState
and require the filter to match exactly every property and value in the object (or nested objects), you can pass the exact
flag to the function:
import { resq$ } from 'resq'
const root = document.getElementById('root')
const myComponent = resq$('MyComponent', root)
const filtered = myComponent.byProps({ someBooleanProp: true }, { exact: true })