Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug on MatInputHarness when setting decimal values to input of type "number" #22129

Closed
seawave23 opened this issue Mar 5, 2021 · 1 comment · Fixed by #22395
Closed

Bug on MatInputHarness when setting decimal values to input of type "number" #22129

seawave23 opened this issue Mar 5, 2021 · 1 comment · Fixed by #22395
Assignees
Labels
area: cdk/testing P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent

Comments

@seawave23
Copy link

Affected Package

@angular/material - MatInputHarness: setValue(newValue: string): Promise<void>;

Is this a regression?

No, it was thought as a fix for matInputs of e.g. color type (#19561), but did not test nor fix decimals in detail, only mentioned they should also be fixed.

Description

When having a FormControl (in a formGroup) which is a matInput of type "number", matInputHarnessInstance.setValue() sets and displays the value, but the formControl's value in the formGroup is the wrong one, namely the decimal value ignoring all numbers before the separator: 12.345 is then 345 only.

After investigation, I found out that this originates in the implemenation of the setValue method:
image
image

In the sendKeys, the single keys are sent in this order: 1-12-null-3-34-345, so 345 is the last value emitted to the reactive form.
Afterwards, through the setInputValue (see above in image), the correct value is assigned, but not caught by change detection.

When asking for matInputHarness.getValue(), the correct value is retrieved (123.456), but when asking for the formControl's value, the value is the last emitted one from sendKeys.
This issue could also affect inputs of other types than type "number" which rely on the setInputValue() part.

In order to fix this, I needed to add
await (await matInputHarnessInstance.host()).dispatchEvent('input');
after calling matInputHarnessInstance.setValue(newValue) in all of my tests.
And it doesn't matter if the formControl has "updateOn: blur" or "updateOn: change".

🔬 Minimal Reproduction

Reproduction on Stackblitz

  • Tests proving that the formGroup really has only values after decimal,
  • tests proving that the formGroup doesn't have the correct value
  • test proving that the "input" event dispatching fixes the problem, at least for matInput of type "number"

🔥 Exception or Error

No exception, but failing tests, or tests proving that setValue doesn't emit the new value correctly.

🌍 Your Environment

Angular Version:
11.2.0

@gkalpak gkalpak transferred this issue from angular/angular Mar 5, 2021
@crisbeto crisbeto added needs triage This issue needs to be triaged by the team area: cdk/testing P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent and removed needs triage This issue needs to be triaged by the team labels Mar 8, 2021
@crisbeto crisbeto self-assigned this Apr 4, 2021
@crisbeto crisbeto added the has pr label Apr 4, 2021
crisbeto added a commit to crisbeto/material2 that referenced this issue Apr 4, 2021
Currently the `UnitTestElement` simulates typing into an input by assigning the value character-by-character and dispatching fake events along the way. The problem is that for input types that require the value to be in a particular format (e.g. `number`, `color`, `date`) doing so will temporarily assign an invalid value which will be rejected by the browser with a warning like `The specified value "12." cannot be parsed, or is out of range.`.

These changes resolve the issue by looking at the type of the input, and if it's a type that requires a specific format, we assign the value immediately.

Fixes angular#22129.
crisbeto added a commit to crisbeto/material2 that referenced this issue Apr 4, 2021
Currently the `UnitTestElement` simulates typing into an input by assigning the value character-by-character and dispatching fake events along the way. The problem is that for input types that require the value to be in a particular format (e.g. `number`, `color`, `date`) doing so will temporarily assign an invalid value which will be rejected by the browser with a warning like `The specified value "12." cannot be parsed, or is out of range.`.

This can become a problem for some common use cases like the `ReactiveFormsModule` where a directive might be keeping track of the value by looking at the DOM inside of an `input` event (e.g. the `FormControl` directive does this).

These changes resolve the issue by looking at the type of the input, and if it's a type that requires a specific format, we assign the value immediately.

Fixes angular#22129.
crisbeto added a commit to crisbeto/material2 that referenced this issue Apr 4, 2021
Currently the `UnitTestElement` simulates typing into an input by assigning the value character-by-character and dispatching fake events along the way. The problem is that for input types that require the value to be in a particular format (e.g. `number`, `color`, `date`) doing so will temporarily assign an invalid value which will be rejected by the browser with a warning like `The specified value "12." cannot be parsed, or is out of range.`.

This can become a problem for some common use cases like the `ReactiveFormsModule` where a directive might be keeping track of the value by looking at the DOM inside of an `input` event (e.g. the `FormControl` directive does this).

These changes resolve the issue by looking at the type of the input, and if it's a type that requires a specific format, we assign the value immediately.

Fixes angular#22129.
mmalerba pushed a commit that referenced this issue Apr 13, 2021
…eys (#22395)

Currently the `UnitTestElement` simulates typing into an input by assigning the value character-by-character and dispatching fake events along the way. The problem is that for input types that require the value to be in a particular format (e.g. `number`, `color`, `date`) doing so will temporarily assign an invalid value which will be rejected by the browser with a warning like `The specified value "12." cannot be parsed, or is out of range.`.

This can become a problem for some common use cases like the `ReactiveFormsModule` where a directive might be keeping track of the value by looking at the DOM inside of an `input` event (e.g. the `FormControl` directive does this).

These changes resolve the issue by looking at the type of the input, and if it's a type that requires a specific format, we assign the value immediately.

Fixes #22129.
mmalerba pushed a commit that referenced this issue Apr 13, 2021
…eys (#22395)

Currently the `UnitTestElement` simulates typing into an input by assigning the value character-by-character and dispatching fake events along the way. The problem is that for input types that require the value to be in a particular format (e.g. `number`, `color`, `date`) doing so will temporarily assign an invalid value which will be rejected by the browser with a warning like `The specified value "12." cannot be parsed, or is out of range.`.

This can become a problem for some common use cases like the `ReactiveFormsModule` where a directive might be keeping track of the value by looking at the DOM inside of an `input` event (e.g. the `FormControl` directive does this).

These changes resolve the issue by looking at the type of the input, and if it's a type that requires a specific format, we assign the value immediately.

Fixes #22129.

(cherry picked from commit 2f177b6)
@angular-automatic-lock-bot
Copy link

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators May 14, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area: cdk/testing P3 An issue that is relevant to core functions, but does not impede progress. Important, but not urgent
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants