kazu22002の技術覚書

PHPer, Golang, AWS エンジニアの日々

puppeteerでテスト時のテクニック

e2eテスト自体いままでやって来なかったため知見がない状態で進めていましたが、やってみて詰まったことや解決方法を書いてみます。

要素の表示まで待つ

入力フォームの要素のテストをする場合に、入力表示がでるまで待つ必要があります。

表示される前にデータを入力するプログラムが動作すると、要素がありません。というエラーで落ちます。

SPAやajaxでデータ取得後に入力欄の表示をしている場合に困ります。

対策は、要素の表示まで待機するようにしましょう。(idがageの要素)

await this.page.waitForSelector('#age');

実際にはname要素だと思うので、nameの場合

await this.page.waitForSelector('input[name=age]');

selectorを使えますので、jqueryに慣れている人は問題ないでしょう。

入力画面の表示まで待つ

データを読み込むまでローディング機能を入れている場合も要素にデータが入力できない。というエラーで落ちます。

これは要素を待つ処理をいれていても、エラーになります。

理由としては要素自体はすでに表示されているため、通過するためです。

要素が隠れるまで待ちましょう(classが「black-overlay」のローディング表示)

await this.page.waitForSelector('.black-overlay', {hidden: true});

これで表示が消えるまで待機してくれます。

あとは指定時間を待つ処理もあります。

await this.page.waitFor(1000);

ミリ秒指定になります。

要素が一定でない場合や、純粋に時間待ちたい場合に有効でしょう。

ただ時間待機でやってた時はあまり安定しなかったため出来るだけ減らすようにしています。ロード時間とか結構PCの状態に左右されるので安定しなかった感じです。

あとは時間がかかるようになります。e2eテスト自体時間がかかる印象ですが、時間待機をいれると指定時間分必ず遅くなるため処理時間が増えるのがネックです。

試しながら使い所を見極めてください。

ボタンの位置まで移動

ボタンを押す際に画面内に表示されていない場合、エラーで落ちます。

要素まで移動して表示されることを確認してからボタンクリックイベントで回避します。

                        await this.page.evaluate(() => {
                            const name = document.querySelector('#add');
                            name.scrollIntoView({
                                behavior: 'auto',
                                block: 'center',
                                inline: 'nearest',
                            });
                        });
                        await this.page.click("#add");

別タブ

別タブで表示する内容をスクリーンショットするコードの一部です。

        const page = await browser.newPage();
        await page.goto("url", {waitUntil: 'domcontentloaded'});
        await page.setViewport({width: 720, height: 1280});

        newPagePromise = new Promise(resolve => browser.once('targetcreated', target => resolve(target.page())));
        await page.click('#popup');
        await page.waitFor(200);
        newPage = await newPagePromise;
        await newPage.setViewport({
            width: 720,
            height: 1280
        });
        await newPage.waitFor(2000);
        await this.screenShot(newPage, "tab.png");
        await page.bringToFront();
        await newPage.close();

ターゲットを指定して表示をしています。

書いてみれば難しくないですね。

Puppeteer入門 スクレイピング+Web操作自動処理プログラミング

Puppeteer入門 スクレイピング+Web操作自動処理プログラミング