Sponsored Link
Looking for a unified way to  viewmonitor, and  debug Playwright Test Automation runs?
Try the Playwright Dashboard by today. Use the coupon code PWSOL10 for a 12 month 10% discount.

Playwright API POST request to upload a file with Content-Type: multipart/form-data

When writing automation against my API, I ran into an issue attempting to make a post using playwright api to upload a file. The answer came in the form of a slack thread, I figured I would re-share here.

The api call I was trying to make was a POST request to a files endpoint to upload a file, in the below case a .png. The endpoint specified that the request of type multipart/form-data would be required. The first thing I checked was the Playwright Docs for the apiRequestContext.post() section, and found that one of the options I could pass in was multipart (rather than data which is normally used in posting json data).


  • multipart <Object<string, string|number|boolean|[ReadStream]|Object>> Provides an object that will be serialized as html form using multipart/form-data encoding and sent as this request body. If this parameter is specified content-type header will be set to multipart/form-data unless explicitly provided. File values can be passed either as fs.ReadStream or as file-like object containing file name, mime-type and its content.#
  • name <string> File name
  • mimeType <string> File type
  • buffer <Buffer> File content

After reviewing the docs and the slack thread, it was clear I had to do a bit more learning on creating a buffer to pass into the post request. From there I was able to construct a working playwright test in the example below.

import { expect, request } from "@playwright/test";
import fs from "fs";
import path from "path";


test("POST: Upload a file", async ({ request, baseURL }) => {
  const file = path.resolve("lib/", "logo.png");
  const image = fs.readFileSync(file);
  
  const response = await request.post(baseURL + "/files", {
    headers: {
      Accept: "*/*",
      ContentType: "multipart/form-data",
    },
    multipart: {
      file: {
        name: file,
        mimeType: "image/png",
        buffer: image,
      },
      title: "Logo of Business",
    },
  });
  const body = JSON.parse(await response.text());
  
  expect(response.status()).toBe(201);
  expect(body.title).toBe("Logo of Business");
  expect(body.type).toBe("png");  
}

More details on the different request types for Http POST method can be found on MDN Web Docs.