Skip to content

Instantly share code, notes, and snippets.

@Dobby89
Last active April 9, 2024 12:29
Show Gist options
  • Save Dobby89/0cb28497440aead3ffa03aea231439df to your computer and use it in GitHub Desktop.
Save Dobby89/0cb28497440aead3ffa03aea231439df to your computer and use it in GitHub Desktop.
Jest / React Testing Library

Only run tests against files which have been changed (--passWithNoTests used in case no tested files have changed)

jest --onlyChanged --passWithNoTests

Text content matcher

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
  };
}

Partial text match

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();
});

Mock useLocation from React Router

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());
  });
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment