From c688cf0233968ddf7131ec0055c38a7d9999e39b Mon Sep 17 00:00:00 2001 From: Srividya Ramaswamy Date: Mon, 26 Oct 2026 18:07:08 -0700 Subject: [PATCH] test(accordion): cover SPEC expansion ownership and disclosure anatomy Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 4b66f3ef-85ac-4405-bd35-dcc167a077b1 --- .changeset/wise-owls-build.md | 5 ++ .../components/accordion/accordion.test.tsx | 46 +++++++++++++++++++ 2 files changed, 51 insertions(+) create mode 100644 .changeset/wise-owls-build.md diff --git a/.changeset/wise-owls-build.md b/.changeset/wise-owls-build.md new file mode 100644 index 0000000000..064435dc68 --- /dev/null +++ b/.changeset/wise-owls-build.md @@ -0,0 +1,5 @@ +--- + +--- + + diff --git a/packages/agentic/components/src/components/accordion/accordion.test.tsx b/packages/agentic/components/src/components/accordion/accordion.test.tsx index 52496a9d45..bf8217a99e 100644 --- a/packages/agentic/components/src/components/accordion/accordion.test.tsx +++ b/packages/agentic/components/src/components/accordion/accordion.test.tsx @@ -33,6 +33,52 @@ function getTitleStyle(component: RenderResult): TextStyle { } describe('Accordion', () => { + it('ACC-001 ignores defaultExpanded while controlled and requests the inverse of each supplied value', async () => { + const onExpandedChange = jest.fn(); + const component = await renderAccordion({ expanded: true, defaultExpanded: false, onExpandedChange }); + + await fireEvent.press(getHeader(component)); + await fireEvent.press(getHeader(component)); + expect(onExpandedChange.mock.calls).toEqual([[false], [false]]); + expect(getHeader(component).props.accessibilityState.expanded).toBe(true); + + await component.rerender(); + await fireEvent.press(getHeader(component)); + expect(onExpandedChange.mock.calls).toEqual([[false], [false], [true]]); + expect(getHeader(component).props.accessibilityState.expanded).toBe(false); + }); + + it('ACC-004 retains the body identity and hides descendants only while collapsed', async () => { + const component = await renderAccordion({ bodyContent: { children: Persistent details } }); + const bodyId = getBody(component).props.id; + + expect(getHeader(component).props.accessibilityControls).toBe(bodyId); + expect(getHeader(component).props['aria-controls']).toBe(bodyId); + expect(getBody(component).props.accessibilityElementsHidden).toBe(true); + expect(getBody(component).props.importantForAccessibility).toBe('no-hide-descendants'); + expect(component.getByText('Persistent details', { includeHiddenElements: true })).toBeOnTheScreen(); + + await fireEvent.press(getHeader(component)); + expect(getBody(component).props.id).toBe(bodyId); + expect(getBody(component).props.accessibilityElementsHidden).toBe(false); + expect(getBody(component).props.importantForAccessibility).toBeUndefined(); + expect(component.getByText('Persistent details')).toBeOnTheScreen(); + + await fireEvent.press(getHeader(component)); + expect(getBody(component).props.id).toBe(bodyId); + expect(getBody(component).props.accessibilityElementsHidden).toBe(true); + expect(getBody(component).props.importantForAccessibility).toBe('no-hide-descendants'); + }); + + it.each(['chevronStart', 'chevronEnd'] as const)('ACC-002 omits null optional header slots in %s layout', async (layout) => { + const component = await renderAccordion({ layout, title: null, leadingIcon: null, accessibilityLabel: 'Details' }); + expect(component.queryByTestId('accordion-title')).toBeNull(); + expect(component.queryByTestId('accordion-leading-icon')).toBeNull(); + expect(getHeader(component).children).toHaveLength(1); + expect(getHeader(component).props.accessibilityLabel).toBe('Details'); + expect(component.getByTestId('accordion-chevron-icon').props.accessible).toBe(false); + }); + it('renders a default header, default icon, and hidden body wiring', async () => { const component = await renderAccordion({}); const header = getHeader(component);