# Интеграционные тесты задач — mock-сервер ARC запускается как обычно (реальные Android-устройства через ADB), но подключается к локальному Flask-моку вместо боевого бэкенда. Мок раздаёт задачи по одной на material, собирает результаты и показывает отчёт в браузере. --- ## 1. Требования | Компонент | macOS | Windows | |---|---|---| | Python | `brew install python` или встроенный | [python.org](https://python.org), галочка «Add to PATH» | | Flask | `pip install flask` | `pip install flask` | | ADB | `brew install android-platform-tools` | Используется из `tools\adb\windows\` | | ARC | `cmake --build build_test` | `cmake --build build --config Release` | | Устройства | `adb devices` → `device` | `tools\adb\windows\adb.exe devices` | --- ## 2. Генерация тестовых данных из БД Перед первым запуском (или при смене устройств/аккаунтов) нужно сгенерировать мок-данные из локальной базы. Скрипты читают `config.ini → [db] dbPath`. ### 2.1 Стартовые данные: профиль + FETCH_PROFILE ```bash # macOS (из корня проекта) python3 tests/mock_server/gen_mock_data.py # Windows python tests\mock_server\gen_mock_data.py ``` Скрипт: - Находит `config.ini` в текущей директории (или `build/Release/config.ini`) - Открывает БД, читает `bank_profiles` с проверенным PIN-кодом (`pin_code_checked = 'yes'`) и активные `materials` - Генерирует: - `tests/mock_server/default_profile.json` — профиль для мока - `tests/mock_server/scenarios/*__fetch_profile.json` — по одному на материал (с номером карты в имени) - Очищает таблицу `events` в БД Пример вывода: ``` config: config.ini database: database/app_data.db deleted 5 old events wrote default_profile.json (3 bank_profiles) wrote scenarios/pixel_7_ozon_7919_fetch_profile.json wrote scenarios/pixel_7_ozon_9865_fetch_profile.json wrote scenarios/pixel_7_dushanbe_city_bank_3258_fetch_profile.json wrote scenarios/tecno_km4_ozon_0982_fetch_profile.json Devices (2): pixel_7: ozon/7919 (50393cc1…), ozon/9865 (06a1ae15…), dushanbe_city_bank/3258 (36002ac2…) tecno_km4: ozon/0982 (7e3a7e4e…) ``` Флаги: `--config C:\path\to\config.ini` — если config не в текущей директории. ### 2.2 Пул FETCH_TRANSACTIONS с живого устройства ```bash # macOS python3 tests/mock_server/gen_fetch_transactions.py # Windows python tests\mock_server\gen_fetch_transactions.py ``` Скрипт: - Читает БД → находит активные материалы - Находит подключённые ADB-устройства → матчит по `adb_serial` - Показывает меню → выбор материала или `all` - Проходит по транзакциям на экране: - **Ozon**: парсит заголовки дат (Сегодня/Вчера/dd месяца), определяет дату каждой транзакции по Y-позиции, тапает для получения времени из деталей, скроллит вниз для следующих - **Dushanbe**: парсит Выписку, тап в детали, время Dushanbe (UTC+5) - Дедупликация по `(amount, created_at)` — одинаковые суммы в один день с разным временем сохраняются как отдельные задачи - Сохраняет `scenarios/pool/*__ft_*.json` с реальными `amount` (в копейках) и `created_at` (UTC) - Если мок запущен — сразу инжектит задачи Флаги: - `--serial 148697059H000712` — явный ADB-серийник - `--kopecks 100` — множитель суммы (по умолчанию 100) - `--config path` — путь к config.ini --- ## 3. Переключение ARC на мок В `config.ini` → `[net]`: ```ini [net] apiBase=http://127.0.0.1:8888 ``` Остальные `path*` оставить как есть. > На Windows: `config.ini` обычно лежит рядом с `ARC.exe` в `build\Release\`. > Совет: держите копию `config.ini.mock` и `config.ini.prod`. --- ## 4. Запуск теста ### Терминал 1 — mock-сервер ```bash # macOS — полный цикл (генерация данных + запуск) cd tests/mock_server && ./run.sh # macOS — только определённые банки cd tests/mock_server && ./run.sh --banks ozon # macOS — только FETCH_TRANSACTIONS (без FETCH_PROFILE) cd tests/mock_server && ./run.sh --types FETCH_TRANSACTIONS --banks ozon # macOS — debug режим (auto-reload при изменении кода) cd tests/mock_server && ./run.sh --banks ozon --debug # Windows cd tests\mock_server python mock_server.py --port 8888 ``` Флаги `mock_server.py`: - `--banks ozon dushanbe_city_bank` — только указанные банки - `--types FETCH_TRANSACTIONS` — только указанные типы задач - `--ft-per-material 3` — сколько FT на материал при бутстрапе (default 3) - `--seed 42` — фиксированный RNG для воспроизводимости - `--debug` — Flask debug режим (auto-reload, состояние сохраняется между перезагрузками) При `--debug`: - Изменения в `.py` файлах применяются автоматически без перезапуска - Состояние задач сохраняется в `.mock_state.json` и восстанавливается при reload - Скриншоты сохраняются в `.mock_screenshots/` (переживают reload) - При **первом** запуске — чистый старт (events в БД очищаются, state сбрасывается) ### Терминал 2 — ARC ```bash # macOS (из корня проекта!) ./build_test/ARC # Windows build\Release\ARC.exe ``` При логине мок автоматически ставит задачи: - 1 × FETCH_PROFILE на каждый материал (если `--types` не ограничивает) - N × FETCH_TRANSACTIONS (случайные из pool) Задачи раздаются **по 1 на material за поллинг** — следующая только после получения результата предыдущей. Это предотвращает expire задач в очереди. ### Терминал 3 — отчёт ```bash # Браузер с авто-обновлением open http://127.0.0.1:8888/_admin/report/html # macOS start http://127.0.0.1:8888/_admin/report/html # Windows ``` --- ## 5. HTML-отчёт `http://127.0.0.1:8888/_admin/report/html` — веб-страница с: - Сводкой: всего / выполнено / ошибки / в очереди - Группировкой по **устройствам** → **банкам** (Pixel 7 → ozon, dushanbe_city_bank) - Для каждой задачи: - Task JSON и Result JSON (для успешных — свёрнуты, кнопка "Показать JSON") - Ошибки — развёрнуты сразу с красным бейджем - Скриншот (если есть) — третья колонка, клик открывает полноэкранный просмотр - Кнопка "Копировать" на каждом JSON блоке - Цветовой индикацией: зелёный = completed, красный = error, жёлтый = pending - Авто-обновлением каждые 2 секунды (состояние свёрнутых/развёрнутых блоков сохраняется) --- ## 6. Скриншоты Приложение отправляет скриншоты через `POST /monitoring/log` с полем `internal_task_id`. Мок-сервер: - Сохраняет PNG на диск в `.mock_screenshots/` - Привязывает к задаче по `internal_task_id` (точное совпадение с `task_result`) - Отображает в отчёте как третью колонку рядом с Task/Result JSON - Клик по скриншоту — полноэкранный просмотр (Escape для закрытия) --- ## 7. Ручной инжект задач ```bash # Одна задача curl -X POST http://127.0.0.1:8888/_admin/inject \ -H "Content-Type: application/json" \ --data-binary @scenarios/pixel_7_ozon_7919_fetch_profile.json # Повторный бутстрап (без перезапуска мока) curl -X POST http://127.0.0.1:8888/_admin/bootstrap # Сброс (очистка очереди + результатов + скриншотов) curl -X POST http://127.0.0.1:8888/_admin/reset ``` --- ## 8. Админ-эндпойнты мока | Метод | Путь | Назначение | |---|---|---| | POST | `/_admin/inject` | Положить задачу (или массив) в очередь | | POST | `/_admin/bootstrap` | Повторный бутстрап | | POST | `/_admin/seed_profile` | Подменить ответ `current_profile` | | POST | `/_admin/seed_devices` | Подменить список устройств | | GET | `/_admin/report` | JSON: полный отчёт | | GET | `/_admin/report/html` | HTML-отчёт с авто-обновлением | | GET | `/_admin/report/pending` | Только незавершённые задачи | | GET | `/_admin/report/fragment` | JSON-фрагмент для JS-обновления | | GET | `/_admin/screenshot/` | PNG скриншот по ID | | GET | `/_admin/state` | Счётчики | | POST | `/_admin/reset` | Очистить всё, сбросить бутстрап | --- ## 9. Полный цикл с нуля ```bash # 1. Установка pip install flask # 2. Собрать ARC, запустить с боевым сервером → залогиниться # Устройства, профили и материалы появятся в БД # 3. Переключить config.ini на мок # [net] # apiBase=http://127.0.0.1:8888 # 4. Сгенерировать стартовые данные из БД python3 tests/mock_server/gen_mock_data.py # 5. Открыть на устройстве банковское приложение → список транзакций # Сгенерировать пул задач python3 tests/mock_server/gen_fetch_transactions.py # 6. Запустить мок cd tests/mock_server && ./run.sh --banks ozon --debug # 7. Запустить ARC (из корня проекта, в отдельном терминале) ./build_test/ARC # 8. Открыть отчёт open http://127.0.0.1:8888/_admin/report/html # 9. Дождаться completed = всего в отчёте # 10. Вернуть config.ini на прод ``` --- ## 10. Структура файлов ``` tests/mock_server/ ├── mock_server.py # Flask mock-сервер ├── run.sh # запуск (macOS/Linux): gen_mock_data + mock_server ├── gen_mock_data.py # генерация default_profile + scenarios из БД ├── gen_fetch_transactions.py # генерация pool из живого устройства ├── inject.sh # curl-обёртка для инжекта ├── default_profile.json # авто-генерированный профиль для мока ├── README.md # эта инструкция ├── WINDOWS.md # Windows-специфичные нюансы ├── .mock_state.json # состояние задач (debug режим, .gitignore) ├── .mock_screenshots/ # скриншоты с устройств (.gitignore) ├── scenarios/ # FETCH_PROFILE сценарии │ ├── pixel_7_ozon_7919_fetch_profile.json │ ├── pixel_7_ozon_9865_fetch_profile.json │ └── ... └── scenarios/pool/ # пул FETCH_TRANSACTIONS ├── pixel_7_ozon_7919_01_minus_108_ft_01.json ├── pixel_7_ozon_9865_01_minus_108_ft_01.json ├── pixel_7_dushanbe_city_bank_3258_01_plus_5_ft_01.json └── ... ``` --- ## 11. Типовые проблемы | Симптом | Причина | Решение | |---|---|---| | `config.ini not found` | Скрипт запущен не из корня проекта | `cd` в корень или `--config path` | | `No active materials` | Нет профилей с проверенным PIN | Запустить ARC с боевым сервером, добавить PIN | | `No ADB devices match` | Устройства не подключены | `adb devices`, проверить USB | | `App restarted` ошибки в отчёте | Events остались от прошлого запуска | Мок-сервер чистит events при старте; используйте `run.sh` или запускайте сервер **до** ARC | | Задача `pending` навсегда | material в `_in_flight` | `/_admin/reset` и перезапустить ARC | | `Transaction not found` | Баг поиска — скролл, видимость кнопок | Анализировать логи (device= в ошибке) | | `Page load error` | Ozon WebView не загрузился | Проблема интернета/устройства, таймаут 5 мин | | Скриншот не привязан | Нет `internal_task_id` | Обновить ARC (фикс в EventHandler.cpp) | | Pool material_id не совпадает | БД обновилась, pool устарел | Перегенерировать pool или обновить material_id в файлах | | Порт занят | Другой процесс на 8888 | `--port 9999` + поменять `apiBase` | --- ## 12. Что мок эмулирует и что нет **Эмулирует:** - Авторизацию (login/refresh) - Синхронизацию профилей (current_profile, bank_profile CRUD) - Выдачу задач (get_tasks) с in-flight контролем - Приём результатов (task_result) с `internal_task_id` - Приём скриншотов (monitoring/log) с привязкой к задачам - Управление устройствами и материалами (toggle) **Не эмулирует:** - Валидацию тел запросов - Webhook-уведомления банков - Сетевые задержки/таймауты