React Testing Library: Detecting Input Pattern Rejection

Viewed 379

I'm using HTML5's validation feature for the <input> tag in React JS, in which you specify a regex pattern like so:

<input pattern="[a-zA-Z]+" />

When this pattern doesn't match the input value, an error dialogue box pops up.

Is there a way to detect or search for this error dialogue box in React Testing Library? Or is it possible to detect that , for a given input value, whether the pattern matches or not?

1 Answers

When this pattern doesn't match the input value, an error dialogue box pops up.

Note: This is not the default behavior, but perhaps you (or someone on your team) has configured your component to show a different style based on pattern validity. Anyway, on to the actual question...

This is how you can test for it: using the HTMLInputElement.validity.patternMismatch property. I've included comments in the example. (Also, I'm using jest as the test runner in this example.)

example.test.tsx:

import {getByLabelText, render} from '@testing-library/react';

// Example component
function Component ({defaultValue}: {defaultValue?: string}) {
  return (
    <label>
      <span>My input</span>
      <input
        type="text"
        pattern="[a-zA-Z]+"
        {...{defaultValue}}
      />
    </label>
  );
}

// We'll use this to validate the test input strings that we supply to the component,
// before we actually test them in the component.
// Note that the `pattern` attribute adds anchors and the unicode flag
// when converting a string pattern to regex. Read more at
// https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/pattern
const validationPattern = /^[a-zA-Z]+$/u;

test('valid pattern', () => {
  const defaultValue = 'helloWorld';
  // First, ensure the input value is valid:
  expect(validationPattern.test(defaultValue)).toBeTruthy();
  const {container} = render(<Component {...{defaultValue}} />);
  const labelText = 'My input';
  const input = getByLabelText<HTMLInputElement>(container, labelText);
  const patternIsValid = !input.validity.patternMismatch;
  expect(patternIsValid).toBeTruthy();
});

test('invalid pattern', () => {
  const defaultValue = 'hello world';
  // First, ensure the input value is invalid:
  expect(validationPattern.test(defaultValue)).toBeFalsy();
  const {container} = render(<Component {...{defaultValue}} />);
  const labelText = 'My input';
  const input = getByLabelText<HTMLInputElement>(container, labelText);
  const patternIsValid = !input.validity.patternMismatch;
  expect(patternIsValid).toBeFalsy();
});

Related