マイク入力をモックする
ユースケース: アプリがユーザーの声を録音する — 音声認識(Speech-to-Text)、ボイスメモ、発音を採点する語学学習アプリ、音声レベルメーター。マイクに向かって話す自動テストを書きたい。
なぜ難しいのか
Section titled “なぜ難しいのか”Playwrightにはマイク入力のためのAPIがありません。よく見つかる回避策には、それぞれ大きな制約があります:
--use-file-for-fake-audio-captureは Chromium専用、WAVのみ対応、しかもファイルはブラウザ起動時に固定されます。最初の画面ではAと言い、次の画面ではBと言う、といったことができません。- OSレベルの仮想オーディオデバイスに音声を流す方法は動きますが、CIで運用するのは非常につらいです。
playwright-audio-mocking は、ページ読み込み前に navigator.mediaDevices.getUserMedia を置き換え、実際のWeb Audioベースの MediaStream を返します。その先にあるもの — MediaRecorder、AnalyserNode、WebRTC、音声認識API — はすべて無改造で動作し、Chromium・Firefox・WebKitに対応しています。
npm install -D playwright-audio-mockingimport { test, expect } from '@playwright/test';import { mockMicrophone } from 'playwright-audio-mocking';
test('transcribes speech', async ({ page }) => { const mic = await mockMicrophone(page); // page.goto() より前にインストールする await page.goto('/voice-memo');
await page.getByRole('button', { name: 'Record' }).click(); await mic.play('tests/fixtures/hello-world.wav'); // マイクに音声を流し込む await mic.waitForEnd(); await page.getByRole('button', { name: 'Stop' }).click();
await expect(page.getByTestId('transcript')).toContainText('hello world');});実行時の制御
Section titled “実行時の制御”起動時フラグと違い、再生はテストの途中でも完全にスクリプトから制御できます:
await mic.play('fixtures/greeting.mp3'); // ブラウザがデコードできる形式なら何でもawait mic.play('fixtures/question.mp3'); // ストリーミング中のファイル切り替えawait mic.play('fixtures/hold-music.mp3', { loop: true });await mic.pause(); // 無音になり、再生位置は保持await mic.resume();await mic.stop(); // 無音になり、再生位置はリセット
const { playing, position, duration } = await mic.status();フィクスチャファイルなしで音声を生成する
Section titled “フィクスチャファイルなしで音声を生成する”ファイルパスの代わりにバイト列を渡せます — たとえばTTS APIの出力を直接流し込めば、テストごとに違う内容を話させることができます:
await mic.play(Buffer.from(await synthesizeSpeech('add milk to my shopping list')));mockMicrophone(page)は 必ずpage.goto()より前に呼んでください — initスクリプトとして注入されるためです。- Chromiumでは
RECOMMENDED_CHROMIUM_ARGS(--autoplay-policy=no-user-gesture-required)を付けて起動すると、ユーザー操作なしでWeb Audioを開始できます。 - モックが置き換えるのは音声トラックのみです。
getUserMedia({ audio, video })の場合、videoの制約はデフォルトで本来の実装にパススルーされます。
- WebRTC通話をテストする — モックしたマイクを発信者の声として使う。
- 音が鳴っていることを検証する — 同じ問題の出力側。
- カメラ入力をモックする — 映像版。