diff --git a/lib/turbo/test_assertions.rb b/lib/turbo/test_assertions.rb index c80be538..827ac8a3 100644 --- a/lib/turbo/test_assertions.rb +++ b/lib/turbo/test_assertions.rb @@ -79,5 +79,79 @@ 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. + # + # ==== Arguments + # + # * ids [String, Array] matches the element's [id] attribute + # + # ==== Options + # + # * :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(*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 + selector << %([target="#{target}"]) if target + assert_select selector, count: count, &block + end + + # Assert that the rendered fragment of HTML does not contain a `` + # element. + # + # ==== Arguments + # + # * ids [String, Array] matches the [id] attribute + # + # ==== Options + # + # * :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(*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 72805297..45bddfd7 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 "tray" + end + + test "assert_turbo_frame fails without matching frame" do + get tray_path(id: 1) + assert_raises Minitest::Assertion do + 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 "tray" + end + end + + test "assert_no_turbo_frame fails without matching frame" do + get tray_path(id: 1) + assert_no_turbo_frame "missing" + end + end end