From: Mark Otto Date: Tue, 6 Jan 2026 06:33:37 +0000 (-0800) Subject: Add tests for new form components X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=35dc86922045538ce7c0a2d70c68865e6cfb1ca0;p=thirdparty%2Fbootstrap.git Add tests for new form components --- diff --git a/js/tests/unit/otp-input.spec.js b/js/tests/unit/otp-input.spec.js index 406f236c85..8d98408473 100644 --- a/js/tests/unit/otp-input.spec.js +++ b/js/tests/unit/otp-input.spec.js @@ -243,6 +243,40 @@ describe('OtpInput', () => { expect(inputs[0].value).toEqual('1') }) + + it('should distribute multi-character input across inputs', () => { + fixtureEl.innerHTML = getOtpHtml() + + const otpEl = fixtureEl.querySelector('.otp-input') + new OtpInput(otpEl) // eslint-disable-line no-new + const inputs = otpEl.querySelectorAll('input') + + inputs[0].focus() + // Simulate autofill that puts multiple characters in first input + inputs[0].value = '1234' + inputs[0].dispatchEvent(createEvent('input')) + + expect(inputs[0].value).toEqual('1') + expect(inputs[1].value).toEqual('2') + expect(inputs[2].value).toEqual('3') + expect(inputs[3].value).toEqual('4') + expect(document.activeElement).toEqual(inputs[3]) + }) + + it('should not advance when entering digit in last input', () => { + fixtureEl.innerHTML = getOtpHtml() + + const otpEl = fixtureEl.querySelector('.otp-input') + new OtpInput(otpEl) // eslint-disable-line no-new + const inputs = otpEl.querySelectorAll('input') + + inputs[5].focus() + inputs[5].value = '9' + inputs[5].dispatchEvent(createEvent('input')) + + expect(inputs[5].value).toEqual('9') + expect(document.activeElement).toEqual(inputs[5]) + }) }) describe('keydown handling', () => { @@ -301,6 +335,86 @@ describe('OtpInput', () => { expect(document.activeElement).toEqual(inputs[3]) }) + + it('should not navigate left when at first input', () => { + fixtureEl.innerHTML = getOtpHtml() + + const otpEl = fixtureEl.querySelector('.otp-input') + new OtpInput(otpEl) // eslint-disable-line no-new + const inputs = otpEl.querySelectorAll('input') + + inputs[0].focus() + + const arrowEvent = new KeyboardEvent('keydown', { + key: 'ArrowLeft', + bubbles: true + }) + inputs[0].dispatchEvent(arrowEvent) + + expect(document.activeElement).toEqual(inputs[0]) + }) + + it('should not navigate right when at last input', () => { + fixtureEl.innerHTML = getOtpHtml() + + const otpEl = fixtureEl.querySelector('.otp-input') + new OtpInput(otpEl) // eslint-disable-line no-new + const inputs = otpEl.querySelectorAll('input') + + inputs[5].focus() + + const arrowEvent = new KeyboardEvent('keydown', { + key: 'ArrowRight', + bubbles: true + }) + inputs[5].dispatchEvent(arrowEvent) + + expect(document.activeElement).toEqual(inputs[5]) + }) + + it('should shift values left on Delete key', () => { + fixtureEl.innerHTML = getOtpHtml() + + const otpEl = fixtureEl.querySelector('.otp-input') + const otp = new OtpInput(otpEl) + const inputs = otpEl.querySelectorAll('input') + + otp.setValue('123456') + inputs[2].focus() + + const deleteEvent = new KeyboardEvent('keydown', { + key: 'Delete', + bubbles: true + }) + inputs[2].dispatchEvent(deleteEvent) + + expect(inputs[0].value).toEqual('1') + expect(inputs[1].value).toEqual('2') + expect(inputs[2].value).toEqual('4') + expect(inputs[3].value).toEqual('5') + expect(inputs[4].value).toEqual('6') + expect(inputs[5].value).toEqual('') + }) + + it('should not move focus on backspace when current input has value', () => { + fixtureEl.innerHTML = getOtpHtml() + + const otpEl = fixtureEl.querySelector('.otp-input') + new OtpInput(otpEl) // eslint-disable-line no-new + const inputs = otpEl.querySelectorAll('input') + + inputs[1].value = '5' + inputs[1].focus() + + const backspaceEvent = new KeyboardEvent('keydown', { + key: 'Backspace', + bubbles: true + }) + inputs[1].dispatchEvent(backspaceEvent) + + // Should stay on same input (browser handles clearing the value) + expect(document.activeElement).toEqual(inputs[1]) + }) }) describe('paste handling', () => { diff --git a/js/tests/unit/strength.spec.js b/js/tests/unit/strength.spec.js index c79a389848..e65033401c 100644 --- a/js/tests/unit/strength.spec.js +++ b/js/tests/unit/strength.spec.js @@ -106,6 +106,40 @@ describe('Strength', () => { expect(strength._input).toEqual(otherInput) }) + + it('should handle missing input gracefully', () => { + fixtureEl.innerHTML = ` +
+
+
+
+
+
+ ` + + const strengthEl = fixtureEl.querySelector('.strength') + const strength = new Strength(strengthEl) + + expect(strength._input).toBeNull() + expect(strength.getStrength()).toBeNull() + }) + + it('should use element directly when input config is an element', () => { + fixtureEl.innerHTML = ` +
+ +
+
+
+
+ ` + + const strengthEl = fixtureEl.querySelector('.strength') + const inputEl = fixtureEl.querySelector('#my-password') + const strength = new Strength(strengthEl, { input: inputEl }) + + expect(strength._input).toEqual(inputEl) + }) }) describe('getStrength', () => {