import { describe, it, expect } from 'vitest' import { pageSchema, type Page } from '@/lib/schema/page' import { exportPage } from '@/lib/exporter/html' function makePage(fields: Page['form']['fields']): Page { return pageSchema.parse({ title: 'Matrix', locale: 'en', theme: { primaryColor: '#0ea5e9', fontFamily: 'Inter' }, sections: [], form: { actionUrl: '', fields, spamProtection: { honeypotFieldName: '_hp', minSubmitSeconds: 2 }, }, seo: { title: 'SEO', description: 'Desc' }, }) } describe('Exporter - form helptext matrix (required/maxLength/pattern/help)', () => { it('text: required + maxLength + help → has required, maxlength, help id and aria-describedby', () => { const page = makePage([ { type: 'text', name: 'nick', label: 'Nickname', required: true, maxLength: 10, help: 'Public name' }, ]) const html = exportPage(page).html expect(html).toContain('id="field-nick"') expect(html).toMatch(/name="nick"[^"]*[^>]*required/) expect(html).toMatch(/name="nick"[^"]*[^>]*maxlength="10"/) expect(html).toContain('id="field-nick-help"') expect(html).toContain('aria-describedby="field-nick-help"') }) it('tel: pattern only, no help → has pattern, no aria-describedby', () => { const page = makePage([ { type: 'tel', name: 'phone', label: 'Phone', required: false, pattern: '^\\+?[0-9\\- ]{7,}$' }, ]) const html = exportPage(page).html expect(html).toMatch(/name="phone"[^"]*[^>]*pattern="\^\\\+\?\[0-9\\\- \]\{7,\}\$"/) expect(html).not.toContain('field-phone-help') // ensure no false aria-describedby expect(html).not.toMatch(/name="phone"[^"]*[^>]*aria-describedby=/) }) it('select: help present → select has aria-describedby and help element exists', () => { const page = makePage([ { type: 'select', name: 'plan', label: 'Plan', required: false, options: ['Free','Pro'], help: 'Choose one' }, ]) const html = exportPage(page).html expect(html).toContain('id="field-plan"') expect(html).toContain('aria-describedby="field-plan-help"') expect(html).toContain('id="field-plan-help"') }) it('radio: help present → fieldset has aria-describedby; radios do not individually', () => { const page = makePage([ { type: 'radio', name: 'size', label: 'Size', required: false, options: ['S','M'], help: 'Pick one' }, ]) const html = exportPage(page).html // fieldset wiring expect(html).toContain('