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

# Uploading & Downloading Files To The File System

> Upload and download binary files in multistep checks with Playwright's request object, hosting files externally and validating them with HTTP requests.

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://httpbin.org/post', {
        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://httpbin.org/post', {
        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.
