Module 11 · Human Verification
One-Time Passwords & Multi-Factor Authentication
This lab covers four practical MFA patterns: TOTP authentication, a controlled Email OTP environment built for deterministic automation practice, real Email OTP delivery so you can experience how OTP email actually arrives, and a realistic SMS simulation (production SMS normally costs money — this free lab doesn't pretend otherwise). Practice the automated flows deterministically while experiencing how real-world OTP delivery works. Along the way you'll also exercise the negative paths every serious suite needs: expiry, wrong codes, resend invalidation, and lockout.
1 · TOTP Authenticator (Google / Microsoft Authenticator)
A time-based code derived from a shared secret and the current time — the same concept Google Authenticator or Microsoft Authenticator use. In Playwright you generate it on the fly with otplib — no device needed. Set up a secret, then verify a 6-digit token against it.
Provision a shared secret
Shared secret (Base32)
—
otpauth URI
—
—
A real authenticator app scans the QR code once, then generates a fresh 6-digit code every 30s from the secret alone — no network round-trip. This page won't show the secret again after you leave — treat it like a real shared secret.
Generate & verify a token
The compute button is a convenience so you can try it by hand — in a real test your script calls authenticator.generate(secret).
✓ TOTP verified
✗ Not verified
Current Execution
TOTPNo request executed yet — set up a secret to begin.
Status
Not run yet
Response body
Not run yet
TOTP (Time-based One-Time Password, RFC 6238) is what powers Google Authenticator, Microsoft Authenticator, Authy, and most hardware-free 2FA. Both sides — server and authenticator app — independently derive the same 6-digit code from a shared secret and the current time, so no network round-trip is needed at verification time.
Everything in this section is real: the secret this lab issues is a genuine Base32 TOTP secret, the QR code encodes a real otpauth:// URI any authenticator app can scan, and POST /totp/verify performs a real cryptographic check — nothing here is simulated.
2 · Email OTP
Controlled Test EnvironmentIn production, the application generates the OTP and hands it to an email delivery provider. You then retrieve the code from the actual inbox and enter it — the same pattern professional test suites use with a controlled test mailbox instead of a real inbox.
Recommended for automation practice — the controlled inbox provides deterministic OTP retrieval.
Request a verification code
Retrieve the code
Open your simulated inbox and copy the 6-digit code — real email retrieval works the same way, just against your actual mailbox.
Inbox is empty — request a code, then fetch.
Enter & verify
✓ Code verified
A session token was issued:
—
✗ Not verified
Current Execution
EMAILNo request executed yet — send a code to begin.
Status
Not run yet
Response body
Not run yet
The code is delivered out-of-band: the application generates it, then hands it to an email provider for delivery. The chain is Application → OTP generator → Email provider → Inbox → User → Verification endpoint. This lab attempts real delivery when a free email provider is configured, and always keeps a simulated inbox as a guaranteed fallback so the lab never becomes unusable.
3 · Real Email OTP — Live Experience
Manual · Real SMTPSend a real OTP through this platform's SMTP delivery, then retrieve it by hand from your actual inbox — the closest this lab gets to a live, real-world experience, without automating a personal mailbox.
✉ Learning Note — Real Email vs Automation
REAL EMAIL
Application → OTP → SMTP → Your Inbox → You Read OTP
AUTOMATION
Test → OTP → Controlled Inbox → Playwright → Verify
Use Real Email to experience actual delivery. Use the controlled Email OTP section above for automation practice. See Learn More below ↓
Send a real verification email
Open your real mailbox
Check the inbox (and Spam folder) for the address above, then copy the 6-digit code. There's no "Fetch inbox" button here on purpose — reading your actual mailbox is the point of this section.
Enter & verify
✓ Code verified
A session token was issued:
—
✗ Not verified
Current Execution
REAL EMAILNo request executed yet — send a real email to begin.
Status
Not run yet
Response body
Not run yet
This section sends a real OTP through the platform's own SMTP delivery (the same provider abstraction the Email OTP section can also trigger) to whatever address you enter, then asks you to retrieve and enter it by hand. There's no Fetch inbox button here on purpose — reading an actual mailbox is the whole point of this exercise.
✓ Professional pattern
Test
→ Request OTP
→ Controlled Test Mailbox / Email API
→ Retrieve Email
→ Extract OTP
→ Enter OTP
→ Verify
✗ Not recommended
Test
→ Automate Gmail login UI
→ Scrape inbox
→ Extract OTP
Real-world QA teams retrieve OTP emails programmatically through a dedicated test mailbox or email API (Mailosaur, Mailslurp, Mailtrap, a self-hosted catcher) — not by driving a personal Gmail inbox. For deterministic Playwright practice on this platform, use the Email OTP section above instead: its simulated inbox is always populated, whether or not real delivery is active.
// Real-world pattern: retrieve a REAL OTP email via a dedicated test
// mailbox/API — never scrape a personal Gmail UI, and never read the
// OTP from the app's own network response.
const res = await request.post('/api/arena/otp/request', { data: { channel: 'email', recipient: testInboxAddress } });
// res never contains the OTP — only masked recipient + delivery metadata.
const message = await testMailboxClient.waitForMessage({ to: testInboxAddress, timeout: 15000 });
const otp = message.text.match(/\b(\d{6})\b/)[1];
await page.getByTestId('otp-real-code-input').fill(otp);
await page.getByTestId('otp-real-verify-btn').click();
await expect(page.getByTestId('otp-real-verify-success')).toBeVisible();
Credentials never leave the server
The SMTP username/password (a Gmail App Password, in this platform's case) lives only in server-side configuration. It is never sent to the browser, and never present in an API response, the DOM, cookies, localStorage, or sessionStorage.
The OTP itself is never returned by the API
POST /request and POST /verify only ever return masked recipient, delivery status, expiry, and — on a successful verify — a session token. The 6-digit code only ever exists in the actual delivered email.
Failures are generic on purpose
If a real send fails, the response and UI show a generic fallback message — never a raw SMTP error, which could otherwise leak provider/config details.
This is the same experience as: your bank emailing a one-time code when you sign in from a new device, a SaaS product confirming a new sign-up, or a password-reset email containing a verification code.
In each case, a human reads the email and types the code back in — this section reproduces exactly that, using this platform's own SMTP delivery.
It requires storing personal credentials in test automation
Automating a Gmail login means your test suite needs a real account password (or an OAuth token) checked into CI — a genuine security liability.
Interactive login blocks most CI environments
2FA prompts, "new device" verification, and CAPTCHAs on Gmail's own login page are specifically designed to stop exactly this kind of automation.
It's slow and brittle
Gmail's UI changes independently of your app under test — a selector change there breaks tests that have nothing to do with your product.
A dedicated test mailbox/API solves all three
No personal credentials, no interactive login, a stable API contract — which is exactly what this platform's own simulated inbox (Email OTP section) demonstrates.
Wrong code
Same contract as Email OTP: returns invalid_code plus attemptsLeft.
Expired code
Codes expire after 120 seconds — a real-world reason real OTP emails sometimes "don't work" if you're slow to check your inbox.
Lockout after 5 wrong attempts
Returns 429 with lockedForSeconds, identical to every other OTP flow here.
Real delivery unavailable
If SMTP isn't configured or today's quota is exhausted, the request still succeeds at the API level but no email reaches a real inbox — the banner above explains why.
Shared state with Email OTP
This section calls the same backend as Email OTP above. Using the identical address in both sections shares code/lockout state — use different addresses (or Reset) to test them independently.
4 · SMS OTP — Realistic Simulation
Realistic SimulationReal SMS delivery normally requires an SMS provider (e.g. Twilio) and can incur per-message charges. This free lab uses a realistic SMS simulation so you can learn and automate the complete OTP lifecycle without paying for SMS.
Deterministic and free — the simulated gateway provides the same reliable OTP source for automation practice as Email OTP above.
Send a verification SMS
Open the simulated message
Open the simulated SMS below and copy the 6-digit code — a real integration would poll your SMS provider's test-number API the same way.
Inbox is empty — request a code, then fetch.
Enter & verify
✓ Code verified
A session token was issued:
—
✗ Not verified
Current Execution
SMSNo request executed yet — send a code to begin.
Status
Not run yet
Response body
Not run yet
The code is delivered out-of-band: the application generates it, then hands it to an SMS gateway for delivery over the mobile carrier network. The chain is Application → OTP generator → SMS provider → Carrier network → Phone → User → Verification endpoint. Real SMS delivery normally requires a paid provider, so this free lab uses a realistic simulated SMS gateway instead.