Skip to content

Commit

Permalink
docs: update variables and file system docs.
Browse files Browse the repository at this point in the history
  • Loading branch information
tnolet committed Nov 21, 2023
1 parent 579564a commit fca699c
Show file tree
Hide file tree
Showing 7 changed files with 203 additions and 61 deletions.
4 changes: 2 additions & 2 deletions site/content/docs/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,15 @@ monitoring in minutes.
class="two-column-card"
headerTag="h3"
title="Create a multistep API check"
img="/docs/images/icons/multistep-check.svg"
img="/docs/images/icons/multistep-check-stroked.svg"
description="Write Node.js scripts that run multiple API requests in sequence, with arbitrary code between requests and get all the data."
link="/docs/multistep-checks/"
>}}
{{< doc-card
class="two-column-card"
headerTag="h3"
title="Create a heartbeat check"
img="/docs/images/icons/heartbeats-check.svg"
img="/docs/images/icons/heartbeats-check-stroked.svg"
description="Monitor your backup jobs, data imports, and other recurring jobs or scripts by pinging Checkly at a regular interval."
link="/docs/heartbeat-checks/"
>}}
Expand Down
50 changes: 26 additions & 24 deletions site/content/docs/api-checks/setup-teardown-scripts.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ Inside each script, you have access to certain data structures of the API check
1. Environment variables for reading tokens and other secrets you have stored.
2. The `request` object.
3. The `response` object, only in teardown scripts as there is no response till after the API check runs.
4. General runtime variables injected automatically, like `process.env.CHECK_NAME`
4. Built-in runtime variables injected automatically, like `process.env.CHECK_NAME`

### Environment

Expand Down Expand Up @@ -180,29 +180,31 @@ Request properties are exposed as a standard JavaScript object. This object is a

Response properties are exposed a standard Javascript object. These are only available in teardown scripts.

| property | description | type |
| ------------- | ------------- | ---- |
| `response.statusCode` | The response status code, i.e. 200 or 404. | Number |
| `response.statusText` | The response status text, i.e. 'Ok' or 'Not found'. | String |
| `response.body` | The response body in string format. You will need to use `JSON.parse(response.body)` to access JSON responses.| String |
| `response.headers` | The response headers in the form of a standard Javascript object. | Object |
| `response.timings` | Various timestamps for the request stage relative to the starting time. | Object |
| `response.timingPhases` | Time durations for each request phase. | Object |

### General runtime variables

[The setup and teardown runtime](/docs/runtimes/) also exposes a set of environment variables (e.g. `process.env.CHECK_NAME`)
to figure out what check, check type etc. you are running.

| property | description | type |
|-------------------|------------------------------------------------------------|--------|
| `GROUP_BASE_URL` | The `{{GROUP_BASE_URL}}` value of the grouped `API` check. | String |
| `CHECK_NAME` | The name of the check being executed. | String |
| `CHECK_ID` | The UUID of the check being executed. | String |
| `CHECK_TYPE` | The type of the check being executed, (`API`) | String |
| `CHECK_RESULT_ID` | The UUID of the result where the run result will be saved. | String |
| `REGION` | The region where a check is executed, e.g `eu-west-1` | String |
| `REQUEST_URL` | The request URL of the `API` check executed. | String |
| property | description | type |
|-------------------------|----------------------------------------------------------------------------------------------------------------|--------|
| `response.statusCode` | The response status code, i.e. 200 or 404. | Number |
| `response.statusText` | The response status text, i.e. 'Ok' or 'Not found'. | String |
| `response.body` | The response body in string format. You will need to use `JSON.parse(response.body)` to access JSON responses. | String |
| `response.headers` | The response headers in the form of a standard Javascript object. | Object |
| `response.timings` | Various timestamps for the request stage relative to the starting time. | Object |
| `response.timingPhases` | Time durations for each request phase. | Object |

### Built-in runtime variables

