|
| 1 | +--- |
| 2 | +id: guide-events |
| 3 | +title: Considerations for fireEvent |
| 4 | +--- |
| 5 | + |
| 6 | +## Interactions vs. events |
| 7 | + |
| 8 | +Based on [the Guiding Principles](guiding-principles.md), your test should |
| 9 | +resemble how users interact with your code (component, page, etc.) as much as |
| 10 | +possible. With this in mind, you should know that `fireEvent` isn't _exactly_ |
| 11 | +how the user interacts with your application, but it's close enough for most |
| 12 | +scenarios. |
| 13 | + |
| 14 | +Consider `fireEvent.click` which creates a click event and dispatches that event |
| 15 | +on the given DOM node. This works properly for most situations when you simply |
| 16 | +want to test what happens when your element is clicked, but when the _user_ |
| 17 | +actually clicks your element, these are the events that are typically fired (in |
| 18 | +order): |
| 19 | + |
| 20 | +- fireEvent.mouseOver(element) |
| 21 | +- fireEvent.mouseMove(element) |
| 22 | +- fireEvent.mouseDown(element) |
| 23 | +- element.focus() (if that element is focusable) |
| 24 | +- fireEvent.mouseUp(element) |
| 25 | +- fireEvent.click(element) |
| 26 | + |
| 27 | +And then, if that element happens to be a child of a `label`, then it will also |
| 28 | +move focus to the form control that the label is labeling. So even though all |
| 29 | +you really are trying to test is the click handler, by simply using |
| 30 | +`fireEvent.click` you're missing out on several other potentially important |
| 31 | +events the user is firing along the way. |
| 32 | + |
| 33 | +Again, most of the time this isn't critical for your tests and the trade-off of |
| 34 | +simply using `fireEvent.click` is worth it. |
| 35 | + |
| 36 | +## Alternatives |
| 37 | + |
| 38 | +We will describe a couple of simple adjustments to your tests that will increase |
| 39 | +your confidence in the interactive behavior of your components. For other |
| 40 | +interactions you may want to either consider using |
| 41 | +[`user-event`](ecosystem-user-event) or testing your components in a real |
| 42 | +environment (e.g. manually, automatic with cypress etc.). |
| 43 | + |
| 44 | +### Keydown |
| 45 | + |
| 46 | +[A keydown is dispatched on the currently focused element, the body element or the document element](https://w3c.github.io/uievents/#events-keyboard-event-order). |
| 47 | +Following this you should prefer |
| 48 | + |
| 49 | +```diff |
| 50 | +- fireEvent.keyDown(getByText('click me')); |
| 51 | ++ getByText('click me').focus(); |
| 52 | ++ fireEvent.keyDown(document.activeElement || document.body); |
| 53 | +``` |
| 54 | + |
| 55 | +This will also test that the element in question can even receive keyboard |
| 56 | +events. |
| 57 | + |
| 58 | +### Focus/Blur |
| 59 | + |
| 60 | +If an element is focused not only a focus event is dispatched. The active |
| 61 | +element in the document also changes as well as the previously focused element |
| 62 | +getting blurred. To simulate this behavior you can simply replace `fireEvent` |
| 63 | +with imperative focus: |
| 64 | + |
| 65 | +```diff |
| 66 | +- fireEvent.focus(getByText('focus me'); |
| 67 | ++ getByText('focus me').focus(); |
| 68 | +``` |
| 69 | + |
| 70 | +A nice side-effect of this approach is that any assertion on fired focus events |
| 71 | +will fail if the element is not focusable. This is especially important if you |
| 72 | +follow-up with a keydown event. |
0 commit comments