diff --git a/src/shared/ui/Popover/Popover.svelte.test.ts b/src/shared/ui/Popover/Popover.svelte.test.ts
new file mode 100644
index 0000000..603c7a9
--- /dev/null
+++ b/src/shared/ui/Popover/Popover.svelte.test.ts
@@ -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');
+ });
+});
diff --git a/src/shared/ui/Popover/PopoverHarness.svelte b/src/shared/ui/Popover/PopoverHarness.svelte
new file mode 100644
index 0000000..566e154
--- /dev/null
+++ b/src/shared/ui/Popover/PopoverHarness.svelte
@@ -0,0 +1,21 @@
+
+
+
+
+ {#snippet trigger(props)}
+
+ {/snippet}
+ {#snippet children({ close })}
+
+
+
+ {/snippet}
+