How to Test Password Reset Flow (Mobile and Web)

Password reset is where frustrated users go when locked out. If the flow is broken, users give up and churn. It is also a common attack vector. Security and usability must balance. This guide covers t

March 28, 2026 · 3 min read · How-To Guides

Password reset is where frustrated users go when locked out. If the flow is broken, users give up and churn. It is also a common attack vector. Security and usability must balance. This guide covers testing both dimensions.

What to test

Request reset

  1. "Forgot password" link visible on login
  2. Email input accepts valid email
  3. Invalid email format rejected inline
  4. Non-existent email — ambiguous response (do not leak account existence)
  5. Rate-limit applied (prevent abuse)
  6. Confirmation message generic ("If an account exists, email sent")

Reset email

  1. Email arrives within minutes
  2. Email comes from verified sender (SPF, DKIM)
  3. Reset link clearly identifies as password reset
  4. Link has expiration (visible or stated)
  5. Link is unique (not guessable)
  6. Link is single-use (second use invalid)

Reset page

  1. Link opens reset form
  2. Form shows email (confirmation) or not (privacy)
  3. New password field with complexity rules visible
  4. Confirm password field
  5. Submit enabled when valid
  6. Server-side validates rules (not trusting client)
  7. Success navigates to login or auto-login

Post-reset

  1. User can login with new password
  2. Old password no longer works
  3. Existing sessions invalidated (per security policy)
  4. Confirmation email sent
  5. Login notifications fire for unusual device

Security

  1. Reset link not reusable
  2. Reset link expires (typically 1-24 hours)
  3. Rate limit on reset requests per email / IP
  4. Email sent via authenticated channel (not spoofed)
  5. Account does not unlock on reset request (still locked until reset completed if account was locked)
  6. Password not logged / not in URL
  7. Reset does not reveal user existence to non-user

Edge cases

  1. User requests multiple resets — most recent link wins, older invalidated
  2. User clicks old link → expired, offer to request new
  3. Email arrives after user manually resolved (cached)
  4. Link opens in wrong app (WebView vs native)
  5. Reset while logged in on another device — session preserved or cleared per policy
  6. Email contains "Hey [Name]" — name rendered correctly across clients
  7. Reset attempted for soft-deleted account — rejected

Accessibility

  1. Email form labeled
  2. Reset form inputs labeled
  3. Error messages announced
  4. Keyboard navigable
  5. Links in email accessible when opened

Mobile-specific

  1. Email link opens the app (deep link) or browser fallback
  2. Reset form mobile-friendly layout
  3. Password paste enabled (respects password managers)

Web-specific

  1. Reset URL works across browsers
  2. CORS / CSRF protected

Manual testing

Use a dedicated test email for each reset cycle. Test:

Automated

Integration test (backend)


def test_reset_request_sends_email(api_client, mock_mailer):
    api_client.post("/api/auth/request-reset", json={"email": "test@example.com"})
    assert mock_mailer.sent_count == 1
    assert "reset" in mock_mailer.last_email.subject.lower()

End-to-end (Playwright)


def test_reset_flow(page, mailbox):
    # Request
    page.goto("/login")
    page.click("text=Forgot password?")
    page.fill("#email", "test@example.com")
    page.click("text=Send reset link")
    # Fetch email from test mailbox
    link = mailbox.get_latest_link("reset")
    page.goto(link)
    page.fill("#new-password", "NewStrongP@ss456")
    page.fill("#confirm-password", "NewStrongP@ss456")
    page.click("text=Reset password")
    expect(page.locator("text=Password reset")).to_be_visible()

How SUSA handles reset

SUSA drives the reset request form. For full end-to-end (requires email interception), pair SUSA with a test mail capture like Mailtrap or a local SMTP sink.

The adversarial persona probes:


susatest-agent test myapp.apk --persona adversarial --steps 50 --flow password-reset

Common production bugs

  1. Reset link leaks user existence — 404 for nonexistent vs 200 for existent
  2. Rate limit absent — attacker spams reset emails as harassment
  3. Reset password allowed weak, login rejects it — server-side validation mismatch
  4. Link still works after password successfully changed — single-use not enforced
  5. Old sessions remain active — compromised session persists post-reset

Password reset is high-value, high-risk. Test thoroughly, secure properly.

Test Your App Autonomously

Upload your APK or URL. SUSA explores like 10 real users — finds bugs, accessibility violations, and security issues. No scripts.

Try SUSA Free