Merge pull request #6584 from betagouv/system-specs

Migration des tests d'intégration vers des "system specs" (#6584)
This commit is contained in:
Pierre de La Morinerie 2021-10-26 12:43:30 +02:00 committed by GitHub
commit 8bc925ae50
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
43 changed files with 59 additions and 88 deletions

View file

@ -59,7 +59,7 @@ jobs:
- bin/rspec spec/controllers/*_spec.rb - bin/rspec spec/controllers/*_spec.rb
- bin/rspec spec/controllers/[a-l]**/*_spec.rb - bin/rspec spec/controllers/[a-l]**/*_spec.rb
- bin/rspec spec/controllers/[m-z]**/*_spec.rb - bin/rspec spec/controllers/[m-z]**/*_spec.rb
- bin/rspec spec/features - bin/rspec spec/system
- bin/rspec spec/helpers spec/lib spec/middlewares - bin/rspec spec/helpers spec/lib spec/middlewares
- bin/rspec spec/mailers spec/jobs spec/policies - bin/rspec spec/mailers spec/jobs spec/policies
- bin/rspec spec/models - bin/rspec spec/models

View file

@ -722,7 +722,7 @@ Rails/DelegateAllowBlank:
Rails/DynamicFindBy: Rails/DynamicFindBy:
Enabled: true Enabled: true
Exclude: Exclude:
- "spec/features/**/*.rb" - "spec/system/**/*.rb"
Rails/EnumUniqueness: Rails/EnumUniqueness:
Enabled: true Enabled: true

View file

@ -89,11 +89,10 @@ group :test do
gem 'capybara' # Integration testing gem 'capybara' # Integration testing
gem 'capybara-email' # Access emails during integration tests gem 'capybara-email' # Access emails during integration tests
gem 'capybara-screenshot' # Save a dump of the page when an integration test fails gem 'capybara-screenshot' # Save a dump of the page when an integration test fails
gem 'capybara-selenium'
gem 'database_cleaner'
gem 'factory_bot' gem 'factory_bot'
gem 'launchy' gem 'launchy'
gem 'rails-controller-testing' gem 'rails-controller-testing'
gem 'selenium-webdriver'
gem 'shoulda-matchers', require: false gem 'shoulda-matchers', require: false
gem 'timecop' gem 'timecop'
gem 'vcr' gem 'vcr'

View file

@ -162,9 +162,6 @@ GEM
capybara-screenshot (1.0.25) capybara-screenshot (1.0.25)
capybara (>= 1.0, < 4) capybara (>= 1.0, < 4)
launchy launchy
capybara-selenium (0.0.6)
capybara
selenium-webdriver
case_transform (0.2) case_transform (0.2)
activesupport activesupport
caxlsx (3.1.0) caxlsx (3.1.0)
@ -189,12 +186,6 @@ GEM
css_parser (1.9.0) css_parser (1.9.0)
addressable addressable
daemons (1.3.1) daemons (1.3.1)
database_cleaner (2.0.1)
database_cleaner-active_record (~> 2.0.0)
database_cleaner-active_record (2.0.0)
activerecord (>= 5.a)
database_cleaner-core (~> 2.0.0)
database_cleaner-core (2.0.1)
datetime_picker_rails (0.0.7) datetime_picker_rails (0.0.7)
momentjs-rails (>= 2.8.1) momentjs-rails (>= 2.8.1)
deep_cloneable (3.0.0) deep_cloneable (3.0.0)
@ -798,13 +789,11 @@ DEPENDENCIES
capybara capybara
capybara-email capybara-email
capybara-screenshot capybara-screenshot
capybara-selenium
charlock_holmes charlock_holmes
chartkick chartkick
chunky_png chunky_png
clamav-client clamav-client
daemons daemons
database_cleaner
deep_cloneable deep_cloneable
delayed_cron_job delayed_cron_job
delayed_job_active_record delayed_job_active_record
@ -874,6 +863,7 @@ DEPENDENCIES
sanitize-url sanitize-url
sassc-rails sassc-rails
scss_lint scss_lint
selenium-webdriver
sentry-delayed_job sentry-delayed_job
sentry-rails sentry-rails
sentry-ruby sentry-ruby

View file

@ -2,7 +2,7 @@
# More info at https://github.com/guard/guard#readme # More info at https://github.com/guard/guard#readme
## Uncomment and set this to only include directories you want to watch ## Uncomment and set this to only include directories you want to watch
# directories %w(app lib config test spec features) \ # directories %w(app lib config test spec system) \
# .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")} # .select{|d| Dir.exists?(d) ? d : UI.warning("Directory #{d} does not exist")}
## Note: if you are using the `directories` clause above and you are not ## Note: if you are using the `directories` clause above and you are not
@ -77,8 +77,8 @@ guard :rspec, cmd: 'spring rspec' do
watch('app/controllers/application_controller.rb') { "spec/controllers" } watch('app/controllers/application_controller.rb') { "spec/controllers" }
watch('spec/rails_helper.rb') { "spec" } watch('spec/rails_helper.rb') { "spec" }
# Capybara features specs # Capybara system specs
watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/features/#{m[1]}_spec.rb" } watch(%r{^app/views/(.+)/.*\.(erb|haml|slim)$}) { |m| "spec/system/#{m[1]}_spec.rb" }
# Turnip features and steps # Turnip features and steps
watch(%r{^spec/acceptance/(.+)\.feature$}) watch(%r{^spec/acceptance/(.+)\.feature$})

View file

@ -58,7 +58,7 @@ RSpec.configure do |config|
# If you're not using ActiveRecord, or you'd prefer not to run each of your # 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 # examples within a transaction, remove the following line or assign false
# instead of true. # instead of true.
config.use_transactional_fixtures = false config.use_transactional_fixtures = true
# RSpec Rails can automatically mix in different behaviours to your tests # RSpec Rails can automatically mix in different behaviours to your tests
# based on their file location, for example enabling you to call `get` and # based on their file location, for example enabling you to call `get` and
@ -127,4 +127,5 @@ RSpec.configure do |config|
config.include Shoulda::Matchers::ActiveModel, type: :model config.include Shoulda::Matchers::ActiveModel, type: :model
config.include Devise::Test::ControllerHelpers, type: :controller config.include Devise::Test::ControllerHelpers, type: :controller
config.include Devise::Test::ControllerHelpers, type: :view config.include Devise::Test::ControllerHelpers, type: :view
config.include Devise::Test::IntegrationHelpers, type: :system
end end

View file

@ -3,9 +3,6 @@ require 'capybara-screenshot/rspec'
require 'capybara/email/rspec' require 'capybara/email/rspec'
require 'selenium/webdriver' require 'selenium/webdriver'
Capybara.javascript_driver = :headless_chrome
Capybara.ignore_hidden_elements = false
Capybara.register_driver :chrome do |app| Capybara.register_driver :chrome do |app|
Capybara::Selenium::Driver.new(app, browser: :chrome) Capybara::Selenium::Driver.new(app, browser: :chrome)
end end
@ -34,11 +31,10 @@ Capybara.register_driver :headless_chrome do |app|
end end
end end
# FIXME: remove this line when https://github.com/rspec/rspec-rails/issues/1897 has been fixed
Capybara.server = :puma, { Silent: true }
Capybara.default_max_wait_time = 2 Capybara.default_max_wait_time = 2
Capybara.ignore_hidden_elements = false
# Save a snapshot of the HTML page when an integration test fails # Save a snapshot of the HTML page when an integration test fails
Capybara::Screenshot.autosave_on_failure = true Capybara::Screenshot.autosave_on_failure = true
# Keep only the screenshots generated from the last failing test suite # Keep only the screenshots generated from the last failing test suite
@ -49,13 +45,21 @@ Capybara::Screenshot.register_driver :headless_chrome do |driver, path|
end end
RSpec.configure do |config| RSpec.configure do |config|
# Set the user preferred language before Javascript feature specs. config.before(:each, type: :system) do
driven_by :rack_test
end
config.before(:each, type: :system, js: true) do
driven_by :headless_chrome
end
# Set the user preferred language before Javascript system specs.
# #
# Features specs without Javascript run in a Rack stack, and respect the Accept-Language value. # System specs without Javascript run in a Rack stack, and respect the Accept-Language value.
# However specs using Javascript are run into a Headless Chrome, which doesn't support setting # However specs using Javascript are run into a Headless Chrome, which doesn't support setting
# the default Accept-Language value reliably. # the default Accept-Language value reliably.
# So instead we set the locale cookie explicitly before each Javascript test. # So instead we set the locale cookie explicitly before each Javascript test.
config.before(:each, js: true) do config.before(:each, type: :system, js: true) do
visit '/' # Webdriver needs visiting a page before setting the cookie visit '/' # Webdriver needs visiting a page before setting the cookie
Capybara.current_session.driver.browser.manage.add_cookie( Capybara.current_session.driver.browser.manage.add_cookie(
name: :locale, name: :locale,

View file

@ -1,23 +0,0 @@
RSpec.configure do |config|
expect_list = []
config.before(:suite) do
DatabaseCleaner.clean_with(:truncation, except: expect_list)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, js: true) do
DatabaseCleaner.strategy = :deletion, { except: expect_list }
end
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
end

View file

@ -1,4 +1,4 @@
module FeatureHelpers module SystemHelpers
include ActiveJob::TestHelper include ActiveJob::TestHelper
def login_admin def login_admin
@ -177,5 +177,5 @@ module FeatureHelpers
end end
RSpec.configure do |config| RSpec.configure do |config|
config.include FeatureHelpers, type: :feature config.include SystemHelpers, type: :system
end end

View file

@ -1,4 +1,4 @@
feature 'wcag rules for usager', js: true do describe 'wcag rules for usager', js: true do
let(:procedure) { create(:procedure, :with_type_de_champ, :with_all_champs, :with_service, :for_individual, :published) } let(:procedure) { create(:procedure, :with_type_de_champ, :with_all_champs, :with_service, :for_individual, :published) }
let(:password) { 'a very complicated password' } let(:password) { 'a very complicated password' }
let(:litteraire_user) { create(:user, password: password) } let(:litteraire_user) { create(:user, password: password) }

View file

@ -1,4 +1,4 @@
feature 'As an administrateur', js: true do describe 'As an administrateur', js: true do
let(:super_admin) { create(:super_admin) } let(:super_admin) { create(:super_admin) }
let(:admin_email) { 'new_admin@gouv.fr' } let(:admin_email) { 'new_admin@gouv.fr' }
let(:new_admin) { Administrateur.by_email(admin_email) } let(:new_admin) { Administrateur.by_email(admin_email) }

View file

@ -1,6 +1,6 @@
require 'features/admin/procedure_spec_helper' require 'system/admin/procedure_spec_helper'
feature 'As an administrateur I wanna clone a procedure', js: true do describe 'As an administrateur I wanna clone a procedure', js: true do
include ProcedureSpecHelper include ProcedureSpecHelper
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }

View file

@ -1,6 +1,6 @@
require 'features/admin/procedure_spec_helper' require 'system/admin/procedure_spec_helper'
feature 'As an administrateur I wanna create a new procedure', js: true do describe 'As an administrateur I wanna create a new procedure', js: true do
include ProcedureSpecHelper include ProcedureSpecHelper
let(:administrateur) { create(:administrateur, :with_procedure) } let(:administrateur) { create(:administrateur, :with_procedure) }

View file

@ -1,4 +1,4 @@
feature 'procedure locked' do describe 'procedure locked' do
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }
before do before do

View file

@ -1,6 +1,6 @@
require 'features/admin/procedure_spec_helper' require 'system/admin/procedure_spec_helper'
feature 'Publication de démarches', js: true do describe 'Publication de démarches', js: true do
include ProcedureSpecHelper include ProcedureSpecHelper
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }

View file

@ -1,6 +1,6 @@
require 'features/admin/procedure_spec_helper' require 'system/admin/procedure_spec_helper'
feature 'Administrateurs can edit procedures', js: true do describe 'Administrateurs can edit procedures', js: true do
include ProcedureSpecHelper include ProcedureSpecHelper
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }

View file

