Fixing a stubborn class of flaky Turbo Stream system tests
If you've written system tests against a Rails app that uses Turbo Streams, you've probably hit this: the test clicks a button, a background job runs, and a progress bar (or some other element) sho...

Source: DEV Community
If you've written system tests against a Rails app that uses Turbo Streams, you've probably hit this: the test clicks a button, a background job runs, and a progress bar (or some other element) should update — but the assertion intermittently fails because the DOM hasn't caught up yet. The usual advice is to use Turbo::SystemTestHelper#connect_turbo_cable_stream_sources, which waits for the WebSocket subscription to be established before proceeding. That fixes the most common race condition: a broadcast firing before the browser has connected to the cable stream. But there's a second, less-discussed race condition that connect_turbo_cable_stream_sources doesn't address. The real problem Consider a job that broadcasts twice in sequence — once at 0% and once at 100% when it finishes: # in your job def broadcast_update(message = nil) ProgressBar.new(percent_complete:, result_message:).update(stream_id) end And the test: click_on('Update') expect(page).to have_css(data_test('progress-bar')