diff --git a/Gemfile b/Gemfile
index 9c558d0f6..993727c80 100644
--- a/Gemfile
+++ b/Gemfile
@@ -109,6 +109,7 @@ group :development do
 end
 
 group :development, :test do
+  gem 'axe-matchers' # accessibility rspec matchers
   gem 'byebug' # Call 'byebug' anywhere in the code to stop execution and get a debugger console
   gem 'graphql-schema_comparator'
   gem 'mina', git: 'https://github.com/mina-deploy/mina.git', require: false # Deploy
diff --git a/Gemfile.lock b/Gemfile.lock
index 99c5c2955..efd583670 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -97,6 +97,13 @@ GEM
     attr_required (1.0.1)
     autoprefixer-rails (9.7.4)
       execjs
+    axe-matchers (2.6.1)
+      dumb_delegator (~> 0.8)
+      virtus (~> 1.0)
+    axiom-types (0.1.1)
+      descendants_tracker (~> 0.0.4)
+      ice_nine (~> 0.11.0)
+      thread_safe (~> 0.3, >= 0.3.1)
     axlsx_styler (1.0.0)
       activesupport (>= 3.1)
       caxlsx (>= 2.0.2)
@@ -146,6 +153,8 @@ GEM
     chunky_png (1.3.11)
     clamav-client (3.1.0)
     coderay (1.1.2)
+    coercible (1.0.0)
+      descendants_tracker (~> 0.0.1)
     coffee-rails (4.2.2)
       coffee-script (>= 2.2.0)
       railties (>= 4.0.0)
@@ -179,6 +188,8 @@ GEM
       delayed_job (> 2.0.3)
       rack-protection (>= 1.5.5)
       sinatra (>= 1.4.4)
+    descendants_tracker (0.0.4)
+      thread_safe (~> 0.3, >= 0.3.1)
     devise (4.7.1)
       bcrypt (~> 3.0)
       orm_adapter (~> 0.1)
@@ -198,9 +209,11 @@ GEM
       dotenv (= 2.7.5)
       railties (>= 3.2, < 6.1)
     dry-inflector (0.2.0)
+    dumb_delegator (0.8.1)
     em-websocket (0.5.1)
       eventmachine (>= 0.12.9)
       http_parser.rb (~> 0.6.0)
+    equalizer (0.0.11)
     erubi (1.9.0)
     erubis (2.7.0)
     et-orbi (1.2.4)
@@ -319,6 +332,7 @@ GEM
     httpclient (2.8.3)
     i18n (1.8.3)
       concurrent-ruby (~> 1.0)
+    ice_nine (0.11.2)
     ipaddress (0.8.3)
     jaro_winkler (1.5.4)
     jquery-rails (4.3.5)
@@ -678,6 +692,11 @@ GEM
       activemodel (>= 3.0.0)
       addressable
     vcr (4.0.0)
+    virtus (1.0.5)
+      axiom-types (~> 0.1)
+      coercible (~> 1.0)
+      descendants_tracker (~> 0.0, >= 0.0.3)
+      equalizer (~> 0.0, >= 0.0.9)
     warden (1.2.8)
       rack (>= 2.0.6)
     web-console (3.7.0)
@@ -728,6 +747,7 @@ DEPENDENCIES
   administrate
   after_party
   anchored
+  axe-matchers
   bcrypt
   bootstrap-sass (>= 3.4.1)
   bootstrap-wysihtml5-rails (~> 0.3.3.8)
