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.
You can contribute to this documentation by editing this page on Github