testing-library / testing-library/dom-testing-library

Add `level` filter for `treeitem`

Open
#980 4 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

enhancement
Dominant language
JavaScript
Stars
3.3k
Forks
474
PR merge metrics
No merged PRs in 30d

Description

Summary

@testing-library/jest-dom explicitly disallows the use of the level property in getByRole for all roles except heading.
This needs to be broadened as W3 also supports this property on the treeitem, listitem, and row roles.

Relevant code or config:
  • "@testing-library/jest-dom": "^5.14.1"
  • "@testing-library/react": "^11.2.7"
test("Can select by role treeitem with level", () => {
  render(<Hello />);
  expect(
    screen.getByRole("treeitem", { name: "project-3B.docx", level: 3 })
  ).toBeInTheDocument();
  expect(
    screen.getByRole("treeitem", { name: "project-3B.docx", level: 1 })
  ).not.toBeInTheDocument();
});
What you did:

I am trying to select an element with role="treeitem" based on its level. In my actual app I have the same names appearing as both a parent and a child.

What happened:

The test cannot be executed due to an error:

Role "treeitem" cannot have "level" property.

at queryAllByRole (node_modules/@testing-library/dom/dist/queries/role.js:72:13)

at node_modules/@testing-library/dom/dist/query-helpers.js:87:17

at node_modules/@testing-library/dom/dist/query-helpers.js:62:17

at getByRole (node_modules/@testing-library/dom/dist/query-helpers.js:111:19)

at Object. (src/components/bubbles/BubblesScreen.test.tsx:24:28)

Reproduction:

Created a CodeSandbox

Problem description:

The aria-level attribute and implicit levels are supported by W3 for multiple roles, as seen here:

  • heading
  • listitem
  • row
  • treeitem

However @testing-library/dom does a validation check which only allows for level to be used with the heading role.

The problematic code appears on lines 67-72 of /src/queries/roles.js:

if (level !== undefined) { 
   // guard against using `level` option with any role other than `heading`
    if (role !== 'heading') {
      throw new Error(`Role "${role}" cannot have "level" property.`)
    }
}
Suggested solution:

The code section above needs to be modified to prevent throwing the error.

The actual computation of the level property happens here. The current code will work on treeitem elements which use the explicit aria-level attribute. The implicit level is based on the current item's position in the tree, so additional work needs to be done to compute the implicit level. heading levels can be computed just from the tagName but treeitem levels cannot. It would require some sort of querying of the parents and the tree.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/queries/role.js at the validation that rejects level for non-heading roles, then read the level computation in src/role-helpers.js. Extend support for the listed roles and determine how implicit treeitem levels should be computed from parent tree structure. Done means explicit and implicit levels work for treeitem, listitem, and row without the current validation error.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript
Domain
testing-qa
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.