@ -1,4 +1,4 @@
feature 'fetch API Particulier Data', js: true do describe 'fetch API Particulier Data', js: true do
let(:administrateur) { create(:administrateur) } let(:administrateur) { create(:administrateur) }
let(:expected_token) { 'd7e9c9f4c3ca00caadde31f50fd4521a' } let(:expected_token) { 'd7e9c9f4c3ca00caadde31f50fd4521a' }

View file

@ -1,4 +1,4 @@
feature 'Inviting an expert:' do describe 'Inviting an expert:' do
include ActiveJob::TestHelper include ActiveJob::TestHelper
include ActionView::Helpers include ActionView::Helpers

View file

@ -1,4 +1,4 @@
feature 'Protecting against request forgeries:', :allow_forgery_protection, :show_exception_pages do describe 'Protecting against request forgeries:', :allow_forgery_protection, :show_exception_pages do
let(:user) { create(:user, password: password) } let(:user) { create(:user, password: password) }
let(:password) { 'ThisIsTheUserPassword' } let(:password) { 'ThisIsTheUserPassword' }

View file

@ -1,4 +1,4 @@
feature 'France Connect Particulier Connexion' do describe 'France Connect Particulier Connexion' do
let(:code) { 'plop' } let(:code) { 'plop' }
let(:given_name) { 'titi' } let(:given_name) { 'titi' }
let(:family_name) { 'toto' } let(:family_name) { 'toto' }

View file

@ -1,4 +1,4 @@
feature 'Getting help:' do describe 'Getting help:' do
scenario 'a Help button is visible on public pages' do scenario 'a Help button is visible on public pages' do
visit '/' visit '/'
within('.new-header') do within('.new-header') do

View file

@ -1,4 +1,4 @@
feature 'Accessing the website in different languages:' do describe 'Accessing the website in different languages:' do
context 'when the i18n feature-flag is enabled' do context 'when the i18n feature-flag is enabled' do
before { ENV['LOCALIZATION_ENABLED'] = 'true' } before { ENV['LOCALIZATION_ENABLED'] = 'true' }
after { ENV['LOCALIZATION_ENABLED'] = 'false' } after { ENV['LOCALIZATION_ENABLED'] = 'false' }

View file

@ -1,4 +1,4 @@
feature 'Inviting an expert:', js: true do describe 'Inviting an expert:', js: true do
include ActiveJob::TestHelper include ActiveJob::TestHelper
include ActionView::Helpers include ActionView::Helpers

View file

@ -1,4 +1,4 @@
feature 'As an instructeur', js: true do describe 'As an instructeur', js: true do
let(:administrateur) { create(:administrateur, :with_procedure) } let(:administrateur) { create(:administrateur, :with_procedure) }
let(:procedure) { administrateur.procedures.first } let(:procedure) { administrateur.procedures.first }
let(:instructeur_email) { 'new_instructeur@gouv.fr' } let(:instructeur_email) { 'new_instructeur@gouv.fr' }

View file

@ -1,4 +1,4 @@
feature 'Instructing a dossier:', js: true do describe 'Instructing a dossier:', js: true do
include ActiveJob::TestHelper include ActiveJob::TestHelper
let(:password) { 'my-s3cure-p4ssword' } let(:password) { 'my-s3cure-p4ssword' }

View file

@ -1,4 +1,4 @@
feature "procedure filters" do describe "procedure filters" do
let(:instructeur) { create(:instructeur) } let(:instructeur) { create(:instructeur) }
let(:procedure) { create(:procedure, :published, :with_type_de_champ, instructeurs: [instructeur]) } let(:procedure) { create(:procedure, :published, :with_type_de_champ, instructeurs: [instructeur]) }
let!(:type_de_champ) { procedure.types_de_champ.first } let!(:type_de_champ) { procedure.types_de_champ.first }

View file

@ -1,4 +1,4 @@
feature 'As an administrateur I can edit types de champ', js: true do describe 'As an administrateur I can edit types de champ', js: true do
let(:administrateur) { procedure.administrateurs.first } let(:administrateur) { procedure.administrateurs.first }
let(:procedure) { create(:procedure) } let(:procedure) { create(:procedure) }

View file

