primefaces / primeng

The Most Complete Angular UI Component Library
https://primeng.org
Other
10.46k stars 4.6k forks source link

p-inputNumber: value does not update when typing with @testing-library/user-event #14776

Open angelo-v opened 9 months ago

angelo-v commented 9 months ago

Describe the bug

When typing into a p-inputnumber field using @testing-library/user-event (userEvent.type(input, '42');) the value does not update

Environment

jest, testing-library, angular, primeng

Reproducer

https://stackblitz.com/edit/stackblitz-starters-xzt6ad?file=src%2Fprimeng-form.component.spec.ts

Angular version

17.1.2

PrimeNG version

17.5.0

Build / Runtime

Angular CLI App

Language

TypeScript

Node version (for AoT issues node --version)

v20.10.0

Browser(s)

No response

Steps to reproduce the behavior

Run the tests in the stackblitz reproducer

Expected behavior

This should work:

  it('userEvent should change p-inputnumber value', async () => {
    const renderResult = await render(PrimeNgFormComponent, {});
    const input = screen.getByLabelText('Age');
    await userEvent.type(input, '42');
    expect(input).toHaveValue('42');
    expect(renderResult.fixture.componentInstance.form.value.age).toEqual(42);
  });
jonath92 commented 6 months ago

I hat the same problem and could figure out that tis is related to some accessibility problems see: https://github.com/primefaces/primeng/issues/13439.

As a workaround, it is possible to use fire a keyPress event:

import { fireEvent, render, screen } from "@testing-library/angular";

const myInput = screen.getByRole("spinbutton") as HTMLInputElement;

  // user.type not possible because of accessible issues in primeNg. See: https://github.com/primefaces/primeng/issues/13439
  fireEvent.keyPress(myInput, {
    code: "Digit5",
    key: "5",
    keyCode: "5".codePointAt(0),
  });

expect(myInput.value).toBe("5.00");
jadir-junior commented 4 months ago

I create a little helper with the jonaths code

import { fireEvent } from '@testing-library/angular';

export class UserEvent {
  static typeNumber(
    element: Element | Node | Document | Window,
    number: number
  ) {
    if (number.toString().length > 1) {
      const numbers = number.toString().split('');
      numbers.forEach((number) => this.keyPress(element, number));
      return;
    }

    this.keyPress(element, number.toString());
  }

  private static keyPress(
    element: Element | Node | Document | Window,
    number: string
  ) {
    fireEvent.keyPress(element, {
      code: `Digit${number}`,
      key: number,
      keyCode: number.codePointAt(0),
    });
  }
}

in tests


 UserEvent.typeNumber(prepTimeHoursInput, 1);
 UserEvent.typeNumber(prepTimeMinutesInput, 30);