peterabraham
peterabraham

Reputation: 43

Run Specs With VCR without explicitly specifying the cassette name

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?

Upvotes: 4

Views: 889

Answers (1)

Adim
Adim

Reputation: 1776

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

Upvotes: 2

Related Questions