React-testing-library with Ionic v5 (react) and react-hook-form- change events do not fire

724 views Asked by At

I am trying to test a component rendered with Controller from react-hook-form with react-testing-library

          <Controller
            render={({ onChange, onBlur, value }) => (
              <IonInput
                onIonChange={onChange}
                onIonBlur={onBlur}
                value={value}
                type="text"
                data-testid="firstname-field"
              />
            )}
            name="firstName"
            control={control}
            defaultValue={firstName}
          />

Default values are as expected when I render the component with a some mock data. However, when I go about changing values, it seems the events are not firing. From this blog post it looks like ionic exports a set of test utils to handle ionic's custom events. After setting that up in my setupTests.ts I'm attempting to use both the ionFireEvent and the fireEvent from RTU, neither of which reflect changes in the component when I use debug(). I've set it up so I can use both fireEvent and ionFireEvent to test:

import { render, screen, wait, fireEvent } from "@testing-library/react";
import { ionFireEvent } from "@ionic/react-test-utils";


  // using RTL fireEvent - no change
  it("fires change event on firstname", () => {
    const { baseElement } = renderGolferContext(mockGolfer);
    const firstNameField = screen.getByTestId("firstname-field") as HTMLInputElement;
    fireEvent.change(firstNameField, { target: { detail: { value: "Jill" } } });
    expect(firstNameField.value).toBe("Jill");
  });

  // using IRTL ionFireEvent/ionChange - no change
  it("fires change event on firstname", () => {
    const { baseElement } = renderGolferContext(mockGolfer);
    const firstNameField = screen.getByTestId("firstname-field") as HTMLInputElement;
    ionFireEvent.ionChange(firstNameField, "Jill");
    expect(firstNameField.value).toBe("Jill");
  });    
    screen.debug(baseElement);

I've also tried moving the data-testid property to the controller rather than the IonInput suggested here, with the result being the same: no event is fired.

Here are the versions I'm using:

Using Ionic 5.1.1
@ionic/react-test-utils 0.0.3
jest  24.9
@testing-library/react 9.5
@testing-library/dom 6.16

Here is a repo I've created to demonstrate.

Any help would be much appreciated!

1

There are 1 answers

0
Aaron Saunders On BEST ANSWER

this line appears to be incorrect...

expect(firstNameField.value).toBe("Jill");

It should be looking at detail.value since that is what you set

expect((firstNameField as any).detail.value).toBe("Jill");

this is my test,

describe("RTL fireEvent on ion-input", () => {
  it("change on firstname", () => {
    const { baseElement, getByTestId } = render(<IonicHookForm />);
    const firstNameField = screen.getByTestId(
      "firstname-field"
    ) as HTMLInputElement;
    fireEvent.change(firstNameField, {
      target: { detail: { value: "Princess" } },
    });
    expect((firstNameField as any).detail.value).toEqual("Princess");
  });
});