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 @@ Bloc-marque Ademe & République française {% 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 %}