Only run tests against files which have been changed (--passWithNoTests used in case no tested files have changed)
jest --onlyChanged --passWithNoTestsOnly run tests against files which have been changed (--passWithNoTests used in case no tested files have changed)
jest --onlyChanged --passWithNoTestsIf you an error like below when trying to run a command, you can prefix the command with export NODE_TLS_REJECT_UNAUTHORIZED=0 && (as per below).
Error: self-signed certificate in certificate chain
at TLSSocket.onConnectSecure (node:_tls_wrap:1677:34)
at TLSSocket.emit (node:events:519:28)
at TLSSocket._finishInit (node:_tls_wrap:1076:8)
at ssl.onhandshakedone (node:_tls_wrap:862:12) {
code: 'SELF_SIGNED_CERT_IN_CHAIN' }
export NODE_TLS_REJECT_UNAUTHORIZED=0 && <command you want to run>If you use React.useId in your components then it might break some snapshots as it will generate a random ID every time.
Based on https://stackoverflow.com/a/79539013/5243574
// setTests.ts
beforeEach(() => {
vi.mock('react', async (importOriginal) => ({
// Mock useId from react so that snapshots are stable
...(await importOriginal<typeof import('react')>()),
useId: () => 1,
}));
});You must ensure you set vi.useFakeTimers({ shouldAdvanceTime: true }); otherwise validation does not get triggered.
// Component file
// --------------
import { render, screen, waitFor } from '@testing-library/react';
import SimpleForm from './SimpleForm';
import userEvent from '@testing-library/user-event';
describe('SimpleForm default journey', () => {
const user = userEvent.setup();
beforeEach(() => {
vi.useFakeTimers({ shouldAdvanceTime: true });
});
afterAll(() => {
vi.useRealTimers();
});
it('should validate the form', async () => {
render(<SimpleForm />);
expect(screen.getByText('Name')).toBeInTheDocument();
await user.click(screen.getByRole('button', { name: 'Submit' }));
await waitFor(() => {
expect(screen.getByText('Name is required.')).toBeInTheDocument();
});
});
});
// Test file
// --------------
import { render, screen, waitFor } from '@testing-library/react';
import SimpleForm from './SimpleForm';
import userEvent from '@testing-library/user-event';
describe('SimpleForm default journey', () => {
const user = userEvent.setup();
beforeEach(() => {
vi.useFakeTimers({ shouldAdvanceTime: true });
});
afterAll(() => {
vi.useRealTimers();
});
it('should validate and submit the name', async () => {
render(<SimpleForm />);
expect(screen.getByText('Name')).toBeInTheDocument();
await user.click(screen.getByRole('button', { name: 'Submit' }));
await waitFor(() => {
expect(screen.getByText('Name is required.')).toBeInTheDocument();
});
});
});Taken from testing-library/dom-testing-library#410 (comment)
/**
* Getting the deepest element that contain string / match regex even when it split between multiple elements
*
* @example
* For:
* <div>
* <span>Hello</span><span> World</span>
* </div>
*
* screen.getByText('Hello World') // ❌ Fail
* screen.getByText(textContentMatcher('Hello World')) // ✅ pass
*/
function textContentMatcher(textMatch: string | RegExp) {
const hasText = (typeof textMatch === 'string')
? (node: Element) => node.textContent === textMatch
: (node: Element) => textMatch.test(node.textContent);
return (_content: string, node: Element) => {
if (!hasText(node)) {
return false;
}
const childrenDontHaveText = Array.from(node?.children || []).every((child) => !hasText(child));
return childrenDontHaveText
};
}/**
* Creates a custom matcher function to check if an element's textContent
* matches a given string exactly or a given regular expression.
* @param matcher The string or RegExp to match against the element's textContent.
* @returns A MatcherFunction compatible with React Testing Library queries.
*/
export const toHaveTextContent = (
matcher: string | RegExp,
): MatcherFunction => {
return (_content, element) => {
// Ensure element is not null and has textContent property
if (!element || typeof element.textContent !== 'string') {
return false;
}
const elementText = element.textContent;
if (typeof matcher === 'string') {
// If matcher is a string, perform an exact match
return elementText === matcher;
} else if (matcher instanceof RegExp) {
// If matcher is a RegExp, test against it
return matcher.test(elementText);
}
// Fallback for unexpected matcher types (though TypeScript helps prevent this)
return false;
};
};When you want to find some text within a string of text, you may get the following error
TestingLibraryElementError: Unable to find an element with the text: string to find. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
Instead, you can convert the string you want to find into a regex expression and find it that way.
import React from 'react';
import { render, screen } from '@testing-library/react';
function escapeRegExp(stringToGoIntoTheRegex: string) {
return stringToGoIntoTheRegex.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
}
test('find text', () => {
render(<div>This is a sentence with a string to find</div>);
// This will work
expect(screen.getByText('This is a sentence with a string to find')).toBeInTheDocument();
// This will work
expect(screen.getByText(new RegExp(escapeRegExp('string to find'), 'g'))).toBeInTheDocument();
// This will NOT work
expect(screen.getByText('string to find')).toBeInTheDocument();
});Yoinked from https://stackoverflow.com/a/74820547/5243574
import React from 'react';
import ExampleComponent from './ExampleComponent';
import { fireEvent, render } from '@testing-library/react';
import { MemoryRouter} from 'react-router-dom';
import { shallow } from 'enzyme';
const renderComponent = () => {
return (
<MemoryRouter
initialEntries={["/one", "/two", { pathname: 'https://URL/' }]}
initialIndex={1}>
<ExampleComponent />
</MemoryRouter>
);
}
describe('<ExampleComponent />', () => {
it('should render correctly', () => {
shallow(renderComponent());
});
});