emberjs / emberjs/ember-test-helpers
Rethinking helpers for forms input
- Dominant language
- JavaScript
- Stars
- 188
- Forks
- 254
- PR merge metrics
- No merged PRs in 30d
Description
The main test helper for simulating how users enter data into a form field is `fillIn()`. Trying to use it to simulate form validations that happen on either `input` _or_ `change` revealed that this helper is actually pretty weird IMHO.
I think the guiding principle for test helpers in this addon, and for the overall testing story of Ember in general, is that they replicate what a _real_ user would do, in a _real_ browser.
And it turns out `fillIn()` does not pass these criteria, as it will mutate `input.value` (ok), trigger `input` (also ok) and `change`, without triggering `blur`/`focusout` - which is an interaction that a real user _cannot_ do, at least for a text input!
`change` is triggered...
> When the element loses focus after its value was changed: for elements where the user's interaction is typing rather than selection
[Source](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/change_event)
In my case I was trying to test things _while_ a user is typing, i.e. they enter text into an input, the `input` event gets triggered, but (in a real-world scenario) _no_ `change` event is triggered. But `fillIn()` does that, giving me false positives in tests, i.e. they pass while the real world behaviour of my component is actually wrong (because it relied on `change` events which don't happen while typing)
I don't think we can even think of dropping `fillIn()` or changing its behaviour, given that it would break _every_ app, and would cause a mountain of unnecessary churn, while most tests probably don't care about the subtle differences here. But I would at least like to have additional test helpers that correctly replicate user interactions as they occur in the real world. Off the top of my head something like
* `input()` (or `type()`) that simulates a user typing into a field _without_ explicitly "committing" the change. Which would mean:
* for text-based input only `input` is triggered
* for selects/radios/checkboxes/date pickers etc.: `input` and `change` are triggered, as they are implicitly committed (see the MDN doc)
* `enter()` (or `fillInAndLeave()` or whatever): simulate a user entering data (or selecting something) and leaving the field, which would trigger `input`, `change` (as `fillIn()` does today) but _also_ `blur` and `focusout` (as again, you _cannot_ have `change` without `blur` for text-based inputs)
What do you think?
If there is some general level of agreement, would that be a case for "PRs welcome" or "needs RFC"? 🤔
Contributor guide
Assessment
This issue has not been assessed yet.