[The setup and teardown runtime](/docs/runtimes/) also exposes a set of specific environment variables to the setup and teardown scripts,
next to the "generic" runtime variables like `process.env.CHECK_NAME` you find in all check runtimes

#### Setup & teardown specific variables

| variable | description |
|------------------|------------------------------------------------------------|
| `GROUP_BASE_URL` | The `{{GROUP_BASE_URL}}` value of the grouped `API` check. |
| `REQUEST_URL` | The request URL of the `API` check executed. |

#### Generic runtime variables

{{< markdownpartial "/_shared/runtime-env-vars.md" >}}


## Included libraries

Expand Down
122 changes: 95 additions & 27 deletions site/content/docs/browser-checks/file-system.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,118 @@
---
title: Using the file system
title: File uploads, downloads and the file system
weight: 20
menu:
resources:
parent: "Browser checks"
aliases:
- /docs/browser-checks/file-system/
cli: true
---

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.
You might want to use (binary) files in your browser checks. For example, you might want to upload a file to an upload
form in your webapp. Or, you might want to validate some aspect of a file that is available for download on your
app.

Due to this sandbox, certain Node.js variables are adapted to our platform and have values we set for them:
* `__dirname` will have the value of `/`
* `__filename` will have the value of `/script.js`
## Testing uploads with the browser's File API

The values these variables correspond to might change in the future. Therefore, we recommend using `__dirname`, like `path.join(__dirname, 'example.png')` or relative paths, like `./example.png` or just `example.png`, while using the file system-related operation. You can find an example code snippet below:
To test any upload features with Playwright's `.setInputFiles()` method, you need to provide a file object. Currently,
Checkly does 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.

In the example below, we do not need to interact with the file system. We can just:

{{< tabs "Basic example" >}}
1. Fetch a file from a public URL using the `request` object.
2. Pass the resulting `Buffer` into the `.setInputFiles()` method.
3. Wait for the upload to finish.

{{< tabs "Basic upload test example" >}}
{{< tab "Typescript" >}}
```ts
import { test, expect } from '@playwright/test'

test('upload a file', async ({ page, request }) => {
// fetch the file to upload
const fileUrl = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
const fileBuffer = await request.get(fileUrl)

// upload the file
await page.goto('https://filebin.net/')
await page.getByLabel('Select files to upload').setInputFiles({
name: 'file.pdf',
mimeType: 'application/pdf',
buffer: await fileBuffer.body()
})

// validate the upload was successful
await expect(page.getByRole('link', { name: 'Download file' })).toBeVisible()
await page.screenshot({ path: 'filebin.png' })
})
```
{{< /tab >}}
{{< tab "Javascript" >}}
```js
const { test, expect } = require('@playwright/test')

test('upload a file', async ({ page, request }) => {
// fetch the file to upload
const fileUrl = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
const fileBuffer = await request.get(fileUrl)

// upload the file
await page.goto('https://filebin.net/')
await page.getByLabel('Select files to upload').setInputFiles({
name: 'file.pdf',
mimeType: 'application/pdf',
buffer: await fileBuffer.body()
})

// validate the upload was successful
await expect(page.getByRole('link', { name: 'Download file' })).toBeVisible()
await page.screenshot({ path: 'filebin.png' })
})
```
{{< /tab >}}
{{< /tabs >}}

Notice we don't need to interact with the file system, we can just pass buffers around.

## Testing uploads using HTTP POST requests

You can also "upload" files using a simple HTTP POST request with a (binary) body using Playwright's built-in `request` object.
You would use this when you want to test a file upload feature that is not using the browser's File API, but just an HTTP/REST endpoint
that accepts a file upload.

