diff --git a/Gemfile b/Gemfile index 3039202f0..0084b7546 100644 --- a/Gemfile +++ b/Gemfile @@ -29,15 +29,8 @@ gem "discard" group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem "byebug", platforms: %i[mri mingw x64_mingw] - gem "capybara", require: false gem "dotenv-rails" - gem "factory_bot_rails" gem "pry-byebug" - gem "selenium-webdriver", require: false - gem "simplecov", require: false - %w[rspec-core rspec-expectations rspec-mocks rspec-rails rspec-support].each do |lib| - gem lib, git: "https://github.com/rspec/#{lib}.git", branch: "main", require: false - end end group :development do @@ -54,5 +47,16 @@ group :development do gem "scss_lint-govuk" end +group :test do + gem "capybara", require: false + gem "factory_bot_rails" + gem "selenium-webdriver", require: false + gem "simplecov", require: false + gem "database_cleaner-active_record", require: false + %w[rspec-core rspec-expectations rspec-mocks rspec-rails rspec-support].each do |lib| + gem lib, git: "https://github.com/rspec/#{lib}.git", branch: "main", require: false + end +end + # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem "tzinfo-data", platforms: %i[mingw mswin x64_mingw jruby] diff --git a/Gemfile.lock b/Gemfile.lock index b48165040..8abc24776 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -26,7 +26,7 @@ GIT GIT remote: https://github.com/rspec/rspec-rails.git - revision: 3f0e35085f5765decf96fee179ec9a2e132a67c1 + revision: cfe4db707cc5a0c9437aa90e3059256f30368da4 branch: main specs: rspec-rails (5.1.0.pre) @@ -40,7 +40,7 @@ GIT GIT remote: https://github.com/rspec/rspec-support.git - revision: 28526172c42302858c18681d7d7580490d885b4d + revision: 2a17194b9fc868a4b4a41d7168103dca825c3004 branch: main specs: rspec-support (3.11.0.pre) @@ -115,8 +115,9 @@ GEM msgpack (~> 1.0) builder (3.2.4) byebug (11.1.3) - capybara (3.35.3) + capybara (3.36.0) addressable + matrix mini_mime (>= 0.1.3) nokogiri (~> 1.8) rack (>= 1.6.0) @@ -127,6 +128,10 @@ GEM coderay (1.1.3) concurrent-ruby (1.1.9) crass (1.0.6) + database_cleaner-active_record (2.0.1) + activerecord (>= 5.a) + database_cleaner-core (~> 2.0.0) + database_cleaner-core (2.0.1) deep_merge (1.2.1) diff-lcs (1.4.4) discard (1.2.0) @@ -145,7 +150,7 @@ GEM ffi (1.15.4) globalid (0.5.2) activesupport (>= 5.0) - govuk-components (2.1.3) + govuk-components (2.1.4) activemodel (>= 6.0) railties (>= 6.0) view_component (~> 2.39.0) @@ -172,6 +177,7 @@ GEM mail (2.7.1) mini_mime (>= 0.1.1) marcel (1.0.2) + matrix (0.4.2) method_source (1.0.0) mini_mime (1.1.2) minitest (5.14.4) @@ -334,6 +340,7 @@ DEPENDENCIES bootsnap (>= 1.4.4) byebug capybara + database_cleaner-active_record discard dotenv-rails factory_bot_rails diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 726c09017..b873a5929 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -6,6 +6,7 @@ require File.expand_path("../config/environment", __dir__) abort("The Rails environment is running in production mode!") if Rails.env.production? require "rspec/rails" require "capybara/rspec" +require 'database_cleaner/active_record' # Comment to run `js: true specs` with visible browser interaction Capybara.javascript_driver = :selenium_headless @@ -42,7 +43,48 @@ RSpec.configure do |config| # If you're not using ActiveRecord, or you'd prefer not to run each of your # examples within a transaction, remove the following line or assign false # instead of true. - config.use_transactional_fixtures = true + # config.use_transactional_fixtures = true + + config.before(:suite) do + if config.use_transactional_fixtures? + raise(<<-MSG) + Delete line `config.use_transactional_fixtures = true` from rails_helper.rb + (or set it to false) to prevent uncommitted transactions being used in + JavaScript-dependent specs. + + During testing, the app-under-test that the browser driver connects to + uses a different database connection to the database connection used by + the spec. The app's database connection would not be able to access + uncommitted transaction data setup over the spec's database connection. + MSG + end + DatabaseCleaner.clean_with(:truncation) + end + + config.before(:each) do + DatabaseCleaner.strategy = :transaction + end + + config.before(:each, type: :feature) do + # :rack_test driver's Rack app under test shares database connection + # with the specs, so continue to use transaction strategy for speed. + driver_shares_db_connection_with_specs = Capybara.current_driver == :rack_test + + unless driver_shares_db_connection_with_specs + # Driver is probably for an external browser with an app + # under test that does *not* share a database connection with the + # specs, so use truncation strategy. + DatabaseCleaner.strategy = :truncation + end + end + + config.before(:each) do + DatabaseCleaner.start + end + + config.append_after(:each) do + DatabaseCleaner.clean + end # You can uncomment this line to turn off ActiveRecord support entirely. # config.use_active_record = false