diff --git a/app/javascript/controllers/autosave_status_controller.ts b/app/javascript/controllers/autosave_status_controller.ts index 9b87ceda3..99b6b9eb4 100644 --- a/app/javascript/controllers/autosave_status_controller.ts +++ b/app/javascript/controllers/autosave_status_controller.ts @@ -27,6 +27,8 @@ export class AutosaveStatusController extends ApplicationController { connect(): void { this.onGlobal('autosave:enqueue', () => this.didEnqueue()); this.onGlobal('autosave:end', () => this.didSucceed()); + // This event is used in tests to reset the state of the controller + this.onGlobal('autosave:reset', () => this.didReset()); this.onGlobal('autosave:error', (event) => this.didFail(event) ); @@ -46,6 +48,10 @@ export class AutosaveStatusController extends ApplicationController { this.debounce(this.hideSucceededStatus, AUTOSAVE_STATUS_VISIBLE_DURATION); } + private didReset() { + this.setState('idle'); + } + private didFail(event: CustomEvent<{ error: ResponseError }>) { const error = event.detail.error; diff --git a/spec/support/system_helpers.rb b/spec/support/system_helpers.rb index 6a3be5cf0..8a528617b 100644 --- a/spec/support/system_helpers.rb +++ b/spec/support/system_helpers.rb @@ -171,6 +171,12 @@ module SystemHelpers def form_id_for(libelle) find(:xpath, ".//label[contains(text()[normalize-space()], '#{libelle}')]")[:for] end + + def wait_for_autosave(brouillon = true) + blur + expect(page).to have_css('span', text: "#{brouillon ? 'Brouillon' : 'Dossier'} enregistré", visible: true) + page.execute_script("document.documentElement.dispatchEvent(new CustomEvent('autosave:reset'));") + end end RSpec.configure do |config| diff --git a/spec/system/api_particulier/api_particulier_spec.rb b/spec/system/api_particulier/api_particulier_spec.rb index 9f385536f..97395d90b 100644 --- a/spec/system/api_particulier/api_particulier_spec.rb +++ b/spec/system/api_particulier/api_particulier_spec.rb @@ -274,9 +274,7 @@ describe 'fetch API Particulier Data', js: true do fill_in 'Le numéro d’allocataire CAF', with: numero_allocataire fill_in 'Le code postal', with: 'wrong_code' - - blur - expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true) + wait_for_autosave dossier = Dossier.last cnaf_champ = dossier.champs.find(&:cnaf?) @@ -286,12 +284,15 @@ describe 'fetch API Particulier Data', js: true do click_on 'Déposer le dossier' expect(page).to have_content(/code postal doit posséder 5 caractères/) - fill_in 'Le code postal', with: code_postal - VCR.use_cassette('api_particulier/success/composition_familiale') do - perform_enqueued_jobs { click_on 'Déposer le dossier' } + perform_enqueued_jobs do + fill_in 'Le code postal', with: code_postal + wait_for_autosave + end end + click_on 'Déposer le dossier' + visit demande_dossier_path(dossier) expect(page).to have_content(/Des données.*ont été reçues depuis la CAF/) @@ -329,21 +330,24 @@ describe 'fetch API Particulier Data', js: true do click_button('Continuer') fill_in "Identifiant", with: 'wrong code' - - blur - expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true) + wait_for_autosave dossier = Dossier.last pole_emploi_champ = dossier.champs.find(&:pole_emploi?) expect(pole_emploi_champ.identifiant).to eq('wrong code') - - fill_in "Identifiant", with: identifiant + clear_enqueued_jobs + pole_emploi_champ.update(external_id: nil, identifiant: nil) VCR.use_cassette('api_particulier/success/situation_pole_emploi') do - perform_enqueued_jobs { click_on 'Déposer le dossier' } + perform_enqueued_jobs do + fill_in "Identifiant", with: identifiant + wait_until { pole_emploi_champ.reload.external_id.present? } + end end + click_on 'Déposer le dossier' + visit demande_dossier_path(dossier) expect(page).to have_content(/Des données.*ont été reçues depuis Pôle emploi/) @@ -397,21 +401,24 @@ describe 'fetch API Particulier Data', js: true do click_button('Continuer') fill_in "INE", with: 'wrong code' - - blur - expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true) + wait_for_autosave dossier = Dossier.last mesri_champ = dossier.champs.find(&:mesri?) expect(mesri_champ.ine).to eq('wrong code') - - fill_in "INE", with: ine + clear_enqueued_jobs + mesri_champ.update(external_id: nil, ine: nil) VCR.use_cassette('api_particulier/success/etudiants') do - perform_enqueued_jobs { click_on 'Déposer le dossier' } + perform_enqueued_jobs do + fill_in "INE", with: ine + wait_until { mesri_champ.reload.external_id.present? } + end end + click_on 'Déposer le dossier' + visit demande_dossier_path(dossier) expect(page).to have_content(/Des données.*ont été reçues depuis le MESRI/) @@ -457,9 +464,7 @@ describe 'fetch API Particulier Data', js: true do fill_in 'Le numéro fiscal', with: numero_fiscal fill_in "La référence d'avis d'imposition", with: 'wrong_code' - - blur - expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true) + wait_for_autosave dossier = Dossier.last dgfip_champ = dossier.champs.find(&:dgfip?) @@ -469,12 +474,15 @@ describe 'fetch API Particulier Data', js: true do click_on 'Déposer le dossier' expect(page).to have_content(/reference avis doit posséder 13 ou 14 caractères/) - fill_in "La référence d'avis d'imposition", with: reference_avis - VCR.use_cassette('api_particulier/success/avis_imposition') do - perform_enqueued_jobs { click_on 'Déposer le dossier' } + perform_enqueued_jobs do + fill_in "La référence d'avis d'imposition", with: reference_avis + wait_for_autosave + end end + click_on 'Déposer le dossier' + visit demande_dossier_path(dossier) expect(page).to have_content(/Des données.*ont été reçues depuis la DGFiP/) diff --git a/spec/system/routing/full_scenario_spec.rb b/spec/system/routing/full_scenario_spec.rb index 0556a4c07..7ffe7c2c8 100644 --- a/spec/system/routing/full_scenario_spec.rb +++ b/spec/system/routing/full_scenario_spec.rb @@ -120,8 +120,8 @@ describe 'The routing', js: true do click_on 'Modifier mon dossier' fill_in litteraire_user.dossiers.first.champs.first.libelle, with: 'some value' - blur - expect(page).to have_css('span', text: 'Dossier enregistré', visible: true) + wait_for_autosave(false) + log_out # the litteraires instructeurs should have a notification @@ -199,6 +199,7 @@ describe 'The routing', js: true do click_button('Continuer') select(groupe, from: 'dossier_groupe_instructeur_id') + wait_for_autosave click_on 'Déposer le dossier' expect(page).to have_text('Merci') @@ -215,7 +216,8 @@ describe 'The routing', js: true do expect(page).not_to have_selector("option", text: "Groupe inactif") select(new_group, from: 'dossier_groupe_instructeur_id') - expect(page).to have_css('span', text: 'Dossier enregistré', visible: true) + wait_for_autosave(false) + expect(page).to have_text(new_group) log_out diff --git a/spec/system/users/brouillon_spec.rb b/spec/system/users/brouillon_spec.rb index 062b39913..45868d19c 100644 --- a/spec/system/users/brouillon_spec.rb +++ b/spec/system/users/brouillon_spec.rb @@ -43,8 +43,7 @@ describe 'The user' do find('.editable-champ-piece_justificative input[type=file]').attach_file(Rails.root + 'spec/fixtures/files/file.pdf') expect(page).to have_css('span', text: 'Votre brouillon est automatiquement enregistré', visible: true) - blur - expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true) + wait_for_autosave # check data on the dossier expect(user_dossier.brouillon?).to be true @@ -116,18 +115,14 @@ describe 'The user' do end expect(page).to have_content('Supprimer', count: 2) - - blur - expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true) + wait_for_autosave expect(page).to have_content('Supprimer', count: 2) within '.repetition .row:first-child' do click_on 'Supprimer l’élément' end - - blur - expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true) + wait_for_autosave expect(page).to have_content('Supprimer', count: 1) end @@ -140,8 +135,8 @@ describe 'The user' do # Check an incomplete dossier can be saved as a draft, even when mandatory fields are missing fill_in('texte optionnel', with: 'ça ne suffira pas') - blur - expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true) + wait_for_autosave + expect(page).to have_current_path(brouillon_dossier_path(user_dossier)) # Check an incomplete dossier cannot be submitted when mandatory fields are missing @@ -151,6 +146,7 @@ describe 'The user' do # Check a dossier can be submitted when all mandatory fields are filled fill_in('texte obligatoire', with: 'super texte') + wait_for_autosave click_on 'Déposer le dossier' expect(user_dossier.reload.en_construction?).to be(true) @@ -370,8 +366,7 @@ describe 'The user' do expect(page).to have_no_css('label', text: 'tonnage', visible: true) fill_in('age', with: '18') - blur - expect(page).to have_css('span', text: 'Dossier enregistré', visible: true) + wait_for_autosave(false) # the champ keeps their previous value so they are all displayed expect(page).to have_css('label', text: 'permis de conduire', visible: true) @@ -389,9 +384,7 @@ describe 'The user' do expect(page).to have_content('Votre brouillon est automatiquement enregistré') fill_in('texte obligatoire', with: 'a valid user input') - blur - - expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true) + wait_for_autosave visit current_path expect(page).to have_field('texte obligatoire', with: 'a valid user input') @@ -410,7 +403,7 @@ describe 'The user' do # Test that retrying after a failure works allow_any_instance_of(Users::DossiersController).to receive(:update_brouillon).and_call_original click_on 'réessayer' - expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true) + wait_for_autosave visit current_path expect(page).to have_field('texte obligatoire', with: 'a valid user input') @@ -434,8 +427,7 @@ describe 'The user' do expect(page).to have_current_path(brouillon_dossier_path(user_dossier)) fill_in('texte obligatoire', with: 'a valid user input') - blur - expect(page).to have_css('span', text: 'Brouillon enregistré', visible: true) + wait_for_autosave end end diff --git a/spec/system/users/dossier_shared_examples.rb b/spec/system/users/dossier_shared_examples.rb index 35e7c418c..1f212d450 100644 --- a/spec/system/users/dossier_shared_examples.rb +++ b/spec/system/users/dossier_shared_examples.rb @@ -10,8 +10,7 @@ RSpec.shared_examples 'the user can edit the submitted demande' do expect(page).to have_current_path(modifier_dossier_path(dossier)) fill_in('Texte obligatoire', with: 'Nouveau texte') - blur - expect(page).to have_css('span', text: 'Dossier enregistré', visible: true) + wait_for_autosave(false) click_on 'Demande' expect(page).to have_current_path(demande_dossier_path(dossier))