Учитывая, что Puppeteer предоставляет множество возможностей по обработке запросов HTTP / S, я пришел к следующему решению. При отправке формы я высмеиваю ответ сервера своим собственным. По сути, я установил перехватчик, который заменяет следующий запрос, соответствующий заданному фрагменту URL-адреса, пользовательским ответом сервера:
await bs.mockRequest( "response.json", { "GET", "500 Internal Server Error", "application/javascript", "{ \"status\": \"FAIL\" }", [] });
Пока он наблюдает за сетью, я могу отправить форму, например, эмулируя нажатие на кнопку отправки. кнопка. Следующий запрос будет заменен так, чтобы тестируемое приложение обрабатывало его как в случае реальной ошибки сервера.
Вот исходный код mockRequest:
class BrowserSession {
// obtaining page context from Puppeteer
// @see https://pptr.dev/#?product=Puppeteer&version=v2.0.0&show=api-puppeteerlaunchoptions
async setup( options ) {
this.browser = await puppeteer.launch( options );
this.context = await this.browser.createIncognitoBrowserContext();
this.page = await this.context.newPage();
}
/**
* Intercept and replace request
* @param {String} url - URL substring to match
* @param {Object} newRespond
*/
async mockRequest( url, { method, status, contentType, newBody, headers }) {
const session = await this.page.target().createCDPSession(),
patterns = [ `*${ url }*` ];
await session.send( "Network.enable" );
await session.send( "Network.setRequestInterception", {
patterns: patterns.map( pattern => ({
urlPattern: pattern,
interceptionStage: "HeadersReceived"
}))
});
session.on( "Network.requestIntercepted", async ({ interceptionId, request, responseHeaders, resourceType }) => {
if ( ( method || "GET" ) !== request.method.toUpperCase() ) {
await session.send( "Network.continueInterceptedRequest", { interceptionId });
return;
}
const newHeaders = [
"Date: " + ( new Date() ).toUTCString(),
"Connection: closed",
"Content-Length: " + newBody.length,
"Content-Type: " + contentType,
...headers
];
await session.send( "Network.continueInterceptedRequest", {
interceptionId,
rawResponse: btoa( `HTTP/1.1 ${ status }\r\n`
+ newHeaders.join('\r\n') + '\r\n\r\n' + newBody )
});
session.detach();
});
}
}