> ## Documentation Index
> Fetch the complete documentation index at: https://checklyhq.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Uploading & Downloading Files To 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.

<CodeGroup dropdown>
  ```ts http-upload.spec.ts theme={null}
  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()
    })
  })
  ```

  ```js http-upload.spec.js theme={null}
  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()
    })
  })
  ```
</CodeGroup>

## 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.

<CodeGroup dropdown>
  ```ts theme={null}
  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)
  })
  ```

  ```js save-file.spec.js theme={null}
  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)
  })
  ```
</CodeGroup>

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.
