Tested on 26 October 2026 · Developer guide
Email verification testing: from temporary inbox to verified form
Reading an email code is one step in a verification test. Your application must also accept the code, reject wrong or expired values, and prevent reuse. This runnable Python example connects a real browser form to a disposable gecici.email inbox so you can check the full application result.
Scope: Chrome form + hosted API simulation. The message is inserted with the authenticated simulation endpoint. This test does not exercise SMTP, an external sender, an LLM or a browser-use agent. It creates no real account.
- 01
Create
A disposable inbox and a server-side challenge for this QA session.
- 02
Read
Extract the synthetic code from the hosted inbox into a masked field.
- 03
Verify
Submit the form and check the application’s verified state.
- 04
Clean up
Reject reuse, delete the inbox and stop the local server.
1. Run the local application
Use Python 3.8 or later with a working HTTPS certificate store. There are no pip dependencies, model keys or paid services. Review the code, then run these commands in a new folder. The fixed Git revision points to the tested source.
git clone https://github.com/codeonthetable/gecici-email.git
cd gecici-email
git checkout 050da5aa0b977212d95ff128852b3e241078ace3
python3 -m unittest discover -s tests -p 'test_verification_app.py' -v
python3 examples/verification_app.py --serveOpen http://127.0.0.1:8797 in Chrome. The fixture listens only on your computer. If the port is busy, add --port 8798 and use that port in the URL. The Windows Python launcher may be py instead of python3.
2. Check the browser form, not just extraction
- Start QA session: creates a new inbox and a random six-digit challenge. The application inserts a synthetic message into that inbox.
- Try wrong code: confirms rejection. Then select Read test inbox; the received code enters the masked field without being printed.
- Verify code: submits the actual form. Require verified (HTTP 200) before calling the test successful.
- Check replay rejection: checks that a completed challenge cannot be used again. Finally, select Delete test inbox.
| Result | What it proves |
|---|---|
| message_simulated · 201 | Synthetic message inserted into our own QA inbox. |
| wrong_code · 400 | The application rejected an incorrect code. |
| code_loaded · 200 | The hosted inbox returned the test code; verification was not complete yet. |
| verified · 200 | The form submitted the code and the server accepted it. |
| already_used · 409 | The verified challenge refused another submission. |
| cleaned · 200 | The disposable inbox was deleted through the API. |
Ten local tests passed on Python 3.8.3rc1. Expiry, the five-attempt limit, session requirements, host/origin checks and cleanup retry were covered locally. The separate Chrome run used one hosted QA inbox and deleted it. These are test results, not production traffic or successful AI usage.
3. Handle failures and cleanup
not_arrived · 408: no code is available yet. Check message insertion before retrying within the 120-second challenge lifetime.expired · 410 / attempt_limit · 429: clean up, then start a new QA session. Mailbox lifetime and application challenge lifetime are separate.cleanup_failed_retry: retry Delete test inbox while the server is still running. Ctrl+C also attempts cleanup and prints only aggregate shutdown_cleanup and sessions fields.
A forced process kill cannot execute cleanup; the inbox may remain until expiry. Deletion is logical API deletion, not a guarantee of physical erasure. Never disable TLS checks to solve a certificate error.
Use the pattern in your own tests
In a separate test environment, replace simulation with your application’s existing sender. Pass only the inbox address to your form; retain the bearer token in your test runner. Wait for the correct message with a deadline, fill the code, assert the application’s verified state, and delete the inbox in a finally block. Use a new inbox for each parallel run.
The Read test inbox button is a QA convenience. A production application must not expose an endpoint that retrieves the user’s verification code. This sequential teaching server is not a production authentication design, delivery benchmark or load test. Requests are tagged qa-test; addresses, tokens, message bodies and codes are not logged.
Implementation references: Python http.server · secrets · Full test instructions