turbo_rspec 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d66e89583c0c374bd4b69c308390e275e70623726fd8cdc6f7f44e4df7028e06
4
- data.tar.gz: a0be5a9653a1cfc59604b506ac2d890db6f1fd931800e21f9eccf528895d3bb8
3
+ metadata.gz: 3211f811cbd7919d35f8b918260ea97346668fb2ef3213f189d91c642a014b53
4
+ data.tar.gz: dda8641bcf4d6cb1a8ebc6de4ee5d7622f90bcec3a79b8180444b6e4bfcd2c38
5
5
  SHA512:
6
- metadata.gz: 49f3d0f02e97d332ed7a8c9bc28bd5c555c7ce8d969647a691e38d064afe94a77e8f0b1bd4c42b3138917c0291031aab073ae132482db60569c252acbe889c97
7
- data.tar.gz: 41dad12a7885d0091afc1d5fa01b322f884c295b12ae753795c59ba86bbf86123281c768415c9bfa89c79d3f2812210680fcb7fd19e7f66a402db0b31cf7106e
6
+ metadata.gz: 352e59c5604c6362263a51d6b0eb9903b1b7c7b337bca65a05e01c15b42bae5e121def5d638ed66f8b73d06fda382460a85dce4d15ab7a3bff234fb26c310759
7
+ data.tar.gz: 1243fc05f3fc0256f3e028c66d505a0cbf8335108238c6fde0c0b4e6a0fc97f630bd2ae59c51cb37e64a0ce81265fb20b2d8c9be2e850ef7b29a3442c18f6991
data/CHANGELOG.md CHANGED
@@ -1,5 +1,14 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [1.6.0] - 2026-06-02
4
+
5
+ ### Added
6
+
7
+ - `have_stimulus_controller`, `have_stimulus_action`, `have_stimulus_target` request-spec matchers — assert Stimulus `data-*` attributes in response HTML, auto-included in `type: :request` and `type: :controller` example groups
8
+ - `assert_broadcasted_turbo_stream_to` and `refute_broadcasted_turbo_stream_to` in `TurboRspec::Assertions` — Minitest broadcast parity with the RSpec `have_broadcasted_turbo_stream_to` matcher
9
+ - `have_turbo_frame` (Capybara) `.eager` chain — asserts `loading="eager"` on the frame (Turbo 8)
10
+ - `have_turbo_frame` (Capybara) `.strict` chain — asserts the `[strict]` boolean attribute on the frame (Turbo 8)
11
+
3
12
  ## [1.5.0] - 2026-06-02
4
13
 
5
14
  ### Added
data/README.md CHANGED
@@ -8,10 +8,10 @@
8
8
 
