Installation

Don’t want to read all this?

Just drop a link to https://xedant.com/agents/test/install.md or to 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).

VariablePurposeDefault
TEST_AGENT_BRANDbrand and interface language: xedant (English) or pastukhov (Russian)xedant
TEST_AGENT_DATApermanent data folder (inside the container — /apps/tests)/apps/tests
TEST_AGENT_API_KEYthe 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_URLthe address of your Xedant Agent: the chat, comment analysis, action generation and auto-fix work through it— (chat hidden)
AGENT_API_KEYthe access key to your Xedant Agent—
TEST_AGENT_PUBLIC_URLthe 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_FOLDERthe folder holding projects with rules, actions, scripts and tests/project/apps/tests
TEST_AGENT_SCRIPTS_ENABLEDthe master switch of script execution: the value 0 stops all runs at onceenabled
TEST_AGENT_PYTHONwhich Python interpreter to use: the environment for scripts is created from itpython3
TEST_AGENT_DBdatabase: a PostgreSQL connection string; empty value — the built-in SQLiteSQLite (/apps/tests/data.db)
TEST_AGENT_BASE_PATHserve from a first-level subfolder (for example, /tests)— (domain root)
TEST_AGENT_LOGINlogin of a pre-configured administrator; together with the password, creates the user at startup— (the first to register)
TEST_AGENT_PASSWORDlowercase SHA-256 hash of the password, not the password itself—
TEST_AGENT_SSLself-signed HTTPS of your own: auto — enable— (HTTP only)
TEST_AGENT_SSL_PORTport for HTTPS (by default — the one following the HTTP port)—
TEST_AGENT_SSL_DOMAINScomma-separated names the certificate is issued for—
TEST_AGENT_ERROR_REPORTING0 — disable error reporting— (no receiving address configured, nothing is sent)
SSO_PROXY_TOKENsign-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 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 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 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 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 section.
  10. Walk through the setup 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 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 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 page.

← Back to the Test Agent section home