Тесты и стенды

> Кратко. Веб проверяют vitest (npm run check — ещё и lint и typecheck) и Playwright e2e на живом стенде; API — pytest. Стенд — API и веб на копии базы города со своим Redis. Инструкция docs/manual собирается из сценариев съёмки и текстов (npm run manual:capture, npm run manual:pages).

Веб: проверки без стенда

Команда Что
npm run lint ESLint по всему проекту
npm run typecheck nuxt typecheck (vue-tsc) — идёт минуты
npm run test vitest: tests/**/*.spec.ts, среда happy-dom, tests/setup.ts
npm run check всё сразу: lint, typecheck, test и проверка подсказок значков (check:hints)
npm run ci check и сборка

Тесты vitest лежат по слоям кода: tests/utils/ (чистые функции: протокол встраивания, подпись вебхуков, клиенты MCP и ArcGIS), tests/components/, tests/stores/, tests/services/. Один файл: npx vitest run tests/utils/webhooks.spec.ts.

Веб: Playwright e2e

Сквозные проверки идут по живому стенду и в CI не запускаются (нужна база). Браузер не скачивается: берётся установленный Chromium Playwright (ревизия под закреплённый @playwright/test), PW_CHROMIUM_PATH или системный Chrome.

Где Что
e2e/smoke.spec.ts карта, карточка, анализ режима, пьезометр, отчёты
e2e/functions/*.spec.ts функции по разделам инструкции: действие → ответ API → результат в окне; запись — с меткой SYNTH-E2E и уборкой
e2e/functions/developer-api.spec.ts API для разработчиков без окна: OpenAPI, OGC, FeatureServer, MCP, API v2, подпись вебхуков, встраивание, PMTiles
e2e/permissions.spec.ts роль и флаги: ответы /auth/config и /auth/me подменяются
e2e/a11y.spec.ts, e2e/resilience.spec.ts, e2e/visual.spec.ts, e2e/devices.spec.ts доступность (axe), сбои сети, эталонные снимки, телефоны и планшеты
e2e/audit.spec.ts обход всех окон на трёх языках (около часа)

Переменные:

Переменная Что По умолчанию
E2E_BASE_URL адрес веба стенда http://127.0.0.1:3040/itwin-map/
E2E_API_URL адрес API стенда (проверки ответов, уборка) http://127.0.0.1:8040
E2E_READONLY 1 — пропустить тесты, которые пишут в базу —
E2E_FRAGMENT_ID фрагмент для карты и сверок 74
E2E_TOKEN токен входа для стенда с включённым входом (developer-api.spec.ts) —
E2E_LOCALES языки e2e/functions.spec.ts все три
E2E_HEADED 1 — с окном браузера —

Запуск одного набора на собранном стенде:

E2E_BASE_URL=http://127.0.0.1:3090/itwin-map/ E2E_API_URL=http://127.0.0.1:8090 \
  npx playwright test e2e/functions/developer-api.spec.ts --project=chromium --workers=1

Прогон этого набора на копии Алматы (07.11.2026): 16 тестов прошли, 4 пропущены — три помечены test.fixme с найденными ошибками (повтор OBJECTID потребителей, 500 у /api/ogc/jobs, task_status MCP), один требует стенда с включённым входом.

Правила e2e-тестов: окна открывать через uiStore.requestToolDialog и ждать конца анимации (образец — openDialog в e2e/functions/operations.spec.ts); сверять числа окна с ответом API; созданные записи помечать SYNTH-E2E и удалять через API в afterAll; права проверять подменой auth/me; расчёты и вызовы модели ИИ на общем стенде не запускать (ответы ИИ подменяются, как в e2e/functions/ai.spec.ts). Подробно — docs/e2e-smoke.md.

API: pytest

cd itwin-api
JWT_SECRET=test-secret-test-secret-test-secret-123 AUTH_DISABLED=false \
  venv/Scripts/python.exe -m pytest -q tests/test_mcp.py tests/test_arcgis.py tests/test_webhooks.py
# 36 passed
  • Тесты маршрутов поднимают приложение через FastAPI TestClient и подменяют зависимости и базу; живой базы не нужно.
  • tests/pg/ — права PostgreSQL на копии базы: только с PG_AUTH_TESTS=1 и базой, помеченной как копия.
  • tests/golden/, tests/heatnet/ — сверка расчёта с эталонами десктопного sety; нужны эталоны и исходники десктопа.

Стенд на копии базы

Стенд — API, воркер и веб на копии базы города. Боевую базу к стенду не подключают.

  1. Копия базы: createdb -T <база города> <база>_copy (или восстановление дампа), так же — копия UsersDB.
  2. API: .env с DB_NAME=<копия>, USERS_DB_NAME=<копия>, своим REDIS_DB (иначе воркер стенда заберёт чужие задачи из очереди и выполнит их на своей базе), CORS_ALLOWED_ORIGINS с адресом веба стенда. Для стенда без входа — AUTH_DISABLED=true (каждый запрос — пользователь dev со всеми правами), MUTATIONS_ENABLED=true, TOPOLOGY_MUTATIONS_ENABLED=true; вебхуки выключить — WEBHOOK_POLL_S=0. Запуск: uvicorn main:app --host 127.0.0.1 --port 8090. При первом запуске API сам доводит базу копии (city_schema): таблицы tgid_*, индексы, функции тайлов.
  3. Воркер (для расчётов, выгрузок, запекания): celery -A worker.celery_app worker -P solo --hostname <имя стенда>@%h с тем же окружением.
  4. Веб: сборка npm run build с NUXT_PUBLIC_MAP_API_BASE_URL=http://127.0.0.1:8090, запуск node .output/server/index.mjs с PORT=3090 и NUXT_APP_BASE_URL=/itwin-map/. Сборку делайте в отдельной рабочей копии, а не в каталоге, из которого работает служба. npm run dev тоже годится, но ленивые окна там грузятся по нескольку секунд, и e2e идут медленнее.
  5. Проверка: GET /health (база, Redis, city_schema, флаги) и GET /api/v1/auth/config.

Все переменные окружения API и веба — на странице Переменные окружения.

На общем стенде пишите только свои записи с меткой SYNTH-E2E или SYNTH-MANUAL и удаляйте их после проверки. Ключи ArcGIS, MCP и API v2 отозвать нельзя, а подписаны они секретом JWT_SECRET из .env — на стенде, который делит секрет с рабочим сервером, их не выпускайте.

Инструкция docs/manual

Что Где
сценарии съёмки окон scripts/manual/scenarios/<раздел>.mjs
шаги и данные страниц функций scripts/manual/pages.json
тексты страниц scripts/manual/text/<раздел>/<id>.md: у страницы функции — только разделы «Возможности» … «Для разработчика»; самостоятельная страница начинается со строк keywords, order, level и заголовка # …
снимки и видео npm run manual:capture (MANUAL_BASE_URL, MANUAL_API_URL, MANUAL_STORAGE_PREFIX, MANUAL_ONLY=id1,id2)
сборка страниц npm run manual:pages — пишет docs/manual/** и index.json, проверяет ссылки между страницами и на снимки; битая ссылка — ошибка
журнал проверки функций docs/manual-qa.md

Съёмку ведут на собранном вебе стенда; записи, созданные для кадра, помечены SYNTH-MANUAL и убираются сценарием, иначе сценарий падает.

Хотите увидеть эту функцию на своих данных?Покажем ТГИД на демонстрации и ответим на вопросы инженеров.
Запросить демо