Skip to content

Add level option for *ByRole('heading') #743

Closed
@winterlamon

Description

@winterlamon

Describe the feature you'd like:

Add new queries for *ByHeadingLevel that allow the specification of the heading level by which to query, e.g. getAllByHeadingLevel('h2').

I know that suggestions about adding queries by tag have been rejected because they go against the user-centric testing principles, but I think this particular case is user-centric, especially for those using assistive technologies.

Suggested implementation:

getByHeadingLevel, queryByHeadingLevel, getAllByHeadingLevel, queryAllByHeadingLevel, findByHeadingLevel, findAllByHeadingLevel

getByHeadingLevel(
  container: HTMLElement, // or skip this if using `screen`
  level: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
  // I don't think this would need to use to standard options like `exact` (with the way it's typed)
  // or `normalizer`, but please correct me if I'm wrong
): HTMLElement

Describe alternatives you've considered:

While *ByRole('heading') can grab the headings on the DOM, there is currently no way to specify the heading levels. And while a custom query could be made, or simply using document.querySelector(), this particular query seems like it should be a built-in as it is one of the ways that people using assistive technologies navigate web pages.

Screen Shot 2020-08-18 at 11 59 33 AM

Teachability, Documentation, Adoption, Migration Strategy:

Because the syntax is similar to other queries, I imagine the teachability and adoption should take minimal effort (beyond what's needed to learn any of the other queries).

Possible Documentation

ByHeadingLevel

getByHeadingLevel, queryByHeadingLevel, getAllByHeadingLevel, queryAllByHeadingLevel, findByHeadingLevel, findAllByHeadingLevel

getByHeadingLevel(
  container: HTMLElement, // if you're using `screen`, then skip this argument
  level: HeadingLevel ('h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6')
  // I don't think this would need to use to standard options like `exact` (with the way it's typed)
  // or `normalizer`, but please correct me if I'm wrong
): HTMLElement

Queries headings by their level and returns the element -- either the HTML heading element (<h1> - <h6>) or the element with role="heading" and aria-level with matching level.

Although ByHeadingLevel queries elements with role="heading" and the aria-level attribute present, it is strongly encouraged to use the semantic HTML heading elements (<h1> - <h6>).

Note that the ByHeadingLevel query only supports heading levels h1-h6. While, it is possible to use aria-level with a heading level greater than 6, it is discouraged due to inconsistent browser and assistive technology support.

For example in

<body>
  <main>
    <h1>All About Tuesday</h1>

    <h2>What I Did Today</h2>
    <p>I didn't get as much done today as I would have liked.</p>

    <h3>Drinking Coffee</h3>
    <p>I drank a lot of iced coffee. It was a Kona blend with oat milk.</p>
    <p>I'm really bad at coming up with examples.</p>

    <h2>What I Didn't Accomplish Today</h2>
    <p>Everything else.</p>
  </main>
</body>

getByHeadingLabel('h3') would return <h3>Drinking Coffee</h3>.
getAllByHeadingLabel('h2') would return [<h2>What I Did Today</h2>, <h2>What I Didn't Accomplish Today</h2>].

(...plus some reference links thrown in...)

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions