1
0
forked from BRT/arc

Add scenarios for "FETCH_TRANSACTIONS" testing and improve bank-specific bootstrapping logic in mock server.

This commit is contained in:
trnsmkot 2026-04-12 17:29:48 +07:00
parent 31f3b04751
commit abdd81e771
25 changed files with 269 additions and 2 deletions

View File

@ -209,7 +209,7 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
const QString tzName = AdbUtils::getDeviceTimezone(m_deviceId);
QTimeZone deviceTz(tzName.toUtf8());
if (!deviceTz.isValid()) deviceTz = QTimeZone("Europe/Moscow");
const int maxScrolls = 8;
const int maxScrolls = 30;
const int navBarTop = device.screenHeight - (device.screenHeight / 10);
// Целевая дата в таймзоне устройства для поиска заголовка дня в списке
@ -258,6 +258,15 @@ void GetLastTransactionsScript::searchTransaction(const DeviceInfo &device, int
return false;
};
// Ждём пока WebView раскроет accessibility tree (иначе dump пустой)
for (int wait = 0; wait < 5; ++wait) {
xmlScreenParser.parseAndSaveXml(AdbUtils::getScreenDumpAsXml(m_deviceId, ++m_counter));
if (xmlScreenParser.findTransactionButtons(1).size() > 0) break;
if (hasDateOnScreen()) break;
qDebug() << "[FetchTransactions] Waiting for WebView content..." << (wait + 1);
QThread::msleep(2000);
}
bool dateFound = false;
for (int scroll = 0; scroll < maxScrolls; ++scroll) {
if (QThread::currentThread()->isInterruptionRequested()) {

View File

@ -130,9 +130,28 @@ python mock_server.py --port 8888
```
Флаги:
- `--banks ozon` — генерировать задачи только для указанных банков
- `--banks ozon dushanbe_city_bank` — несколько банков через пробел
- `--ft-per-material 3` — сколько FT на материал при бутстрапе (default 3)
- `--seed 42` — фиксированный RNG для воспроизводимости
Без `--banks` задачи генерируются для всех активных банков.
Примеры:
```bash
# Только Ozon
./run.sh --banks ozon
# Только Dushanbe
./run.sh --banks dushanbe_city_bank
# Ozon + Dushanbe, по 2 FT на материал
./run.sh --banks ozon dushanbe_city_bank --ft-per-material 2
# Все банки (по умолчанию)
./run.sh
```
### Терминал 2 — ARC
```bash
@ -241,8 +260,10 @@ python tests/mock_server/gen_mock_data.py
# Сгенерировать пул задач
python tests/mock_server/gen_fetch_transactions.py
# 6. Запустить мок
# 6. Запустить мок (все банки)
cd tests/mock_server && python mock_server.py --port 8888
# или только определённые:
# cd tests/mock_server && python mock_server.py --port 8888 --banks ozon
# 7. Запустить ARC (в отдельном терминале)
./build/ARC # macOS

View File

@ -43,6 +43,7 @@ powershell -ExecutionPolicy Bypass -File setup.ps1
|---|---|---|
| `-Port` | 8888 | Порт mock-сервера |
| `-FtPerMaterial` | 3 | FETCH_TRANSACTIONS на материал при бутстрапе (из пула) |
| `-Banks` | все | Банки через запятую: `ozon`, `dushanbe_city_bank`, `black` |
| `-SkipInstall` | — | Пропустить установку Python/Flask |
| `-GenerateOnly` | — | Только сгенерировать данные, не запускать сервер |
| `-Clean` | — | Также очистить пул транзакций (`scenarios/pool/`) |
@ -56,6 +57,15 @@ powershell -ExecutionPolicy Bypass -File setup.ps1
# На другом порту с 5 транзакциями на материал
.\setup.ps1 -Port 9999 -FtPerMaterial 5
# Только Ozon
.\setup.ps1 -Banks ozon
# Только Dushanbe, по 2 транзакции
.\setup.ps1 -Banks dushanbe_city_bank -FtPerMaterial 2
# Ozon + Dushanbe
.\setup.ps1 -Banks ozon,dushanbe_city_bank
# Пропустить установку (Python/Flask уже есть)
.\setup.ps1 -SkipInstall

View File

@ -112,6 +112,19 @@ def device_label(name: str) -> str:
return m.group(1) if m else name
def cleanup_events(db_path: Path):
"""Delete all events from previous runs."""
conn = sqlite3.connect(str(db_path))
count = conn.execute("SELECT count(*) FROM events").fetchone()[0]
if count > 0:
conn.execute("DELETE FROM events")
conn.commit()
print(f" deleted {count} old events")
else:
print(" events table clean")
conn.close()
def generate(materials: list, out_dir: Path):
out_dir.mkdir(parents=True, exist_ok=True)
scenarios_dir = out_dir / "scenarios"
@ -195,6 +208,8 @@ def main():
db_path = resolve_db_path(config_path)
print(f"database: {db_path}")
cleanup_events(db_path)
materials = query_active_materials(db_path)
if not materials:
print("No active materials found in database.", file=sys.stderr)

View File

@ -73,6 +73,7 @@ _device_label_by_material: dict = {} # material_id -> "TECNO KM4" etc.
_in_flight: set = set() # material_ids with a delivered-but-not-yet-resulted task
_bootstrap_done = False
_bootstrap_ft_count = 3
_bootstrap_banks: list | None = None # None = all banks
def ok(data=None):
@ -164,6 +165,8 @@ def bootstrap_tasks():
queued = 0
for bp in _bank_profiles:
bank = bp.get("bank_name")
if _bootstrap_banks and bank not in _bootstrap_banks:
continue
for mat in bp.get("materials", []):
mid = mat.get("id")
if not mid:
@ -946,11 +949,16 @@ if __name__ == "__main__":
parser.add_argument("--port", type=int, default=8888)
parser.add_argument("--ft-per-material", type=int, default=3,
help="How many random FETCH_TRANSACTIONS to bootstrap per material")
parser.add_argument("--banks", nargs="+", default=None,
help="Only bootstrap tasks for these banks (e.g. --banks ozon dushanbe_city_bank)")
parser.add_argument("--seed", type=int, default=None,
help="RNG seed for reproducible bootstrap picks")
args = parser.parse_args()
_bootstrap_ft_count = args.ft_per_material
_bootstrap_banks = args.banks
if _bootstrap_banks:
print(f"[mock] bootstrap limited to banks: {_bootstrap_banks}")
if args.seed is not None:
random.seed(args.seed)

View File

@ -2,4 +2,18 @@
# Start the mock ARC backend. Requires `flask` in the active Python env.
set -euo pipefail
cd "$(dirname "$0")"
# Find config.ini (project root is two levels up)
PROJECT_ROOT="$(cd ../.. && pwd)"
CONFIG=""
for c in "$PROJECT_ROOT/config.ini" "$PROJECT_ROOT/build/config.ini" "$PROJECT_ROOT/build/Release/config.ini"; do
if [ -f "$c" ]; then CONFIG="$c"; break; fi
done
if [ -n "$CONFIG" ]; then
echo "[run.sh] generating mock data + cleaning events..."
python3 gen_mock_data.py --config "$CONFIG"
echo ""
fi
exec python3 mock_server.py --host 127.0.0.1 --port 8888 "$@"

View File

@ -0,0 +1,10 @@
{
"bank_name": "dushanbe_city_bank",
"material_id": "61d967d1-8d3e-4d05-ba01-8c8ab327b945",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": -100,
"created_at": "2026-04-10T09:39:15Z"
},
"_tag": "pixel7_dushanbe_01_embedded_minus_1"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "dushanbe_city_bank",
"material_id": "61d967d1-8d3e-4d05-ba01-8c8ab327b945",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": -100,
"created_at": "2026-04-05T14:31:21Z"
},
"_tag": "pixel7_dushanbe_02_minus_1_2131"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "dushanbe_city_bank",
"material_id": "61d967d1-8d3e-4d05-ba01-8c8ab327b945",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": -100,
"created_at": "2026-04-05T14:25:48Z"
},
"_tag": "pixel7_dushanbe_03_minus_1_2125"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "dushanbe_city_bank",
"material_id": "61d967d1-8d3e-4d05-ba01-8c8ab327b945",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": -100,
"created_at": "2026-04-05T11:36:06Z"
},
"_tag": "pixel7_dushanbe_04_minus_1_1836"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "dushanbe_city_bank",
"material_id": "61d967d1-8d3e-4d05-ba01-8c8ab327b945",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": -100,
"created_at": "2026-04-05T11:19:43Z"
},
"_tag": "pixel7_dushanbe_05_minus_1_1819"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "dushanbe_city_bank",
"material_id": "61d967d1-8d3e-4d05-ba01-8c8ab327b945",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": 100,
"created_at": "2026-04-03T13:52:06Z"
},
"_tag": "pixel7_dushanbe_06_plus_1_2052"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "30bc106c-6935-4f4b-85f3-f1a06adc5c13",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": 10000,
"created_at": "2026-04-11T10:39:00Z"
},
"_tag": "pixel7_ozon_01_evgeny_plus_100"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "30bc106c-6935-4f4b-85f3-f1a06adc5c13",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": -10000,
"created_at": "2026-04-10T09:40:00Z"
},
"_tag": "pixel7_ozon_02_vlad_minus_100"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "30bc106c-6935-4f4b-85f3-f1a06adc5c13",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": -30000,
"created_at": "2026-04-08T08:34:00Z"
},
"_tag": "pixel7_ozon_03_vlad_minus_300"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "30bc106c-6935-4f4b-85f3-f1a06adc5c13",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": 10000,
"created_at": "2026-04-08T08:14:00Z"
},
"_tag": "pixel7_ozon_04_vlad_plus_100"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "30bc106c-6935-4f4b-85f3-f1a06adc5c13",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": 10000,
"created_at": "2026-04-08T08:02:00Z"
},
"_tag": "pixel7_ozon_05_vlad_plus_100_b"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "30bc106c-6935-4f4b-85f3-f1a06adc5c13",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": 10000,
"created_at": "2026-04-06T13:54:00Z"
},
"_tag": "pixel7_ozon_06_evgeny_plus_100_b"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": 10000,
"created_at": "2026-04-10T09:40:00Z"
},
"_tag": "tecno_ozon_01_galina_plus_100"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": 30000,
"created_at": "2026-04-08T08:34:00Z"
},
"_tag": "tecno_ozon_02_galina_plus_300"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": -10000,
"created_at": "2026-04-08T08:32:00Z"
},
"_tag": "tecno_ozon_03_vlad_minus_100_a"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": -10000,
"created_at": "2026-04-08T08:23:00Z"
},
"_tag": "tecno_ozon_04_vlad_minus_100_b"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": -10000,
"created_at": "2026-04-08T08:14:00Z"
},
"_tag": "tecno_ozon_05_galina_minus_100_a"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": -10000,
"created_at": "2026-04-08T08:02:00Z"
},
"_tag": "tecno_ozon_06_galina_minus_100_b"
}

View File

@ -0,0 +1,10 @@
{
"bank_name": "ozon",
"material_id": "49001bb5-3b24-478d-b913-c2242aea0732",
"type": "FETCH_TRANSACTIONS",
"body": {
"amount": 55000,
"created_at": "2026-03-20T14:36:00Z"
},
"_tag": "tecno_ozon_07_vlad_plus_550"
}