dom-testing-library
                                
                                 dom-testing-library copied to clipboard
                                
                                    dom-testing-library copied to clipboard
                            
                            
                            
                        Add `level` filter for `treeitem`
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:
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.
Thanks for the feedback.
We're waiting on a new release of aria-query for this.
Though I strongly advise against using level for treeitems since you'd have to explicitly declare these attributes (which may be redundant). We currently don't support computing the actual level of a treeitem within a tree.
@eps1lon am I missing something? it looks like this one is supported in Aria 1.1 and the change on our end seems quite straightforwards since there's no computation needed, just adding the role to this if statement
Can you please elaborate what are we waiting for from aria-query? If we're not waiting anymore, I'd be more than happy to fix this one.
Not sure anymore why this was an issue.
But we definitely would need to add support for computing implicit level of a treeitem