Skip to main content

Credentials in UI Tests

UI tests log into the application under test using the {{username}}/{{password}} placeholders shown in the YAML format page. This guide explains where those values come from and how to control them when running a test.

Resolution chain

When you trigger a test (POST /api/ui-tests/{id}/run), the backend resolves credentials in this order — first match wins:

PrioritySourceWhen used
1inlineCredentials in the run requestA wizard or one-off run passing a literal {username, password} map
2credentialTag matching auth_config.credentials[].tag on the environmentPinned to a specific saved credential
3Environment-level auth_config.defaultCredentialTagA team default set on the environment
4Any credential with isDefault: true in auth_config.credentials[]Sane fallback for self-test / regression projects

If none of those resolve, no credential is injected. There's intentionally no "first-active-credential" last-resort fallback — silently picking an arbitrary credential is the kind of "convenient" behaviour that lets a misconfigured test pass against the wrong user.

If none of those resolve and the test YAML contains {{username}}, {{password}}, {{token}}, or {{apiKey}}, the request is rejected with HTTP 400 before any job is dispatched — no doomed run, no misleading green steps that "passed" because they typed {{username}} literally into the login form.

Configuring credentials on an environment

Credentials live in the environment's auth_config.credentials[] array. Each entry has:

{
"id": "9a20e1b5-...",
"tag": "admin",
"username": "admin",
"password": "...",
"token": null,
"apiKeyValue": null,
"isDefault": true,
"isActive": true,
"description": "Platform admin credential"
}

Add or edit entries under Settings → Environments → <env> → Auth in the UI, or via POST /api/environments/{environmentId}/auth-config/credentials.

Mark exactly one entry as isDefault: true — that's the credential the API and any in-app wizard will pick when no explicit tag is supplied.

Triggering a test

From the wizard (default flow)

The UI wizard automatically attaches the environment's default credential. You don't have to think about it — pick the environment, pick the test, hit Run.

From the REST API

TOKEN=... # JWT from /api/auth/login

# 1. Use the env's default credential (whatever isDefault=true points to)
curl -X POST https://app.proofarc.ai/api/ui-tests/70/run \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"target": "https://app.proofarc.ai",
"environmentId": 7,
"browsers": ["chrome"]
}'

# 2. Pin to a specific saved credential
curl -X POST https://app.proofarc.ai/api/ui-tests/70/run \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"target": "https://app.proofarc.ai",
"environmentId": 7,
"credentialTag": "regression-test",
"browsers": ["chrome"]
}'

# 3. One-off inline credentials (not stored)
curl -X POST https://app.proofarc.ai/api/ui-tests/70/run \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"target": "https://app.proofarc.ai",
"environmentId": 7,
"inlineCredentials": {"username": "qa-user", "password": "..."},
"browsers": ["chrome"]
}'

What happens on the wire

The resolved credential becomes the credentials map on the dispatched job:

{
"yamlContent": "steps: …",
"testId": 70,
"browser": "chrome",
"credentials": {
"username": "admin",
"password": "admin123"
}
}

The UI Test Agent then substitutes {{username}} / {{password}} (and the alternative ${username} / ${password} syntax) using Apache Commons Text's StringSubstitutor before each SEND_KEYS action.

Troubleshooting

Symptom: Login screen shows the literal string {{username}} in the username field and a "Login failed" banner; subsequent steps cascade-skip.

Cause: No credentials were resolvable at dispatch time and the validation guard was bypassed (older builds), or the test YAML uses a placeholder name not in {username, password, token, apiKey} (e.g. {{adminUser}}) — the guard won't catch custom names.

Fix: Either (a) mark a credential isDefault: true on the environment, (b) pass credentialTag explicitly, or (c) use placeholder names from the supported set.