🎭

Playwrightでリクエストを確認する

2024/03/08に公開

こんにちは!saimyonです👶

今回はPlaywrightでリクエストを確認する方法について書きます🎭

はじめに

みなさん、Webアプリケーションを開発していてこんなことはありませんか?

  • APIは触ってないけどUIを刷新した!素敵!美しい!🥰
  • でも、新UIでぽちぽちした時に投げられるリクエストって、本当にこれまでと同じ形になっているの…?🤔

…もう不安で不安で夜しか眠れないですよね。
こういうリグレッションテスト的なことを「Playwrightでできないのかな?」と思い調べてみたところ、公式ドキュメントに載っている2つの方法で達成できそうだったので、そちらを紹介します!

Playwrightでリクエストを確認する方法

準備

今回はPOSTリクエストのボディを対象とし例を紹介したいのですが、手軽にPOSTできるWebサービスがなかなか思いつかず…最終的にGoogleフォームに行きつきました。
Googleフォームに回答する(POSTする)際のリクエストボディをPlaywrightで確認して行こうと思います。
そのまえに、実際に回答した場合はどんなリクエストボディになっているかを見てみます。

テストで作ったフォームを埋めて

開発者ツールを開きながら送信ボタンを押すと…

なるほど、

  • POSTメソッドでURLはhttps://docs.google.com/forms/d/e/GoogleフォームID/formResponse/
  • リクエストボディはentry.質問IDにその回答内容が入っている

って感じですね。
これがPlaywrightで確認できるのか?
やっていきます!

1. page.on('request')

https://playwright.dev/docs/api/class-page#page-event-request
まずはpage.on(’request’)です。
page.on(’request’)は、リクエストが投げられた際にコールバック関数を実行するメソッドです。
こんな感じで使います。

typescript
import { test } from "@playwright/test";

test("page.on('request')で確認", async ({page}) => {
  // リクエストが発生したときにイベントをキャッチ
  page.on('request', async (request) => {
    // 回答POSTだけに絞る
    if (request.method() === 'POST' && request.url().match(/https:\/\/docs.google.com\/forms\/d\/e\/.*\/formResponse/)) {
      console.log('url: ', request.url());
      console.log('method: ', request.method());
      console.log('postData: ', request.postDataJSON());
    }
  });

  // Googleフォームに回答
  await page.goto('https://docs.google.com/forms/d/e/GoogleフォームID/viewform');
  await page.getByLabel('好きなアイドルは?').fill('星宮いちご');
  await page.getByLabel('5').click();
  await page.getByRole('button', { name: '送信' }).click();

  await page.waitForSelector(`div:has-text('回答を記録しました。')`);
});

回答POSTをキャッチできたらログに表示します。
ではUIモードで実行してみましょう。

Consoleに準備で確認したリクエストボディが表示されてますね!

2. waitForRequest

https://playwright.dev/docs/api/class-page#page-wait-for-request
2つ目はwaitForRequestです。
waitForRequestは、指定されたリクエストが来るまで待ちます。
こんな感じで使います。

typescript
test("waitForRequestで確認", async ({page}) => {
  // 回答POSTを待機
  const requestPromise = page.waitForRequest(request => request.url().match(/https:\/\/docs.google.com\/forms\/d\/e\/.*\/formResponse/) && request.method() === 'POST');

  // Googleフォームに回答
  await page.goto('https://docs.google.com/forms/d/e/GoogleフォームID/viewform');
  await page.getByLabel('好きなアイドルは?').fill('星宮いちご');
  await page.getByLabel('5').click();
  await page.getByRole('button', { name: '送信' }).click();

  // リクエストが来るのを待つ
  const request = await requestPromise;
  console.log('url: ', request.url());
  console.log('method: ', request.method());
  console.log('postData: ', request.postDataJSON());

  await page.waitForSelector(`div:has-text('回答を記録しました。')`);
});

こちらもUIモードで実行してみましょう。

こちらもいけてますね!

まとめ

Playwrightを使ってPOSTリクエストの中身を確認することができました!
どちらを使うべきか?といわれると、特定のURLに注目する場合であればwaitForRequestを使う方がわかりやすいかな?と思います。

これで「こういうjsonが送られてくるはず」というAPI側の仕様を期待値としてassertすれば、不安も解消されてたくさん寝られますね。よかったよかった。

今回はボディを紹介しましたが、それ以外にもヘッダーなども確認できるので、気になった方はぜひドキュメントをご覧ください。
https://playwright.dev/docs/api/class-request

とはいえ、リグレッションテストとして実用的に使うためにはハードルがたくさんありそうだなぁとは感じています。
新UIに対応するように事前にコード修正しなきゃだし、そのためには開発者と擦り合わせておく必要があるし、そもそも検証パターンが膨大だったら本当にPlaywrightでやるべきなのか?と立ち返るべき?などなど…
みなさんはこういうときどのように検証されてますか?ぜひ教えていただけると幸いです!

それでは!よいE2E自動テストライフを!

ソーシャルデータバンク テックブログ

Discussion