コンテンツにスキップ

手元で通るテストは、1 つの変更だけで CI でも動きます。API キー を CI システムのシークレットから渡すことです。このページでは、その方法、並列実行が互いに干渉しないアドレスの使い方、各実行のメールをまとめたプルリクエストへのレポート、クラウドのコーディングエージェントにアクセスを与える方法を説明します。

アプリの Project settings → API keys でキーを作成し(API キー を参照)、PROXYMAIL_QA_API_KEY という名前のシークレットとして保存します。GitHub Actions では次のとおりです。

.github/workflows/e2e.yml
jobs:
e2e:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v7
- uses: actions/setup-node@v7
with:
node-version: 22
- run: npm ci
- run: npx playwright install --with-deps
- run: npx playwright test
env:
PROXYMAIL_QA_API_KEY: ${{ secrets.PROXYMAIL_QA_API_KEY }}

ほかの CI システムでも同じです。GitLab ではマスクされた CI/CD 変数、CircleCI ではコンテキストまたはプロジェクト変数、Jenkins では認証情報の環境変数を使います。キーはリポジトリにもログにも含めないでください。

キーは 1 つのプロジェクト内で有効なので、CI 専用のプロジェクト(少なくとも専用のキー)を用意してください。そうすればアドレスが手動で使うものと分かれ、CI のキーを取り消しても誰にも影響しません。

実行ごとに 1 つのアドレスとプラスタグ

Section titled “実行ごとに 1 つのアドレスとプラスタグ”

Free アカウントのアドレスは合計 500 件、1 日最大 50 件で、頻繁に動くパイプラインでは使い切ることがあります。Team プランには制限がありません。テストごとに新しいアドレスは不要です。name+anything@ 宛てのメールは name@ に届き、タグ付きアドレスで待機すると、そのタグ宛てのメールだけが見つかります。

そこで、実行ごとに 1 つのアドレスを作成し、各テストに専用のタグを付けます。

One address, a tag per test
// Once per run (Playwright's globalSetup, say): POST /v1/addresses
const base = 'k7f2x9ab12cd@mailclub.dev';
// In each test: sign up with a tagged version of it…
const address = base.replace('@', `+${process.env.GITHUB_RUN_ID}-${testInfo.workerIndex}-${Date.now()}@`);
// …then wait on that same tagged address.
// GET /v1/addresses/{address}/code only finds mail sent to that tag.

Node.js クライアント では、qa.createAddress() を 1 回、テストごとに qa.waitForCode(tagged, { since }) を使います。

登録フォームで + を受け付けないアプリもあります。その場合はテストごとにアドレスを作成してください。タグに使える文字は 特殊なメールアドレス にあります。

テストがフォームを送信した時刻を since に渡すと、以前のステップや実行のメールを拾うことがなくなります。

const submitted = new Date();
await page.getByRole('button', { name: 'Sign up' }).click();
// GET /v1/addresses/{address}/code?since=<submitted, ISO 8601>

キーごとのリクエスト上限は、Free で 1 分あたり 60、Team で 600 です(制限)。待機はどれだけ長く続いても(最大 30 秒)1 リクエストなので、Free でも少数の並列ワーカーなら問題ありません。大規模なスイートでは Team プランを使うか、パイプラインごとにキーを分けてください。

実行の最後に DELETE /v1/addresses/{address} でアドレスを削除します。たとえば Playwright の globalTeardown で行います。残したものは期限切れ時に削除されます。ベースアドレスを削除すると、そのタグ宛てのメールも削除されます。

Proxy Mail QA アクションは、ジョブのメールテストを 1 つの 実行 にまとめ、確認した内容をプルリクエストに投稿します。届いたメールとテスト送信から届くまでの時間、コード、各リンクの行き先、実行した メールチェック(Labs でスパムチェックが有効な場合は、迷惑メールに入りそうなメールの数も含む)、配信停止・特典・クーポンのチェック、失敗したテスト、届かなかったメールです。同じレポートはジョブのサマリーにも入り、プロジェクトの全員がアプリで実行を開けます。QA report for this run を使うと、実行のアドレスとメールを QA レポート として印刷または PDF で保存できます。