diff --git a/spec/features/accessibilite/wcag_usager_spec.rb b/spec/features/accessibilite/wcag_usager_spec.rb
new file mode 100644
index 000000000..30064e805
--- /dev/null
+++ b/spec/features/accessibilite/wcag_usager_spec.rb
@@ -0,0 +1,124 @@
+feature 'wcag rules for usager', js: true do
+  let(:procedure) { create(:procedure, :with_type_de_champ, :with_all_champs, :with_service, :for_individual, :published) }
+  let(:password) { 'a very complicated password' }
+  let(:litteraire_user) { create(:user, password: password) }
+
+  context 'pages without the need to be logged in' do
+    scenario 'homepage' do
+      visit root_path
+      expect(page).to be_accessible.excluding ".footer-logo"
+    end
+
+    scenario 'sign_up page' do
+      visit new_user_registration_path
+      expect(page).to be_accessible.excluding ".footer-logo"
+    end
+
+    scenario 'account confirmation page' do
+      visit new_user_registration_path
+
+      fill_in :user_email, with: "some@email.com"
+      fill_in :user_password, with: "epeciusetuir"
+
+      perform_enqueued_jobs do
+        click_button 'Créer un compte'
+        expect(page).to be_accessible.skipping(:'page-has-heading-one', :'role-img-alt', :label)
+      end
+    end
+
+    scenario 'sign_in page' do
+      visit new_user_session_path
+      expect(page).to be_accessible.excluding ".footer-logo", '#user_email'
+    end
+
+    scenario 'contact page' do
+      visit contact_path
+      expect(page).to be_accessible.excluding ".footer-logo"
+    end
+
+    scenario 'commencer page' do
+      visit commencer_path(path: procedure.reload.path)
+      expect(page).to be_accessible
+    end
+  end
+
+  context "logged in, depot d'un dossier as individual" do
+    before do
+      login_as litteraire_user, scope: :user
+      visit commencer_path(path: procedure.reload.path)
+    end
+
+    scenario 'écran identité usager' do
+      click_on 'Commencer la démarche'
+      expect(page).to be_accessible
+    end
+
+    # with no surprise, there's a lot of work on this one
+    scenario "dépot d'un dossier" do
+      click_on 'Commencer la démarche'
+
+      choose 'M.'
+      fill_in('individual_prenom', with: 'prenom')
+      fill_in('individual_nom', with: 'nom')
+      click_on 'Continuer'
+
+      expect(page).to be_accessible.skipping :'aria-input-field-name', :'heading-order', :label
+    end
+  end
+
+  context "logged in, depot d'un dossier entreprise" do
+    let(:procedure) { create(:procedure, :with_type_de_champ, :with_all_champs, :with_service, :published) }
+
+    before do
+      login_as litteraire_user, scope: :user
+      visit commencer_path(path: procedure.reload.path)
+    end
+
+    scenario "écran identification de l'entreprise" do
+      click_on 'Commencer la démarche'
+      expect(page).to be_accessible.skipping :label
+    end
+  end
+
+  context "logged in, avec des dossiers dossiers déposés" do
+    let(:dossier) { create(:dossier, procedure: procedure, user: litteraire_user) }
+    before do
+      login_as litteraire_user, scope: :user
+    end
+
+    scenario 'liste des dossiers' do
+      visit dossiers_path
+      expect(page).to be_accessible
+    end
+
+    scenario 'dossier' do
+      visit dossier_path(dossier)
+      expect(page).to be_accessible.skipping :'heading-order', :label, :'aria-input-field-name'
+    end
+
+    scenario 'merci' do
+      visit merci_dossier_path(dossier)
+      expect(page).to be_accessible
+    end
+
+    scenario 'demande' do
+      visit demande_dossier_path(dossier)
+      expect(page).to be_accessible
+    end
+
+    scenario 'messagerie' do
+      visit messagerie_dossier_path(dossier)
+      expect(page).to be_accessible
+    end
+
+    scenario 'modifier' do
+      visit modifier_dossier_path(dossier)
+      expect(page).to be_accessible.skipping :'aria-input-field-name', :'heading-order', :label
+    end
+
+    scenario 'brouillon' do
+      visit brouillon_dossier_path(dossier)
+      expect(page).to be_accessible.skipping :'aria-input-field-name', :'heading-order', :label
+    end
+  end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 9de69b119..8d9099c30 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -26,6 +26,7 @@ require 'webmock/rspec'
 require 'shoulda-matchers'
 require 'devise'
 require 'factory_bot'
+require 'axe/rspec'
 
 require 'selenium/webdriver'
 Capybara.javascript_driver = :headless_chrome