Linting de componentes personalizados con el endpoint REST

Link to Linting de componentes personalizados con el endpoint REST copied to clipboard

Tutorial sobre cómo usar axe DevTools Linter para lintear componentes personalizados con el punto final REST

Free Trial
Not for use with personal data

Este artículo muestra cómo utilizar el punto final REST de axe DevTools Linter para lintear y encontrar errores de accesibilidad en componentes personalizados.

important

Este artículo es para los usuarios del punto final REST de axe DevTools Linter. Si usa la extensión axe Accessibility Linter para VS Code o el complemento para JetBrains, consulte Linting de componentes personalizados con la extensión axe Accessibility Linter para VS Code o el complemento para JetBrains para obtener más información.

Prerrequisitos

Necesitará acceso a la versión SaaS o a una versión en las instalaciones de axe DevTools Linter. Consulte Obtener una clave de API SaaS de axe DevTools Linter o Configurar la edición local de axe DevTools Linter para obtener más información.

También necesitarás una herramienta REST que:

  • Puede enviar solicitudes POST
  • Puede agregar encabezados (para la versión SaaS de axe DevTools Linter) Authorization
  • Permite crear cuerpos de solicitud JSON

Tutorial sobre el linting de componentes personalizados

Cuando usa axe DevTools Linter para realizar linting en el código fuente, proporciona un cuerpo JSON que contiene el código fuente y la configuración en su solicitud HTTP. Por ejemplo, el siguiente HTML muestra el uso del elemento img :

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

(Este es un ejemplo muy simplificado solo para demostrar el linting en lugar de un ejemplo real).

El cuerpo JSON de la solicitud que se enviará a axe DevTools Linter se vería así:

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

Envía este JSON a axe DevTools Linter como una solicitud REST POST al endpoint /linter-source . Para obtener más información, consulte El endpoint de Lint en la documentación de referencia.

Para seguir este tutorial, puede utilizar cualquier herramienta REST que pueda enviar solicitudes POST con cuerpos de solicitud JSON. Los siguientes ejemplos muestran el cuerpo de la solicitud enviada a axe DevTools Linter y el cuerpo de la respuesta JSON, que muestra los errores de accesibilidad encontrados por axe DevTools Linter.

Debido a que este elemento no tiene un atributo, recibirá un error de accesibilidad de axe DevTools Linter: img alt

{
  "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 componente de imagen personalizado

El siguiente ejemplo muestra un componente personalizado: custom-image

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

Para enviar el HTML a axe DevTools Linter mediante una solicitud POST, utilice lo siguiente como cuerpo JSON:

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

El servidor responde sin errores de accesibilidad porque no hay una asignación entre custom-image y img, por lo que axe DevTools Linter no puede marcar la falta de un atributo alt :

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

Mapeo de custom-image a img

Si proporciona una asignación entre custom-image y img, axe DevTools Linter puede asignar su componente personalizado como un elemento HTML estándar y localizar errores de accesibilidad. Puede especificar la asignación mediante la opción de configuración (parte del objeto): global-components 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 ahora responde con lo siguiente:

{
  "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"
      }
    ]
  }
}

También puede indicar la misma asignación que la anterior con cualquiera de estas sintaxis:

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

O, alternativamente, abreviando element como el:

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

Cuando se utiliza una asignación de elementos como la que se muestra arriba, todos los atributos del componente personalizado se copian al elemento emitido, y ese elemento emitido se somete a linting.

Cómo solucionar el problema de la accesibilidad

Puede agregar un atributo a su alt custom-image para solucionar el problema de accesibilidad (como se muestra a continuación con el cuerpo JSON de la solicitud):

{
  "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"
}

El servidor responde con la siguiente matriz vacía porque su componente personalizado tiene el atributo requerido (que se copió, junto con todos los demás atributos del componente, al elemento emitido): errors alt ** custom-image img

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

Asignación del atributo alternative-text

Si su componente de imagen personalizado utiliza un atributo diferente para indicar texto alternativo, puede especificar ese atributo en la configuración. Por ejemplo, supongamos que su componente usa un atributo en lugar de otro, como se muestra a continuación: custom-image alternative-text alt

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

En este caso, puede especificar una asignación entre el atributo alternative-text y el atributo alt como se muestra con la matriz attributes en el cuerpo de la solicitud JSON que se muestra a continuación:

