emberjs / emberjs/ember-test-helpers

Rethinking helpers for forms input

Open
#1,336 2 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.