.github/workflows/e2e.yml
jobs:
e2e:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v7
- uses: aaquib90/proxymail-qa-action@v1
with:
api-key: ${{ secrets.PROXYMAIL_QA_API_KEY }}
- run: npm ci
- run: npx playwright test
env:
PROXYMAIL_QA_API_KEY: ${{ secrets.PROXYMAIL_QA_API_KEY }}

このアクションは、後続のステップに PROXYMAIL_QA_RUN を設定します。Node.js クライアント(0.5.0 以降)、Python ヘルパー、Detox と Appium のヘルパー がこれを読むため、テストが既に行っている呼び出しが実行に追加されます。ほかの モバイル用ヘルパー は、キーと同じ方法で受け取ります。XCUITest は環境変数、Espresso は instrumentation 引数、Flutter は --dart-define、Maestro は -e です。ほかのツールからは、ID をヘッダーで送ってください: Proxy-Mail-QA-Run: $PROXYMAIL_QA_RUN。

ジョブの後、成否にかかわらず、アクションは実行を終了してレポートを投稿し、プッシュのたびにコメントを更新します。実行が失敗になるのは、テストが待ったメールが届かなかった、届くべきでないメールが届いた、メールチェックが失敗した、テストが失敗した、配信停止後にマーケティングメールが届いた、1 人が特典を 2 回受け取った、受け付けるべきでないクーポンが受け付けられた、またはメモでそう指定された場合です。テストが通ってもその場合にジョブを失敗させるには、fail-job: true を設定します。同じ名前の実行は 1 つのコメントを共有するため、マトリックスジョブには別の名前を付けてください: name: e2e (${{ matrix.browser }})。

レポートは、同じ名前の直近 10 件の完了済み実行とも比較し、変化した点を一覧にします。到着がいつもよりかなり遅かったメール、1 通ではなく 2 通届くようになったテスト、初めて失敗した、またはときどき失敗するテスト、新たに失敗するようになったメールのチェック、前回は成功したのに実行されなかった、または失敗するようになったステップ(待機、件数、配信停止、オファーとクーポンのチェック)、そして新しい送信元やリンク先のサイトです。これが機能するのは、実行ごとに名前を同じにしているからです。

フォークからのプルリクエストにはシークレットが渡されないため、その場合アクションは警告を出し、実行を開始しません。

@v1 は 1.x の各リリースに追従するため、変更しなくても修正が届きます。変更を自分のタイミングで取り込みたい場合は、代わりにリリースのコミットを固定し、そのバージョンをコメントに書きます: uses: aaquib90/proxymail-qa-action@<commit> # v1.0.1。コミットは タグのページ にあり、Dependabot が固定したコミットを最新に保ちます。

実行には、アドレス、コード(クーポンの割引額とチェックアウトの応答を含む)、所要時間、チェックの判定、失敗したテストの名前とエラー、各リンクのサイトとパスが保存されます。パスのうちトークンに見える部分は隠されます。メールの本文や件名、サインイン用トークンが通常含まれるリンクのクエリは保存しません。実行は 90 日間保存されます。

それ以外の環境(別の CI システムやエージェントのセッション)では、POST /v1/runs で実行を開始し、その ID を Proxy-Mail-QA-Run ヘッダーで送り、POST /v1/runs/{id}/finish で完了させ、GET /v1/runs/{id}?format=markdown でレポートを取得します。Node.js クライアントでは qa.startRun()、qa.finishRun()、qa.runReport() です。REST API を参照してください。

各メールがどのテストから来たか

Section titled “各メールがどのテストから来たか”

レポートでは、各メールがどのテストのものかを示し、失敗したテストとそのメールの状況を一覧にできます。

Playwright: proxymail-qa/playwright から test をインポートして、その qa フィクスチャ(すべての呼び出しでテスト名を伝えるクライアント)を使い、失敗したテスト、不安定なテスト、合計を記録するレポーターを追加します。失敗したテストの行には、失敗したステップやブラウザ操作(At “Enter the code › locator.fill(…)” など)が示されます:

playwright.config.ts
export default defineConfig({
reporter: [['list'], ['proxymail-qa/playwright/reporter']],
});
signup.spec.ts
import { test, expect } from 'proxymail-qa/playwright';
test('sign-up sends one code', async ({ page, qa }) => {
const { address } = await qa.createAddress();
// …sign up, wait for the code, check the email…
});

