web-dev-qa-db-ja.com

Puppeteerでページ上のXHRリクエストをインターセプトし、モックレスポンスを返す最良の方法

Puppeteer でロードされたページでXHRリクエストをインターセプトし、モック応答を返す必要があります。これは、Webアプリのバックエンドレステストを整理するためです。これを行う最良の方法は何ですか?

14
s.ermakovich

上手。最新の操り人形師では、この状況を処理するrequest.respond()メソッドを提供します。

5
X Rene

行く方法は確かにrequest.respond()のようですが、それでも、それを使用する方法についての具体的な例をウェブで見つけることができませんでした。私がやった方法は次のようなものでした:

_// Intercept API response and pass mock data for Puppeteer
await page.setRequestInterception(true);
page.on('request', request => {
    if (request.url() === constants.API) {
        request.respond({
            content: 'application/json',
            headers: {"Access-Control-Allow-Origin": "*"},
            body: JSON.stringify(constants.biddersMock)
        });
    }
    else {
        request.continue();
    }
});
_

ここで正確に何が起こりますか?

  1. まず、すべてのリクエストはpage.setRequestInterception()でインターセプトされます
  2. 次に、リクエストごとにif (request.url() === constants.API)でURLと照合することで、興味のあるものを探します。ここで_constants.API_は照合する必要があるエンドポイントです。
  3. 見つかった場合は、request.respond()を使用して独自の応答を渡します。それ以外の場合は、request.continue()を使用して要求を続行します。

さらに2つのポイント:

  • _constants.biddersMock_は配列です
  • CORSヘッダーは重要です。そうでない場合、モックデータへのアクセスは許可されません。

より良い例でコメントするか、リソースを参照してください。

19
Kostas Siabanis

誰かが興味を持っている場合、テストのニーズに合わせて特別なアプリビルドを作成し、ページに Pretender を追加しました。そして、Puppeteerのevaluateメソッドを使用してPretenderサーバーと通信します。

これは理想的ではありませんが、必要なものをPuppeteerだけで達成する方法を見つけることができませんでした。 Puppeteerでリクエストをインターセプトする方法はありますが、特定のリクエストに対して偽の応答を提供する方法はないようです。

UPDATE:

X Rene 言及 として、 request.respond() メソッドを使用して、Puppeteer v0.13.0でこれをネイティブにサポートするようになりました。 Pretenderの代わりに使用するようにテストを書き直します。これにより、多くのことが簡単になります。

更新2:

pptr-mock-server がこれを達成するために現在利用可能です。内部的には、リクエストのインターセプトと request.respond() メソッドに依存しています。ライブラリはごくわずかであり、ニーズに合わないかもしれませんが、少なくともPuppeteerを使用してバックエンドテストを実装する方法の例を提供します。免責事項:私はそれの著者です。

5
s.ermakovich

Puppeteerのpage.on('request')およびpage.on('response')を使用して、モックされたリクエストを記録して応答するライブラリを作成しました。

https://github.com/axiomhq/puppeteer-request-intercepter

npm install puppeteer-request-intercepter
const puppeteer = require('puppeteer');

const { initFixtureRouter } = require('puppeteer-request-intercepter');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // Intercept and respond with mocked data.
  const fixtureRouter = await initFixtureRouter(page, { baseUrl: 'https://news.ycombinator.com' });
  fixtureRouter.route('GET', '/y18.gif', 'y18.gif', { contentType: 'image/gif' });

  await page.goto('https://news.ycombinator.com', { waitUntil: 'networkidle2' });
  await page.pdf({ path: 'hn.pdf', format: 'A4' });

  await browser.close();
})();
0
cdeutsch