4

I have capybara feature specs I intend running without explicitly specifying a cassette name. E.g:

  scenario "by searching via a title" do
    visit root_path

    fill_in "search", with: "cheddar"
    find(".search-btn").click


    expect(page).to have_content(/White Cheddar/)
  end
  scenario "by searching via a description" do
    visit root_path

    fill_in "search", with: "cheddar"
    select "Description", from: "search_field"
    find(".search-btn").click


    expect(page).to have_content(/White Cheddars Are Scarce/)
  end

Each of these specs goes out to hit a third party API. I want to use a different cassette name for each of these specs without having to explicitly use VCR.use_cassette. I want my feature specs to be clear and concise enough just focusing on the user's action. Is there a way to achieve this?

1 Answers1

2

The way I have handled something like this in the past is by configuring it from within the rails_helper file.

In your Rspec.configure block, you can retrieve details of each running spec and alter things either before, around or after the running of each spec example. That enabled me to have a nice DSL that allows me to specify the cassette name as a vcr tag. So in your case, it can become:

  scenario "by searching via a title", vcr: :search_title do
    visit root_path

    fill_in "search", with: "cheddar"
    find(".search-btn").click


    expect(page).to have_content(/White Cheddar/)
  end
  scenario "by searching via a description", vcr: :search_description do
    visit root_path

    fill_in "search", with: "cheddar"
    select "Description", from: "search_field"
    find(".search-btn").click


    expect(page).to have_content(/White Cheddars Are Scarce/)
  end

The changes I had to do to make this work were within the rails_helper file:

RSpec.configure do |c|
  c.around(:each, :vcr) do |example|
    name = Array(example.metadata.dig(:vcr)).join
    options = example.metadata.slice(:record, :match_requests_on)
    VCR.use_cassette(name, options) { example.call }
  end
end

For each spec example with a vcr tag, grab the spec's metadata and retrieve whatever is stored in the vcr tag as the cassette name. The rest of the lines just activates VCR for only specs having the VCR tag. You can see more of why I did this from this railscast episode

Adim
  • 1,716
  • 12
  • 13
  • Thanks for your answer. I think it falls inline with what I want. So I guess this creates a separate cassette yaml file for each of the examples? Also, I don't want to have VCR activated for all the feature specs. Is this restricted to only specs with vcr tags? – peterabraham Jan 22 '20 at 11:08
  • This configuration will ensure that VCR is only activated for specs with the VCR tag. Also, a separate yaml file will only be created for different spec names. If you have 2 spec examples using the same vcr tag name, only one yaml file will be created – Adim Jan 22 '20 at 11:15