Testing Interactions
Rendering is half a component. The other half is what happens when somebody clicks it — and that half is where the bugs live.
fireEvent clicks things. It takes an element and dispatches a real
DOM event at it, which runs your onClick, which mutates count, which
makes Marko re-render the button. Combined with getByText, a whole
interaction test reads like a sentence: find the button that says Count
is 4, click it, expect Count is 5.
There’s a second test in the file now. It does exactly that. It is red.
- Run
pnpm testin the terminal. - The first test still passes. The second fails: Unable to find an element with the text: Count is 5.
- That looks like the click didn’t work. It did — you just didn’t wait for it.
- Add
awaitin front offireEvent.click(...)and runpnpm testagain.
Why the await. Marko doesn’t re-render the moment you mutate state.
Updates are batched and applied asynchronously, so the DOM your assertion
reads is still one tick behind the click. Every fireEvent method in
@marko/testing-library therefore returns a promise that resolves once
Marko has caught up. await it and the DOM is settled; skip it and you
assert against the past.
The failure mode is common enough that a linter rule exists purely to catch it, and you’ll wire that rule up later in this chapter. Until then, the habit is the tool.
You should now see 2 passed. You have a tag that renders correctly and
behaves correctly, proven in about a second, without opening a browser.
Next: a place to look at that tag while you build it.
- Installing dependencies
- Starting dev server