User registration is often the first interaction users have with your product. It needs to work flawlessly. This guide covers how to thoroughly test signup flows, password resets, and email verification using Docmailer.
What to Test
A complete signup flow typically includes:
- Form validation (email format, password strength)
- Account creation in database
- Welcome email delivery
- Verification email with working link/code
- Link expiration handling
- Resend verification functionality
Testing Email Verification
Basic Flow
// 1. Create a test inbox
const inbox = await docmailer.createInbox();
// 2. Submit signup form
await signup({
email: inbox.email,
password: 'SecurePass123!',
name: 'Test User'
});
// 3. Check for verification email
const emails = await docmailer.listEmails(inbox.id);
const verifyEmail = emails.find(e =>
e.subject.includes('Verify') || e.subject.includes('Confirm')
);
expect(verifyEmail).toBeDefined();
// 4. Extract verification link
const linkMatch = verifyEmail.html.match(
/href="(https?:\/\/[^"]*(?:verify|confirm)[^"]*)"/i
);
const verifyLink = linkMatch[1];
// 5. Click the link
const response = await fetch(verifyLink);
expect(response.ok).toBe(true);
// 6. Verify account is now active
const user = await getUser(inbox.email);
expect(user.emailVerified).toBe(true);
Testing OTP/Code Verification
// Some apps use 6-digit codes instead of links
const codeMatch = verifyEmail.text.match(/\b(\d{6})\b/);
const verificationCode = codeMatch[1];
await submitVerificationCode(inbox.email, verificationCode);
const user = await getUser(inbox.email);
expect(user.emailVerified).toBe(true);
Testing Password Reset
// 1. Request password reset
await requestPasswordReset(inbox.email);
// 2. Get the reset email
const emails = await docmailer.listEmails(inbox.id);
const resetEmail = emails.find(e =>
e.subject.toLowerCase().includes('password')
);
// 3. Extract reset link
const resetLink = resetEmail.html.match(
/href="(https?:\/\/[^"]*reset[^"]*)"/i
)[1];
// 4. Set new password
await fetch(resetLink);
await setNewPassword('NewSecurePass456!');
// 5. Verify login works with new password
const loginResult = await login(inbox.email, 'NewSecurePass456!');
expect(loginResult.success).toBe(true);
💡 Pro Tip: Test that old password no longer works after reset, and that the reset link expires after use.
Testing Welcome Emails
const welcomeEmail = emails.find(e =>
e.subject.includes('Welcome') || e.subject.includes('Getting Started')
);
// Check email content
expect(welcomeEmail.html).toContain('Test User'); // Personalization
expect(welcomeEmail.html).toContain('Get Started'); // CTA
expect(welcomeEmail.from).toBe('hello@yourapp.com');
Edge Cases to Test
Expired Verification Links
// Wait for link to expire (or mock time)
await advanceTime({ hours: 25 });
const response = await fetch(verifyLink);
// Should show "link expired" page, not error
Resend Verification
// Request new verification email
await resendVerification(inbox.email);
const emails = await docmailer.listEmails(inbox.id);
// Should have 2 verification emails now
expect(emails.filter(e => e.subject.includes('Verify'))).toHaveLength(2);
// Old link should be invalidated
const oldResponse = await fetch(oldVerifyLink);
expect(oldResponse.status).toBe(400);
Duplicate Signup Attempt
// Try to sign up with same email
const result = await signup({
email: inbox.email,
password: 'AnotherPass123!'
});
expect(result.error).toContain('already exists');
Testing with AI Agents
With Claude Code or other AI agents, you can describe tests in natural language:
> Test the full signup flow:
> 1. Create a Docmailer inbox
> 2. Go to myapp.com/signup
> 3. Fill the form with the test email
> 4. Submit and wait for verification email
> 5. Extract the verification link and click it
> 6. Verify the success message appears