Feature/popover #48
@@ -0,0 +1,49 @@
|
||||
import {
|
||||
fireEvent,
|
||||
render,
|
||||
screen,
|
||||
} from '@testing-library/svelte';
|
||||
import Harness from './PopoverHarness.svelte';
|
||||
|
||||
/**
|
||||
* Resolve the popover content element (the [popover] ancestor of the test content).
|
||||
*/
|
||||
function getContent(): HTMLElement {
|
||||
return screen.getByTestId('content').closest('[popover]') as HTMLElement;
|
||||
}
|
||||
|
||||
describe('Popover', () => {
|
||||
it('renders the trigger with aria wiring, closed by default', () => {
|
||||
render(Harness);
|
||||
const trigger = screen.getByRole('button', { name: 'Open' });
|
||||
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
||||
expect(trigger).toHaveAttribute('aria-haspopup', 'dialog');
|
||||
expect(trigger).toHaveAttribute('popovertarget');
|
||||
expect(getContent()).toHaveAttribute('data-state', 'closed');
|
||||
});
|
||||
|
||||
it('opens via the popover toggle and syncs aria-expanded + data-state', async () => {
|
||||
render(Harness);
|
||||
const trigger = screen.getByRole('button', { name: 'Open' });
|
||||
// jsdom does not auto-invoke popovertarget; call the API the browser would.
|
||||
getContent().showPopover();
|
||||
await Promise.resolve();
|
||||
expect(getContent()).toHaveAttribute('data-state', 'open');
|
||||
expect(trigger).toHaveAttribute('aria-expanded', 'true');
|
||||
});
|
||||
|
||||
it('opens when the parent sets open=true (state -> browser)', async () => {
|
||||
render(Harness, { open: true });
|
||||
await Promise.resolve();
|
||||
expect(getContent()).toHaveAttribute('data-state', 'open');
|
||||
});
|
||||
|
||||
it('close() hides the popover and resets aria-expanded', async () => {
|
||||
render(Harness, { open: true });
|
||||
await Promise.resolve();
|
||||
const trigger = screen.getByRole('button', { name: 'Open' });
|
||||
await fireEvent.click(screen.getByTestId('close'));
|
||||
expect(getContent()).toHaveAttribute('data-state', 'closed');
|
||||
expect(trigger).toHaveAttribute('aria-expanded', 'false');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
<!--
|
||||
Component: PopoverHarness
|
||||
Test-only fixture: renders Popover with a button trigger and simple content
|
||||
exposing the close() callback.
|
||||
-->
|
||||
<script lang="ts">
|
||||
import Popover from './Popover.svelte';
|
||||
|
||||
let { open = $bindable(false) }: { open?: boolean } = $props();
|
||||
</script>
|
||||
|
||||
<Popover bind:open>
|
||||
{#snippet trigger(props)}
|
||||
<button {...props}>Open</button>
|
||||
{/snippet}
|
||||
{#snippet children({ close })}
|
||||
<div data-testid="content">
|
||||
<button onclick={close} data-testid="close">Close</button>
|
||||
</div>
|
||||
{/snippet}
|
||||
</Popover>
|
||||
Reference in New Issue
Block a user