Authentication
OTP verification
Six-digit code modal validates length, supports paste, and rejects expired codes.
User story
As a user signing in from a new device, I want to enter a one-time code so my account stays protected.
Acceptance criteria
- Six independent inputs auto-advance focus on each digit
- Pasting a 6-digit value distributes across all inputs
- Verify is disabled until all 6 inputs are filled
- Expired code shows a recoverable error
Manual test steps
- 1.Trigger OTP modal from registration
- 2.Paste 123456 into the first input
- 3.Click Verify
- 4.Confirm dashboard land
Expected result
Pasting 123456 fills all 6 inputs and the Verify button enables.
Possible bug risks
- Paste drops digits when first input has focus mid-type
- Verify can be invoked via keyboard while disabled
- Resend button has no cooldown timer
Reference Playwright spec
otp-verification.spec.ts
ts1234567891011121314
import { test, expect } from '@playwright/test';
test('otp paste fills six fields @smoke', async ({ page }) => {
await page.goto('https://lab.hakdogan.com/register');
// open the OTP modal via the demo flow
await page.getByRole('button', { name: /continue to verification/i }).click();
const first = page.locator('#otp-0');
await first.focus();
await page.keyboard.insertText('123456');
await page.getByRole('button', { name: /^verify$/i }).click();
await expect(page).toHaveURL(/\/dashboard$/);
});