Skip to content

Playwright

Terminal window
npm install --save-dev @playwright/test @inboxical/playwright
playwright.config.ts
export default {
use: {
baseURL: 'http://localhost:3000',
},
}

Set your API key:

.env.test
INBOXICAL_API_KEY=ixk_live_...

The recommended approach is to use createMailboxFixture() for automatic inbox lifecycle management:

tests/fixtures.ts
import { test as base } from '@playwright/test'
import { InboxicalMailbox, createMailboxFixture } from '@inboxical/playwright'
export const test = base.extend<{ mailbox: InboxicalMailbox }>({
mailbox: createMailboxFixture(),
})

The fixture automatically cleans up the inbox after each test, even on failure.

tests/signup.spec.ts
import { test } from './fixtures'
import { expect } from '@playwright/test'
test('welcome email is sent after signup', async ({ page, mailbox }) => {
const { email } = await mailbox.create({ name: 'signup-test' })
await page.goto('/register')
await page.fill('[name=email]', email)
await page.fill('[name=password]', 'test-password-123')
await page.click('[type=submit]')
await expect(page).toHaveURL('/dashboard')
// Wait for the welcome email
const message = await mailbox.waitForMessage({ timeout: 30 })
expect(message.subject).toBe('Welcome to MyApp!')
})
test('verification code flow', async ({ page, mailbox }) => {
const { email } = await mailbox.create()
await page.goto('/register')
await page.fill('[name=email]', email)
await page.fill('[name=password]', 'test-password-123')
await page.click('[type=submit]')
// Wait for verification email and extract the code
const message = await mailbox.waitForMessage({ timeout: 30 })
const code = await mailbox.extractCode()
// Enter the code on the verification page
await page.fill('#verification-code', code)
await page.click('#verify-button')
await expect(page.locator('text=Email verified')).toBeVisible()
})
test('verification link works', async ({ page, mailbox }) => {
const { email } = await mailbox.create()
await page.goto('/register')
await page.fill('[name=email]', email)
await page.fill('[name=password]', 'test-password-123')
await page.click('[type=submit]')
// Get the verification email
const message = await mailbox.waitForMessage({ timeout: 30 })
// Extract the link from the HTML body
const match = message.body_html.match(/href="(https?:\/\/[^"]+verify[^"]+)"/)
expect(match).not.toBeNull()
const verifyUrl = match![1]
// Click through
await page.goto(verifyUrl)
await expect(page.locator('text=Email verified')).toBeVisible()
})

You can also use InboxicalMailbox directly without the fixture:

import { test, expect } from '@playwright/test'
import { InboxicalMailbox } from '@inboxical/playwright'
test('email test', async ({ page }) => {
const mailbox = new InboxicalMailbox()
const { email } = await mailbox.create()
// ... test logic ...
await mailbox.cleanup() // Manual cleanup
})
  • The mailbox fixture handles create/cleanup automatically
  • Use page.waitForURL after form submit before calling waitForMessage
  • Run sharded for parallel CI: playwright test --shard=1/4
  • Access the underlying SDK client via mailbox.getClient() for advanced operations