pytest: Python ヘルパーの フックを conftest.py にインポートします:

conftest.py
from proxymail_qa import pytest_runtest_setup, pytest_runtest_teardown, pytest_runtest_logreport, pytest_sessionfinish

モバイルテスト: 各 モバイルヘルパー はテスト名を受け取ります。Swift、Kotlin、Dart では ProxyMailQA(test:)、Maestro スクリプトの env では TEST、Detox と Appium では現在の Jest テスト(または setTest)です。

その他のツールは、パーセントエンコードしたテスト名を Proxy-Mail-QA-Test ヘッダーで送り、結果を POST /v1/runs/{id}/tests に送ります(REST API)。どちらも実行の外では何もせず、テスト自体を失敗させることはありません。

待機が空で返ったとき、レスポンスには Proxy Mail QA でわかる範囲の理由が含まれます(hint、および受信を拒否したメールについては refused)。CI でよくある原因は、ステージング環境のメールプロバイダーです。サンドボックスやテストモードでは確認済みのアドレスにしか送信しないため、メールが送り出されません。GET /v1/addresses/{address}/delivery は待たずにアドレスを確認します。詳しくは テストメールが届かない場合 を参照してください。

すべての実行が一斉に失敗する場合や、API が 5xx エラーを返す場合は、テストを変更する前に ステータスページ を確認してください。

クラウドのコーディングエージェント

Section titled “クラウドのコーディングエージェント”

ブラウザでの MCP server へのサインインには人の操作が必要なため、クラウドで動くエージェントは代わりに API キー を Bearer トークン として送ります。そのために作ったプロジェクトのキーを渡してください。

アクションの前のステップで MCP の設定を書き、キーはシークレットから取得し、エージェントに必要なツールを許可します:

.github/workflows/claude.yml
- name: Proxy Mail QA for Claude
run: |
cat > /tmp/mcp.json << 'EOF'
{
"mcpServers": {
"proxymail-qa": {
"type": "http",
"url": "https://api.proxymail.qa/mcp",
"headers": { "Authorization": "Bearer ${{ secrets.PROXYMAIL_QA_API_KEY }}" }
}
}
}
EOF
- uses: anthropics/claude-code-action@v1
with:
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
claude_args: |
--mcp-config /tmp/mcp.json
--allowedTools mcp__proxymail-qa__get_project,mcp__proxymail-qa__create_address,mcp__proxymail-qa__wait_for_code,mcp__proxymail-qa__wait_for_link,mcp__proxymail-qa__check_delivery,mcp__proxymail-qa__delete_address

GitHub Copilot コーディングエージェント

Section titled “GitHub Copilot コーディングエージェント”

リポジトリの Settings → Copilot → MCP servers に次を追加します:

{
"mcpServers": {
"proxymail-qa": {
"type": "http",
"url": "https://api.proxymail.qa/mcp",
"headers": { "Authorization": "Bearer $COPILOT_MCP_PROXYMAIL_QA_API_KEY" },
"tools": ["get_project", "create_address", "wait_for_code", "wait_for_link", "check_delivery", "delete_address"]
}
}
}

次に、リポジトリの copilot 環境に、COPILOT_MCP_PROXYMAIL_QA_API_KEY という名前の Agents シークレットとしてキーを追加します。Copilot は COPILOT_MCP_ で始まる名前のシークレットだけを MCP サーバーに渡します。Copilot のコーディングエージェントはブラウザでサインインできないため、キーが必要です。

CI ジョブ(codex exec)で Codex CLI を使う場合は、サーバーを ~/.codex/config.toml に追加し、CI シークレットから PROXYMAIL_QA_API_KEY を設定します:

~/.codex/config.toml
[mcp_servers.proxymail-qa]
url = "https://api.proxymail.qa/mcp"
bearer_token_env_var = "PROXYMAIL_QA_API_KEY"

Codex のドキュメントには、クラウドタスクがリモートの MCP サーバーに接続できるかどうか書かれていません。接続できない場合は、環境の設定にあるキーを使って REST API を呼び出すよう Codex に頼んでください。

このページについて質問がありますか?

質問はどの言語でもかまいません。ドキュメントからすぐに回答を得ることも、Proxy Mail QA チームに質問を送ることもできます。チームからの返信は英語です。