dánwòdánwò

Writing tests

Secrets

Configure passwords, keys and codes by name. Tests and the agent use the name; the value never reaches the model, a record or a report.

A secret is a value your tests type but nobody should see: a password, an API key, a 2FA key. You configure it once by name. Tests fill it with secret(name), and danwo keeps the value out of everything it writes or sends to a model.

Configure a secret

List secrets in danwo.config.ts. Read their values from the environment, not from the file:

danwo.config.ts
import { defineConfig } from "@danwo/sdk"

export default defineConfig({
  testDir: "tests",
  secrets: {
    password: { value: process.env.APP_PASSWORD ?? "", purpose: "password" },
    apiKey: process.env.APP_API_KEY ?? "",
  },
})

A plain value is a generic secret. Give a purpose to say what the secret is for.

Fill it in a test

Pass secret(name) wherever you would pass the value:

tests/sign-in.danwo.ts
import { test } from "@danwo/sdk"

test("signs in", async ({ app, screen, secret }) => {
  await app.open("/login")
  await screen.getByLabel("Email").fill("[email protected]")
  await screen.getByLabel("Password").fill(secret("password"))
  await screen.getByRole("button", { name: "Sign in" }).click()
})

Give it to the agent

The agent takes secrets as params. It only ever sees the name {password}:

tests/sign-in.danwo.ts · with the agent
await agent.act("sign in as [email protected] with {password}", {
  params: { password: secret("password") },
})

When the step replays, danwo fills the value again. No model is involved.

Where a secret may go

A secret only goes into a field its purpose allows. Anything else is refused with SECRET_REFUSED, so a password never lands in a search box by mistake:

PurposeFields it can fill
passwordpassword inputs
otp, totpone-time-code and text inputs
generic-secret (default)any field except a password input

Set fields: "any", or a list such as ["text", "other"], on a secret to override it.

What's redacted

PlaceWhat happens
Flight records, the HTML report, failure pagesevery secret's value is removed
The terminal, results, JUnit and run historythe same, in each test's error
The PR comment, job summary and GitHub checkthe same
Apps' startup outputthe config's secret values are removed
Screenshotsfields that hold a secret are masked
Videonot kept once a secret shows on the page
Provider keys and tokensremoved even if you didn't configure them

danwo also removes a secret's encoded forms: URL-encoded, base64, HTML-escaped and other-case.

Video can't mask text. When a secret danwo knows shows as text, it drops that run's video and the record says why. A secret it doesn't know stays on screen, so turn video off for that suite with video: "off".

Next

On this page

Run it on every pull request

A GitHub check and one comment per pull request, with the flight records attached.

Set up CI