Looking for resources on how to use RSpec with Hotwire

Building an app with Hotwire for the first time. I think I finally wrapped my head around the unique way it forces you to structure view markup, but now I need to write some tests and I haven’t been able to find a guide on using RSpec with Hotwire.

Can anyone refer me to some good resources?

Thanks!

Good to know that you’re starting to use it!

First thing is separate the two scenarios:

  1. Turbo frame
    Normally the important things to check on frames is that you’re not rendering the layout and that you’re returning the turbo_frame.
expect(response).to have_http_status(:ok)
expect(response).to render_template(layout: false)
expect(response.body).to include('<turbo-frame id="frame_id">')
  1. Turbo stream
    You can check the turbo stream test helpers that they created on turbo-rails, and use those kind of checks on the specs of actions that respond to turbo_streams.
    Here something like that for rspec:
    expect(response).to have_http_status(:ok)
    expect(response.media_type).to eq Mime[:turbo_stream]
    expect(response).to render_template(layout: false)
    expect(response.body).to include('<turbo-stream action="append" target="flash">')
    
    And remember add the , as: :turbo_stream on the action when you execute it.

This is what I use most of the time to test turbo interactions with rspec

3 Likes

Thank you for that clear, concise response. This is very helpful!

Hi, I am also starting on Hotwire and TDD and I’m having trouble implementing these examples.
For Turbo frame, it works with this feature test with js: true:

# spec/features/clinics_select_spec.rb
feature 'when user clicks create_clinic btn', js: true do
  scenario 'turbo frame loads form' do
    visit root_path

    click_link "new_clinic"

    expect(page).to have_field('clinic_name') # field from new_clinic form
    expect(page).to have_field('clinics_select') # field from original page, making sure that turbo frame was used
  end
end

However this feels rather fragile and prone to changes in the future.
For Turbo stream, I implemented a broadcast on clinics that updates the select tag with a clinic when added to database. This works in the browser: clinics_select is updated if I add a clinic through the console. The test however doesn’t work:

# spec/features/clinics_select_spec.rb
feature 'a clinic is added', js: true do
  scenario 'and turbostream updates select' do
    clinic1 = create(:clinic, name:'clinic1')
    visit root_path

    clinic1 = create(:clinic, name:'clinic2')

    expect(page).to have_css 'option', text:'clinic1'
    expect(page).to have_css 'option', text:'clinic2'
  end
end

I get the error:

Failures:

  1) a clinic is added and turbostream updates select
     Failure/Error: expect(page).to have_css 'option', text:'clinic2'
       expected to find visible css "option" with text "clinic2" but there were no matches. Also found "clinic1", which matched the selector but not all filters. 
     # ./spec/features/appointments/clinics_select_spec.rb:28:in `block (2 levels) in <top (required)>'

I would welcome any comment on these specs as I have little experience.
Also it would be great if you could complete the examples above with the setup and action parts.
Thanks!