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:
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:
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}:
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:
| Purpose | Fields it can fill |
|---|---|
password | password inputs |
otp, totp | one-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
| Place | What happens |
|---|---|
| Flight records, the HTML report, failure pages | every secret's value is removed |
| The terminal, results, JUnit and run history | the same, in each test's error |
| The PR comment, job summary and GitHub check | the same |
| Apps' startup output | the config's secret values are removed |
| Screenshots | fields that hold a secret are masked |
| Video | not kept once a secret shows on the page |
| Provider keys and tokens | removed 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".