Overview
Keystone’s email testing system enables automated tests to create temporary email inboxes, receive emails, and extract verification codes, links, and other data. This feature is essential for testing email-based workflows like user registration, password resets, and order confirmations.Key Features
- On-demand inbox creation - Generate unique email addresses for each test
- Real-time email delivery - Receive emails via SendGrid webhooks
- Data extraction - Extract codes, links, and custom patterns from emails
- Organization isolation - Complete separation between different organizations
- Auto-cleanup - Inboxes automatically expire after 24 hours
How It Works
The email testing workflow follows these steps:- Create Inbox → Generate a unique test email address
- Use in Application → Fill forms with the test email
- Wait for Email → Poll until the email arrives
- Extract Data → Get verification codes, links, or custom content
- Continue Testing → Use extracted data in subsequent steps
Email Address Format
Email addresses follow this format: +@withkeystonemail.com Examples: Components:org_prefix: Unique identifier for your organization (auto-generated)inbox_name: Your chosen inbox identifier@withkeystonemail.com: Keystone’s email domain
Email Testing Steps
EMAIL_CREATE_INBOX
Creates or retrieves a test email inbox for receiving emails during test execution.Unique name for the inbox. Use timestamps or random values for uniqueness across test runs.
Custom email address to use instead of auto-generated format
Variable name to store the generated email address
WAIT_FOR_EMAIL
Waits for an email to arrive in the specified inbox with optional filtering.Email address to check. Supports variable interpolation.
Maximum wait time in seconds
Filter by sender address (partial match)
Filter by email subject (partial match)
Variable name to store the received email data
EMAIL_EXTRACT
Extracts specific data from a received email.Variable containing email data from WAIT_FOR_EMAIL
Type of extraction:
code- Extract verification codes (6-digit, 4-digit, alphanumeric)link- Extract URLs from the emailsubject- Get the email subject linesender- Get the sender email addresscustom- Use custom regex pattern
For
link type: text of the link to findFor
custom type: regex pattern to matchVariable name to store the extracted value
Complete Examples
User Signup Flow
-
Create email inbox
- Step type: EMAIL_CREATE_INBOX
- Inbox name: signup-
- Store as: TEST_EMAIL
-
Fill signup form
- Type email address using variable
- Type password
- Click signup button
-
Wait for verification email
- Step type: WAIT_FOR_EMAIL
- Check inbox:
- Subject filter: “Verify your email”
- Timeout: 30 seconds
- Store as: VERIFY_EMAIL
-
Extract verification code
- Step type: EMAIL_EXTRACT
- From variable: VERIFY_EMAIL
- Extract type: code
- Store as: VERIFY_CODE
-
Complete verification
- Type verification code using
- Click verify button
Password Reset Flow
-
Setup test email
- Step type: EMAIL_CREATE_INBOX
- Inbox name: reset-pw-test
- Store as: USER_EMAIL
-
Request password reset
- Navigate to forgot password page
- Type email using
- Click reset button
-
Get reset link from email
- Step type: WAIT_FOR_EMAIL
- Check inbox:
- Subject filter: “Reset your password”
- Store as: RESET_EMAIL
-
Extract reset link
- Step type: EMAIL_EXTRACT
- From variable: RESET_EMAIL
- Extract type: link
- Link text: “Reset Password”
- Store as: RESET_URL
-
Complete password reset
- Navigate to
- Type new password
Order Confirmation
-
Setup customer email
- Step type: EMAIL_CREATE_INBOX
- Inbox name: order-test
- Store as: CUSTOMER_EMAIL
-
Complete purchase
- (Your checkout steps here)
-
Wait for order confirmation
- Step type: WAIT_FOR_EMAIL
- Check inbox:
- From filter: [email protected]
- Subject filter: “Order Confirmation”
- Store as: ORDER_EMAIL
-
Extract order number
- Step type: EMAIL_EXTRACT
- From variable: ORDER_EMAIL
- Extract type: custom
- Pattern: Order #(\w+)
- Store as: ORDER_ID
-
Verify order
- Navigate to order status page using
Advanced Usage
Using Timestamps for Unique Inboxes
To ensure unique inbox names across test runs:- Step type: EMAIL_CREATE_INBOX
- Inbox name: test-
- Store as: UNIQUE_EMAIL
Multiple Email Filtering
When expecting multiple emails, use filters to find the right one:- Step type: WAIT_FOR_EMAIL
- Check inbox:
- From filter: [email protected]
- Subject filter: “Invoice”
- Timeout: 120 seconds
- Store as: INVOICE_EMAIL
Extracting Multiple Values
You can extract different data from the same email: First extraction - Get verification code:- Step type: EMAIL_EXTRACT
- From variable: SIGNUP_EMAIL
- Extract type: code
- Store as: CODE
- Step type: EMAIL_EXTRACT
- From variable: SIGNUP_EMAIL
- Extract type: link
- Link text: “Activate”
- Store as: ACTIVATION_URL
Code Pattern Recognition
The system automatically recognizes various code formats:- 6-digit codes:
123456 - 4-digit codes:
1234 - Alphanumeric:
ABC123 - Labeled codes:
Code: 123456,PIN: 1234 - OTP formats:
OTP: 567890
Troubleshooting
Common Issues
Ensure your test environment has
ORGANIZATION_ID or ORG_ID configured.Possible causes:
- Email delivery delayed
- Incorrect filters (fromAddress/subject)
- Application didn’t send email
- Wrong inbox name
- Increase timeout value
- Remove or adjust filters
- Check application logs
- Verify inbox name matches
Cause: Trying to extract from email before waiting for it.Solution: Ensure WAIT_FOR_EMAIL step has
storeAs parameter.Possible causes:
- Email format doesn’t match expected patterns
- Code is in HTML-only section
- Custom format needs regex
Best Practices
- Use unique inbox names - Add timestamps or random values
- Set reasonable timeouts - 30-60 seconds usually sufficient
- Use filters wisely - Only when multiple emails expected
- Store email data - Always use
storeAsin WAIT_FOR_EMAIL - Test incrementally - Verify each step works before adding more
Debug Information
Email data structure contains these fields:- id: Unique email identifier
- subject: Email subject line
- from: Sender email address
- to: Recipient email address
- text: Plain text email body
- html: HTML email body
- headers: Email headers (Message-ID, Date, etc.)
- received_at: Timestamp when email was received
Technical Details
Infrastructure
- Email Domain:
withkeystonemail.com - Provider: SendGrid Inbound Parse
- Storage: PostgreSQL
- Cleanup: Automatic after 24 hours
- Rate Limits: 100 emails/hour per organization
Security
- Organization-level isolation
- No cross-organization email access
- Automatic expiration
- API key authentication for runners
Limitations
- Maximum email size: 10MB
- Attachment support: Basic (stored references)
- Custom domains: Not currently supported
- Email sending: Receive-only system
Email Flow Architecture
The email testing system follows this flow:- Your Application → Sends email via your email service
- SendGrid → Receives and processes the email
- Webhook Delivery → SendGrid forwards to Keystone
- Keystone Backend → Stores email in database
- Test Runner → Polls for new emails
- Email Retrieved → Test continues with email data
The email system is idempotent - re-running tests with the same inbox name will clear previous emails and start fresh.

