We’re writing some Rails system test (capybara) and one of the problems we’re coming across is intermittent test failures when there’s dynamic HTML injected.
For example, let’s say we fetch the following HTML and inject it into the DOM:
The moment it’s injected, the “foo” Stimulus controller gets attached via MutationObserver callback. However, during system tests, there a possibility that click_button("Go") is performed before the controller’s actions are even registered. This results in the click not performing the action perform().
So, is there a way to know when Stimulus is finished working its magic for newly injected content?
In JavaScript, the easiest way to queue a microtask is to wait on an empty promise:
document.body.insertAdjacentHTML("beforeend", "...")
Promise.resolve().then(() => {
// Stimulus has responded to the change by now
})
In Capybara, you’ll probably just want to sleep for a very small amount of time after each DOM modification. (I’m not an expert with Capybara, so feel free to chime in here if you are!)