I set up a simple controller with its according feature_spec:
stamps_controller.rb
class StampsController < ApplicationController
def new
@stamp = Stamp.new
end
def create
@stamp = Stamp.new(stamp_params)
if @stamp.save
redirect_to(stamp_url(@stamp.id), status: 201)
else
render 'new'
end
end
def show
@stamp = Stamp.find(params[:id])
end
private
def stamp_params
params.require(:stamp).permit(::percentage)
end
end
specs/requests/stamps_request_spec.rb
RSpec.describe 'stamp requests', type: :request do
describe 'stamp creation', js: true do
before do
FactoryBot.create_list(:domain, 2)
FactoryBot.create_list(:label, 2)
end
it 'allows users to create new stamps' do
visit new_stamp_path
expect(page).to have_content('Percentage')
find('#stamp_percentage').set('20')
click_button 'Create'
expect(current_path).to eq(stamp_path(Stamp.first.id))
end
end
end
According to the capybara docs:
Capybara automatically follows any redirects, and submits forms associated with buttons.
But this does not happen in the test, instead it throws an error:
expected: "/stamps/1
got: "/stamps"
The results are obvious: it successfully creates the stamp but fails to redirect to the new stamp. I also confirmed this by using binding.pry
.
Why wouldn't capybara follow the redirect as described in the docs?
Sidenotes:
- it even fails if I use the normal driver instead of js
- I've looked into lots of SO questions and docs, finding nothing useful. One potential attempt I was unable to grasp was an answer with no specifics of how to implement it.
- my configs:
support/capybara.rb
require 'capybara/rails'
require 'capybara/rspec'
Capybara.server = :puma
Capybara.register_driver :selenium do |app|
Capybara::Selenium::Driver.new(app, browser: :firefox, marionette: true)
end
Capybara.javascript_driver = :selenium
RSpec.configure do |config|
config.include Capybara::DSL
end
spec_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../config/environment', __dir__)
require 'rspec/rails'
require 'factory_bot_rails'
require 'pundit/matchers'
Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
RSpec.configure do |config|
# .
# unrelated stuff
# .
end