RSpec content matchers for turbo-stream response
Rails
RSpec
if you have RSpec request test and
In capybara if you want to check turbo stream content like
# spec/requests/hello_spec.rb
it do
put my_path, params: { }, as: :turbo_stream
expect(page).to have_content("hello")
end
it will not work
reason is that
page is alias to
def page
Capybara.string(response.body)
end
which gets pretty much converted to #text on have_content RSpec natcher evaluation
And `Capybara.string` will remove any <template> tags.
try this in Rails c
Capybara.string("<template>foo</template> bar").text
=> bar # foo was ignored
Guess what: Turbo stream response wraps the response in <template> ...frames... </template>
Source: this GH ticket for more info
so only way to test response with capybara
it do
put my_path, params: { }, as: :turbo_stream
template = Nokogiri(response.body).css('template').last.inner_html # fetch inner content of <template> that contains frames
parsed = Capybara.string(template # parse the template content so RSpec matcher have_content works
expect(parsed).to have_content("Is this good?")
end
Helper
# rails_spec.rb
# ...
def turbo_stream_page
# turbo_stream wraps response in <template> tag, Capybara ignore template tags
template_content = Nokogiri(response.body).css('template').last.inner_html
Capybara.string(template_content)
end
test
# spec/requests/hello_spec.rb
it do
put my_path, params: { }, as: :turbo_stream
expect(turbo_stream_page).to have_content("hello")
end