To guarantee the delivery of high-quality software, engineering teams implementing modern web applications must not only dedicate time to the development of new features or the maintenance of already existing code, but also to the verification of application behavior through manual and automated testing.
By emulating the DOM (Document Object Model) events in our automated tests, we get closer to mimicking our app’s behavior accurately. In this article, you’ll learn what DOM events are and how you can leverage them in your testing approach for more reliable test coverage.
<button> element, triggering many DOM events while doing so, including, but not limited to the
Here’s a typical sequence of the DOM events sent whenever a button is clicked using a mouse device:
Imagine we were building an amazing file upload component that allows users to click a button to browse for a file on their machine, select it and then subsequently upload its content to the app.
If we wrote our app using EmberJS, as we’re doing for our open-source component library mx-ui-components at Meroxa, the component may be structured similarly to this:
And in a similar fashion, we may want to build such a component in a React library like this:
In a production environment, a user can now upload their files using the
<Upload> component by clicking the
Browse file button and selecting their file from their local machine.
In our test suite, natively executing the full user interaction would be impossible: when our tests run in our continuous integration workflow, we won’t have easy access to the file directory of the remote machine from which a file is supposed to be selected for upload.
Let’s leverage Ember ’s
triggerEvent function to test the file upload behavior of our
<Upload /> component shown earlier:
In a React app on the other hand, we can assert the same user flow using the handy helper methods from
@testing-library in a similar manner:
Many HTML elements have built-in methods for programmatically triggering common user interactions on them, which makes testing user flows more straightforward.
For example, if we wanted to mock a user clicking a button element, we could emulate this as follows in our integration test:
Sometimes we would like to assert an application state change in our automated test that is elicited by a DOM event for which there is no corresponding DOM element method, such as element.click.
What if we updated our app state anytime a user was starting and stopping to hover over the button mentioned in the example above, regardless if the button was clicked or not? In that case, we might want to emulate the
For such test scenarios based on less common DOM events, we can leverage the
dispatchEvent()method of the EventTarget sends an Event to the object, (synchronously) invoking the affected EventListeners in the appropriate order.
from the MDN docs on
Any DOM event can be programmatically triggered where needed, by calling the
dispatchEvent method on the target element:
In our file upload component example from above, we could write our own test helper to emulate the feature functionality. Using the
dispatchEvent method in combination with the
change event in our test helper util already does the trick: