Files
headlessui/packages/@headlessui-react/src/components/disclosure/disclosure.test.tsx
T
2023-09-11 19:09:53 +02:00

960 lines
29 KiB
TypeScript

import { render } from '@testing-library/react'
import React, { createElement, Suspense, useEffect, useRef } from 'react'
import {
assertActiveElement,
assertDisclosureButton,
assertDisclosurePanel,
DisclosureState,
getByText,
getDisclosureButton,
getDisclosurePanel,
} from '../../test-utils/accessibility-assertions'
import { click, focus, Keys, MouseButton, press } from '../../test-utils/interactions'
import { suppressConsoleLogs } from '../../test-utils/suppress-console-logs'
import { Transition } from '../transitions/transition'
import { Disclosure } from './disclosure'
jest.mock('../../hooks/use-id')
afterAll(() => jest.restoreAllMocks())
function nextFrame() {
return new Promise<void>((resolve) => {
requestAnimationFrame(() => {
requestAnimationFrame(() => {
resolve()
})
})
})
}
describe('Safe guards', () => {
it.each([
['Disclosure.Button', Disclosure.Button],
['Disclosure.Panel', Disclosure.Panel],
])(
'should error when we are using a <%s /> without a parent <Disclosure />',
suppressConsoleLogs((name, Component) => {
expect(() => render(createElement<typeof Component>(Component))).toThrowError(
`<${name} /> is missing a parent <Disclosure /> component.`
)
})
)
it(
'should be possible to render a Disclosure without crashing',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>Contents</Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
})
)
})
describe('Rendering', () => {
describe('Disclosure', () => {
it(
'should be possible to render a Disclosure using a render prop',
suppressConsoleLogs(async () => {
render(
<Disclosure>
{({ open }) => (
<>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>Panel is: {open ? 'open' : 'closed'}</Disclosure.Panel>
</>
)}
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
await click(getDisclosureButton())
assertDisclosureButton({
state: DisclosureState.Visible,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.Visible, textContent: 'Panel is: open' })
})
)
it('should be possible to render a Disclosure in an open state by default', async () => {
render(
<Disclosure defaultOpen>
{({ open }) => (
<>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>Panel is: {open ? 'open' : 'closed'}</Disclosure.Panel>
</>
)}
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.Visible,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.Visible, textContent: 'Panel is: open' })
await click(getDisclosureButton())
assertDisclosureButton({ state: DisclosureState.InvisibleUnmounted })
})
it(
'should expose a close function that closes the disclosure',
suppressConsoleLogs(async () => {
render(
<Disclosure>
{({ close }) => (
<>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>
<button onClick={() => close()}>Close me</button>
</Disclosure.Panel>
</>
)}
</Disclosure>
)
// Focus the button
await focus(getDisclosureButton())
// Ensure the button is focused
assertActiveElement(getDisclosureButton())
// Open the disclosure
await click(getDisclosureButton())
// Ensure we can click the close button
await click(getByText('Close me'))
// Ensure the disclosure is closed
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Ensure the Disclosure.Button got the restored focus
assertActiveElement(getByText('Trigger'))
})
)
it(
'should expose a close function that closes the disclosure and restores to a specific element',
suppressConsoleLogs(async () => {
render(
<>
<button id="test">restoreable</button>
<Disclosure>
{({ close }) => (
<>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>
<button onClick={() => close(document.getElementById('test')!)}>
Close me
</button>
</Disclosure.Panel>
</>
)}
</Disclosure>
</>
)
// Focus the button
await focus(getDisclosureButton())
// Ensure the button is focused
assertActiveElement(getDisclosureButton())
// Open the disclosure
await click(getDisclosureButton())
// Ensure we can click the close button
await click(getByText('Close me'))
// Ensure the disclosure is closed
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Ensure the restoreable button got the restored focus
assertActiveElement(getByText('restoreable'))
})
)
it(
'should expose a close function that closes the disclosure and restores to a ref',
suppressConsoleLogs(async () => {
function Example() {
let elementRef = useRef(null)
return (
<>
<button ref={elementRef}>restoreable</button>
<Disclosure>
{({ close }) => (
<>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>
<button onClick={() => close(elementRef)}>Close me</button>
</Disclosure.Panel>
</>
)}
</Disclosure>
</>
)
}
render(<Example />)
// Focus the button
await focus(getDisclosureButton())
// Ensure the button is focused
assertActiveElement(getDisclosureButton())
// Open the disclosure
await click(getDisclosureButton())
// Ensure we can click the close button
await click(getByText('Close me'))
// Ensure the disclosure is closed
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Ensure the restoreable button got the restored focus
assertActiveElement(getByText('restoreable'))
})
)
it('should not crash when using Suspense boundaries', async () => {
render(
<Disclosure defaultOpen={true}>
<Disclosure.Button>Click me!</Disclosure.Button>
<Disclosure.Panel>
<Suspense fallback={null}>
<p>Hi there</p>
</Suspense>
</Disclosure.Panel>
</Disclosure>
)
})
})
describe('Disclosure.Button', () => {
it(
'should be possible to render a Disclosure.Button using a render prop',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button>{JSON.stringify}</Disclosure.Button>
<Disclosure.Panel></Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
textContent: JSON.stringify({ open: false }),
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
await click(getDisclosureButton())
assertDisclosureButton({
state: DisclosureState.Visible,
attributes: { id: 'headlessui-disclosure-button-1' },
textContent: JSON.stringify({ open: true }),
})
assertDisclosurePanel({ state: DisclosureState.Visible })
})
)
it(
'should be possible to render a Disclosure.Button using a render prop and an `as` prop',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button as="div" role="button">
{JSON.stringify}
</Disclosure.Button>
<Disclosure.Panel />
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
textContent: JSON.stringify({ open: false }),
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
await click(getDisclosureButton())
assertDisclosureButton({
state: DisclosureState.Visible,
attributes: { id: 'headlessui-disclosure-button-1' },
textContent: JSON.stringify({ open: true }),
})
assertDisclosurePanel({ state: DisclosureState.Visible })
})
)
describe('`type` attribute', () => {
it('should set the `type` to "button" by default', async () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
</Disclosure>
)
expect(getDisclosureButton()).toHaveAttribute('type', 'button')
})
it('should not set the `type` to "button" if it already contains a `type`', async () => {
render(
<Disclosure>
<Disclosure.Button type="submit">Trigger</Disclosure.Button>
</Disclosure>
)
expect(getDisclosureButton()).toHaveAttribute('type', 'submit')
})
it('should set the `type` to "button" when using the `as` prop which resolves to a "button"', async () => {
let CustomButton = React.forwardRef<HTMLButtonElement>((props, ref) => (
<button ref={ref} {...props} />
))
render(
<Disclosure>
<Disclosure.Button as={CustomButton}>Trigger</Disclosure.Button>
</Disclosure>
)
expect(getDisclosureButton()).toHaveAttribute('type', 'button')
})
it('should not set the type if the "as" prop is not a "button"', async () => {
render(
<Disclosure>
<Disclosure.Button as="div">Trigger</Disclosure.Button>
</Disclosure>
)
expect(getDisclosureButton()).not.toHaveAttribute('type')
})
it('should not set the `type` to "button" when using the `as` prop which resolves to a "div"', async () => {
let CustomButton = React.forwardRef<HTMLDivElement>((props, ref) => (
<div ref={ref} {...props} />
))
render(
<Disclosure>
<Disclosure.Button as={CustomButton}>Trigger</Disclosure.Button>
</Disclosure>
)
expect(getDisclosureButton()).not.toHaveAttribute('type')
})
})
})
describe('Disclosure.Panel', () => {
it(
'should be possible to render Disclosure.Panel using a render prop',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>{JSON.stringify}</Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
await click(getDisclosureButton())
assertDisclosureButton({
state: DisclosureState.Visible,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({
state: DisclosureState.Visible,
textContent: JSON.stringify({ open: true }),
})
})
)
it('should be possible to always render the Disclosure.Panel if we provide it a `static` prop', () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel static>Contents</Disclosure.Panel>
</Disclosure>
)
// Let's verify that the Disclosure is already there
expect(getDisclosurePanel()).not.toBe(null)
})
it('should be possible to use a different render strategy for the Disclosure.Panel', async () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel unmount={false}>Contents</Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({ state: DisclosureState.InvisibleHidden })
assertDisclosurePanel({ state: DisclosureState.InvisibleHidden })
// Let's open the Disclosure, to see if it is not hidden anymore
await click(getDisclosureButton())
assertDisclosureButton({ state: DisclosureState.Visible })
assertDisclosurePanel({ state: DisclosureState.Visible })
// Let's re-click the Disclosure, to see if it is hidden again
await click(getDisclosureButton())
assertDisclosureButton({ state: DisclosureState.InvisibleHidden })
assertDisclosurePanel({ state: DisclosureState.InvisibleHidden })
})
it(
'should expose a close function that closes the disclosure',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>
{({ close }) => <button onClick={() => close()}>Close me</button>}
</Disclosure.Panel>
</Disclosure>
)
// Focus the button
await focus(getDisclosureButton())
// Ensure the button is focused
assertActiveElement(getDisclosureButton())
// Open the disclosure
await click(getDisclosureButton())
// Ensure we can click the close button
await click(getByText('Close me'))
// Ensure the disclosure is closed
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Ensure the Disclosure.Button got the restored focus
assertActiveElement(getByText('Trigger'))
})
)
it(
'should expose a close function that closes the disclosure and restores to a specific element',
suppressConsoleLogs(async () => {
render(
<>
<button id="test">restoreable</button>
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>
{({ close }) => (
<button onClick={() => close(document.getElementById('test')!)}>Close me</button>
)}
</Disclosure.Panel>
</Disclosure>
</>
)
// Focus the button
await focus(getDisclosureButton())
// Ensure the button is focused
assertActiveElement(getDisclosureButton())
// Open the disclosure
await click(getDisclosureButton())
// Ensure we can click the close button
await click(getByText('Close me'))
// Ensure the disclosure is closed
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Ensure the restoreable button got the restored focus
assertActiveElement(getByText('restoreable'))
})
)
it(
'should expose a close function that closes the disclosure and restores to a ref',
suppressConsoleLogs(async () => {
function Example() {
let elementRef = useRef(null)
return (
<>
<button ref={elementRef}>restoreable</button>
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>
{({ close }) => <button onClick={() => close(elementRef)}>Close me</button>}
</Disclosure.Panel>
</Disclosure>
</>
)
}
render(<Example />)
// Focus the button
await focus(getDisclosureButton())
// Ensure the button is focused
assertActiveElement(getDisclosureButton())
// Open the disclosure
await click(getDisclosureButton())
// Ensure we can click the close button
await click(getByText('Close me'))
// Ensure the disclosure is closed
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Ensure the restoreable button got the restored focus
assertActiveElement(getByText('restoreable'))
})
)
})
})
describe('Composition', () => {
function Debug({ fn, name }: { fn: (text: string) => void; name: string }) {
useEffect(() => {
fn(`Mounting - ${name}`)
return () => {
fn(`Unmounting - ${name}`)
}
}, [fn, name])
return null
}
it(
'should be possible to control the Disclosure.Panel by wrapping it in a Transition component',
suppressConsoleLogs(async () => {
let orderFn = jest.fn()
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Debug name="Disclosure" fn={orderFn} />
<Transition>
<Debug name="Transition" fn={orderFn} />
<Disclosure.Panel>
<Transition.Child>
<Debug name="Transition.Child" fn={orderFn} />
</Transition.Child>
</Disclosure.Panel>
</Transition>
</Disclosure>
)
// Verify the Disclosure is hidden
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Open the Disclosure component
await click(getDisclosureButton())
// Verify the Disclosure is visible
assertDisclosurePanel({ state: DisclosureState.Visible })
// Unmount the full tree
await click(getDisclosureButton())
// Wait for all transitions to finish
await nextFrame()
await nextFrame()
// Verify that we tracked the `mounts` and `unmounts` in the correct order
expect(orderFn.mock.calls).toEqual([
['Mounting - Disclosure'],
['Mounting - Transition'],
['Mounting - Transition.Child'],
['Unmounting - Transition'],
['Unmounting - Transition.Child'],
])
})
)
})
describe('Keyboard interactions', () => {
describe('`Enter` key', () => {
it(
'should be possible to open the Disclosure with Enter',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>Contents</Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Focus the button
await focus(getDisclosureButton())
// Open disclosure
await press(Keys.Enter)
// Verify it is open
assertDisclosureButton({ state: DisclosureState.Visible })
assertDisclosurePanel({
state: DisclosureState.Visible,
attributes: { id: 'headlessui-disclosure-panel-2' },
})
// Close disclosure
await press(Keys.Enter)
assertDisclosureButton({ state: DisclosureState.InvisibleUnmounted })
})
)
it(
'should not be possible to open the disclosure with Enter when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button disabled>Trigger</Disclosure.Button>
<Disclosure.Panel>Content</Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Focus the button
await focus(getDisclosureButton())
// Try to open the disclosure
await press(Keys.Enter)
// Verify it is still closed
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
})
)
it(
'should be possible to close the disclosure with Enter when the disclosure is open',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>Contents</Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Focus the button
await focus(getDisclosureButton())
// Open disclosure
await press(Keys.Enter)
// Verify it is open
assertDisclosureButton({ state: DisclosureState.Visible })
assertDisclosurePanel({
state: DisclosureState.Visible,
attributes: { id: 'headlessui-disclosure-panel-2' },
})
// Close disclosure
await press(Keys.Enter)
// Verify it is closed again
assertDisclosureButton({ state: DisclosureState.InvisibleUnmounted })
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
})
)
})
describe('`Space` key', () => {
it(
'should be possible to open the disclosure with Space',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>Contents</Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Focus the button
await focus(getDisclosureButton())
// Open disclosure
await press(Keys.Space)
// Verify it is open
assertDisclosureButton({ state: DisclosureState.Visible })
assertDisclosurePanel({
state: DisclosureState.Visible,
attributes: { id: 'headlessui-disclosure-panel-2' },
})
})
)
it(
'should not be possible to open the disclosure with Space when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button disabled>Trigger</Disclosure.Button>
<Disclosure.Panel>Contents</Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Focus the button
await focus(getDisclosureButton())
// Try to open the disclosure
await press(Keys.Space)
// Verify it is still closed
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
})
)
it(
'should be possible to close the disclosure with Space when the disclosure is open',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>Contents</Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Focus the button
await focus(getDisclosureButton())
// Open disclosure
await press(Keys.Space)
// Verify it is open
assertDisclosureButton({ state: DisclosureState.Visible })
assertDisclosurePanel({
state: DisclosureState.Visible,
attributes: { id: 'headlessui-disclosure-panel-2' },
})
// Close disclosure
await press(Keys.Space)
// Verify it is closed again
assertDisclosureButton({ state: DisclosureState.InvisibleUnmounted })
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
})
)
})
})
describe('Mouse interactions', () => {
it(
'should be possible to open a disclosure on click',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>Contents</Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Open disclosure
await click(getDisclosureButton())
// Verify it is open
assertDisclosureButton({ state: DisclosureState.Visible })
assertDisclosurePanel({
state: DisclosureState.Visible,
attributes: { id: 'headlessui-disclosure-panel-2' },
})
})
)
it(
'should not be possible to open a disclosure on right click',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>Contents</Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Open disclosure
await click(getDisclosureButton(), MouseButton.Right)
// Verify it is still closed
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
})
)
it(
'should not be possible to open a disclosure on click when the button is disabled',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button disabled>Trigger</Disclosure.Button>
<Disclosure.Panel>Contents</Disclosure.Panel>
</Disclosure>
)
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Try to open the disclosure
await click(getDisclosureButton())
// Verify it is still closed
assertDisclosureButton({
state: DisclosureState.InvisibleUnmounted,
attributes: { id: 'headlessui-disclosure-button-1' },
})
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
})
)
it(
'should be possible to close a disclosure on click',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button>Trigger</Disclosure.Button>
<Disclosure.Panel>Contents</Disclosure.Panel>
</Disclosure>
)
// Open disclosure
await click(getDisclosureButton())
// Verify it is open
assertDisclosureButton({ state: DisclosureState.Visible })
// Click to close
await click(getDisclosureButton())
// Verify it is closed
assertDisclosureButton({ state: DisclosureState.InvisibleUnmounted })
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
})
)
it(
'should be possible to close the Disclosure by clicking on a Disclosure.Button inside a Disclosure.Panel',
suppressConsoleLogs(async () => {
render(
<Disclosure>
<Disclosure.Button>Open</Disclosure.Button>
<Disclosure.Panel>
<Disclosure.Button>Close</Disclosure.Button>
</Disclosure.Panel>
</Disclosure>
)
// Open the disclosure
await click(getDisclosureButton())
let closeBtn = getByText('Close')
expect(closeBtn).not.toHaveAttribute('id')
expect(closeBtn).not.toHaveAttribute('aria-controls')
expect(closeBtn).not.toHaveAttribute('aria-expanded')
// The close button should close the disclosure
await click(closeBtn)
// Verify it is closed
assertDisclosurePanel({ state: DisclosureState.InvisibleUnmounted })
// Verify we restored the Open button
assertActiveElement(getDisclosureButton())
})
)
})