uNmAnNeR / imaskjs

vanilla javascript input mask

Home Page:https://imask.js.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Cannot trigger onAccept with react testing library when testing input created with IMaskMixin

BrianBusby opened this issue · comments

Describe the bug
It appears to not be possible to trigger onAccept for components created via IMaskMixin when using react testing library.

For reference, here is a masked date input I created with IMaskMixin:

export const MaskedDateInput = (props: MaskedDateInputProps) => {
  const { onClear, onAccept, value, isClearable, width, leftIcon, borderStyle, customCss, testId } = props;
  const MaskedInput = IMaskMixin<HTMLInputElement, IMaskInputProps<HTMLInputElement>>(
    ({ inputRef }) => {
      return (
        <Input
          ref={inputRef}
          data-testid={testId}
          type="text"
          size="md"
          width={width}
          borderStyle={borderStyle}
          leftIcon={leftIcon}
          placeholder="MM/DD/YYYY"
          onClear={onClear}
          isClearable={isClearable}
          onKeyDown={e => {
            // inside of filter submenu we need to stop propagation for key presses other than arrows
            // otherwise the text input loses focus since there is a type-ahead search for menu items
            if (!navigationKeys.includes(e.key)) {
              e.stopPropagation();
            }
          }}
          css={
            customCss
              ? css`
                  ${customCss}
                `
              : undefined
          }
        />
      );
    },
  );

  return (
    <MaskedInput
      mask={Date}
      onComplete={onAccept}
      pattern="m{/}`d{/}`Y"
      format={(date: Date | null) => {
        return date ? format(parseISO(date?.toISOString()), 'MM/dd/yyyy') : '';
      }}
      parse={(str: string) => {
        return parse(str, DATE_FNS_DATE_STRING, new Date());
      }}
      placeholder="MM/DD/YYYY"
      value={value}
      onAccept={onAccept}
    />
  );
};

When I target the input component by getting its data-testid and then change its value, the value of the input changes, but the onAccept function doesn't fire. I found that many folks have been able to work around this with the following:

function changeInputMaskValue(element, value = '') {
  element.value = value;
  element.selectionStart = element.selectionEnd = value?.length ?? 0;
  TestUtils.Simulate.change(element);
}

However this solution doesn't seem to work with a component created with IMaskMixin. I think the issue is that we're targeting the inner Input component with the change but the onAccept is on the MaskedInput component, which I'm not sure how to target.

Environment:

  • OS: MacOS
  • Browser: Chrome
  • Version 118.0.5993.117
  • IMask version: 7.1.3

can it simulate input event for inner Input? You can get MaskedInput component by using ref on MaskedInput