From 99fe2405f74146d2ab1fda18f2433f73637eeb31 Mon Sep 17 00:00:00 2001 From: Chris Oliver Date: Thu, 29 May 2025 10:51:42 -0500 Subject: [PATCH 1/4] Add turbo frame assertion test helpers --- lib/turbo/test_assertions.rb | 71 ++++++++++++++++++++ test/frames/frame_request_controller_test.rb | 26 +++++++ 2 files changed, 97 insertions(+) diff --git a/lib/turbo/test_assertions.rb b/lib/turbo/test_assertions.rb index c80be538..6fe66e1f 100644 --- a/lib/turbo/test_assertions.rb +++ b/lib/turbo/test_assertions.rb @@ -79,5 +79,76 @@ def assert_no_turbo_stream(action:, target: nil, targets: nil) selector << %([targets="#{targets}"]) if targets assert_select selector, count: 0 end + + # Assert that the rendered fragment of HTML contains a `` + # element. + # + # ==== Options + # + # * :id [String] matches the element's [id] attribute + # * :loading [String] matches the element's [loading] + # attribute + # * :src [String] matches the element's [src] attribute + # * :target [String] matches the element's [target] + # attribute + # * :count [Integer] indicates how many turbo frames are expected. + # Defaults to 1. + # + # Given the following HTML fragment: + # + # + # + # The following assertion would pass: + # + # assert_turbo_frame id: "example", target: "_top" + # + # You can also pass a block make assertions about the contents of the + # element. Given the following HTML fragment: + # + # + #

Hello!

