table of contents Table of contents

File uploads, downloads and the file system

You might want to use (binary) files in your Multistep checks. For example, you might want to upload a file to an API endpoint using a binary body. Or, you might want to validate some aspect of a file that is available for download on your app.

Testing uploads using HTTP POST requests

To test any binary uploads, you need to provide a file object. Currently, Checkly does not have a dedicated storage layer where you could upload that file, so you need to host it yourself at a (publicly) accessible location like an AWS S3 bucket, Dropbox or any other file hosting service.

Having done that, you can “upload” files using a simple HTTP POST request with a (binary) body using Playwright’s built-in request object.

import { test, expect } from '@playwright/test'

test('Upload a file using a POST request', async ({ request }) => {
  const fileBuffer = await test.step('Fetch file', async () => {
    const fileUrl  = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
    return request.get(fileUrl)
  })

  await test.step('Upload file', async () => {
    const response = await request.post('https://filebin.net/pp9on3zvwv7zq6lm/dummy.pdf', {
      data: await fileBuffer.body(),
    })
    await expect(response).toBeOK()
  })
})
const { test, expect } = require('@playwright/test')

test('Upload a file using a POST request', async ({ request }) => {
  const fileBuffer = await test.step('Fetch file', async () => {
    const fileUrl  = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
    return request.get(fileUrl)
  })

  await test.step('Upload file', async () => {
    const response = await request.post('https://filebin.net/pp9on3zvwv7zq6lm/dummy.pdf', {
      data: await fileBuffer.body(),
    })
    await expect(response).toBeOK()
  })
})

Using the file system

Sometimes, you do want to explicitly save a file to disk. This is what you need to know.

Checkly creates a sandboxed directory for each check run. During the run you can use this directory to save or upload artifacts. This directory is destroyed after a check is finished.

import path from 'path'
import fs from 'fs'
import { test } from '@playwright/test'

test('Save file in directory', async ({ page }) => {
  const image = await page.goto('https://picsum.photos/200/300')
  const imagePath = path.join('example.jpg')
  const buffer = await image.body()
  fs.writeFileSync(imagePath, buffer)
  const readFileFromDisk = fs.readFileSync(imagePath)
})
const path = require('path')
const fs = require('fs')
const { test } = require('@playwright/test')

test('Save file in directory', async ({ page }) => {
  const image = await page.goto('https://picsum.photos/200/300')
  const imagePath = path.join('example.jpg')
  const buffer = await image.body()
  fs.writeFileSync(imagePath, buffer)
  const readFileFromDisk = fs.readFileSync(imagePath)
})

Due to this sandbox, certain Node.js variables are adapted to our platform and have values we set for them. The behaviour is slightly different when creating a browser check in the Web UI or using the Checkly CLI.

When creating a browser check in the Web UI, the variables are:

  • __dirname will have the value of /
  • __filename will have the value of /script.js

When creating a browser check using the Checkly CLI the variables are:

  • __dirname will have the value of /
  • __filename will have the value of the actual file in your code base, relative to the project root.

Last updated on April 3, 2024. You can contribute to this documentation by editing this page on Github