Validation de composants personnalisés avec le point de terminaison REST

This page is not available in the language you requested. You have been redirected to the English version of the page.
Link to this page copied to clipboard

Un guide pour utiliser Axe DevTools Linter pour valider des composants personnalisés avec le point de terminaison REST

Free Trial
Not for use with personal data

Cet article montre comment utiliser le point de terminaison REST d'Axe DevTools Linter pour détecter des erreurs d'accessibilité dans des composants personnalisés.

important

Cet article s'adresse aux utilisateurs du point de terminaison REST d'Axe DevTools Linter. Si vous utilisez l'extension Axe Accessibility Linter pour VS Code ou le plugin pour JetBrains, consultez Validation de composants personnalisés avec l’extension Axe Accessibility Linter pour VS Code ou le Plugin pour JetBrains pour plus d'informations.

Prérequis

Vous aurez besoin d'accéder soit à la version SaaS, soit à une version sur site d'Axe DevTools Linter. Voir Obtenir une clé API SaaS Axe DevTools Linter ou Configuration de l'édition sur site d'Axe DevTools Linter pour plus d'informations.

Vous aurez également besoin d'un outil REST qui :

  • Peut envoyer des requêtes POST
  • Peut ajouter des en-têtes Authorization (pour la version SaaS d'Axe DevTools Linter)
  • Permet de créer des corps de requêtes JSON

Guide de validation d'un composant personnalisé

Lorsque vous utilisez Axe DevTools Linter pour valider du code source, vous fournissez un corps JSON contenant le code source et la configuration dans votre requête HTTP. Par exemple, le HTML suivant montre l'utilisation de l'élément img :

<img src="path/to/image.jpg"/>

(Ceci est un exemple grandement simplifié uniquement pour démontrer la validation plutôt qu'un exemple réel.)

Le corps JSON de la requête à envoyer à Axe DevTools Linter ressemblerait à ceci :

{ 
  "source": "<img src=\"path/to/image.jpg\"/>",
  "filename": "image-demo.html"
}
note

Vous envoyez ce JSON à Axe DevTools Linter en tant que requête POST REST au point de terminaison /linter-source. Pour plus d'informations, voir Le point de terminaison de validation dans la documentation de référence.

Pour suivre ce guide, vous pouvez utiliser n'importe quel outil REST capable d'envoyer des requêtes POST avec des corps de requête JSON. Les exemples suivants montrent le corps de la requête envoyé à Axe DevTools Linter et le corps de la réponse JSON, qui montre les erreurs d'accessibilité trouvées par Axe DevTools Linter.

Parce que cet élément img n'a pas d'attribut alt, vous obtiendrez une erreur d'accessibilité d'Axe DevTools Linter :

{
  "report": {
    "errors": [
      {
        "column": 1,
        "description": "Ensures <img> elements have alternate text or a role of none or presentation",
        "endColumn": 31,
        "helpURL": "https://dequeuniversity.com/rules/axe/4.4/image-alt?application=axe-linter",
        "lineContent": "<img src=\"path/to/image.jpg\"/>",
        "lineNumber": 1,
        "linterType": "html",
        "ruleId": "image-alt"
      }
    ]
  }
}

Un composant d'image personnalisé

L'exemple suivant montre un exemple de composant personnalisé custom-image :

<custom-image src="path/to/image.jpg"></custom-image>

Pour envoyer le HTML à Axe DevTools Linter via une requête POST, utilisez ce qui suit comme corps JSON :

{
  "source": "<custom-image src=\"path/to/image.jpg\"></custom-image>",
  "filename": "custom-image.html"
}

Le serveur répond sans erreurs d'accessibilité car il n'y a pas de correspondance entre custom-image et img, donc Axe DevTools Linter ne peut pas signaler un attribut alt manquant :

{
  "report": {
    "errors": []
  }
}

Mappage de custom-image vers img

Si vous fournissez un mappage entre custom-image et img, Axe DevTools Linter peut mapper votre composant personnalisé comme un élément HTML standard et localiser les erreurs d'accessibilité. Vous pouvez spécifier le mappage en utilisant l'option de configuration global-components (faisant partie de l'objet config) :

{
  "config": {
    "global-components": {
      "custom-image": "img"
    }
  },
  "filename": "c-image.html",
  "source": "<custom-image src=\"path/to/image.jpg\"></custom-image>\n\n"
}

Axe DevTools Linter répond désormais comme suit :

{
  "report": {
    "errors": [
      {
        "column": 1,
        "description": "Ensures <img> elements have alternate text or a role of none or presentation",
        "endColumn": 54,
        "helpURL": "https://dequeuniversity.com/rules/axe/4.4/image-alt?application=axe-linter",
        "lineContent": "<custom-image src=\"path/to/image.jpg\"></custom-image>",
        "lineNumber": 1,
        "linterType": "html",
        "ruleId": "image-alt"
      }
    ]
  }
}

Vous pouvez également indiquer le même mappage qu'au-dessus avec l'une des syntaxes suivantes :

{
  "config": {
    "global-components": {
      "custom-image": {
        "element": "img"
      }
    }
  }
}

Ou, alternativement, en abrégant element en el :

{
  "config": {
    "global-components": {
      "custom-image": {
        "el": "img"
      }
    }
  }
}
important

Lorsque vous utilisez un mappage d'éléments comme montré ci-dessus, tous les attributs du composant personnalisé sont copiés vers l'élément émis, et cet élément émis est validé.

Correction du problème d'accessibilité

Vous pouvez ajouter un attribut alt à votre custom-image pour résoudre le problème d'accessibilité (comme montré ci-dessous avec le corps JSON de la requête) :

{
  "config": {
    "global-components": {
      "custom-image": "img"
    }
  },
  "filename": "c-image.html",
  "source": "<custom-image src=\"path/to/image.jpg\" alt=\"alt text\"></custom-image>\n\n"
}

Le serveur répond avec le tableau vide errors car votre composant personnalisé possède l'attribut requis alt (qui a été copié—avec tous autres attributs sur le composant custom-image—vers l'élément émis img) :

{
  "report": {
    "errors": []
  }
}

Mappage de l'attribut alternative-text

Si votre composant d'image personnalisé utilise plutôt un attribut différent pour indiquer le texte alternatif, vous pouvez spécifier cet attribut dans la configuration. Par exemple, supposons que votre composant custom-image utilise un attribut alternative-text au lieu de alt, comme montré ci-dessous :

<custom-image src="path/to/image.jpg" alternative-text="alt text"></custom-image>

Dans ce cas, vous pourriez spécifier un mappage entre l'attribut alternative-text et l'attribut alt comme montré avec le tableau attributes dans le corps de la requête JSON ci-dessous :

{
  "config": {
    "global-components": {
      "custom-image": {
        "element": "img",
        "attributes": [
          {
            "alternative-text": "alt"
          }
        ]
      }
    }
  },
  "filename": "c-image.html",
  "source": "<custom-image src=\"path/to/image.jpg\" alternative-text=\"alt text\"></custom-image>\n\n"
}
note

Notez que la configuration global-components diffère légèrement du mappage précédent d'un composant personnalisé à un élément HTML. Avec seulement les éléments, vous utilisez un mappage d'une chaîne ("custom-image") à une autre chaîne ("img"). Avec l'inclusion du tableau attributes, vous êtes maintenant tenu d'utiliser la propriété element (ou el) pour spécifier l'élément HTML émis.

Axe DevTools Linter répond comme suit car la règle alt-text a été satisfaite par votre attribut alternative-text :

{
  "report": {
    "errors": []
  }
}
important

Parce que vous avez spécifié le tableau attributes dans la configuration, lorsque le serveur effectue le mappage de custom-image à img, seuls les attributs spécifiés dans le tableau attributes sont copiés vers l'élément HTML émis.

Vous pouvez également abréger attributes en attrs :

{
  "config": {
    "global-components": {
      "custom-image": {
        "attrs": [
          {
            "alternative-text": "alt"
          }
        ],
        "element": "img"
      }
    }
  }
}

Valeurs d'attributs spéciales : <text>, aria-* et <element>

Supposons que vous utilisiez un composant custom-button comme suit :

<custom-button aria-controls="expand-region" aria-expanded="false" aria-colindex="1" message="Show Region"></custom-button>

(Le bouton personnalisé, en utilisant JavaScript et CSS qui ne sont pas inclus ici, cachera et affichera un div.)

Il y a deux problèmes avec cette utilisation :

  1. Si vous mappez ce composant custom-button directement à un élément button, il n'y aura pas de contenu textuel à afficher sur le bouton. L'intention de l'auteur du composant est cependant que l'attribut message soit utilisé comme contenu textuel : <button> valeur de l'attribut message </button>
  2. L'élément button émis a un rôle implicite de button, donc l'attribut aria-colindex est incorrect et doit être supprimé.

Si vous envoyez le code ci-dessus à Axe DevTools Linter (sans mappage global-components), vous recevez cette réponse :

{
  "report": {
    "errors": []
  }
}

La valeur spéciale <text>

Pour résoudre le premier problème (le contenu textuel de l'élément button provenant d’un attribut message), vous pouvez utiliser la valeur spéciale <text> qui associe un attribut au contenu textuel de l'élément émis. Dans ce cas, le texte de l'attribut message doit être copié dans le contenu textuel de l'élément button émis.

Pour configurer la requête afin d'alerter Axe DevTools Linter que l'attribut message doit être considéré comme le contenu textuel de l'élément HTML button, vous pouvez utiliser la valeur spéciale <text> et envoyer la requête suivante :

{
  "config": {
    "global-components": {
      "custom-button": {
        "attributes": [
          {
            "message": "<text>"
          }
        ],
        "element": "button"
      }
    }
  },
  "filename": "aria-button.html",
  "source": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>\n"
}

Parce que vous avez défini l'attribut message comme <text>, vous avez indiqué à Axe DevTools Linter de considérer cet attribut comme remplaçant le contenu textuel de l'élément HTML button par la valeur de l'attribut message.

Malheureusement, en utilisant le tableau attributes, le seul attribut transmis à l'élément button émis était uniquement l'attribut message ; tout attribut non présent dans le tableau attributes n'est pas transmis. Cela signifie que le aria-colindex incorrect n'a pas été détecté par le serveur.

Utilisation de aria-*

Vous pouvez utiliser la valeur spéciale aria-* pour transmettre tous les attributs ARIA, comme illustré ci-dessous :

{
  "config": {
    "global-components": {
      "custom-button": {
        "attributes": [
          {
            "message": "<text>"
          },
          "aria-*"
        ],
        "element": "button"
      }
    }
  },
  "filename": "aria-button.html",
  "source": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>\n"
}

Le serveur répond avec :

{
  "report": {
    "errors": [
      {
        "column": 1,
        "description": "Ensures ARIA attributes are allowed for an element's role",
        "endColumn": 124,
        "helpURL": "https://dequeuniversity.com/rules/axe/4.4/aria-allowed-attr?application=axe-linter",
        "lineContent": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>",
        "lineNumber": 1,
        "linterType": "html",
        "ruleId": "aria-allowed-attr"
      }
    ]
  }
}

Cette erreur se produit car l'élément button a une role="button" implicite et l'utilisation de aria-colindex est invalide avec les boutons. Avec aria-*, tous les attributs ARIA sont copiés dans l'élément émis ; cela inclut la copie de l'attribut aria-colindex invalide.

<element>

Avec des composants complexes, vous pourriez vouloir émettre un élément HTML différent de l'élément par défaut dans certains cas spécifiques. Par exemple, vous pourriez avoir un composant de bouton qui se comporte généralement comme un bouton et, dans d'autres états, comme une image de remplacement. La valeur <element> vous permet de spécifier un attribut sur votre composant personnalisé qui détermine l'élément émis.

{  
  "config": {
    "global-components": {
      "my-button": {
        "element": "button",
        "attributes": [
         {
          "use": "<element>"
         },
         'src',
         'alt'
        ]
      } 
    }
  },

  "filename": "aria-button.html",
  "source": "<my-button use=\"img\" src=\"globe.jpg\"></my-button>"
}

Dans ce cas, l'attribut use sur le composant my-button indique l'élément à émettre. Comme l'élément img émis ne contient pas d'attribut alt, vous recevrez une erreur :

{
  "report": {
    "errors": [
      {
        "ruleId": "image-alt",
        "helpURL": "https://dequeuniversity.com/rules/axe/4.10/image-alt?application=axe-linter",
        "description": "Images must have alternative text",
        "lineNumber": 1,
        "column": 1,
        "linterType": "html",
        "lineContent": "<my-button use=\"img\" src=\"globe.jpg\"></my-button>",
        "endColumn": 50
      }
    ]
  }
}

Passage implicite de tous les attributs

Notez que si vous n'utilisiez que le mappage des éléments (où le mappage n'utilise pas le tableau attributes), tous les attributs seraient, par défaut, copiés dans l'élément button comme illustré ci-dessous :

{
  "config": {
    "global-components": {
      "custom-button": "button"
    }
  },
  "filename": "aria-button.html",
  "source": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>\n"
}

Avec cette réponse serveur, vous pouvez voir que tous les attributs de custom-button sont vérifiés pour des problèmes d'accessibilité, et deux erreurs sont trouvées :

{
  "report": {
    "errors": [
      {
        "column": 1,
        "description": "Ensures ARIA attributes are allowed for an element's role",
        "endColumn": 124,
        "helpURL": "https://dequeuniversity.com/rules/axe/4.4/aria-allowed-attr?application=axe-linter",
        "lineContent": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>",
        "lineNumber": 1,
        "linterType": "html",
        "ruleId": "aria-allowed-attr"
      },
      {
        "column": 1,
        "description": "Ensures buttons have discernible text",
        "endColumn": 124,
        "helpURL": "https://dequeuniversity.com/rules/axe/4.4/button-name?application=axe-linter",
        "lineContent": "<custom-button aria-controls=\"expand-region\" aria-expanded=\"false\" aria-colindex=\"1\" message=\"Show Region\"></custom-button>",
        "lineNumber": 1,
        "linterType": "html",
        "ruleId": "button-name"
      }
    ]
  }
}

L'exemple ci-dessus montre qu'un premier pas pratique lors du démarrage de l'analyse de composants personnalisés serait de commencer par un mappage d'éléments (copiant ainsi tous les attributs vers l'élément HTML standard émis) puis de voir quels attributs doivent être ajoutés à la configuration (que les attributs du composant personnalisé doivent être mappés à différents attributs ou si vous devez utiliser <text> ou aria-*).

Attributs par défaut

Les attributs par défaut vous permettent de définir des valeurs pour des attributs dans votre fichier de configuration plutôt que de mapper un attribut à un autre. Par exemple, la configuration d'exemple suivante montre un composant custom-menu mappé à un élément li avec un role de menu :

{
  "config": {
    "global-components": {
      "custom-menu": {
        "element": "li",
        "attributes": [
          {
            "role": {
              "name": null,
              "default": "menu"
            }
          }
        ]
      }
    }
  }
}

Parce que l'attribut role a une valeur par défaut de menu, définie dans le fichier de configuration, les utilisateurs n'ont pas besoin de spécifier un attribut role lorsqu'ils utilisent le composant custom-menu dans leur code. L'implication est que l'implémentation de votre composant personnalisé crée ces attributs sur l'élément de sortie et définit leurs valeurs plutôt que d'exiger des utilisateurs qu'ils les définissent lorsqu'ils utilisent votre composant.

Facultativement, la valeur name est définie sur null dans la configuration, ce qui amène Axe DevTools Linter à ignorer tout attribut role que les utilisateurs ont spécifié sur custom-menu dans le code analysé.

note

La valeur spécifiée avec default doit être une chaîne de caractères.

Analyse des violations de composants personnalisés

Lorsque vous avez de nombreux composants personnalisés configurés, il peut être difficile de déterminer quelles violations dans la réponse proviennent des mappages de composants personnalisés par opposition au HTML standard. Ajouter "properties": ["customName"] à votre corps de requête amène Axe DevTools Linter à inclure une propriété customName sur chaque erreur provenant d'un composant mappé personnalisé.

En se basant sur l'exemple custom-image ci-dessus, ajouter "properties": ["customName"] à la requête :

{
  "properties": ["customName"],
  "config": {
    "global-components": {
      "custom-image": "img"
    }
  },
  "filename": "c-image.html",
  "source": "<custom-image src=\"path/to/image.jpg\"></custom-image>\n\n"
}

La réponse inclut désormais une propriété customName sur l'erreur montrant quel composant personnalisé a déclenché la violation :

{
  "report": {
    "errors": [
      {
        "column": 1,
        "customName": "custom-image",
        "description": "Ensures <img> elements have alternate text or a role of none or presentation",
        "endColumn": 54,
        "helpURL": "https://dequeuniversity.com/rules/axe/4.4/image-alt?application=axe-linter",
        "lineContent": "<custom-image src=\"path/to/image.jpg\"></custom-image>",
        "lineNumber": 1,
        "linterType": "html",
        "ruleId": "image-alt"
      }
    ]
  }
}

Les erreurs provenant de composants qui ne font pas partie d'un mappage personnalisé n'auront pas de propriété customName.

Voir aussi