9
9
  Drop-in test matchers for [hotwired/turbo-rails](https://github.com/hotwired/turbo-rails) — replace every hand-rolled Turbo helper in your test suite with a single gem.
10
10
 
11
- - **Request/controller specs** — `have_turbo_stream`, `have_turbo_frame`, `have_turbo_streams`
11
+ - **Request/controller specs** — `have_turbo_stream`, `have_turbo_frame`, `have_turbo_streams`, `have_stimulus_controller`, `have_stimulus_action`, `have_stimulus_target`
12
12
  - **Broadcast specs** — `have_broadcasted_turbo_stream_to` with count qualifiers
13
13
  - **System/feature specs** — Capybara matchers: `have_turbo_frame`, `have_turbo_stream_tag`, `within_turbo_frame`, `have_stimulus_controller`, `have_stimulus_action`, `have_stimulus_target`
14
- - **Minitest** — `assert_turbo_stream`, `refute_turbo_stream`, `assert_turbo_frame`, `refute_turbo_frame`
14
+ - **Minitest** — `assert_turbo_stream`, `refute_turbo_stream`, `assert_turbo_frame`, `refute_turbo_frame`, `assert_broadcasted_turbo_stream_to`, `refute_broadcasted_turbo_stream_to`
15
15
  - **Factory helpers** — `turbo_stream_html`, `turbo_frame_html`
16
16
  - **Shared examples** — `it_behaves_like "a turbo stream response"`
17
17
  - **Auto-included** — zero setup required when `turbo-rails` is in your bundle
@@ -220,6 +220,12 @@ expect(page).to have_turbo_frame("messages").loaded
220
220
  # Lazy frame — assert loading="lazy" attribute
221
221
  expect(page).to have_turbo_frame("messages").lazy
222
222
 
223
+ # Eager frame — assert loading="eager" attribute (Turbo 8)
224
+ expect(page).to have_turbo_frame("messages").eager
225
+
226
+ # Strict frame — assert [strict] attribute (Turbo 8)
227
+ expect(page).to have_turbo_frame("messages").strict
228
+
223
229
  # With src — assert the src attribute on a lazy-loaded frame
224
230
  expect(page).to have_turbo_frame("messages").with_src("/messages/new")
225
231
 
@@ -246,22 +252,22 @@ end
246
252
 
247
253
  ### Stimulus matchers
248
254
 
249
- Assert Stimulus controller, action, and target attributes on the page (Capybara).
255
+ `have_stimulus_controller`, `have_stimulus_action`, and `have_stimulus_target` work in both **request specs** (parsing response HTML) and **system/feature specs** (Capybara).
250
256
 
251
257
  ```ruby
252
- # Controllerdata-controller contains "hello"
253
- expect(page).to have_stimulus_controller("hello")
258
+ # Request specs asserts Stimulus attributes in rendered HTML response
259
+ expect(response).to have_stimulus_controller("hello")
260
+ expect(response).to have_stimulus_action("click->hello#greet")
261
+ expect(response).to have_stimulus_action("hello#greet") # shorthand — matches any event
262
+ expect(response).to have_stimulus_target("hello", "name")
254
263
 
255
- # Actionfull descriptor
264
+ # System/feature specs asserts on the live Capybara page
265
+ expect(page).to have_stimulus_controller("hello")
256
266
  expect(page).to have_stimulus_action("click->hello#greet")
257
-
258
- # Action — shorthand without event (matches any event prefix)
259
- expect(page).to have_stimulus_action("hello#greet")
260
-
261
- # Target — data-hello-target contains "name"
262
267
  expect(page).to have_stimulus_target("hello", "name")
263
268
 
264
269
  # Negation
270
+ expect(response).not_to have_stimulus_controller("missing")
265
271
  expect(page).not_to have_stimulus_controller("missing")
266
272
  ```
267
273
 
@@ -430,6 +436,11 @@ refute_turbo_frame(response, id: "notifications")
430
436
 
431
437
  # Custom failure message
432
438
  assert_turbo_stream(response, action: :append, message: "expected append stream")
439
+
440
+ # Broadcast assertions (requires ActionCable test adapter)
441
+ assert_broadcasted_turbo_stream_to("notifications") { MyJob.perform_now }
442
+ assert_broadcasted_turbo_stream_to("notifications", action: :append, target: "messages") { MyJob.perform_now }
443
+ refute_broadcasted_turbo_stream_to("notifications") { MyJob.perform_now }
433
444
  ```
434
445
 
435
446
  ## Contributing
data/ROADMAP.md CHANGED
@@ -2,14 +2,6 @@
2
2
 
3
3
  RSpec matchers for [Turbo](https://github.com/hotwired/turbo-rails): Turbo Streams, Turbo Frames, and ActionCable broadcasts. The goal is to replace the hand-rolled helpers that every Rails/Turbo project accumulates.
4
4
 
5
- ## 1.6 — Minitest & Turbo 8 extensions
6
-
7
- - **`assert_broadcasted_turbo_stream_to` / `refute_broadcasted_turbo_stream_to`** — `TurboRspec::Assertions` covers request-spec stream and frame assertions but has no broadcast counterpart. Teams using Minitest with ActionCable have no parity with the RSpec broadcast matcher.
8
- - **`have_turbo_frame` Capybara `.eager` and `.strict` chains** — `.lazy` is already supported; Turbo 8 also added `loading="eager"` and a `[strict]` boolean attribute for strict frame loading. Both are missing from the Capybara matcher.
9
- - **Stimulus request-spec matchers** — `have_stimulus_controller`, `have_stimulus_action`, and `have_stimulus_target` currently only work in Capybara system/feature specs. Teams writing request specs can't assert Stimulus attributes on rendered HTML responses without dropping to raw string matching.
10
-
11
- ---
12
-
13
5
  ## Guiding principles
14
6
 
15
7
  - **Zero magic by default.** Auto-include only when it's unambiguous (Rails request specs). Everything else is opt-in.
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require_relative "matchers/have_broadcasted_turbo_stream_to"
3
4
  require_relative "matchers/have_turbo_frame"
4
5
  require_relative "matchers/have_turbo_stream"
5
6
 
@@ -12,6 +13,30 @@ module TurboRspec
12
13
  #
13
14
  # No RSpec dependency required.
14
15
  module Assertions
16
+ # Assert that a block broadcasts a +<turbo-stream>+ to the given stream.
17
+ # Requires ActionCable's test adapter.
18
+ #
19
+ # @param stream [String] the stream name
20
+ # @param action [Symbol, String, nil] optional action constraint
21
+ # @param target [String, nil] optional target constraint
22
+ # @param targets [String, nil] optional targets (CSS selector) constraint
23
+ # @param content [String, nil] optional content constraint
24
+ # @param partial [String, nil] optional partial path constraint
25
+ # @param message [String, nil] optional custom failure message
26
+ def assert_broadcasted_turbo_stream_to(stream, action: nil, target: nil, targets: nil, content: nil, partial: nil, message: nil, &block)
27
+ matcher = build_broadcast_matcher(stream, action: action, target: target, targets: targets, content: content, partial: partial)
28
+ assert matcher.matches?(block), message || matcher.failure_message
29
+ end
30
+
31
+ # Assert that a block does NOT broadcast a +<turbo-stream>+ to the given stream.
32
+ # Requires ActionCable's test adapter.
33
+ #
34
+ # @param stream [String] the stream name
35
+ def refute_broadcasted_turbo_stream_to(stream, action: nil, target: nil, targets: nil, content: nil, partial: nil, message: nil, &block)
36
+ matcher = build_broadcast_matcher(stream, action: action, target: target, targets: targets, content: content, partial: partial)
37
+ assert matcher.does_not_match?(block), message || matcher.failure_message_when_negated
38
+ end
39
+
15
40
  def assert_turbo_stream(response_or_body, action: nil, target: nil, targets: nil, content: nil, partial: nil, message: nil)
16
41
  matcher = build_stream_matcher(action: action, target: target, targets: targets, content: content, partial: partial)
17
42
  assert matcher.matches?(response_or_body), message || matcher.failure_message
@@ -34,6 +59,16 @@ module TurboRspec
34
59
 
35
60
  private
36
61
 
62
+ def build_broadcast_matcher(stream, action:, target:, targets:, content:, partial:)
63
+ matcher = Matchers::HaveBroadcastedTurboStreamTo.new(stream)
64
+ matcher.with_action(action) if action
65
+ matcher.targeting(target) if target
66
+ matcher.targeting_all(targets) if targets
67
+ matcher.with_content(content) if content
68
+ matcher.rendering(partial) if partial
69
+ matcher
70
+ end
71
+
37
72
  def build_stream_matcher(action:, target:, targets:, content:, partial:)
38
73
  matcher = Matchers::HaveTurboStream.new
39
74
  matcher.with_action(action) if action
@@ -10,6 +10,8 @@ module TurboRspec
10
10
  @loaded = false
11
11
  @src = nil
12
12
  @lazy = false
13
+ @eager = false
14
+ @strict = false
13
15
  end
14
16
 
15
17
  def with_content(text)
@@ -37,11 +39,27 @@ module TurboRspec
37
39
  self
38
40
  end
39
41
 
42
+ # Constrains the match to frames with +loading="eager"+.
43
+ # @return [self]
44
+ def eager
45
+ @eager = true
46
+ self
47
+ end
48
+
49
+ # Constrains the match to frames with the +[strict]+ attribute (Turbo 8).
50
+ # @return [self]
51
+ def strict
52
+ @strict = true
53
+ self
54
+ end
55
+
40
56
  def matches?(page_or_node)
41
57
  @node = find_frame(page_or_node)
42
58
  return false unless @node
43
59
  return false if @loaded && !@node[:complete]
44
60
  return false if @lazy && @node[:loading] != "lazy"
61
+ return false if @eager && @node[:loading] != "eager"
62
+ return false if @strict && @node[:strict].nil?
45
63
  return false if @src && @node[:src] != @src
46
64
  return false if @content && !@node.has_content?(@content, wait: 0)
47
65
  true
@@ -58,6 +76,10 @@ module TurboRspec
58
76
  "expected turbo-frame##{@id} to be loaded (missing [complete] attribute)"
59
77
  elsif @lazy && @node[:loading] != "lazy"
60
78
  "expected turbo-frame##{@id} to be lazy (missing loading=\"lazy\" attribute)"
79
+ elsif @eager && @node[:loading] != "eager"
80
+ "expected turbo-frame##{@id} to be eager (missing loading=\"eager\" attribute)"
81
+ elsif @strict && @node[:strict].nil?
82
+ "expected turbo-frame##{@id} to be strict (missing [strict] attribute)"
61
83
  elsif @src && @node[:src] != @src
62
84
  "expected turbo-frame##{@id} to have src #{@src.inspect}, got #{@node[:src].inspect}"
63
85
  else
@@ -85,6 +107,8 @@ module TurboRspec
85
107
  parts = []
86
108
  parts << " loaded" if @loaded
87
109
  parts << " lazy" if @lazy
110
+ parts << " eager" if @eager
111
+ parts << " strict" if @strict
88
112
  parts << " with src #{@src.inspect}" if @src
89
113
  parts << " with content #{@content.inspect}" if @content
90
114
  parts.join
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nokogiri"
4
+
5
+ module TurboRspec
6
+ module Matchers
7
+ # RSpec matcher for asserting that a response body contains an element with
8
+ # the given Stimulus action descriptor (+data-action+ contains the descriptor
9
+ # as a space-separated token).
10
+ #
11
+ # Accepts a full descriptor (+click->hello#greet+) or a shorthand without
12
+ # an event (+hello#greet+), which matches any event prefix.
13
+ #
14
+ # @example Full descriptor
15
+ # expect(response).to have_stimulus_action("click->hello#greet")
16
+ #
17
+ # @example Shorthand (any event)
18
+ # expect(response).to have_stimulus_action("hello#greet")
19
+ class HaveStimulusAction
20
+ def initialize(action_descriptor)
21
+ @action_descriptor = action_descriptor.to_s
22
+ end
23
+
24
+ # @param response_or_body [#body, String]
25
+ # @return [Boolean]
26
+ def matches?(response_or_body)
27
+ @body = extract_body(response_or_body)
28
+ Nokogiri::HTML5.fragment(@body).css(selector).any?
29
+ end
30
+
31
+ # @param response_or_body [#body, String]
32
+ # @return [Boolean]
33
+ def does_not_match?(response_or_body)
34
+ !matches?(response_or_body)
35
+ end
36
+
37
+ # @return [String]
38
+ def failure_message
39
+ "expected response to have Stimulus action #{@action_descriptor.inspect}"
40
+ end
41
+
42
+ # @return [String]
43
+ def failure_message_when_negated
44
+ "expected response not to have Stimulus action #{@action_descriptor.inspect}"
45
+ end
46
+
47
+ # @return [String]
48
+ def description
49
+ "have Stimulus action #{@action_descriptor.inspect}"
50
+ end
51
+
52
+ private
53
+
54
+ def extract_body(response_or_body)
55
+ if response_or_body.respond_to?(:body)
56
+ response_or_body.body
57
+ else
58
+ response_or_body.to_s
59
+ end
60
+ end
61
+
62
+ def selector
63
+ if @action_descriptor.include?("->")
64
+ "[data-action~='#{@action_descriptor}']"
65
+ else
66
+ "[data-action*='#{@action_descriptor}']"
67
+ end
68
+ end
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,58 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nokogiri"
4
+
5
+ module TurboRspec
6
+ module Matchers
7
+ # RSpec matcher for asserting that a response body contains an element with
8
+ # the given Stimulus controller (+data-controller+ contains the name as a
9
+ # space-separated token).
10
+ #
11
+ # @example
12
+ # expect(response).to have_stimulus_controller("hello")
13
+ # expect(response).not_to have_stimulus_controller("missing")
14
+ class HaveStimulusController
15
+ def initialize(controller_name)
16
+ @controller_name = controller_name.to_s
17
+ end
18
+
19
+ # @param response_or_body [#body, String]
20
+ # @return [Boolean]
21
+ def matches?(response_or_body)
22
+ @body = extract_body(response_or_body)
23
+ Nokogiri::HTML5.fragment(@body).css("[data-controller~='#{@controller_name}']").any?
24
+ end
25
+
26
+ # @param response_or_body [#body, String]
27
+ # @return [Boolean]
28
+ def does_not_match?(response_or_body)
29
+ !matches?(response_or_body)
30
+ end
31
+
32
+ # @return [String]
33
+ def failure_message
34
+ "expected response to have Stimulus controller #{@controller_name.inspect}"
35
+ end
36
+
37
+ # @return [String]
38
+ def failure_message_when_negated
39
+ "expected response not to have Stimulus controller #{@controller_name.inspect}"
40
+ end
41
+
42
+ # @return [String]
43
+ def description
44
+ "have Stimulus controller #{@controller_name.inspect}"
45
+ end
46
+
47
+ private
48
+
49
+ def extract_body(response_or_body)
50
+ if response_or_body.respond_to?(:body)
51
+ response_or_body.body
52
+ else
53
+ response_or_body.to_s
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "nokogiri"
4
+
5
+ module TurboRspec
6
+ module Matchers
7
+ # RSpec matcher for asserting that a response body contains an element with
8
+ # the given Stimulus target (+data-{controller}-target+ contains the target
9
+ # name as a space-separated token).
10
+ #
11
+ # @example
12
+ # expect(response).to have_stimulus_target("hello", "name")
13
+ # expect(response).not_to have_stimulus_target("hello", "missing")
14
+ class HaveStimulusTarget
15
+ def initialize(controller_name, target_name)
16
+ @controller_name = controller_name.to_s
17
+ @target_name = target_name.to_s
18
+ end
19
+
20
+ # @param response_or_body [#body, String]
21
+ # @return [Boolean]
22
+ def matches?(response_or_body)
23
+ @body = extract_body(response_or_body)
24
+ Nokogiri::HTML5.fragment(@body).css("[data-#{@controller_name}-target~='#{@target_name}']").any?
25
+ end
26
+
27
+ # @param response_or_body [#body, String]
28
+ # @return [Boolean]
29
+ def does_not_match?(response_or_body)
30
+ !matches?(response_or_body)
31
+ end
32
+
33
+ # @return [String]
34
+ def failure_message
35
+ "expected response to have Stimulus target #{@target_name.inspect} for controller #{@controller_name.inspect}"
36
+ end
37
+
38
+ # @return [String]
39
+ def failure_message_when_negated
40
+ "expected response not to have Stimulus target #{@target_name.inspect} for controller #{@controller_name.inspect}"
41
+ end
42
+
43
+ # @return [String]
44
+ def description
45
+ "have Stimulus target #{@target_name.inspect} for #{@controller_name.inspect}"
46
+ end
47
+
48
+ private
49
+
50
+ def extract_body(response_or_body)
51
+ if response_or_body.respond_to?(:body)
52
+ response_or_body.body
53
+ else
54
+ response_or_body.to_s
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,6 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative "matchers/have_broadcasted_turbo_stream_to"
4
+ require_relative "matchers/have_stimulus_action"
5
+ require_relative "matchers/have_stimulus_controller"
6
+ require_relative "matchers/have_stimulus_target"
4
7
  require_relative "matchers/have_turbo_frame"
5
8
  require_relative "matchers/have_turbo_stream"
6
9
  require_relative "matchers/have_turbo_streams"
@@ -48,6 +51,28 @@ module TurboRspec
48
51
  HaveTurboStreams.new(matchers)
49
52
  end
50
53
 
54
+ # Assert that a response body contains an element with the given Stimulus controller.
55
+ # @param controller_name [String]
56
+ # @return [HaveStimulusController]
57
+ def have_stimulus_controller(controller_name)
58
+ HaveStimulusController.new(controller_name)
59
+ end
60
+
61
+ # Assert that a response body contains an element with the given Stimulus action.
62
+ # @param action_descriptor [String]
63
+ # @return [HaveStimulusAction]
64
+ def have_stimulus_action(action_descriptor)
65
+ HaveStimulusAction.new(action_descriptor)
66
+ end
67
+
68
+ # Assert that a response body contains an element with the given Stimulus target.
69
+ # @param controller_name [String]
70
+ # @param target_name [String]
71
+ # @return [HaveStimulusTarget]
72
+ def have_stimulus_target(controller_name, target_name)
73
+ HaveStimulusTarget.new(controller_name, target_name)
74
+ end
75
+
51
76
  # Assert that a response body matches a stored turbo stream snapshot.
52
77
  # Creates the snapshot on the first run; diffs against it on subsequent runs.
53
78
  # Set +UPDATE_TURBO_SNAPSHOTS=1+ to overwrite an existing snapshot.
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TurboRspec
4
- VERSION = "1.5.0"
4
+ VERSION = "1.6.0"
5
5
  end
data/sig/turbo_rspec.rbs CHANGED
@@ -26,6 +26,9 @@ module TurboRspec
26
26
  def have_turbo_stream: () -> HaveTurboStream
27
27
  def assert_no_turbo_stream: () -> HaveTurboStream
28
28
  def have_turbo_streams: (*HaveTurboStream matchers) -> HaveTurboStreams
29
+ def have_stimulus_controller: (String controller_name) -> HaveStimulusController
30
+ def have_stimulus_action: (String action_descriptor) -> HaveStimulusAction
31
+ def have_stimulus_target: (String controller_name, String target_name) -> HaveStimulusTarget
29
32
  def match_turbo_stream_snapshot: (String name) -> MatchTurboStreamSnapshot
30
33
  def have_turbo_frame: () -> HaveTurboFrame
31
34
  def have_broadcasted_turbo_stream_to: (String | untyped stream_or_object) -> HaveBroadcastedTurboStreamTo
@@ -105,6 +108,33 @@ module TurboRspec
105
108
  def description: () -> String
106
109
  end
107
110
 
111
+ class HaveStimulusController
112
+ def initialize: (String controller_name) -> void
113
+ def matches?: (untyped response_or_body) -> bool
114
+ def does_not_match?: (untyped response_or_body) -> bool
115
+ def failure_message: () -> String
116
+ def failure_message_when_negated: () -> String
117
+ def description: () -> String
118
+ end
119
+
120
+ class HaveStimulusAction
121
+ def initialize: (String action_descriptor) -> void
122
+ def matches?: (untyped response_or_body) -> bool
123
+ def does_not_match?: (untyped response_or_body) -> bool
124
+ def failure_message: () -> String
125
+ def failure_message_when_negated: () -> String
126
+ def description: () -> String
127
+ end
128
+
129
+ class HaveStimulusTarget
130
+ def initialize: (String controller_name, String target_name) -> void
131
+ def matches?: (untyped response_or_body) -> bool
132
+ def does_not_match?: (untyped response_or_body) -> bool
133
+ def failure_message: () -> String
134
+ def failure_message_when_negated: () -> String
135
+ def description: () -> String
136
+ end
137
+
108
138
  class MatchTurboStreamSnapshot
109
139
  def initialize: (String name) -> void
110
140
  def matches?: (untyped response_or_body) -> bool
@@ -130,6 +160,8 @@ module TurboRspec
130
160
  end
131
161
 
132
162
  module Assertions
163
+ def assert_broadcasted_turbo_stream_to: (String stream, ?action: (Symbol | String)?, ?target: String?, ?targets: String?, ?content: String?, ?partial: String?, ?message: String?) { () -> void } -> void
164
+ def refute_broadcasted_turbo_stream_to: (String stream, ?action: (Symbol | String)?, ?target: String?, ?targets: String?, ?content: String?, ?partial: String?, ?message: String?) { () -> void } -> void
133
165
  def assert_turbo_stream: (untyped response_or_body, ?action: (Symbol | String)?, ?target: String?, ?targets: String?, ?content: String?, ?partial: String?, ?message: String?) -> void
134
166
  def refute_turbo_stream: (untyped response_or_body, ?action: (Symbol | String)?, ?target: String?, ?targets: String?, ?content: String?, ?partial: String?, ?message: String?) -> void
135
167
  def assert_turbo_frame: (untyped response_or_body, ?id: String?, ?content: String?, ?partial: String?, ?message: String?) -> void
@@ -153,6 +185,8 @@ module TurboRspec
153
185
  def loaded: () -> self
154
186
  def with_src: (String url) -> self
155
187
  def lazy: () -> self
188
+ def eager: () -> self
189
+ def strict: () -> self
156
190
 
157
191
  # Capybara matcher interface
158
192
  def matches?: (untyped page_or_node) -> bool
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: turbo_rspec
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Chuck Smith
@@ -64,6 +64,9 @@ files:
64
64
  - lib/turbo_rspec/helpers.rb
65
65
  - lib/turbo_rspec/matchers.rb
66
66
  - lib/turbo_rspec/matchers/have_broadcasted_turbo_stream_to.rb
67
+ - lib/turbo_rspec/matchers/have_stimulus_action.rb
68
+ - lib/turbo_rspec/matchers/have_stimulus_controller.rb
69
+ - lib/turbo_rspec/matchers/have_stimulus_target.rb
67
70
  - lib/turbo_rspec/matchers/have_turbo_frame.rb
68
71
  - lib/turbo_rspec/matchers/have_turbo_stream.rb
69
72
  - lib/turbo_rspec/matchers/have_turbo_streams.rb