---
title: "Installation"
id: "1864"
type: "page"
slug: "install"
published_at: "2026-09-21T00:36:24+00:00"
modified_at: "2026-09-30T23:50:35+00:00"
url: "https://xedant.com/agents/test/install"
markdown_url: "https://xedant.com/agents/test/install.md"
excerpt: "Test Agent is a program that checks your website, app or internal system. It lives…"
---

# Installation

[https://xedant.com/agents/test/install.md](https://xedant.com/agents/test/install.md)

Don’t want to read all this? Just drop a link to [https://xedant.com/agents/test/install.md](https://xedant.com/agents/test/install.md)
 or to [https://xedant.com/llms.txt](https://xedant.com/llms.txt)
 into any AI chat (Claude, ChatGPT, etc.) and ask it to generate the config files and commands. It will read the docs, ask you a few questions about your setup, and hand you a ready-to-use configuration. Save time — let the model do the reading for you.

 You can also reach me on Telegram — I’m always glad to help. And that’s not just politeness — I genuinely enjoy talking to like-minded people, especially if you love coding as much as I do.

 Test Agent is a program that checks your website, app or internal system. It lives on your server and deploys as a single Docker container, with permanent data in the `/apps/tests` volume. No separate database is needed: the built-in one works at once, and PostgreSQL connects optionally. You will also need a Chrome with the addon on the computer that will execute the checks: snapshots of both ordinary screens and visual builds are taken only by the addon enabled in runner mode.

## Minimum requirements

- A server or computer with Docker — Windows, Linux or macOS all work, and an inexpensive server is enough for permanent use.
- About 2 GB of memory and permanent storage for the data (a volume): without it, everything disappears the first time the container is recreated. Visual-build snapshots and baselines are stored in the database too, so plan the space with a margin.
- **A Chrome with our addon on the computer that will execute the checks.** This is a separate requirement that is easy to forget: the server does not open pages by itself, and snapshots for visual checks are taken only by the addon in runner mode. If you want to run tests on a schedule, that computer must be on at the right moments — the simplest way is to keep it on all the time.
- Optionally, the address and key of your Xedant Agent: without it everything works except comment analysis, action generation and auto-fix (more on that below).

## Docker Compose

Create a `compose.yml` file with this content:

```
services:
  test-agent:
    image: xedant/test-agent:min-latest
    container_name: test-agent
    ports:
      - "3978:80"
    volumes:
      - test-agent-data:/apps/tests
      - test-agent-config:/project/apps/tests
    environment:
      - ASPNETCORE_ENVIRONMENT=Production
      - ASPNETCORE_URLS=http://+:80
      - TEST_AGENT_DATA=/apps/tests
      - TEST_AGENT_PROJECTS_FOLDER=/project/apps/tests
# TEST_AGENT_BASE_PATH=/tests  # serve from a first-level subfolder (see ../subfolder-hosting.md)
    restart: unless-stopped
    sysctls:
      fs.inotify.max_user_watches: "524288"
      fs.inotify.max_user_instances: "512"

volumes:
  test-agent-data:
  test-agent-config:
```

Then run:

```
docker compose up -d
```

After startup the interface is available on port `3978`: `http://<server-address>:3978`. The two `sysctls` lines raise the system limits for file-change tracking — without them, some edits in the projects folder may not be picked up on the fly.

This file declares two permanent volumes. The first is the data (`/apps/tests`): the database, the license, the keys and the logs. The second is the projects folder (`/project/apps/tests`): the project’s rules, actions, tests and knowledge. Both survive container recreation, and it is the second volume that makes projects plain files: the folder can be put wholly under git (a version store for files) and moved to another server by simple copying.

## Running without Compose

A single `docker run` command works too:

```
docker run -d \
  --name test-agent \
  -p 3978:80 \
  -v test-agent-data:/apps/tests \
  -v test-agent-config:/project/apps/tests \
  -e TEST_AGENT_DATA=/apps/tests \
  -e TEST_AGENT_PROJECTS_FOLDER=/project/apps/tests \
  --sysctl fs.inotify.max_user_watches=524288 \
  --sysctl fs.inotify.max_user_instances=512 \
  --restart unless-stopped \
  xedant/test-agent:min-latest
```

The remaining environment variables are conveniently passed through a file with the `--env-file .env` flag — that way they are easier to change without rewriting a long command.

## Environment variables

Settings are passed through environment variables — you write them once into `compose.yml` and change them without touching the code. Almost all names start with `TEST_AGENT_`; the exceptions are the connection to the agent (`AGENT_API_URL`, `AGENT_API_KEY`) and sign-in through a shared proxy (`SSO_PROXY_TOKEN`).

| Variable | Purpose | Default |
| --- | --- | --- |
| TEST_AGENT_BRAND | brand and interface language: xedant (English) or pastukhov (Russian) | xedant |
| TEST_AGENT_DATA | permanent data folder (inside the container — /apps/tests) | /apps/tests |
| TEST_AGENT_API_KEY | the secret key guarding everything machine-facing: the link with the Chrome addon, external access for agents, the live-page address, the commands for the model and the visual machine addresses; without it these addresses answer “not configured”, with a wrong one — refused | — (not configured) |
| AGENT_API_URL | the address of your Xedant Agent: the chat, comment analysis, action generation and auto-fix work through it | — (chat hidden) |
| AGENT_API_KEY | the access key to your Xedant Agent | — |
| TEST_AGENT_PUBLIC_URL | the address of this server from which the model downloads snapshots and opens the live page, and from which public links and visual-build notifications are built; when unset, the snapshot link is not placed into prompts and the links in notifications become relative | — |
| TEST_AGENT_PROJECTS_FOLDER | the folder holding projects with rules, actions, scripts and tests | /project/apps/tests |
| TEST_AGENT_SCRIPTS_ENABLED | the master switch of script execution: the value 0 stops all runs at once | enabled |
| TEST_AGENT_PYTHON | which Python interpreter to use: the environment for scripts is created from it | python3 |
| TEST_AGENT_DB | database: a PostgreSQL connection string; empty value — the built-in SQLite | SQLite (/apps/tests/data.db) |
| TEST_AGENT_BASE_PATH | serve from a first-level subfolder (for example, /tests) | — (domain root) |
| TEST_AGENT_LOGIN | login of a pre-configured administrator; together with the password, creates the user at startup | — (the first to register) |
| TEST_AGENT_PASSWORD | lowercase SHA-256 hash of the password, not the password itself | — |
| TEST_AGENT_SSL | self-signed HTTPS of your own: auto — enable | — (HTTP only) |
| TEST_AGENT_SSL_PORT | port for HTTPS (by default — the one following the HTTP port) | — |
| TEST_AGENT_SSL_DOMAINS | comma-separated names the certificate is issued for | — |
| TEST_AGENT_ERROR_REPORTING | 0 — disable error reporting | — (no receiving address configured, nothing is sent) |
| SSO_PROXY_TOKEN | sign-in through a shared proxy with other products on the same server | — (regular sign-in) |

`TEST_AGENT_PASSWORD` holds not the password but its hash — a “fingerprint” the password cannot be recovered from. You get it with `printf '%s' 'yourpassword' | sha256sum` and paste it into the variable; at sign-in the app hashes what you typed and compares with the stored value. The `TEST_AGENT_API_KEY` key works differently — it is stored in plain text deliberately: the interface shows it so you can copy the key into the addon settings.

That key has a limitation: it is one per installation and does not fit when access is needed by a build pipeline or an outside runner. For that, the interface issues long-lived API keys (Settings → API tokens): a key is shown once and never recovered again, at work it is passed as the `Authorization: Bearer taj_…` header and comes in two scopes — “read only” (`readonly`) and “read and write” (`full`). Any such key can be revoked instantly, and, importantly, none of them can approve a baseline. Details are in the [API Keys](/agents/test/docs/tokens)
 section.

## Where the data lives

Permanent data lives in the `/apps/tests` volume and survives container recreation:

- `/apps/tests/data.db` — the database (when PostgreSQL is not used);
- `/apps/tests/auth/` — the keys sign-in sessions are signed with;
- `/apps/tests/.xedant/` — the license (with the `pastukhov` brand the folder is called `.pastukhov`);
- `/apps/tests/logs/addon-errors.log` — the Chrome addon error log, useful during investigations;
- `/apps/tests/keys/visual-creds.key` — the encryption key for visual-check credentials: staging logins and passwords are stored in the database encrypted (AES-256-GCM encryption);
- `/apps/tests/scripts/…` — the Python environments and the working directories of scripts: the code itself lives in the project folder, while everything it needs to work the product keeps here, in the data;
- the projects folder (by default `/project/apps/tests`) — the project’s rules, actions, scripts, tests and knowledge.

The dynamic part — screen snapshots, runs, issues and schedules, as well as visual-build snapshots, baselines with their versions and published share links — lives in the database. Rules, actions and tests, on the other hand, are plain files in the projects folder, and that is an important advantage: the folder can be put wholly under git (a version store for files), its edit history is visible, and a project moves to another server by simple copying. Commits into git are made by a person — the server never creates them on its own and pushes nothing to external repositories.

## First sign-in

Open the interface in a browser. While the database has no users, the registration form is open by itself — the first person to register becomes the administrator. If a login and password are set through `TEST_AGENT_LOGIN` and `TEST_AGENT_PASSWORD`, sign in with those (the variable stores the hash; at sign-in you enter the password itself). The sign-in session lives for 90 days, so you will not have to re-enter the password daily. When other products work alongside, sign-in can go through a shared proxy — it is configured with the `SSO_PROXY_TOKEN` variable.

After that the administrator creates the users personally: a login, a name and an initial password the person changes at first sign-in. The roles are: viewer (only looks), reviewer (delivers verdicts and manages the todos), member (queues runs and edits tests), admin (project settings and users) and owner (API keys and ownership handover). A separate flag appoints a design approver — the person who approves design-system changes. There are no email invitations: the login and password are handed over in person. A disabled account cannot sign in, but its trace in the audit log stays. Details are in the [Users and Roles](/agents/test/docs/users)
 section.

## What to do after startup

When the interface is open, a few steps remain before the first check:

1. Set the addon key — the `TEST_AGENT_API_KEY` variable. The Chrome addon connects to the server with it, and the model gets access to the live page.
2. Create a project: a name, the site’s base address and a timezone. A project is a folder where rules, actions and tests will accumulate.
3. Connect Xedant Agent — set `AGENT_API_URL` and `AGENT_API_KEY`. After that the chat with the AI agent, comment analysis, action generation in words and auto-fix appear.
4. Install the Chrome addon — with the one-click install described below. Without it, pages cannot be captured and checks cannot run.
5. Set up visual checks: pick a preset, sensitivity thresholds and capture stabilization — otherwise comparing builds against the baseline will produce noise. Details are in the [Visual Testing Settings](/agents/test/docs/visual-settings) section.
6. Create environments and credentials if the tests reach a protected staging server: the staging address, logins and passwords are stored in the database encrypted and are substituted into actions only for the duration of a run. Details are in the [Environments, Credentials and Variables](/agents/test/docs/environments) section.
7. Issue an API key for the build pipeline — Settings → API tokens. The pipeline queues checks and reads the result with it; the `viz` tool reads the key from the `TEST_AGENT_API_KEY` variable.
8. Capture the first screen and write a comment in words: “the button is invisible on the dark background”. Send the comment to the agent — it will turn it into a rule, and from then on plain code finds this remark.
9. If you plan to write your own checks, open the “Scripts” tab and make sure no execution-environment warning hangs at the top: it appears when the server has no Python or the environment failed to build. Details are in the [Scripts and Extensibility](/agents/test/docs/scripts) section.
10. Walk through the [setup checklist](/agents/test/docs/checklist) — a short list of steps; it shows what is already ready.

Visual snapshots are taken only by the Chrome addon, so builds absolutely need a Chrome connected in runner mode — the same one as for ordinary checks.

More about the first steps is in the [Getting Started](/agents/test/docs/getting-started)
 section.

## Installing the Chrome addon

The addon is installed from the product itself. In the interface open **Settings → UI Testing → “One-click install and pairing”** and choose a folder on disk — the server writes a `test-agent-addon` folder there with the pairing already in place (the server address and the key); nothing needs to be configured by hand. Chrome then asks for three familiar steps:

1. Open `chrome://extensions`.
2. Turn on the Developer mode switch in the top right corner.
3. Click “Load unpacked” and select the `test-agent-addon` folder the app created for you.

Let us be honest: **the addon is private and is not in the Chrome Web Store.** That is deliberate — checks should not go through store review, otherwise every new rule would take weeks to wait for. So after a server update you rewrite the folder from the same dialog (“Update in one click”) and press the “Update” button on the extension’s card at `chrome://extensions`. If the addon was installed another way, it can be paired by hand: enter the server address and the key on the addon’s settings page and press “Test connection”.

## Installing through Xedant MultiAgent

If you have several servers, it is more convenient to install the product from Xedant MultiAgent: it raises the container itself, gives it a permanent address and HTTPS, and connects the database. For Test Agent the catalog has a ready template — “TestAgent” (short name “Tests”, port `6070`) — installation comes down to one click, and the `TEST_AGENT_SSL`, `TEST_AGENT_DB` and `TEST_AGENT_API_KEY` variables are filled in by MultiAgent automatically. One honest caveat: in the template the linked agent is connected through the `TEST_AGENT_BASE_URL` variable, while the product itself reads `AGENT_API_URL` and `AGENT_API_KEY` — that is a discrepancy of the template itself, not an error in this instruction. More about MultiAgent itself is on the [MultiAgent](/agents/multiagent)
 page.

## License

The license key is activated in the license dialog in the interface, or passed through the `AGENT_LICENSE` variable at startup. There is no ready license in the image: a fresh container starts without one. Almost everything works without a license — projects, screens, comments, rules, actions, tests, runs, schedules, issues, auto-fix and the attention summary. The license is needed for exactly one thing: to send a message to the agent in the chat. The trial period is 30 days; the personal license costs $197, the company one $497, the service one $970. The limit is the same for everyone: without a license, visual checks, review, reports, coverage and the build pipeline work too. Details are on the [Licensing](/agents/test/license)
 page.

[← Back to the Test Agent section home](/agents/test)
