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);