dequelabs / axe-core

Accessibility engine for automated Web UI testing
https://www.deque.com/axe/
Mozilla Public License 2.0
5.98k stars 776 forks source link

How can I exclude all elements inside a specific element? #3893

Closed sneko closed 1 year ago

sneko commented 1 year ago

Product

axe-core

Question

Hi,

I'm using Storybook a11y addon but it uses under the hood axe-core that's why I ask my question here. My issue is I adopted an rich text editor library that does not respect a11y at all, so it triggers dozens of rules.

What I want:

But from what I saw in the settings structure I'm only able to:

  1. Exclude a specific element (via exclude)
  2. Disable a specific rule for elements via a CSS selector

The ideal would be a mix of both: being able to disable all rules for a CSS selector.

Did I miss something in the documentation?

Thank you,

straker commented 1 year ago

Thanks for the question. The exclude context option should exclude the element selected and all descendants of that element from the axe run. So you should be able to select the text editor root element and then no rules will be run on it.

sneko commented 1 year ago

@straker thanks for answering! It seems I have an issue from the storybook-addon-a11y side. It does not accept a ContextObject to use exclude.

Though, I tried to directly use an inline selector but it did not work, if you could check my inline selector just to tell me if it looks good or not? I ask you since they bind it directly to axe-core, it works when not using *:not(...): https://github.com/storybookjs/storybook/issues/20813

Thank you :)

th-mailosaur commented 3 months ago

@sneko Was there ever a resolution for this? I'm having the same issue. The a11y config inside preview.ts isn't accepting an ElementContext object. It only accepts a string otherwise it throws a 'The accessibility scan encountered an error. {"name":"SyntaxError"}'

sneko commented 3 months ago

Hi @th-mailosaur , it's been quite some time since then, but you can have a look to the following to try making it working.

This is the preview.jsx file inside Storybook v7 (it may have changed with v8...). Note I was using a js extension for this file, if your typing is yelling I suggest you cast the array as any?

export const parameters = {
  ...
  a11y: {
    config: {
      rules: [
        {
          // A layout footer button targets a theming modal that we do not render to keep things simple, ignore this button violation
          id: 'aria-valid-attr-value',
          selector: '*:not([aria-controls="fr-theme-modal"])',
        },
        {
          // TODO: for now the user avatar background color is generated with a simple algorithm but does not respect the ratio
          id: 'color-contrast',
          selector: '*:not(.MuiAvatar-circular.UserAvatar)',
        },
        {
          // TODO: can be removed once https://github.com/corygibbons/react-file-icon/issues/40 is fixed
          id: 'duplicate-id',
          selector: '*:not(MuiListItemIcon-root.disabledA11y)',
        },
        {
          // When using the `DataGrid` it says: "Element has children which are not allowed"
          // whereas it has `role="rowgroup"` as direct nested elements... it seems a false-positive so ignoring it
          // (multiple posts on internet mentions this wrong trigger)
          id: 'aria-required-children',
          selector: '*:not(.MuiDataGrid-root)',
        },
        {
          // Cannot add the missign piece triggering the error
          id: 'scrollable-region-focusable',
          selector: '*:not(.MuiDataGrid-virtualScroller)',
        },
        {
          // `react-dsfr` uses the same id for desktop and mobile for their quick access items
          id: 'duplicate-id-active',
          selector: '*:not([id^="fr-header-quick-access-item"])',
        },
      ],
    },
  },
};
th-mailosaur commented 3 months ago

@sneko Appreciate the quick response to an old issue. I wanted to disable every rule for specific elements, so what worked for me in the end was just to add 'aria-disabled="true"' to each element I wanted it to not check.