使用 Puppeteer 和 return 模拟响应拦截页面上的 XHR 请求的最佳方法

Best way to intercept XHR request on page with Puppeteer and return mock response

我需要能够拦截加载有 Puppeteer 和 return 模拟响应的页面上的 XHR 请求,以便为我的 Web 应用程序组织后端测试。执行此操作的最佳方法是什么?

如果有人感兴趣,我最终会为我的测试需要创建特殊的应用程序构建,这会将 Pretender 添加到页面中。我使用 Puppeteer 的 evaluate 方法与 Pretender 服务器通信。

这并不理想,但我无法找到一种方法来仅使用 Puppeteer 来实现我所需要的。有一种方法可以使用 Puppeteer 拦截请求,但似乎无法为给定请求提供虚假响应。

更新:

作为 X Rene there is now native support for this in Puppeteer v0.13.0 using request.respond() 方法。我将重写我的测试以使用它而不是 Pretender,因为这会为我简化很多事情。

更新 2:

pptr-mock-server available now to accomplish this. Internally it relies on request interception and request.respond()方法。库非常小,可能无法满足您的需求,但它至少提供了一个示例,说明如何使用 Puppeteer 实现后端测试。免责声明:我是它的作者。

嗯。在最新的puppeteer中,它提供了request.respond()方法来处理这种情况。

似乎要走的路确实是 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. 拦截所有请求
  3. 然后,对于每个请求,我都会通过 URL 与 if (request.url() === constants.API) 匹配来查找我感兴趣的请求,其中 constants.API 只是我需要匹配的端点。
  4. 如果找到,我用 request.respond() 传递我自己的响应,否则我让请求继续 request.continue()

还有两点:

  • constants.biddersMock上面是一个数组
  • CORS header 很重要,否则将不允许访问您的模拟数据

请发表评论或参考具有更好示例的资源。

我创建了一个库,它使用 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();
})();

您可能想尝试 Mockiavelli - 为 Puppeteer 请求模拟库。它专为 Web 应用程序的后端测试而构建。它与 jest 和 jest-puppeteer 集成得最好,但可以与任何测试库一起使用。