{{< tabs "Basic HTTP upload example" >}}
{{< tab "Typescript" >}}
```ts
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(__dirname, 'example.jpg')
const buffer = await image.body()
fs.writeFileSync(imagePath, buffer)
const readFileFromDisk = fs.readFileSync(imagePath)
import { test, expect } from '@playwright/test'

test('Upload a file using a POST request', async ({ request }) => {
const fileUrl = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
const fileBuffer = await request.get(fileUrl)
const response = await request.post('https://filebin.net/pp9on3zvwv7zq6lm/dummy.pdf', {
data: await fileBuffer.body(),
})
await expect(response).toBeOK()
})
```
{{< /tab >}}
{{< tab "Javascript" >}}
```js
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(__dirname, 'example.jpg')
const buffer = await image.body()
fs.writeFileSync(imagePath, buffer)
const readFileFromDisk = fs.readFileSync(imagePath)
const { test, expect } = require('@playwright/test')

test('Upload a file using a POST request', async ({ request }) => {
const fileUrl = 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf'
const fileBuffer = await request.get(fileUrl)
const response = await request.post('https://filebin.net/pp9on3zvwv7zq6lm/dummy.pdf', {
data: await fileBuffer.body(),
})
await expect(response).toBeOK()
})
```
{{< /tab >}}
{{< /tabs >}}

## Using the file system

{{< markdownpartial "/_shared/using-the-file-system.md" >}}
11 changes: 3 additions & 8 deletions site/content/docs/browser-checks/variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,9 @@ You can make use of this by providing a default value for a specific variable at
be overridden at the check level.


## General built-in runtime variables
## Built-in runtime variables

[The Browser Check runtime](/docs/runtimes/) also exposes a set of environment variables (e.g. process.env.CHECK_NAME)
[The Browser Check runtime](/docs/runtimes/) also exposes a set of environment variables (e.g. `process.env.CHECK_NAME`)
to figure out what check, check type etc. you are running.

| property | description | type |
|---------------------------|------------------------------------------------------------|--------|
| `CHECK_NAME` | The name of the check being executed. | String |
| `CHECK_ID` | The UUID of the check being executed. | String |
| `CHECK_TYPE` | The type of the check being executed, (`BROWSER`) | String |
| `CHECK_RESULT_ID` | The UUID of the result where the run result will be saved. | String |
{{< markdownpartial "/_shared/runtime-env-vars.md" >}}
3 changes: 3 additions & 0 deletions site/content/docs/cli/constructs-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,9 @@ Multistep API checks are only supported on runtime 2023.09 or later. See [Runtim
{{< /info >}}

```ts
import { MultiStepCheck, Frequency } from 'checkly/constructs'
import * as path from 'path'

new MultiStepCheck('multistep-check-1', {
name: 'Multistep Check #1',
runtimeId: '2023.09',
Expand Down
8 changes: 8 additions & 0 deletions site/content/docs/multistep-checks/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ When viewing a multistep check run result, you can select any API request in the

Selecting the top node in the check report shows the full job log and the check configuration for the run.

## Built-in runtime variables

[The Multistep Check runtime](/docs/runtimes/) also exposes a set of environment variables (e.g. `process.env.CHECK_NAME`)
to figure out what check, check type etc. you are running.

{{< markdownpartial "/_shared/runtime-env-vars.md" >}}


## Pricing

During beta, a multistep check is billed based on the number of requests done per check run. Each request in a multistep check run is billed as a single regular API check run, as they are performing the same basic operation.
Expand Down
66 changes: 66 additions & 0 deletions site/content/docs/multistep-checks/upload-downloads-filesystem.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
---
title: File uploads, downloads and the file system
weight: 20
menu:
resources:
parent: "Multistep API checks"
identifier: "multistep-checks-uploads"
cli: true
---

You might want to use (binary) files in your Multistep checks. For example, you might want to upload a file to a
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 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.

{{< tabs "Basic HTTP upload example" >}}
{{< tab "Typescript" >}}
```ts
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()
})
})
```
{{< /tab >}}
{{< tab "Javascript" >}}
```js
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()
})
})
```
{{< /tab >}}
{{< /tabs >}}

## Using the file system

{{< markdownpartial "/_shared/using-the-file-system.md" >}}

0 comments on commit fca699c

Please sign in to comment.