Search code examples
axiospuppeteerform-datajest-puppeteer

puppeteer - Inspecting POST request where payload is FormData


I have a process in React that looks something like this:

handleButtonClick() {
  const payload = new FormData();
  payload.append('foo', someFileBlobContent);
  axios.post('/my-api/', payload);
}

When a button is clicked, some data is compiled as FormData, then sent as the payload in a POST request to an API.

In my Jest/Puppeteer tests, I'm trying to confirm that the request contains the data that it should:

page.click('.my-button');

await page.waitForRequest(request => {
  if (request.url().match(/my-api/) && request.method() === 'POST') {
    expect(request.postData()).toBeDefined();
    return true;
  }
});

In this scenario request.postData() is undefined. Is there some way in Puppeteer to inspect the contents of a POST request where the payload is a FormData structure?

When running the process in Chrome, I can see the FormData displayed in the network requests via Chrome devtools, so I know the data is being sent, but I'd like to assert it.


Solution

  • I did some tests, the request.postData() was only working for me on application/x-www-form-urlencoded forms (aka "normal form data"). As soon as you upload a file the content-type is multipart/form-data and puppeteer will not be able to return post data.

    Alternative: Check the Content-Type header

    As you cannot check if post data is send, you can still check if the request is actually a multipart/form-data request. In that case the content-type header looks like this multipart/form-data; boundary=..., so you can check it like this:

    await page.waitForRequest(request => {
      if (request.url().match(/my-api/) && request.method() === 'POST') {
        const headers = request.headers();
        expect(headers['content-type'].startsWith('multipart/form-data')).toBe(true);
        return true;
      }
    });