@@ -311,28 +314,27 @@ describe('Markup', () => {
)
// Focus button
- const button = screen.getByRole('button', {name: /Focusable element/})
+ const button = page.getByRole('button', {name: /Focusable element/})
act(() => {
- button.focus()
+ button.element().focus()
})
- expect(button).toHaveFocus()
+ expect(button.element()).toHaveFocus()
// Move focus to tree
- const item1 = screen.getByRole('treeitem', {name: /Item 1/})
- const toggle = item1.querySelector('.PRIVATE_TreeView-item-toggle') as HTMLElement
+ const item1 = page.getByRole('treeitem', {name: /Item 1/})
+ const toggle = item1.element().querySelector('.PRIVATE_TreeView-item-toggle') as HTMLElement
act(() => {
- // Note: calling `.click()` directly here since the userEvent.click()
- // warns about it not being a known focusable element. This should be a
- // valid pattern based on our TreeView guidelines.
+ // The pointer-only chevron retains its programmatic click exception to
+ // avoid the known focus-zone warning from browser pointer focus.
toggle.click()
})
// Focus should be on current treeitem
- const subItem1 = screen.getByRole('treeitem', {name: /SubItem 1/})
- expect(subItem1).toBeInTheDocument()
+ const subItem1 = page.getByRole('treeitem', {name: /SubItem 1/})
+ await expect.element(subItem1).toBeInTheDocument()
})
- it("should move focus to first treeitem when focusing back in after clicking on a treeitem's secondary action", () => {
+ it("should move focus to first treeitem when focusing back in after clicking on a treeitem's secondary action", async () => {
render(
@@ -350,28 +352,28 @@ describe('Markup', () => {
)
// Click on treeitem's secondary action
- const item2Button = screen.getByText(/Link in Item 2/i)
+ const item2Button = page.getByText(/Link in Item 2/i)
act(() => {
- item2Button.focus()
+ item2Button.element().focus()
})
- expect(item2Button).toHaveFocus()
+ expect(item2Button.element()).toHaveFocus()
// Move focus to button outside of TreeView
- const outerButton = screen.getByRole('button', {name: /Focusable element/})
+ const outerButton = page.getByRole('button', {name: /Focusable element/})
act(() => {
- outerButton.focus()
+ outerButton.element().focus()
})
- expect(outerButton).toHaveFocus()
+ expect(outerButton.element()).toHaveFocus()
// Move focus into TreeView. Focus should be on first treeitem
- const item1 = screen.getByRole('treeitem', {name: /Item 1/})
+ const item1 = page.getByRole('treeitem', {name: /Item 1/})
act(() => {
- item1.focus()
+ item1.element().focus()
})
- expect(item1).toHaveFocus()
+ expect(item1.element()).toHaveFocus()
})
- it('keeps focus on a nested control when pressing ArrowDown', () => {
+ it('keeps focus on a nested control when pressing ArrowDown', async () => {
render(
Item 1
@@ -385,15 +387,20 @@ describe('Markup', () => {
,
)
- const item = screen.getByRole('treeitem', {name: 'Item 2'})
- const button = screen.getByText('Nested action')
+ const item = page.getByRole('treeitem', {
+ name: 'Item 2',
+ exact: true,
+ })
+ const button = page.getByText('Nested action', {
+ exact: true,
+ })
- act(() => item.focus())
- act(() => button.focus())
- expect(button).toHaveFocus()
+ act(() => item.element().focus())
+ act(() => button.element().focus())
+ expect(button.element()).toHaveFocus()
- expect(fireEvent.keyDown(button, {key: 'ArrowDown'})).toBe(false)
- expect(button).toHaveFocus()
+ expect(fireEvent.keyDown(button.element(), {key: 'ArrowDown'})).toBe(false)
+ expect(button.element()).toHaveFocus()
})
describe('as prop', () => {
@@ -404,11 +411,11 @@ describe('Markup', () => {
,
)
- const item = screen.getByRole('treeitem', {name: /Item 1/})
- expect(item.tagName).toBe('LI')
+ const item = page.getByRole('treeitem', {name: /Item 1/})
+ expect(item.element().tagName).toBe('LI')
})
- it('renders as the element specified by `as`', () => {
+ it('renders as the element specified by `as`', async () => {
render(
@@ -417,12 +424,12 @@ describe('Markup', () => {
,
)
- const item = screen.getByRole('treeitem', {name: /Item 1/})
- expect(item.tagName).toBe('A')
- expect(item).toHaveAttribute('href', '#item-1')
+ const item = page.getByRole('treeitem', {name: /Item 1/})
+ expect(item.element().tagName).toBe('A')
+ await expect.element(item).toHaveAttribute('href', '#item-1')
})
- it('wraps the polymorphic element in an `li role="none"` to keep markup valid', () => {
+ it('wraps the polymorphic element in an `li role="none"` to keep markup valid', async () => {
render(
@@ -431,13 +438,13 @@ describe('Markup', () => {
,
)
- const item = screen.getByRole('treeitem', {name: /Item 1/})
- const wrapper = item.parentElement
+ const item = page.getByRole('treeitem', {name: /Item 1/})
+ const wrapper = item.element().parentElement
expect(wrapper?.tagName).toBe('LI')
- expect(wrapper).toHaveAttribute('role', 'none')
+ await expect.element(wrapper).toHaveAttribute('role', 'none')
})
- it('does not add an extra `li role="none"` wrapper when `as="li"`', () => {
+ it('does not add an extra `li role="none"` wrapper when `as="li"`', async () => {
render(
@@ -446,14 +453,14 @@ describe('Markup', () => {
,
)
- const item = screen.getByRole('treeitem', {name: /Item 1/})
- expect(item.tagName).toBe('LI')
+ const item = page.getByRole('treeitem', {name: /Item 1/})
+ expect(item.element().tagName).toBe('LI')
// The treeitem should be a direct child of the tree (`
`), not wrapped
// in an outer `- `.
- expect(item.parentElement).toHaveAttribute('role', 'tree')
+ await expect.element(item.element().parentElement).toHaveAttribute('role', 'tree')
})
- it('supports polymorphic Item with custom component via `as`', () => {
+ it('supports polymorphic Item with custom component via `as`', async () => {
const CustomLink = React.forwardRef<
HTMLAnchorElement,
React.AnchorHTMLAttributes & {custom: boolean}
@@ -472,13 +479,13 @@ describe('Markup', () => {
,
)
- const item = screen.getByRole('treeitem', {name: /Docs/})
- expect(item.tagName).toBe('A')
- expect(item).toHaveAttribute('href', '#docs')
- expect(item).toHaveAttribute('data-custom-link', 'true')
+ const item = page.getByRole('treeitem', {name: /Docs/})
+ expect(item.element().tagName).toBe('A')
+ await expect.element(item).toHaveAttribute('href', '#docs')
+ await expect.element(item).toHaveAttribute('data-custom-link', 'true')
})
- it('preserves treeitem role, tabIndex, and aria attributes when `as` is provided', () => {
+ it('preserves treeitem role, tabIndex, and aria attributes when `as` is provided', async () => {
render(
@@ -487,11 +494,11 @@ describe('Markup', () => {
,
)
- const item = screen.getByRole('treeitem', {name: /Item 1/})
- expect(item).toHaveAttribute('role', 'treeitem')
- expect(item).toHaveAttribute('tabindex', '0')
- expect(item).toHaveAttribute('aria-current', 'true')
- expect(item).toHaveAttribute('aria-level', '1')
+ const item = page.getByRole('treeitem', {name: /Item 1/})
+ await expect.element(item).toHaveAttribute('role', 'treeitem')
+ await expect.element(item).toHaveAttribute('tabindex', '0')
+ await expect.element(item).toHaveAttribute('aria-current', 'true')
+ await expect.element(item).toHaveAttribute('aria-level', '1')
})
it('forwards ref to the element specified by `as`', () => {
@@ -508,7 +515,7 @@ describe('Markup', () => {
expect(ref.current?.tagName).toBe('A')
})
- it('calls onSelect when the polymorphic element is clicked', () => {
+ it('calls onSelect when the polymorphic element is clicked', async () => {
const onSelect = vi.fn()
render(
@@ -518,8 +525,8 @@ describe('Markup', () => {
,
)
- const item = screen.getByRole('treeitem', {name: /Item 1/})
- fireEvent.click(item)
+ const item = page.getByRole('treeitem', {name: /Item 1/})
+ await userEvent.click(item)
expect(onSelect).toHaveBeenCalledTimes(1)
})
})
@@ -527,7 +534,7 @@ describe('Markup', () => {
describe('Keyboard interactions', () => {
describe('ArrowDown', () => {
- it('moves focus to the next visible treeitem', () => {
+ it('moves focus to the next visible treeitem', async () => {
render(
@@ -547,44 +554,56 @@ describe('Keyboard interactions', () => {
,
)
- const item1 = screen.getByRole('treeitem', {name: 'Item 1'})
- const item11 = screen.getByRole('treeitem', {name: 'Item 1.1'})
- const item2 = screen.getByRole('treeitem', {name: 'Item 2'})
- const item3 = screen.getByRole('treeitem', {name: 'Item 3'})
+ const item1 = page.getByRole('treeitem', {
+ name: 'Item 1',
+ exact: true,
+ })
+ const item11 = page.getByRole('treeitem', {
+ name: 'Item 1.1',
+ exact: true,
+ })
+ const item2 = page.getByRole('treeitem', {
+ name: 'Item 2',
+ exact: true,
+ })
+ const item3 = page.getByRole('treeitem', {
+ name: 'Item 3',
+ exact: true,
+ })
act(() => {
// Focus first item
- item1.focus()
+ item1.element().focus()
})
// Press ↓
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
+ await userEvent.keyboard('{ArrowDown}')
// item 1.1 should be focused
- expect(item11).toHaveFocus()
+ await expect.element(item11).toHaveFocus()
// Press ↓
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
+ await userEvent.keyboard('{ArrowDown}')
// item 2 should be focused
- expect(item2).toHaveFocus()
+ await expect.element(item2).toHaveFocus()
// Press ↓
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
+ await userEvent.keyboard('{ArrowDown}')
// item 3 should have focus (skips item 2.1 and item 2.2 because they are hidden)
- expect(item3).toHaveFocus()
+ await expect.element(item3).toHaveFocus()
// Press ↓
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
+ await userEvent.keyboard('{ArrowDown}')
// focus should not change (item 3 is the last visible treeitem)
- expect(item3).toHaveFocus()
+ await expect.element(item3).toHaveFocus()
})
})
describe('ArrowUp', () => {
- it('moves focus to the previous visible treeitem', () => {
+ it('moves focus to the previous visible treeitem', async () => {
render(
@@ -604,53 +623,65 @@ describe('Keyboard interactions', () => {
,
)
- const item1 = screen.getByRole('treeitem', {name: 'Item 1'})
- const item11 = screen.getByRole('treeitem', {name: 'Item 1.1'})
- const item2 = screen.getByRole('treeitem', {name: 'Item 2'})
- const item3 = screen.getByRole('treeitem', {name: 'Item 3'})
+ const item1 = page.getByRole('treeitem', {
+ name: 'Item 1',
+ exact: true,
+ })
+ const item11 = page.getByRole('treeitem', {
+ name: 'Item 1.1',
+ exact: true,
+ })
+ const item2 = page.getByRole('treeitem', {
+ name: 'Item 2',
+ exact: true,
+ })
+ const item3 = page.getByRole('treeitem', {
+ name: 'Item 3',
+ exact: true,
+ })
act(() => {
// Focus first item
- item1.focus()
+ item1.element().focus()
})
// Press ↓ 4 times to move aria-activedescendant to item 3
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
+ await userEvent.keyboard('{ArrowDown}')
+ await userEvent.keyboard('{ArrowDown}')
+ await userEvent.keyboard('{ArrowDown}')
+ await userEvent.keyboard('{ArrowDown}')
// item 3 should be focused
- expect(item3).toHaveFocus()
+ await expect.element(item3).toHaveFocus()
// Press ↑
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowUp'})
+ await userEvent.keyboard('{ArrowUp}')
// Item 2 should have focus (skips item 2.1 and item 2.2 because they are hidden)
- expect(item2).toHaveFocus()
+ await expect.element(item2).toHaveFocus()
// Press ↑
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowUp'})
+ await userEvent.keyboard('{ArrowUp}')
// Item 1.1 should be focused
- expect(item11).toHaveFocus()
+ await expect.element(item11).toHaveFocus()
// Press ↑
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowUp'})
+ await userEvent.keyboard('{ArrowUp}')
// Item 1 should be focused
- expect(item1).toHaveFocus()
+ await expect.element(item1).toHaveFocus()
// Press ↑
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowUp'})
+ await userEvent.keyboard('{ArrowUp}')
// Focus should not change (item 1 is the first visible treeitem)
- expect(item1).toHaveFocus()
+ await expect.element(item1).toHaveFocus()
})
})
describe('ArrowLeft', () => {
- it('collapses an expanded item', () => {
+ it('collapses an expanded item', async () => {
render(
@@ -662,36 +693,39 @@ describe('Keyboard interactions', () => {
,
)
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
- let subtree = screen.queryByRole('group')
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
+ let subtree = page.getByRole('group')
// aria-expanded should be true
- expect(parentItem).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'true')
// Subtree should be visible
- expect(subtree).toBeVisible()
+ await expect.element(subtree).toBeVisible()
act(() => {
// Focus first item
- parentItem.focus()
+ parentItem.element().focus()
})
// Press ←
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowLeft'})
+ await userEvent.keyboard('{ArrowLeft}')
// aria-expanded should now be false
- expect(parentItem).toHaveAttribute('aria-expanded', 'false')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'false')
// Parent item should still be focused
- expect(parentItem).toHaveFocus()
+ await expect.element(parentItem).toHaveFocus()
- subtree = screen.queryByRole('group')
+ subtree = page.getByRole('group')
// Subtree should now be hidden
- expect(subtree).toBeNull()
+ await expect.element(subtree).not.toBeInTheDocument()
})
- it('does nothing on a root-level collapsed item', () => {
+ it('does nothing on a root-level collapsed item', async () => {
render(
@@ -703,48 +737,54 @@ describe('Keyboard interactions', () => {
,
)
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
// aria-expanded should be false by default
- expect(parentItem).toHaveAttribute('aria-expanded', 'false')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'false')
act(() => {
// Focus first item
- parentItem.focus()
+ parentItem.element().focus()
})
// Press ←
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowLeft'})
+ await userEvent.keyboard('{ArrowLeft}')
// aria-expanded should still be false
- expect(parentItem).toHaveAttribute('aria-expanded', 'false')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'false')
// Focus should not change
- expect(parentItem).toHaveFocus()
+ await expect.element(parentItem).toHaveFocus()
})
- it('does nothing on a root-level end item', () => {
+ it('does nothing on a root-level end item', async () => {
render(
Item
,
)
- const item = screen.getByRole('treeitem', {name: 'Item'})
+ const item = page.getByRole('treeitem', {
+ name: 'Item',
+ exact: true,
+ })
act(() => {
// Focus first item
- item.focus()
+ item.element().focus()
})
// Press ←
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowLeft'})
+ await userEvent.keyboard('{ArrowLeft}')
// Focus should not change
- expect(item).toHaveFocus()
+ await expect.element(item).toHaveFocus()
})
- it('moves focus to parent of end item', () => {
+ it('moves focus to parent of end item', async () => {
render(
@@ -757,29 +797,35 @@ describe('Keyboard interactions', () => {
,
)
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
- const child2 = screen.getByRole('treeitem', {name: 'Child 2'})
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
+ const child2 = page.getByRole('treeitem', {
+ name: 'Child 2',
+ exact: true,
+ })
act(() => {
// Focus fist item
- parentItem.focus()
+ parentItem.element().focus()
})
// Press ↓ 2 times to move focus to child 2
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
+ await userEvent.keyboard('{ArrowDown}')
+ await userEvent.keyboard('{ArrowDown}')
// Child 2 should be focused
- expect(child2).toHaveFocus()
+ await expect.element(child2).toHaveFocus()
// Press ←
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowLeft'})
+ await userEvent.keyboard('{ArrowLeft}')
// Parent item should be focused
- expect(parentItem).toHaveFocus()
+ await expect.element(parentItem).toHaveFocus()
})
- it('moves focus to parent of collapsed item', () => {
+ it('moves focus to parent of collapsed item', async () => {
render(
@@ -797,31 +843,37 @@ describe('Keyboard interactions', () => {
,
)
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
- const nestedParentItem = screen.getByRole('treeitem', {name: 'Nested parent'})
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
+ const nestedParentItem = page.getByRole('treeitem', {
+ name: 'Nested parent',
+ exact: true,
+ })
act(() => {
// Focus first item
- parentItem.focus()
+ parentItem.element().focus()
})
// Press ↓ 2 times to move focus to nested parent
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
+ await userEvent.keyboard('{ArrowDown}')
+ await userEvent.keyboard('{ArrowDown}')
// Nested parent item should be focused
- expect(nestedParentItem).toHaveFocus()
+ await expect.element(nestedParentItem).toHaveFocus()
// Press ←
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowLeft'})
+ await userEvent.keyboard('{ArrowLeft}')
// Parent item should be focused
- expect(parentItem).toHaveFocus()
+ await expect.element(parentItem).toHaveFocus()
})
})
describe('ArrowRight', () => {
- it('expands a collapsed item', () => {
+ it('expands a collapsed item', async () => {
render(
@@ -833,32 +885,35 @@ describe('Keyboard interactions', () => {
,
)
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
// aria-expanded should be false by default
- expect(parentItem).toHaveAttribute('aria-expanded', 'false')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'false')
act(() => {
// Focus first item
- parentItem.focus()
+ parentItem.element().focus()
})
// Press →
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowRight'})
+ await userEvent.keyboard('{ArrowRight}')
// aria-expanded should now be true
- expect(parentItem).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'true')
// Parent item should still be focused
- expect(parentItem).toHaveFocus()
+ await expect.element(parentItem).toHaveFocus()
- const subtree = screen.getByRole('group')
+ const subtree = page.getByRole('group')
// Subtree should now be visible
- expect(subtree).toBeVisible()
+ await expect.element(subtree).toBeVisible()
})
- it('moves focus to first child of an expanded item', () => {
+ it('moves focus to first child of an expanded item', async () => {
render(
@@ -870,30 +925,34 @@ describe('Keyboard interactions', () => {
,
)
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
// aria-expanded should be true
- expect(parentItem).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'true')
act(() => {
- parentItem.focus()
+ parentItem.element().focus()
})
- expect(parentItem).toHaveFocus()
+ await expect.element(parentItem).toHaveFocus()
- act(() => {
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowRight'})
- })
+ await userEvent.keyboard('{ArrowRight}')
- const childItem = screen.getByRole('treeitem', {name: 'Child'})
+ const childItem = page.getByRole('treeitem', {
+ name: 'Child',
+ exact: true,
+ })
// Child item should be focused
- expect(childItem).toHaveFocus()
+ await expect.element(childItem).toHaveFocus()
// aria-expanded should still be true
- expect(parentItem).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'true')
})
- it('does nothing on an end item', () => {
+ it('does nothing on an end item', async () => {
render(
@@ -906,30 +965,36 @@ describe('Keyboard interactions', () => {
,
)
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
- const child1 = screen.getByRole('treeitem', {name: 'Child 1'})
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
+ const child1 = page.getByRole('treeitem', {
+ name: 'Child 1',
+ exact: true,
+ })
act(() => {
// Focus first item
- parentItem.focus()
+ parentItem.element().focus()
})
// Press ↓ to move focus to child 1
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
+ await userEvent.keyboard('{ArrowDown}')
// Child 1 should be focused
- expect(child1).toHaveFocus()
+ await expect.element(child1).toHaveFocus()
// Press →
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowRight'})
+ await userEvent.keyboard('{ArrowRight}')
// Focus should not change
- expect(child1).toHaveFocus()
+ await expect.element(child1).toHaveFocus()
})
})
describe('Backspace', () => {
- it('should move focus to the parent item', () => {
+ it('should move focus to the parent item', async () => {
render(
@@ -941,20 +1006,25 @@ describe('Keyboard interactions', () => {
,
)
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
- const child = screen.getByRole('treeitem', {name: 'Child'})
-
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
+ const child = page.getByRole('treeitem', {
+ name: 'Child',
+ exact: true,
+ })
act(() => {
- child.focus()
+ child.element().focus()
})
// Press Backspace
- fireEvent.keyDown(document.activeElement || document.body, {key: 'Backspace'})
+ await userEvent.keyboard('{Backspace}')
- expect(parentItem).toHaveFocus()
+ await expect.element(parentItem).toHaveFocus()
})
- it('should not collapse an expanded item', () => {
+ it('should not collapse an expanded item', async () => {
render(
@@ -966,33 +1036,36 @@ describe('Keyboard interactions', () => {
,
)
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
- const subtree = screen.queryByRole('group')
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
+ const subtree = page.getByRole('group')
// aria-expanded should be true
- expect(parentItem).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'true')
// Subtree should be visible
- expect(subtree).toBeVisible()
+ await expect.element(subtree).toBeVisible()
act(() => {
// Focus first item
- parentItem.focus()
+ parentItem.element().focus()
})
// Press Backspace
- fireEvent.keyDown(document.activeElement || document.body, {key: 'Backspace'})
+ await userEvent.keyboard('{Backspace}')
// aria-expanded should stay set as true
- expect(parentItem).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'true')
// Parent item should still be focused
- expect(parentItem).toHaveFocus()
+ await expect.element(parentItem).toHaveFocus()
})
})
describe('Home', () => {
- it('moves focus to first visible item', () => {
+ it('moves focus to first visible item', async () => {
render(
@@ -1016,30 +1089,36 @@ describe('Keyboard interactions', () => {
,
)
- const parent1 = screen.getByRole('treeitem', {name: 'Parent 1'})
- const parent3 = screen.getByRole('treeitem', {name: 'Parent 2'})
+ const parent1 = page.getByRole('treeitem', {
+ name: 'Parent 1',
+ exact: true,
+ })
+ const parent3 = page.getByRole('treeitem', {
+ name: 'Parent 2',
+ exact: true,
+ })
act(() => {
// Focus first item
- parent1.focus()
+ parent1.element().focus()
})
// Press ↓ 2 times to move focus to parent 3
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
+ await userEvent.keyboard('{ArrowDown}')
// Parent 3 should be focused
- expect(parent3).toHaveFocus()
+ await expect.element(parent3).toHaveFocus()
// Press Home
- fireEvent.keyDown(document.activeElement || document.body, {key: 'Home'})
+ await userEvent.keyboard('{Home}')
// Parent 1 should be focused
- expect(parent1).toHaveFocus()
+ await expect.element(parent1).toHaveFocus()
})
})
describe('End', () => {
- it('moves focus to last visible item', () => {
+ it('moves focus to last visible item', async () => {
render(
@@ -1063,35 +1142,44 @@ describe('Keyboard interactions', () => {
,
)
- const parent1 = screen.getByRole('treeitem', {name: 'Parent 1'})
- const parent3 = screen.getByRole('treeitem', {name: 'Parent 3'})
+ const parent1 = page.getByRole('treeitem', {
+ name: 'Parent 1',
+ exact: true,
+ })
+ const parent3 = page.getByRole('treeitem', {
+ name: 'Parent 3',
+ exact: true,
+ })
act(() => {
// Focus first item
- parent1.focus()
+ parent1.element().focus()
})
// Press End
- fireEvent.keyDown(document.activeElement || document.body, {key: 'End'})
+ await userEvent.keyboard('{End}')
// Parent 3 should be focused
- expect(parent3).toHaveFocus()
+ await expect.element(parent3).toHaveFocus()
// Press → to expand parent 3
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowRight'})
+ await userEvent.keyboard('{ArrowRight}')
// Press End
- fireEvent.keyDown(document.activeElement || document.body, {key: 'End'})
+ await userEvent.keyboard('{End}')
- const child3 = screen.getByRole('treeitem', {name: 'Child 3'})
+ const child3 = page.getByRole('treeitem', {
+ name: 'Child 3',
+ exact: true,
+ })
// Child 3 should be focused
- expect(child3).toHaveFocus()
+ await expect.element(child3).toHaveFocus()
})
})
describe('Enter', () => {
- it('calls onSelect function if provided and checks if the item has been selected', () => {
+ it('calls onSelect function if provided and checks if the item has been selected', async () => {
const onSelect = vi.fn()
render(
@@ -1121,15 +1209,18 @@ describe('Keyboard interactions', () => {
,
)
- const itemChild = screen.getByRole('treeitem', {name: 'Child2'})
+ const itemChild = page.getByRole('treeitem', {
+ name: 'Child2',
+ exact: true,
+ })
act(() => {
// Focus first item
- itemChild.focus()
+ itemChild.element().focus()
})
// Press Enter
- fireEvent.keyDown(document.activeElement || document.body, {key: 'Enter'})
+ await userEvent.keyboard('{Enter}')
// onSelect should have been called
expect(onSelect).toHaveBeenCalledTimes(1)
@@ -1143,7 +1234,7 @@ describe('Keyboard interactions', () => {
expect(onSelect).toHaveBeenCalledTimes(1)
})
- it('toggles expanded state if no onSelect function is provided', () => {
+ it('toggles expanded state if no onSelect function is provided', async () => {
render(
@@ -1156,38 +1247,41 @@ describe('Keyboard interactions', () => {
,
)
- const parent = screen.getByRole('treeitem', {name: 'Parent'})
+ const parent = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
act(() => {
// Focus first item
- parent.focus()
+ parent.element().focus()
})
// aria-expanded should be false
- expect(parent).toHaveAttribute('aria-expanded', 'false')
+ await expect.element(parent).toHaveAttribute('aria-expanded', 'false')
// Press Enter
- fireEvent.keyDown(document.activeElement || document.body, {key: 'Enter'})
+ await userEvent.keyboard('{Enter}')
// aria-expanded should now be true
- expect(parent).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(parent).toHaveAttribute('aria-expanded', 'true')
// Subtree should be visible
- expect(screen.queryByRole('group')).toBeVisible()
+ await expect.element(page.getByRole('group')).toBeVisible()
// Press Enter
- fireEvent.keyDown(document.activeElement || document.body, {key: 'Enter'})
+ await userEvent.keyboard('{Enter}')
// aria-expanded should now be false
- expect(parent).toHaveAttribute('aria-expanded', 'false')
+ await expect.element(parent).toHaveAttribute('aria-expanded', 'false')
// Subtree should no longer be visible
- expect(screen.queryByRole('group')).not.toBeInTheDocument()
+ await expect.element(page.getByRole('group')).not.toBeInTheDocument()
})
})
describe('Space', () => {
- it('calls onSelect function if provided and checks if the item has been selected', () => {
+ it('calls onSelect function if provided and checks if the item has been selected', async () => {
const onSelect = vi.fn()
render(
@@ -1217,15 +1311,18 @@ describe('Keyboard interactions', () => {
,
)
- const itemChild = screen.getByRole('treeitem', {name: 'Child2'})
+ const itemChild = page.getByRole('treeitem', {
+ name: 'Child2',
+ exact: true,
+ })
act(() => {
// Focus first item
- itemChild.focus()
+ itemChild.element().focus()
})
// Press Enter
- fireEvent.keyDown(document.activeElement || document.body, {key: ' '})
+ await userEvent.keyboard(' ')
// onSelect should have been called
expect(onSelect).toHaveBeenCalledTimes(1)
@@ -1239,7 +1336,7 @@ describe('Keyboard interactions', () => {
expect(onSelect).toHaveBeenCalledTimes(1)
})
- it('toggles expanded state if no onSelect function is provided', () => {
+ it('toggles expanded state if no onSelect function is provided', async () => {
render(
@@ -1252,33 +1349,36 @@ describe('Keyboard interactions', () => {
,
)
- const parent = screen.getByRole('treeitem', {name: 'Parent'})
+ const parent = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
act(() => {
// Focus first item
- parent.focus()
+ parent.element().focus()
})
// aria-expanded should be false
- expect(parent).toHaveAttribute('aria-expanded', 'false')
+ await expect.element(parent).toHaveAttribute('aria-expanded', 'false')
// Press Enter
- fireEvent.keyDown(document.activeElement || document.body, {key: 'Enter'})
+ await userEvent.keyboard('{Enter}')
// aria-expanded should now be true
- expect(parent).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(parent).toHaveAttribute('aria-expanded', 'true')
// Subtree should be visible
- expect(screen.queryByRole('group')).toBeVisible()
+ await expect.element(page.getByRole('group')).toBeVisible()
// Press Enter
- fireEvent.keyDown(document.activeElement || document.body, {key: 'Enter'})
+ await userEvent.keyboard('{Enter}')
// aria-expanded should now be false
- expect(parent).toHaveAttribute('aria-expanded', 'false')
+ await expect.element(parent).toHaveAttribute('aria-expanded', 'false')
// Subtree should no longer be visible
- expect(screen.queryByRole('group')).not.toBeInTheDocument()
+ await expect.element(page.getByRole('group')).not.toBeInTheDocument()
})
})
@@ -1318,7 +1418,7 @@ describe('Keyboard interactions', () => {
})
it('allows typing in a nested input without moving focus', async () => {
- const user = userEvent.setup()
+ const user = rtlUserEvent.setup()
render(
@@ -1371,7 +1471,7 @@ describe('Keyboard interactions', () => {
expect(cantalope).toHaveFocus()
})
- it('moves focus to the next item that matches the typed character', () => {
+ it('moves focus to the next item that matches the typed character', async () => {
render(
@@ -1386,25 +1486,31 @@ describe('Keyboard interactions', () => {
,
)
- const apple = screen.getByRole('treeitem', {name: 'Apple'})
- const cherry = screen.getByRole('treeitem', {name: 'Cherry'})
+ const apple = page.getByRole('treeitem', {
+ name: 'Apple',
+ exact: true,
+ })
+ const cherry = page.getByRole('treeitem', {
+ name: 'Cherry',
+ exact: true,
+ })
act(() => {
// Focus first item
- apple.focus()
+ apple.element().focus()
})
// Press C
- fireEvent.keyDown(document.activeElement || document.body, {key: 'c'})
+ await userEvent.keyboard('c')
// Cherry should be focused
- expect(cherry).toHaveFocus()
+ await expect.element(cherry).toHaveFocus()
// Notice that the focus is not set to cantalope because
// it is a child of apple and apple is collapsed.
})
- it('does nothing if no items match the typed character', () => {
+ it('does nothing if no items match the typed character', async () => {
render(
Apple
@@ -1414,24 +1520,27 @@ describe('Keyboard interactions', () => {
,
)
- const apple = screen.getByRole('treeitem', {name: 'Apple'})
+ const apple = page.getByRole('treeitem', {
+ name: 'Apple',
+ exact: true,
+ })
act(() => {
// Focus first item
- apple.focus()
+ apple.element().focus()
})
// Apple should be focused
- expect(apple).toHaveFocus()
+ await expect.element(apple).toHaveFocus()
// Press Z
- fireEvent.keyDown(document.activeElement || document.body, {key: 'z'})
+ await userEvent.keyboard('z')
// Apple should still be focused
- expect(apple).toHaveFocus()
+ await expect.element(apple).toHaveFocus()
})
- it('supports multiple typed characters', () => {
+ it('supports multiple typed characters', async () => {
render(
Apple
@@ -1442,24 +1551,30 @@ describe('Keyboard interactions', () => {
,
)
- const apple = screen.getByRole('treeitem', {name: 'Apple'})
- const cantalope = screen.getByRole('treeitem', {name: 'Cantalope 1'})
+ const apple = page.getByRole('treeitem', {
+ name: 'Apple',
+ exact: true,
+ })
+ const cantalope = page.getByRole('treeitem', {
+ name: 'Cantalope 1',
+ exact: true,
+ })
act(() => {
// Focus first item
- apple.focus()
+ apple.element().focus()
})
// Press C + A + N
- fireEvent.keyDown(document.activeElement || document.body, {key: 'c'})
- fireEvent.keyDown(document.activeElement || document.body, {key: 'a'})
- fireEvent.keyDown(document.activeElement || document.body, {key: 'n'})
+ await userEvent.keyboard('c')
+ await userEvent.keyboard('a')
+ await userEvent.keyboard('n')
// Cantalope should be focused
- expect(cantalope).toHaveFocus()
+ await expect.element(cantalope).toHaveFocus()
})
- it('prioritizes items following the current aria-activedescendant', () => {
+ it('prioritizes items following the current aria-activedescendant', async () => {
render(
Cucumber
@@ -1470,29 +1585,38 @@ describe('Keyboard interactions', () => {
,
)
- const cucumber = screen.getByRole('treeitem', {name: 'Cucumber'})
- const cherry = screen.getByRole('treeitem', {name: 'Cherry'})
- const cantalope = screen.getByRole('treeitem', {name: 'Cantalope'})
+ const cucumber = page.getByRole('treeitem', {
+ name: 'Cucumber',
+ exact: true,
+ })
+ const cherry = page.getByRole('treeitem', {
+ name: 'Cherry',
+ exact: true,
+ })
+ const cantalope = page.getByRole('treeitem', {
+ name: 'Cantalope',
+ exact: true,
+ })
act(() => {
// Focus first item
- cucumber.focus()
+ cucumber.element().focus()
})
// Press ↓ to move focus to cherry
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
+ await userEvent.keyboard('{ArrowDown}')
// Cherry should be focused
- expect(cherry).toHaveFocus()
+ await expect.element(cherry).toHaveFocus()
// Press C
- fireEvent.keyDown(document.activeElement || document.body, {key: 'c'})
+ await userEvent.keyboard('c')
// Cantalope should be focused
- expect(cantalope).toHaveFocus()
+ await expect.element(cantalope).toHaveFocus()
})
- it('wraps around to the beginning if no items match after the current aria-activedescendant', () => {
+ it('wraps around to the beginning if no items match after the current aria-activedescendant', async () => {
render(
Cucumber
@@ -1504,32 +1628,38 @@ describe('Keyboard interactions', () => {
,
)
- const cantalope = screen.getByRole('treeitem', {name: 'Cantalope'})
- const cucumber = screen.getByRole('treeitem', {name: 'Cucumber'})
+ const cantalope = page.getByRole('treeitem', {
+ name: 'Cantalope',
+ exact: true,
+ })
+ const cucumber = page.getByRole('treeitem', {
+ name: 'Cucumber',
+ exact: true,
+ })
act(() => {
// Focus first item
- cucumber.focus()
+ cucumber.element().focus()
})
// Press ↓ 2 times to move focus to cantalope
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
+ await userEvent.keyboard('{ArrowDown}')
+ await userEvent.keyboard('{ArrowDown}')
// Cantalope should be focused
- expect(cantalope).toHaveFocus()
+ await expect.element(cantalope).toHaveFocus()
// Press C
- fireEvent.keyDown(document.activeElement || document.body, {key: 'c'})
+ await userEvent.keyboard('c')
// Cucumber should be focused
- expect(cucumber).toHaveFocus()
+ await expect.element(cucumber).toHaveFocus()
})
})
})
describe('State', () => {
- it('persists expanded state of nested items', () => {
+ it('persists expanded state of nested items', async () => {
render(
@@ -1546,43 +1676,56 @@ describe('State', () => {
,
)
- const item1 = screen.getByRole('treeitem', {name: 'Item 1'})
- const item2 = screen.getByRole('treeitem', {name: 'Item 2'})
+ const item1 = page.getByRole('treeitem', {
+ name: 'Item 1',
+ exact: true,
+ })
+ const item2 = page.getByRole('treeitem', {
+ name: 'Item 2',
+ exact: true,
+ })
// Item 2 should be collapsed by default
- expect(item2).toHaveAttribute('aria-expanded', 'false')
+ await expect.element(item2).toHaveAttribute('aria-expanded', 'false')
act(() => {
// Focus item 2
- item2.focus()
+ item2.element().focus()
})
// Press Enter to expand item 2
- fireEvent.keyDown(document.activeElement || document.body, {key: 'Enter'})
+ await userEvent.keyboard('{Enter}')
// Item 2 should be expanded
- expect(item2).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(item2).toHaveAttribute('aria-expanded', 'true')
// Press ↑ to move focus to item 1
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowUp'})
+ await userEvent.keyboard('{ArrowUp}')
// Press Enter to collapse item 1
- fireEvent.keyDown(document.activeElement || document.body, {key: 'Enter'})
+ await userEvent.keyboard('{Enter}')
// Item 1 should be collapsed
- expect(item1).toHaveAttribute('aria-expanded', 'false')
+ await expect.element(item1).toHaveAttribute('aria-expanded', 'false')
// Press Enter again to expand item 1
- fireEvent.keyDown(document.activeElement || document.body, {key: 'Enter'})
+ await userEvent.keyboard('{Enter}')
// Item 1 should be expanded
- expect(item1).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(item1).toHaveAttribute('aria-expanded', 'true')
// Item 2 should still be expanded
- expect(screen.getByRole('treeitem', {name: 'Item 2'})).toHaveAttribute('aria-expanded', 'true')
+ await expect
+ .element(
+ page.getByRole('treeitem', {
+ name: 'Item 2',
+ exact: true,
+ }),
+ )
+ .toHaveAttribute('aria-expanded', 'true')
})
- it('can be controlled', () => {
+ it('can be controlled', async () => {
function TestTree() {
const [expanded, setExpanded] = React.useState(true)
return (
@@ -1599,24 +1742,32 @@ describe('State', () => {
render()
- const parent = screen.getByRole('treeitem', {name: 'Parent'})
- const child = screen.getByRole('treeitem', {name: 'Child'})
+ const parent = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
+ const child = page.getByRole('treeitem', {
+ name: 'Child',
+ exact: true,
+ })
+
+ const childElement = child.element()
// Parent should be expanded
- expect(parent).toHaveAttribute('aria-expanded', 'true')
- expect(child).toBeVisible()
+ await expect.element(parent).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(child).toBeVisible()
act(() => {
// Focus first item
- parent.focus()
+ parent.element().focus()
})
// Press ← to collapse the parent
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowLeft'})
+ await userEvent.keyboard('{ArrowLeft}')
// Parent should be collapsed
- expect(parent).toHaveAttribute('aria-expanded', 'false')
- expect(child).not.toBeVisible()
+ await expect.element(parent).toHaveAttribute('aria-expanded', 'false')
+ expect(childElement).not.toBeVisible()
})
})
@@ -1663,29 +1814,20 @@ describe('Asynchronous loading', () => {
render()
- const doneButton = screen.getByRole('button', {name: 'Load'})
-
- // Click load button to mimic async loading
- act(() => {
- fireEvent.click(doneButton)
+ const doneButton = page.getByRole('button', {
+ name: 'Load',
+ exact: true,
})
+ await userEvent.click(doneButton)
+
// Get live region after the first announcement creates it
- const liveRegion = await waitFor(() => {
- const region = getLiveRegion()
- expect(region.getMessage('polite')).toBe('Parent content loading')
- return region
- })
+ await expect.poll(() => getLiveRegion().getMessage('polite')).toBe('Parent content loading')
+ const liveRegion = getLiveRegion()
- // Click done button to mimic the completion of async loading
- act(() => {
- fireEvent.click(doneButton)
- })
+ await userEvent.click(doneButton)
- await waitFor(() => {
- // Live region should be updated
- expect(liveRegion.getMessage('polite')).toBe('Parent content loaded')
- })
+ await expect.poll(() => liveRegion.getMessage('polite')).toBe('Parent content loaded')
})
it('moves focus from loading item to first child', async () => {
@@ -1714,21 +1856,24 @@ describe('Asynchronous loading', () => {
render()
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
- const loadingItem = screen.getByRole('treeitem', {name: 'Loading...'})
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
+ const loadingItem = page.getByRole('treeitem', {
+ name: 'Loading...',
+ exact: true,
+ })
act(() => {
// Focus first item
- parentItem.focus()
+ parentItem.element().focus()
})
- // Press ↓ to move focus to loading item
- act(() => {
- fireEvent.keyDown(document.activeElement || document.body, {key: 'ArrowDown'})
- })
+ await userEvent.keyboard('{ArrowDown}')
// Loading item should be focused
- expect(loadingItem).toHaveFocus()
+ await expect.element(loadingItem).toHaveFocus()
await act(async () => {
await vi.advanceTimersByTimeAsync(400)
@@ -1739,10 +1884,13 @@ describe('Asynchronous loading', () => {
})
// Wait for async loading to complete
- const firstChild = screen.getByRole('treeitem', {name: 'Child 1'})
+ const firstChild = page.getByRole('treeitem', {
+ name: 'Child 1',
+ exact: true,
+ })
// First child should be focused
- expect(firstChild).toHaveFocus()
+ expect(firstChild.element()).toHaveFocus()
})
it('moves focus to parent item after closing error dialog', async () => {
@@ -1773,34 +1921,33 @@ describe('Asynchronous loading', () => {
}
render()
- const dialog = screen.getByRole('alertdialog')
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
+ const dialog = page.getByRole('alertdialog')
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
// Parent item should not be focused
- expect(parentItem).not.toHaveFocus()
+ await expect.element(parentItem).not.toHaveFocus()
// Dialog should be visible
- await vi.waitFor(() => {
- expect(dialog).toBeVisible()
- })
+ await expect.element(dialog).toBeVisible()
+ const dialogElement = dialog.element()
- // Press esc to close error dialog
- act(() => {
- fireEvent.keyDown(document, {key: 'Escape'})
- })
+ await userEvent.keyboard('{Escape}')
// Dialog should not be visible
- expect(dialog).not.toBeVisible()
+ expect(dialogElement).not.toBeVisible()
await act(async () => {
await vi.runAllTimersAsync()
})
// Parent item should be focused
- expect(parentItem).toHaveFocus()
+ expect(parentItem.element()).toHaveFocus()
})
- it('ignores arrow keys when error dialog is open', () => {
+ it('ignores arrow keys when error dialog is open', async () => {
render(
@@ -1813,29 +1960,29 @@ describe('Asynchronous loading', () => {
,
)
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
// Parent item should be expanded
- expect(parentItem).toHaveAttribute('aria-expanded', 'true')
-
- const retryButton = screen.getByRole('button', {name: 'Retry'})
- expect(retryButton).toHaveFocus()
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'true')
- // Press ←
- act(() => {
- fireEvent.keyDown(retryButton, {key: 'ArrowLeft'})
+ const retryButton = page.getByRole('button', {
+ name: 'Retry',
+ exact: true,
})
+ await expect.element(retryButton).toHaveFocus()
+
+ await userEvent.keyboard('{ArrowLeft}')
// Parent item should still be expanded
- expect(parentItem).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'true')
- // Press Backspace
- act(() => {
- fireEvent.keyDown(retryButton, {key: 'Backspace'})
- })
+ await userEvent.keyboard('{Backspace}')
// Parent item should still be expanded
- expect(parentItem).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'true')
})
it('should update `aria-expanded` if no content is loaded in', async () => {
@@ -1875,20 +2022,25 @@ describe('Asynchronous loading', () => {
render()
- const treeitem = screen.getByLabelText('Item 1')
- expect(treeitem).toHaveAttribute('aria-expanded', 'false')
- act(() => {
- fireEvent.click(screen.getByText('Item 1'))
+ const treeitem = page.getByRole('treeitem', {
+ name: 'Item 1',
+ exact: true,
})
+ await expect.element(treeitem).toHaveAttribute('aria-expanded', 'false')
+ await userEvent.click(
+ page.getByText('Item 1', {
+ exact: true,
+ }),
+ )
- expect(treeitem).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(treeitem).toHaveAttribute('aria-expanded', 'true')
await act(async () => {
await vi.advanceTimersByTimeAsync(1000)
})
- expect(treeitem).toHaveAttribute('aria-expanded', 'true')
- expect(screen.getByLabelText('No items found')).toBeInTheDocument()
+ expect(treeitem.element()).toHaveAttribute('aria-expanded', 'true')
+ expect(page.getByLabelText('No items found', {exact: true}).element()).toBeInTheDocument()
})
it('should have `aria-expanded` when directory is empty', async () => {
@@ -1913,21 +2065,50 @@ describe('Asynchronous loading', () => {
,
)
- const parentItem = screen.getByRole('treeitem', {name: 'Parent'})
+ const parentItem = page.getByRole('treeitem', {
+ name: 'Parent',
+ exact: true,
+ })
// Parent item should be expanded
- expect(parentItem).toHaveAttribute('aria-expanded', 'true')
+ await expect.element(parentItem).toHaveAttribute('aria-expanded', 'true')
// Current child should not have `aria-expanded`
- expect(screen.getByRole('treeitem', {name: 'child current'})).not.toHaveAttribute('aria-expanded')
+ await expect
+ .element(
+ page.getByRole('treeitem', {
+ name: 'child current',
+ exact: true,
+ }),
+ )
+ .not.toHaveAttribute('aria-expanded')
// Empty child should not have `aria-expanded` when closed
- expect(screen.getByRole('treeitem', {name: 'empty child'})).not.toHaveAttribute('aria-expanded')
+ await expect
+ .element(
+ page.getByRole('treeitem', {
+ name: 'empty child',
+ exact: true,
+ }),
+ )
+ .not.toHaveAttribute('aria-expanded')
- fireEvent.click(screen.getByRole('treeitem', {name: 'empty child'}))
+ await userEvent.click(
+ page.getByRole('treeitem', {
+ name: 'empty child',
+ exact: true,
+ }),
+ )
// Empty child should have `aria-expanded` when opened
- expect(screen.getByRole('treeitem', {name: 'empty child'})).toHaveAttribute('aria-expanded')
+ await expect
+ .element(
+ page.getByRole('treeitem', {
+ name: 'empty child',
+ exact: true,
+ }),
+ )
+ .toHaveAttribute('aria-expanded')
})
})
@@ -1957,10 +2138,10 @@ it('should render `TrailingAction`', async () => {
,
)
- expect(screen.getByRole('button', {hidden: true})).toHaveAttribute('aria-labelledby')
+ await expect.element(page.getByRole('button', {includeHidden: true})).toHaveAttribute('aria-labelledby')
})
-it('should have keyboard shortcut command as part of accessible name when using `TrailingAction`', () => {
+it('should have keyboard shortcut command as part of accessible name when using `TrailingAction`', async () => {
render(
,
)
- expect(screen.getByRole('treeitem', {name: /for more actions\.$/})).toBeInTheDocument()
+ await expect.element(page.getByRole('treeitem', {name: /for more actions\.$/})).toBeInTheDocument()
})
-it('should have keyboard shortcut command as part of accessible name when using `TrailingAction` and `aria-label`', () => {
+it('should have keyboard shortcut command as part of accessible name when using `TrailingAction` and `aria-label`', async () => {
render(
,
)
- expect(screen.getByRole('treeitem', {name: /for more actions\.$/})).toBeInTheDocument()
+ await expect.element(page.getByRole('treeitem', {name: /for more actions\.$/})).toBeInTheDocument()
})
-it('should activate the dialog for trailing action when keyboard shortcut is used', () => {
+it('should activate the dialog for trailing action when keyboard shortcut is used', async () => {
render(
,
)
- const treeItem = screen.getByRole('treeitem', {
+ const treeItem = page.getByRole('treeitem', {
name: /for more actions\.$/,
})
act(() => {
- treeItem.focus()
+ treeItem.element().focus()
})
- expect(treeItem).toHaveFocus()
+ await expect.element(treeItem).toHaveFocus()
- expect(screen.queryByRole('dialog')).not.toBeInTheDocument()
+ await expect.element(page.getByRole('dialog')).not.toBeInTheDocument()
- act(() => {
- fireEvent.keyDown(treeItem, {key: 'u', metaKey: true, shiftKey: true})
- })
+ await userEvent.keyboard('{Meta>}{Shift>}u{/Shift}{/Meta}')
- expect(screen.getByRole('dialog')).toBeInTheDocument()
+ await expect.element(page.getByRole('dialog')).toBeInTheDocument()
})
diff --git a/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.test.tsx b/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.test.tsx
index a080adf631d..9c37a65361e 100644
--- a/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.test.tsx
+++ b/packages/react/src/experimental/UnderlinePanels/UnderlinePanels.test.tsx
@@ -3,8 +3,8 @@
// public API and its integration with Tabs.
import type React from 'react'
-import {act, useState} from 'react'
-import {render, screen} from '@testing-library/react'
+import {useState} from 'react'
+import {act, render, screen} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import {describe, it, afterEach, beforeEach, expect, vi} from 'vitest'
import {CodeIcon, EyeIcon} from '@primer/octicons-react'
diff --git a/packages/react/src/hooks/__tests__/useMedia.test.tsx b/packages/react/src/hooks/__tests__/useMedia.test.tsx
index a2579704eb2..729ef97fc46 100644
--- a/packages/react/src/hooks/__tests__/useMedia.test.tsx
+++ b/packages/react/src/hooks/__tests__/useMedia.test.tsx
@@ -1,6 +1,5 @@
-import {render} from '@testing-library/react'
+import {act, render} from '@testing-library/react'
import {afterEach, describe, expect, it, vi} from 'vitest'
-import {act} from 'react'
import ReactDOM from 'react-dom/server'
import {useMedia, MatchMedia} from '../useMedia'