@ -1,4 +1,4 @@
feature 'Outdated browsers support:' do describe 'Outdated browsers support:' do
context 'when the user browser is outdated' do context 'when the user browser is outdated' do
before(:each) do before(:each) do
ie_10_user_agent = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; .NET4.0E; .NET4.0C; InfoPath.3)' ie_10_user_agent = 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0; .NET4.0E; .NET4.0C; InfoPath.3)'

View file

@ -1,4 +1,4 @@
feature 'The routing', js: true do describe 'The routing', js: true do
let(:password) { 'a very complicated password' } let(:password) { 'a very complicated password' }
let(:procedure) { create(:procedure, :with_type_de_champ, :with_service, :for_individual) } let(:procedure) { create(:procedure, :with_type_de_champ, :with_service, :for_individual) }
let(:administrateur) { create(:administrateur, procedures: [procedure]) } let(:administrateur) { create(:administrateur, procedures: [procedure]) }

View file

@ -1,4 +1,4 @@
feature 'Signin in:' do describe 'Signin in:' do
let!(:user) { create(:user, password: password) } let!(:user) { create(:user, password: password) }
let(:password) { 'my-s3cure-p4ssword' } let(:password) { 'my-s3cure-p4ssword' }

View file

@ -1,4 +1,4 @@
feature 'The user' do describe 'The user' do
let(:password) { 'my-s3cure-p4ssword' } let(:password) { 'my-s3cure-p4ssword' }
let!(:user) { create(:user, password: password) } let!(:user) { create(:user, password: password) }

View file

@ -1,4 +1,4 @@
feature 'Changing an email' do describe 'Changing an email' do
let(:old_email) { 'old@email.com' } let(:old_email) { 'old@email.com' }
let(:user) { create(:user, email: old_email) } let(:user) { create(:user, email: old_email) }

View file

@ -1,4 +1,4 @@
feature 'Creating a new dossier:' do describe 'Creating a new dossier:' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:siret) { '41816609600051' } let(:siret) { '41816609600051' }
let(:siren) { siret[0...9] } let(:siren) { siret[0...9] }

View file

@ -1,4 +1,4 @@
require 'features/users/dossier_shared_examples.rb' require 'system/users/dossier_shared_examples.rb'
describe 'Dossier details:' do describe 'Dossier details:' do
let(:user) { create(:user) } let(:user) { create(:user) }

View file

@ -1,6 +1,6 @@
require 'features/users/dossier_shared_examples.rb' require 'system/users/dossier_shared_examples.rb'
feature 'Invitations' do describe 'Invitations' do
let(:owner) { create(:user) } let(:owner) { create(:user) }
let(:invited_user) { create(:user, email: 'user_invite@exemple.fr') } let(:invited_user) { create(:user, email: 'user_invite@exemple.fr') }
let(:procedure) { create(:simple_procedure) } let(:procedure) { create(:simple_procedure) }

View file

@ -1,4 +1,4 @@
feature 'linked dropdown lists' do describe 'linked dropdown lists' do
let(:password) { 'my-s3cure-p4ssword' } let(:password) { 'my-s3cure-p4ssword' }
let!(:user) { create(:user, password: password) } let!(:user) { create(:user, password: password) }

View file

@ -1,4 +1,4 @@
feature 'Managing password:' do describe 'Managing password:' do
context 'for simple users' do context 'for simple users' do
let(:user) { create(:user) } let(:user) { create(:user) }
let(:new_password) { 'a simple password' } let(:new_password) { 'a simple password' }

View file

@ -1,4 +1,4 @@
feature 'Sign out' do describe 'Sign out' do
context 'when a user is logged in' do context 'when a user is logged in' do
let(:user) { create(:administrateur).user } let(:user) { create(:administrateur).user }

View file

@ -1,4 +1,4 @@
feature 'Signing up:' do describe 'Signing up:' do
let(:user_email) { generate :user_email } let(:user_email) { generate :user_email }
let(:user_password) { 'my-s3cure-p4ssword' } let(:user_password) { 'my-s3cure-p4ssword' }
let(:procedure) { create :simple_procedure, :with_service } let(:procedure) { create :simple_procedure, :with_service }