test(inputs) : tests mode contrôlé email + commentaire caret jsdom

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-03 11:58:06 +02:00
parent 6081f0c90c
commit 4e2303c471
2 changed files with 18 additions and 1 deletions
@@ -258,4 +258,20 @@ describe('MalioInputEmail', () => {
const emits = wrapper.emitted('update:modelValue')! const emits = wrapper.emitted('update:modelValue')!
expect(emits[emits.length - 1]).toEqual(['user@example.com']) expect(emits[emits.length - 1]).toEqual(['user@example.com'])
}) })
it('émet la valeur sanitisée en mode contrôlé', async () => {
const wrapper = mountComponent({modelValue: ''})
await wrapper.get('input').setValue(' a b @ c.com ')
expect(wrapper.emitted('update:modelValue')!.at(-1)).toEqual(['ab@c.com'])
})
it('resynchronise le DOM en mode contrôlé même quand la valeur sanitisée égale déjà modelValue', async () => {
// L'utilisateur ajoute un espace en fin alors que la valeur nettoyée vaut déjà modelValue.
// Le parent ne « changera » pas modelValue → Vue ne re-patche pas le DOM ; l'écriture
// manuelle target.value = sanitized est donc indispensable pour retirer l'espace affiché.
const wrapper = mountComponent({modelValue: 'ab@c.com'})
const input = wrapper.get('input')
await input.setValue('ab@c.com ')
expect(input.element.value).toBe('ab@c.com')
})
}) })
+2 -1
View File
@@ -185,7 +185,8 @@ const onInput = (event: Event) => {
if (sanitized !== raw) { if (sanitized !== raw) {
// `<input type="email">` ne supporte pas l'API de sélection : // `<input type="email">` ne supporte pas l'API de sélection :
// selectionStart vaut null, setSelectionRange lève. On garde défensivement. // selectionStart vaut null et setSelectionRange lève en navigateur.
// (En jsdom selectionStart peut renvoyer un nombre, d'où le code gardé ci-dessous.)
const caret = target.selectionStart const caret = target.selectionStart
target.value = sanitized target.value = sanitized
if (caret !== null) { if (caret !== null) {