Search code examples
htmlaccessibilitypuppeteerui-automationwai-aria

How to properly use aria selectors for definition lists in puppeteer


I'm writing some UI functional tests using puppeteer. After discovering the "Puppetaria" article, I decided that whenever it's possible, I want to use aria selectors. This has been working OK in many cases, but I'm struggling to figure out how to properly do this using a <dl/> definition list. I'm using a <dl/> to show details about an object in the hopes that it's an accessible way to present things. For example:

<dl>
  <dt>ID</dt>
  <dd>6234</dd>

  <dt>Name</dt>
  <dd>Yo Mama</dd>
</dl>

It seems like semantically, the <dt/> elements label the <dd/>'s. However, when I use the puppeteer selector aria/ID I get back nothing and time out waiting on the selector.

I do see that if I explicitly describe that an element labels the other:

<dl>
  <dt id="id-label">ID</dt>
  <dd aria-labelledby="id-label">6234</dd>
</dl>

...then the aria/ID selector works.

Am I doing accessibility wrong making the assumption that dt and dd semantically align without explicit annotations? Am I using Puppeteer incorrectly? Or is this a bug with Chrome's accessibility tree?


Solution

  • Definition lists kind of suck when it comes to accessibility. In your example, you have two terms and two definitions. When you navigate through the list with a screen reader, some screen readers will say the list has 2 items and some will say it has 4 items and some will say there isn't a list.

    Technically, a <dl> does not have a list role by default so screen readers that say there isn't a list are correct.

    I have not used puppeteer but from what I understand, the aria selector is looking for the accessible name. The accessible name calculation follows a set of rules (essentially a big if-then-else statement). <dt> and <dd> elements do not have an accessible name unless you use aria-label or aria-labelledby. They're not like <button> elements where a button can get its accessible name from the "contents" of the button (the text between the <button> and </button>), step 2.F in the calculation. So the text between a <dt> and </dt> is not the accessible name and thus not returned in a puppeteer aria selector.