banner
DIYgod

Hi, DIYgod

写代码是热爱,写到世界充满爱!
github
twitter
follow
bilibili
telegram
email
steam
playstation
nintendo switch

HeadlessChrome 自動テストの探索

埋点は、B 站の HTML5 プレーヤーの開発とテストプロセスでの痛みの一つです。埋点の種類とインターフェースパラメータが多く、テストは面倒でエラーが発生しやすいです。

テストは面倒ですが、ルールは非常にシンプルです。たとえば、ボタンをクリックしたり、ホバーしたり、エラーを報告したり、再生やパフォーマンスを報告したりすることです。では、これらの面倒で機械的でエラーが発生しやすいテスト作業を自動化の E2E テストで代替することはできるでしょうか?

埋点のオンライン事故の後、私は 1 日かけていくつかの探索を行い、最終的にはかなりうまくいきました。ここでは、簡単なまとめをします。

テストスクリプトの作成#

ユーザー操作をシミュレートするには、ヘッドレスブラウザが必要です。私は Jest + Puppeteer の組み合わせを使用しました。

Jest はテストフレームワークであり、Puppeteer は Chrome または Chromium を制御するために使用されます。

Jest を選んだのは、私が Jest に最も精通しているからです。そして、jest-puppeteerというプリセットを見つけました。必須ではありませんが、Puppeteer の操作を簡素化することができます。

依存関係をインストールします:

npm install --save-dev jest jest-puppeteer puppeteer

テストスクリプトは非常にシンプルです:

describe('log', () => {
    beforeAll(async () => {
        page.goto('https://www.bilibili.com/video/av44890855');
    });

    it('play_screen', async (done) => {
        page.on('request', (request) => {
            if (request.url().match(/^https:\/\/data\.bilibili\.com\/log\/web\?play_screen...パラメータパラメータ/)) {
                done();
            }
        });
        page.click('video');
    });
});

HeadlessChrome に再生ページを開かせ、ページのリクエストインターフェースを監視し、video 要素をクリックすることで play_screen の埋め込みがブラウザにリクエストされたことを監視し、テストが成功したことを確認します。

問題はなさそうですが、テストを実行してみると失敗しました。

何が起こったのでしょうか?headless: falseの設定をしてテストのプロセスを見てみました。

headlesschrome1

HTML5 プレーヤーがサポートされていないため、Flash プレーヤーがロードされたことが原因でした。

Puppeteer のドキュメントによると

Puppeteer は Chromium にバンドルされています - Chrome ではありません...Puppeteer は AAC や H.264 などのライセンスされた形式をサポートしていません

解決策も非常に簡単で、Puppeteer に付属している Chromium をローカルの Chrome に置き換えるだけです。

launch: {
    executablePath: '/Applications/Google Chrome.app/Contents/MacOS/Google Chrome'
}

テストが成功しました。

headlesschrome2

Chrome をサービスとして使用する#

先ほどはローカルの Chrome を使用しましたが、これはローカル環境に依存していますし、自動化テストとしてテストマシンで実行することもできません。

そのため、テストマシンでdocker コンテナを実行しました。これにより、Chrome をサービスとして使用できるようになりました。テストスクリプトは、websocket プロトコルを使用して docker 内の Chrome を操作します。これにより、ローカルの Chrome に依存しないようになります。

コンテナを起動します:

docker pull browserless/chrome:release-chrome-stable
docker run -d -p 3000:3000 browserless/chrome:release-chrome-stable

使用方法:

connect: {
    browserWSEndpoint: 'ws://localhost:3000'
}

JavaScript のハイジャック#

これにより、オンラインバージョンが使用され、ローカルのコードがテストされません!

ああ、言い忘れましたが、オンラインの JavaScript をローカルバージョンにハイジャックする必要があります。

await page.setRequestInterception(true);

page.goto('https://www.bilibili.com/video/av44890855');
page.on('request', (request) => {
    if (request.url().match(/player\.js/)) {
        request.respond({
            status: 200,
            contentType: 'application/javascript',
            body: fs.readFileSync('dist/release/player.js').toString()
        });
    } else {
        request.continue();
    }
});
読み込み中...
文章は、創作者によって署名され、ブロックチェーンに安全に保存されています。