From 2e538387ecaa504e6bcffccc894a5a7b2ef07214 Mon Sep 17 00:00:00 2001
From: Fabien Le Frapper
Date: Mon, 20 Jan 2025 16:02:03 +0100
Subject: [PATCH] Accessibilite (#1230)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Accessiblite
- Dé-commenter les tests d'intégration
- Corriger soucis d'accessibilité détectés
- Ajouter fixtures pour les déchets
---
.github/workflows/run_tests.yml | 2 +-
Makefile | 4 ++
e2e_tests/accessibility.spec.ts | 66 ++++++++++++++-----
jinja2/qfdmo/shared/main.html | 1 +
qfdmd/fixtures/produits.json | 21 ++++++
qfdmd/fixtures/synonymes.json | 19 ++++++
.../entrypoints/assistant/script-to-iframe.ts | 1 +
templates/components/footer/_standalone.html | 2 +-
templates/components/header/header.html | 1 +
templates/components/logo/_base.html | 7 ++
templates/components/produit/_detail.html | 1 +
templates/components/search/view.html | 1 +
templates/components/sidebar/action.html | 2 +-
13 files changed, 107 insertions(+), 21 deletions(-)
create mode 100644 qfdmd/fixtures/produits.json
create mode 100644 qfdmd/fixtures/synonymes.json
diff --git a/.github/workflows/run_tests.yml b/.github/workflows/run_tests.yml
index 97f269235..ecf569a1d 100644
--- a/.github/workflows/run_tests.yml
+++ b/.github/workflows/run_tests.yml
@@ -124,7 +124,7 @@ jobs:
- name: Populate database
run: |
- python manage.py loaddata actions acteur_services acteur_types categories objets
+ python manage.py loaddata actions acteur_services acteur_types categories objets produits synonymes
- name: Run serveur
run: |
diff --git a/Makefile b/Makefile
index eb4ea0156..7b24f030c 100644
--- a/Makefile
+++ b/Makefile
@@ -131,6 +131,10 @@ e2e-test:
npx playwright test
$(PYTEST) ./integration_tests
+.PHONY: a11y
+a11y:
+ npx playwright test --reporter=list ./e2e_tests/accessibility.spec.ts
+
.PHONY: js-test
js-test:
npm run test
diff --git a/e2e_tests/accessibility.spec.ts b/e2e_tests/accessibility.spec.ts
index 08ba4f276..e0a4435d1 100644
--- a/e2e_tests/accessibility.spec.ts
+++ b/e2e_tests/accessibility.spec.ts
@@ -1,24 +1,54 @@
-import { AxeBuilder } from "@axe-core/playwright"
-import { expect, test } from "@playwright/test"
+import { AxeBuilder } from "@axe-core/playwright";
+import { expect, test } from "@playwright/test";
-// test("formulaire iFrame is WCAG compliant", async ({ page }) => {
-// await page.goto(`http://localhost:8000/test_iframe`, { waitUntil: "networkidle" })
+// Shared variables
+const BASE_URL = "http://localhost:8000";
+const WCAG_TAGS = ["wcag2a", "wcag2aa", "wcag21a", "wcag21aa"];
+const IFRAME_SELECTOR = "iframe";
-// const accessibilityScanResults = await new AxeBuilder({ page })
-// .include("iframe") // restriction du scan à l'iframe uniquement
-// .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa']) // TODO : trouver quelle règle se rapproche le plus du RGAA
-// .analyze()
+test.describe("WCAG Compliance Tests", () => {
+ test("Formulaire iFrame | Desktop", async ({ page }) => {
+ await page.goto(`${BASE_URL}/test_iframe`, { waitUntil: "networkidle" });
-// expect(accessibilityScanResults.violations).toEqual([])
-// })
+ const accessibilityScanResults = await new AxeBuilder({ page })
+ .include(IFRAME_SELECTOR) // Restrict scan to the iframe
+ .withTags(WCAG_TAGS)
+ .analyze();
-// test("carte iFrame is WCAG compliant", async ({ page }) => {
-// await page.goto(`http://localhost:8000/test_iframe?carte`, { waitUntil: "networkidle" })
+ expect(accessibilityScanResults.violations).toEqual([]);
+ });
-// const accessibilityScanResults = await new AxeBuilder({ page })
-// .include("iframe") // restriction du scan à l'iframe uniquement
-// .withTags(['wcag2a', 'wcag2aa', 'wcag21a', 'wcag21aa']) // TODO : trouver quelle règle se rapproche le plus du RGAA
-// .analyze()
+ test("Carte iFrame | Desktop", async ({ page }) => {
+ await page.goto(`${BASE_URL}/test_iframe?carte`, { waitUntil: "networkidle" });
-// expect(accessibilityScanResults.violations).toEqual([])
-// })
+ const accessibilityScanResults = await new AxeBuilder({ page })
+ .include(IFRAME_SELECTOR) // Restrict scan to the iframe
+ .withTags(WCAG_TAGS)
+ .analyze();
+
+ expect(accessibilityScanResults.violations).toEqual([]);
+ });
+
+ test("Assistant Homepage | Desktop", async ({ page }) => {
+ // TODO: Update the route for production
+ await page.goto(`${BASE_URL}/dechet`, { waitUntil: "networkidle" });
+
+ const accessibilityScanResults = await new AxeBuilder({ page })
+ .exclude("[data-disable-axe]")
+ .withTags(WCAG_TAGS)
+ .analyze();
+
+ expect(accessibilityScanResults.violations).toEqual([]);
+ });
+
+ test("Assistant Detail Page | Desktop", async ({ page }) => {
+ await page.goto(`${BASE_URL}/smartphone`, { waitUntil: "networkidle" });
+
+ const accessibilityScanResults = await new AxeBuilder({ page })
+ .exclude("[data-disable-axe]")
+ .withTags(WCAG_TAGS)
+ .analyze();
+
+ expect(accessibilityScanResults.violations).toEqual([]);
+ });
+});
diff --git a/jinja2/qfdmo/shared/main.html b/jinja2/qfdmo/shared/main.html
index e7be3df6f..cbff12a9a 100644
--- a/jinja2/qfdmo/shared/main.html
+++ b/jinja2/qfdmo/shared/main.html
@@ -47,6 +47,7 @@
{# Is useful for digital view so that the users can scrol in the results #}
qf-overflow-scroll
"
+ tabindex="0"
>
{% block form_result %}
\nRetrouvez des conseils d'entretien de votre téléphone pour prolonger sa durée de vie sur la Bible de l'entretien des objets.",
+ "que_va_t_il_devenir": "Remis à une structure de réemploi ou revendu, votre appareil poursuit une seconde vie. Déposé en déchèterie ou remis à un revendeur, il suit la filière des Déchets d'Équipements Électriques et Électroniques (DEEE). Il est alors acheminé jusqu'à un centre de traitement où il est démantelé et ses différents composants recyclables récupérés (métaux et plastiques). Les substances non-recyclables sont incinérées (avec le plus souvent récupération de chaleur pour produire de l'énergie) ou enfouies dans des installations de stockage de déchets.",
+ "nom": "Téléphone mobile",
+ "synonymes_existants": "Smartphone",
+ "code": "DEEE",
+ "bdd": "ocad3e",
+ "qu_est_ce_que_j_en_fais": "S'il est encore en bon état, donnez-le à une association caritative ou un proche, ou bien revendez-le.
S’il est en panne, privilégiez la réparation. Certains réparateurs peuvent même vous faire bénéficier d'une réduction via le Bonus Réparation.\n
Qu'il soit hors service ou encore fonctionnel vous pouvez :
-\tle déposer en boutique de téléphonie ou le renvoyer via le service de reprise à distance de votre opérateur.
-\tl'envoyer par correspondance grâce aux services de certains éco-organismes (voir \"En savoir plus\" ci-dessous).
\nSinon, apportez-le en déchèterie.",
+ "nom_eco_organisme": "Ecologic / Ecosystem",
+ "filieres_rep": "Equipements électriques et électroniques",
+ "slug": "Téléphone mobile"
+ }
+}
+]
diff --git a/qfdmd/fixtures/synonymes.json b/qfdmd/fixtures/synonymes.json
new file mode 100644
index 000000000..1c3f5d2a7
--- /dev/null
+++ b/qfdmd/fixtures/synonymes.json
@@ -0,0 +1,19 @@
+[
+{
+ "model": "qfdmd.synonyme",
+ "pk": 1915,
+ "fields": {
+ "modifie_le": "2025-01-14T17:45:28.807Z",
+ "qu_est_ce_que_j_en_fais_mauvais_etat": "",
+ "qu_est_ce_que_j_en_fais_bon_etat": "",
+ "comment_les_eviter": "",
+ "que_va_t_il_devenir": "",
+ "slug": "smartphone",
+ "nom": "Smartphone",
+ "produit": 334,
+ "picto": "",
+ "pin_on_homepage": false,
+ "meta_description": ""
+ }
+}
+]
diff --git a/static/to_compile/entrypoints/assistant/script-to-iframe.ts b/static/to_compile/entrypoints/assistant/script-to-iframe.ts
index 96cde9357..69585a86b 100644
--- a/static/to_compile/entrypoints/assistant/script-to-iframe.ts
+++ b/static/to_compile/entrypoints/assistant/script-to-iframe.ts
@@ -11,6 +11,7 @@ const iframeAttributes = {
style: "border: none; width: 100%; display: block; margin: 0 auto;",
allowfullscreen: true,
allow: "geolocation; clipboard-write",
+ title: "Que faire de mes objets et déchets"
};
if (script?.dataset?.testid) {
diff --git a/templates/components/footer/_standalone.html b/templates/components/footer/_standalone.html
index db0b562ad..2656429db 100644
--- a/templates/components/footer/_standalone.html
+++ b/templates/components/footer/_standalone.html
@@ -11,7 +11,7 @@ Comment réduire ses déchets ?
.
-
+
diff --git a/templates/components/header/header.html b/templates/components/header/header.html
index 3cbb55bb4..65885d501 100644
--- a/templates/components/header/header.html
+++ b/templates/components/header/header.html
@@ -8,6 +8,7 @@
{% if not assistant.is_home %}
{% include "components/logo/animated.html" %}
diff --git a/templates/components/logo/_base.html b/templates/components/logo/_base.html
index 8847446a1..d6e1f7a55 100644
--- a/templates/components/logo/_base.html
+++ b/templates/components/logo/_base.html
@@ -2,4 +2,11 @@
data-controller="blink"
data-blink-words-value='["objets"]'
class="qf-text-green-menthe-sun-373-moon-652-hover"
+ {% comment %}
+ This tag is excluded from our automated axe accessibilty tests because
+ it triggers a false positive. Its contrast is sufficient at 4.62 for
+ a big title, but for some reason Axe does not detect that the text
+ here is displayed in a large font-size.
+ {% endcomment %}}
+ data-disable-axe
>déchets{% include "./_cursor.html" %}?
diff --git a/templates/components/produit/_detail.html b/templates/components/produit/_detail.html
index 595394d4f..d56a4097c 100644
--- a/templates/components/produit/_detail.html
+++ b/templates/components/produit/_detail.html
@@ -13,6 +13,7 @@ Où l'apporter ?
{% endif %}
diff --git a/templates/components/search/view.html b/templates/components/search/view.html
index 585029346..009b82856 100644
--- a/templates/components/search/view.html
+++ b/templates/components/search/view.html
@@ -27,6 +27,7 @@
{% csrf_token %}