{
  "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

Tenga en cuenta que la configuración difiere ligeramente de la asignación anterior de un componente personalizado a un elemento HTML. global-components Con elementos, utiliza una asignación de una cadena ("custom-image") a otra cadena ("img"). Con la inclusión de la matriz attributes , ahora debe utilizar la propiedad element (o el) para especificar el elemento HTML emitido.

axe DevTools Linter responde con lo siguiente porque su atributo ha satisfecho la regla: alt-text alternative-text

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

Debido a que especificó la matriz attributes en la configuración, cuando el servidor asigna de custom-image a img, solo los atributos especificados en la matriz attributes se copian al elemento HTML emitido.

También puede abreviar attributes como attrs:

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

Valores de atributos especiales: <text>, aria-* and <element>

Supongamos que utiliza un componente de la siguiente manera: custom-button

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

(El botón personalizado, utilizando JavaScript y CSS que no están incluidos aquí, ocultará y mostrará un div.)

Hay dos problemas con este uso:

  1. Si asigna este componente directamente a un elemento, no se mostrará ningún contenido de texto en el botón. custom-button button Sin embargo, la intención del autor del componente es que el atributo message se utilice como contenido de texto: <button> *valor del atributo message * </button>
  2. El elemento emitido tiene un rol implícito de button , por lo que el atributo es incorrecto y debe eliminarse. button aria-colindex

Si envía el código anterior a axe DevTools Linter (sin asignación), recibirá esta respuesta: global-components

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

El valor especial <text>

Para abordar el primer problema (contenido de texto del elemento que proviene de un atributo), puede utilizar el valor especial que asigna un atributo al contenido de texto del elemento emitido. button message <text> En este caso, el texto del message atributo debe copiarse al contenido de texto del button elemento emitido.

Para configurar la solicitud para alertar a axe DevTools Linter de que el atributo message debe considerarse como contenido de texto para el elemento HTML button , puede usar el valor especial <text> y enviar la siguiente solicitud:

{
  "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"
}

Debido a que definió el atributo message como <text>, le indicó a axe DevTools Linter que considere ese atributo como reemplazo del contenido textual del elemento HTML button con el valor del atributo message .

Desafortunadamente, al usar el array, el único atributo que se pasó al elemento emitido fue el único atributo; cualquier atributo que no esté en el array no se pasa. attributes button message attributes Esto significa que el servidor no detectó lo incorrecto. aria-colindex

Usando aria-*

Puede utilizar el valor especial aria-* para pasar todos los atributos ARIA, como se muestra a continuación:

{
  "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"
}

El servidor responde con:

{
  "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"
      }
    ]
  }
}

Este error se produce porque el elemento button tiene un role="button" implícito y usar aria-colindex no es válido con botones. Con atributo aria-*, all ARIA attributes are copied to the emitted element; this includes copying the invalid aria-colindex.

<element>

Con componentes complejos, es posible que desees emitir un elemento HTML diferente al elemento predeterminado en casos específicos. Por ejemplo, es posible que tenga un componente de botón que normalmente se comporta como un botón y, en otros estados, como una imagen de marcador de posición. El valor <element> le permite especificar un atributo en su componente personalizado que determina el elemento emitido.

{  
  "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>"
}

En este caso, el atributo use en el componente my-button indica el elemento a emitir. Debido a que el elemento img emitido no contiene alt un atributo, recibirá un error:

{
  "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
      }
    ]
  }
}

Pasar todos los atributos implícitamente

Tenga en cuenta que si solo hubiera utilizado la asignación de elementos (donde la asignación no utiliza la matriz), todos los atributos se copiarían, de manera predeterminada, al elemento como se muestra a continuación: attributes button

{
  "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"
}

Con esta respuesta del servidor, puede ver que todos los atributos de custom-button se verifican para detectar problemas de accesibilidad y se encuentran dos errores:

{
  "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"
      }
    ]
  }
}

El ejemplo anterior muestra que un primer paso práctico al comenzar a analizar componentes personalizados sería comenzar con un mapeo de elementos (copiando así todos los atributos al elemento HTML estándar emitido) y luego ver qué atributos necesitan agregarse a la configuración (si los atributos del componente personalizado deben mapearse a diferentes atributos o si necesita usar <text> o aria-*).

Atributos predeterminados

Los atributos predeterminados le permiten establecer valores para los atributos en su archivo de configuración en lugar de asignar un atributo a otro. Por ejemplo, la siguiente configuración de muestra muestra un componente asignado a un elemento con un tipo de menú: custom-menu li role **

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

Debido a que el atributo role tiene un valor predeterminado de menú, establecido en el archivo de configuración, los usuarios no necesitan especificar un atributo role cuando usan el componente custom-menu en su código. La implicación es que la implementación de su componente personalizado crea estos atributos en el elemento de salida y establece sus valores en lugar de requerir que los usuarios los establezcan cuando usan su componente.

De manera opcional, el valor name se establece en null en la configuración, lo que hace que axe DevTools Linter ignore cualquier role atributos que los usuarios hayan especificado en custom-menu el código analizado.

note

El valor especificado con default debe ser una cadena.

Consulte también