+ #
+ # + # The following assertion would pass: + # + # assert_turbo_frame id: "example" do + # assert_select "p", text: "Hello!" + # end + # + def assert_turbo_frame(id:, loading: nil, src: nil, target: nil, count: 1, &block) + selector = %(turbo-frame[id="#{id}"]) + selector << %([loading="#{loading}"]) if loading + selector << %([src="#{src}"]) if src + selector << %([target="#{target}"]) if target + assert_select selector, count: count, &block + end + + # Assert that the rendered fragment of HTML does not contain a `` + # element. + # + # ==== Options + # + # * :id [String] matches the element's [id] attribute + # * :loading [String] matches the element's [loading] + # attribute + # * :src [String] matches the element's [src] attribute + # * :target [String] matches the element's [target] + # attribute + # + # Given the following HTML fragment: + # + # + # + # The following assertion would fail: + # + # assert_no_turbo_frame id: "example", target: "_top" + # + def assert_no_turbo_frame(id:, loading: nil, src: nil, target: nil) + selector = %(turbo-frame[id="#{id}"]) + selector << %([loading="#{loading}"]) if loading + selector << %([src="#{src}"]) if src + selector << %([target="#{target}"]) if target + assert_select selector, count: 0 + end end end diff --git a/test/frames/frame_request_controller_test.rb b/test/frames/frame_request_controller_test.rb index 72805297..95405e28 100644 --- a/test/frames/frame_request_controller_test.rb +++ b/test/frames/frame_request_controller_test.rb @@ -71,4 +71,30 @@ class Turbo::FrameRequestViewTest < ActionView::TestCase end end end + + class Turbo::TestAssertions::FrameTest < ActionDispatch::IntegrationTest + test "assert_turbo_frame passes with matching frame" do + get tray_path(id: 1) + assert_turbo_frame id: "tray" + end + + test "assert_turbo_frame fails without matching frame" do + get tray_path(id: 1) + assert_raises Minitest::Assertion do + assert_turbo_frame id: "missing" + end + end + + test "assert_no_turbo_frame fails with matching frame" do + get tray_path(id: 1) + assert_raises Minitest::Assertion do + assert_no_turbo_frame id: "tray" + end + end + + test "assert_no_turbo_frame fails without matching frame" do + get tray_path(id: 1) + assert_no_turbo_frame id: "missing" + end + end end From 55f74bf19dce7db77f76363abcedf93162806752 Mon Sep 17 00:00:00 2001 From: Chris Oliver Date: Mon, 2 Jun 2025 14:12:29 -0500 Subject: [PATCH 2/4] Apply suggestions from code review Co-authored-by: Sean Doyle --- lib/turbo/test_assertions.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/turbo/test_assertions.rb b/lib/turbo/test_assertions.rb index 6fe66e1f..0a44f12c 100644 --- a/lib/turbo/test_assertions.rb +++ b/lib/turbo/test_assertions.rb @@ -115,7 +115,9 @@ def assert_no_turbo_stream(action:, target: nil, targets: nil) # assert_select "p", text: "Hello!" # end # - def assert_turbo_frame(id:, loading: nil, src: nil, target: nil, count: 1, &block) + def assert_turbo_frame(*ids, loading: nil, src: nil, target: nil, count: 1, &block) + + id = ids.first.respond_to?(:to_key) ? ActionView::RecordIdentifier.dom_id(*ids) : ids.join('_') selector = %(turbo-frame[id="#{id}"]) selector << %([loading="#{loading}"]) if loading selector << %([src="#{src}"]) if src From 7cfc601c571406c30de393515525783efc908cca Mon Sep 17 00:00:00 2001 From: Chris Oliver Date: Mon, 2 Jun 2025 14:51:41 -0500 Subject: [PATCH 3/4] Apply suggestions from code review Co-authored-by: Sean Doyle --- lib/turbo/test_assertions.rb | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/turbo/test_assertions.rb b/lib/turbo/test_assertions.rb index 0a44f12c..cebc06b2 100644 --- a/lib/turbo/test_assertions.rb +++ b/lib/turbo/test_assertions.rb @@ -145,12 +145,8 @@ def assert_turbo_frame(*ids, loading: nil, src: nil, target: nil, count: 1, &blo # # assert_no_turbo_frame id: "example", target: "_top" # - def assert_no_turbo_frame(id:, loading: nil, src: nil, target: nil) - selector = %(turbo-frame[id="#{id}"]) - selector << %([loading="#{loading}"]) if loading - selector << %([src="#{src}"]) if src - selector << %([target="#{target}"]) if target - assert_select selector, count: 0 + def assert_no_turbo_frame(**options, &block) + assert_turbo_frame(**options, count: 0, &block) end end end From f667b862f7d2092d133fca200cf21dc1c2a08143 Mon Sep 17 00:00:00 2001 From: Chris Oliver Date: Mon, 2 Jun 2025 15:07:26 -0500 Subject: [PATCH 4/4] Refactor tests and docs --- lib/turbo/test_assertions.rb | 15 ++++++++++----- test/frames/frame_request_controller_test.rb | 8 ++++---- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/lib/turbo/test_assertions.rb b/lib/turbo/test_assertions.rb index cebc06b2..827ac8a3 100644 --- a/lib/turbo/test_assertions.rb +++ b/lib/turbo/test_assertions.rb @@ -83,9 +83,12 @@ def assert_no_turbo_stream(action:, target: nil, targets: nil) # Assert that the rendered fragment of HTML contains a `` # element. # + # ==== Arguments + # + # * ids [String, Array] matches the element's [id] attribute + # # ==== Options # - # * :id [String] matches the element's [id] attribute # * :loading [String] matches the element's [loading] # attribute # * :src [String] matches the element's [src] attribute @@ -116,7 +119,6 @@ def assert_no_turbo_stream(action:, target: nil, targets: nil) # end # def assert_turbo_frame(*ids, loading: nil, src: nil, target: nil, count: 1, &block) - id = ids.first.respond_to?(:to_key) ? ActionView::RecordIdentifier.dom_id(*ids) : ids.join('_') selector = %(turbo-frame[id="#{id}"]) selector << %([loading="#{loading}"]) if loading @@ -128,9 +130,12 @@ def assert_turbo_frame(*ids, loading: nil, src: nil, target: nil, count: 1, &blo # Assert that the rendered fragment of HTML does not contain a `` # element. # + # ==== Arguments + # + # * ids [String, Array] matches the [id] attribute + # # ==== Options # - # * :id [String] matches the element's [id] attribute # * :loading [String] matches the element's [loading] # attribute # * :src [String] matches the element's [src] attribute @@ -145,8 +150,8 @@ def assert_turbo_frame(*ids, loading: nil, src: nil, target: nil, count: 1, &blo # # assert_no_turbo_frame id: "example", target: "_top" # - def assert_no_turbo_frame(**options, &block) - assert_turbo_frame(**options, count: 0, &block) + def assert_no_turbo_frame(*ids, **options, &block) + assert_turbo_frame(*ids, **options, count: 0, &block) end end end diff --git a/test/frames/frame_request_controller_test.rb b/test/frames/frame_request_controller_test.rb index 95405e28..45bddfd7 100644 --- a/test/frames/frame_request_controller_test.rb +++ b/test/frames/frame_request_controller_test.rb @@ -75,26 +75,26 @@ class Turbo::FrameRequestViewTest < ActionView::TestCase class Turbo::TestAssertions::FrameTest < ActionDispatch::IntegrationTest test "assert_turbo_frame passes with matching frame" do get tray_path(id: 1) - assert_turbo_frame id: "tray" + assert_turbo_frame "tray" end test "assert_turbo_frame fails without matching frame" do get tray_path(id: 1) assert_raises Minitest::Assertion do - assert_turbo_frame id: "missing" + assert_turbo_frame "missing" end end test "assert_no_turbo_frame fails with matching frame" do get tray_path(id: 1) assert_raises Minitest::Assertion do - assert_no_turbo_frame id: "tray" + assert_no_turbo_frame "tray" end end test "assert_no_turbo_frame fails without matching frame" do get tray_path(id: 1) - assert_no_turbo_frame id: "missing" + assert_no_turbo_frame "missing" end end end