Skip to content

Commit

Permalink
Introduce Turbo::SystemTestHelper
Browse files Browse the repository at this point in the history
Introduce the `Turbo::SystemTestHelper` module to be included into
[ActionDispatch::SystemTestCase][] when it's available.

The module is named to mimic [ActionText::SystemTestHelper][].

The module defines a `#wait_for_turbo_cable_stream_sources` helper
method extracted from this project's System Test suite. It aims to
synchronize the test harness with Turbo's Action Cable-powered broadcast
support. The method will find all `<turbo-cable-stream-source>` elements
that are present but not yet `[connected]` (returning the results
immediately with Capybara's `:wait`), then wait for them to connect
(using whatever Capybara's configured wait value).

[ActionDispatch::SystemTestCase]: https://edgeapi.rubyonrails.org/classes/ActionDispatch/SystemTestCase.html
[ActionText::SystemTestHelper]: https://edgeapi.rubyonrails.org/classes/ActionText/SystemTestHelper.html
  • Loading branch information
seanpdoyle committed Feb 13, 2024
1 parent 07d3488 commit e43cf29
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 20 deletions.
7 changes: 7 additions & 0 deletions lib/turbo/engine.rb
Original file line number Diff line number Diff line change
Expand Up @@ -111,5 +111,12 @@ class TurboStreamEncoder < IdentityEncoder
end
end
end

initializer "turbo.system_test_helper" do
ActiveSupport.on_load(:action_dispatch_system_test_case) do
require "turbo/system_test_helper"
include Turbo::SystemTestHelper
end
end
end
end
28 changes: 28 additions & 0 deletions lib/turbo/system_test_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
module Turbo::SystemTestHelper
extend ActiveSupport::Concern

# Delay until every `<turbo-cable-stream-source>` element present in the page
# is ready to receive broadcasts
#
# test "Page receives new Messages broadcast over Action Cable" do
# visit "/"
# click_link "All Messages"
#
# wait_for_turbo_cable_stream_sources
# create_message_record_then_broadcast # do server-side broadcasting
#
# assert_text "Hello from Action Cable"
# end
#
# By default, calls to `#visit` will wait for all `<turbo-cable-stream-source>`
# elements to connect
def wait_for_turbo_cable_stream_sources(**options)
all(:css, "turbo-cable-stream-source:not([connected])", wait: 0).each do |element|
element.assert_matches_selector(:css, "[connected]", visible: :all, **options)
end
end

def visit(...) # :nodoc:
super.tap { wait_for_turbo_cable_stream_sources }
end
end
24 changes: 4 additions & 20 deletions test/system/broadcasts_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ class BroadcastsTest < ApplicationSystemTestCase

test "Message broadcasts Turbo Streams" do
visit messages_path
wait_for_stream_to_be_connected

assert_broadcasts_text "Message 1", to: :messages do |text, target|
Message.create(content: text).broadcast_append_to(target)
Expand All @@ -14,7 +13,6 @@ class BroadcastsTest < ApplicationSystemTestCase

test "Message broadcasts with html: render option" do
visit messages_path
wait_for_stream_to_be_connected

assert_broadcasts_text "Hello, with html: option", to: :messages do |text, target|
Message.create(content: "Ignored").broadcast_append_to(target, html: text)
Expand All @@ -23,25 +21,22 @@ class BroadcastsTest < ApplicationSystemTestCase

test "Message broadcasts with renderable: render option" do
visit messages_path
wait_for_stream_to_be_connected


assert_broadcasts_text "Test message", to: :messages do |text, target|
Message.create(content: "Ignored").broadcast_append_to(target, renderable: MessageComponent.new(text))
end
end

test "Does not render the layout twice when passed a component" do
visit messages_path
wait_for_stream_to_be_connected


Message.create(content: "Ignored").broadcast_append_to(:messages, renderable: MessageComponent.new("test"))

assert_selector("title", count: 1, visible: false, text: "Dummy")
end

test "Message broadcasts with extra attributes to turbo stream tag" do
visit messages_path
wait_for_stream_to_be_connected

assert_broadcasts_text "Message 1", to: :messages do |text, target|
Message.create(content: text).broadcast_action_to(target, action: :append, attributes: { "data-foo": "bar" })
Expand All @@ -50,7 +45,6 @@ class BroadcastsTest < ApplicationSystemTestCase

test "Message broadcasts with correct extra attributes to turbo stream tag" do
visit messages_path
wait_for_stream_to_be_connected

assert_forwards_turbo_stream_tag_attribute attr_key: "data-foo", attr_value: "bar", to: :messages do |attr_key, attr_value, target|
Message.create(content: text).broadcast_action_to(target, action: :test, attributes: { attr_key => attr_value })
Expand All @@ -59,7 +53,6 @@ class BroadcastsTest < ApplicationSystemTestCase

test "Message broadcasts with no rendering" do
visit messages_path
wait_for_stream_to_be_connected

assert_forwards_turbo_stream_tag_attribute attr_key: "data-foo", attr_value: "bar", to: :messages do |attr_key, attr_value, target|
Message.create(content: text).broadcast_action_to(target, action: :test, render: false, partial: "non_existant", attributes: { attr_key => attr_value })
Expand All @@ -68,7 +61,6 @@ class BroadcastsTest < ApplicationSystemTestCase

test "Message broadcasts later with extra attributes to turbo stream tag" do
visit messages_path
wait_for_stream_to_be_connected

perform_enqueued_jobs do
assert_broadcasts_text "Message 1", to: :messages do |text, target|
Expand All @@ -80,7 +72,6 @@ class BroadcastsTest < ApplicationSystemTestCase

test "Message broadcasts later with correct extra attributes to turbo stream tag" do
visit messages_path
wait_for_stream_to_be_connected

perform_enqueued_jobs do
assert_forwards_turbo_stream_tag_attribute attr_key: "data-foo", attr_value: "bar", to: :messages do |attr_key, attr_value, target|
Expand All @@ -91,7 +82,6 @@ class BroadcastsTest < ApplicationSystemTestCase

test "Message broadcasts later with no rendering" do
visit messages_path
wait_for_stream_to_be_connected

perform_enqueued_jobs do
assert_forwards_turbo_stream_tag_attribute attr_key: "data-foo", attr_value: "bar", to: :messages do |attr_key, attr_value, target|
Expand All @@ -102,7 +92,6 @@ class BroadcastsTest < ApplicationSystemTestCase

test "Users::Profile broadcasts Turbo Streams" do
visit users_profiles_path
wait_for_stream_to_be_connected

assert_broadcasts_text "Profile 1", to: :users_profiles do |text, target|
Users::Profile.new(id: 1, name: text).broadcast_append_to(target)
Expand All @@ -111,7 +100,6 @@ class BroadcastsTest < ApplicationSystemTestCase

test "passing extra parameters to channel" do
visit section_messages_path
wait_for_stream_to_be_connected

assert_broadcasts_text "In a section", to: :messages do |text|
Message.create(content: text).broadcast_append_to(:important_messages)
Expand All @@ -120,10 +108,6 @@ class BroadcastsTest < ApplicationSystemTestCase

private

def wait_for_stream_to_be_connected
assert_selector "turbo-cable-stream-source[connected]", visible: false
end

def assert_broadcasts_text(text, to:, &block)
within(:element, id: to) { assert_no_text text }

Expand Down

0 comments on commit e43cf29

Please sign in to comment.