Skip to content

Rethinking helpers for forms input #1336

@simonihmig

Description

@simonihmig

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

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"? 🤔

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions