import { describe, expect, test } from 'vitest' import { render, screen, within } from '@testing-library/react' import React, { useState } from 'react' import SectionCanvas from './SectionCanvas' import type { Section } from '@/lib/state/store' function Wrapper({ withSelect = true }: { withSelect?: boolean }) { const [sections, setSections] = useState([ { type: 'hero', props: { heading: 'H', subheading: '' } }, { type: 'faq', props: { items: [] } }, { type: 'cta', props: { text: 'Go', href: '#' } }, ]) const onMove = (from: number, to: number) => { setSections((prev) => { const next = prev.slice() const [sp] = next.splice(from, 1) next.splice(to, 0, sp) return next }) } const onRemove = () => {} const onSelect = withSelect ? () => {} : undefined return } describe('SectionCanvas aria-labels on control buttons', () => { test('Select/Up/Down/Remove buttons expose index-based aria-labels', () => { render() const list = screen.getByTestId('section-canvas') const items = within(list).getAllByTestId(/sec-item-/) // check first item labels (index 0) const first = items[0] const sel0 = within(first).getByLabelText('Select 0') as HTMLButtonElement const up0 = within(first).getByLabelText('Up 0') as HTMLButtonElement const down0 = within(first).getByLabelText('Down 0') as HTMLButtonElement const rm0 = within(first).getByLabelText('Remove 0') as HTMLButtonElement expect(sel0).toBeInTheDocument() expect(up0).toBeInTheDocument() expect(down0).toBeInTheDocument() expect(rm0).toBeInTheDocument() expect(sel0.title).toBe(sel0.getAttribute('aria-label')) expect(up0.title).toBe(up0.getAttribute('aria-label')) expect(down0.title).toBe(down0.getAttribute('aria-label')) expect(rm0.title).toBe(rm0.getAttribute('aria-label')) // check last item labels (index 2) const last = items[2] const sel2 = within(last).getByLabelText('Select 2') as HTMLButtonElement const up2 = within(last).getByLabelText('Up 2') as HTMLButtonElement const down2 = within(last).getByLabelText('Down 2') as HTMLButtonElement const rm2 = within(last).getByLabelText('Remove 2') as HTMLButtonElement expect(sel2).toBeInTheDocument() expect(up2).toBeInTheDocument() expect(down2).toBeInTheDocument() expect(rm2).toBeInTheDocument() expect(sel2.title).toBe(sel2.getAttribute('aria-label')) expect(up2.title).toBe(up2.getAttribute('aria-label')) expect(down2.title).toBe(down2.getAttribute('aria-label')) expect(rm2.title).toBe(rm2.getAttribute('aria-label')) }) test('Up/Down buttons still present when onSelect not provided', () => { render() const list = screen.getByTestId('section-canvas') const items = within(list).getAllByTestId(/sec-item-/) // when onSelect is undefined, Select button should not exist expect(within(items[0]).queryByLabelText('Select 0')).toBeNull() // Up/Down/Remove must still be present expect(within(items[0]).getByLabelText('Up 0')).toBeInTheDocument() expect(within(items[0]).getByLabelText('Down 0')).toBeInTheDocument() expect(within(items[0]).getByLabelText('Remove 0')).toBeInTheDocument() }) })