如何获取 RequestLogger 的 json 响应

How to get the json response of a RequestLogger

RequestLogger

A 在主测试控制器之外使用 page model and this 配方进行此测试。

/**
  Used to get the periodic analytic id.
  Whenever we are viewing an asset, the server must respond with an id.
  This id is later used by the client, to send periodic analytics.

  @param {object} t          Testcafe's test controller
  @param {object} logger     A testcafe's RequestLogger.
  @returns {string}          Returns the periodic analytic id.
*/
async getPeriodicAnalyticId(t, logger) {
  const logPrefix = 'Get periodic analytic id > ';
  let responseBody;

  await t
    .expect(logger.requests.length).gt(0, logPrefix + 'No requests logged.');

  responseBody = logger.requests[0].response.body;

  await t
    .expect(responseBody).notTypeOf('undefined', logPrefix + 'Logged request does not have a response a body.')
    .expect(Buffer.isBuffer(responseBody)).eql(true, logPrefix + 'Invalid response body (not buffer)');

  // Periodic analytic id can be found on the server response of the 1st analytic sent.
  return JSON.parse(logger.requests[0].response.body.toString()).id;
}

错误

当 运行 此测试针对本地 Http 服务器时,工作正常。但是当测试针对 https 远程服务器时它会失败。我收到此错误:

SyntaxError: Unexpected token  in JSON at position 0

这条线

return JSON.parse(logger.requests[0].response.body.toString()).id;

调试信息

来自有效的本地 Http 服务器的响应正文: localBuffer 它翻译成: localBufferToString

来自失败的远程 https 服务器的响应正文: remoteBuffer 它翻译成: remoteBufferToString

问题

我想知道我用来将响应正文转换为 json 的方法是否可以。目前我使用:

JSON.parse(logger.requests[0].response.body.toString())

我的环境

operating system: Windows 10
testcafe version: 0.21.1
node.js version: 9.3.0

我遇到了同样的问题,因为服务器响应是 gzipped 响应,并且 testcafe logger API 不会自动解压缩 响应。

所以我们遵循了以下步骤:

使用 logResponseBody 参数配置记录器(也如评论中所述,不要将 'stringifyResponseBody' 参数设置为 true)

const logger = RequestLogger(
  /yourApiRegex/,
  { logResponseBody: true },
);

写一个解压请求体的辅助方法:

import zlib from 'zlib';

export const getBody = async body => new Promise((resolve, reject) => {
  zlib.gunzip(body, async (error, buff) => {
    if (error !== null) {
      return reject(error);
    }
    return resolve(JSON.parse(buff.toString()));
  });
});

测试中的示例用法

await t.expect(logger.contains(
  async (record) => {
    const body = await (getBody(record.response.body));
    return body.someProps === 'someValue';
  },
)).ok();