61 lines
2.3 KiB
TypeScript
61 lines
2.3 KiB
TypeScript
import { describe, test, expect } from 'vitest'
|
|
import { pageSchema, type Page } from '@/lib/schema/page'
|
|
import { exportPage } from '@/lib/exporter/html'
|
|
|
|
const makePage = (): Page =>
|
|
pageSchema.parse({
|
|
title: 'Form Tokens Regression',
|
|
locale: 'en',
|
|
theme: { primaryColor: '#0ea5e9', fontFamily: 'Inter' },
|
|
sections: [],
|
|
form: {
|
|
actionUrl: '',
|
|
fields: [
|
|
{ type: 'text', name: 'fullName', label: 'Full Name', required: true, maxLength: 50 },
|
|
{ type: 'email', name: 'email', label: 'Email', required: true },
|
|
{ type: 'tel', name: 'phone', label: 'Phone', pattern: '^\\+?[0-9\\- ]{7,}$' },
|
|
{ type: 'radio', name: 'size', label: 'Size', options: ['S','M','L'] },
|
|
{ type: 'select', name: 'plan', label: 'Plan', options: ['Free','Pro'] },
|
|
{ type: 'checkbox', name: 'agree', label: 'Agree to terms', required: true },
|
|
{ type: 'textarea', name: 'message', label: 'Message' },
|
|
],
|
|
spamProtection: { honeypotFieldName: '_hp', minSubmitSeconds: 2 },
|
|
},
|
|
seo: { title: 'SEO', description: 'Desc' },
|
|
analytics: { ga4MeasurementId: '', metaPixelId: '', customHeadHtml: '' },
|
|
})
|
|
|
|
describe('Exporter - form tokens regression', () => {
|
|
test('renders inputs with required/pattern/maxLength and spam-protection markers', () => {
|
|
const { html, js } = exportPage(makePage())
|
|
|
|
// required + maxlength on text
|
|
expect(html).toMatch(/name="fullName"[^"]*[^>]*required/)
|
|
expect(html).toMatch(/name="fullName"[^"]*[^>]*maxlength="50"/)
|
|
|
|
// email required
|
|
expect(html).toMatch(/name="email"[^"]*[^>]*required/)
|
|
|
|
// tel pattern
|
|
expect(html).toMatch(/name="phone"[^"]*[^>]*pattern="\^\\\+\?\[0-9\\\- \]\{7,\}\$"/)
|
|
|
|
// radio/select options present
|
|
// 라디오 인풋은 id 속성이 먼저 오므로 type만으로 확인
|
|
expect(html).toContain('type="radio"')
|
|
expect(html).toContain('<select')
|
|
expect(html).toContain('<option value="Free">Free</option>')
|
|
|
|
// checkbox/textarea
|
|
expect(html).toContain('type="checkbox"')
|
|
expect(html).toContain('<textarea')
|
|
|
|
// spam-protection hidden inputs
|
|
expect(html).toContain('type="hidden"')
|
|
expect(html).toContain('name="_hp"')
|
|
expect(html).toContain('name="_ts"')
|
|
|
|
// js fills timestamp
|
|
expect(js).toMatch(/querySelector\('input\[name="_ts"\]'\)/)
|
|
})
|
|
})
|