# Ozon 19.19.1 — расхождения вёрстки с парсером Устройство: Pixel 7, Android 17. Версия Ozon: **19.19.1** (versionCode 16030308). Пакет: `ru.ozon.fintech.finance`. Общий вывод: приложение переехало на **Compose-семантику** — интерактивные контролы (кнопки, вкладки) больше не несут видимый `text`, а выставляют стабильные тест-id в `content-desc`. Текстовый контент (балансы, заголовки, строки списков) по-прежнему в `text`. Парсер во многих местах матчит по `node.text` → ломается. Чинить переходом на `content-desc`. ## Найденные расхождения ### 1. PIN-пад (`findPinCodeNodes`, способ 1) — экран `pin_code` - Было: цифра в `text="key 1"` (регулярка `^(?:key\s+)?(\d)$` по `node.text`). - Стало: `text=""`, цифра в **`content-desc="key 1"`** (class Button). - Эффект: способ 1 находит 0 цифр, спасает только геометрический fallback (способ 2) — хрупко (кнопка отпечатка `bioauth` 86×87 почти попадает в группу «квадратных»). - Фикс: в способе 1 матчить регуляркой и `node.text`, и `content-desc`. ### 2. Главный экран (`isHomeScreen`) — экран `home_page` - Было: требует одновременно `text=="Перевести"` и `text=="Пополнить"`. - Стало: этих текстов нет. Кнопки — `content-desc`: `transfer-button-shared` (Перевести), `replenish-button` (Пополнить), `qr-code-button` (Оплата QR). - Нижняя навигация — `content-desc`: `Главная|FINANCE_TAB1` … `Ещё|FINANCE_TAB5`. - Эффект: `isHomeScreen()` всегда возвращает false → флоу не стартует. - Фикс: детектить по `content-desc` (`transfer-button-shared`+`replenish-button` или `FINANCE_TAB1`). ### 2b. `findButtonNode("Перевести")` на главной — PayByPhone/PayByCard старт - `findButtonNode()` матчит ТОЛЬКО `node.text` (class Button). Кнопка «Перевести» на главной — `content-desc="transfer-button-shared"`, `text=""` → возвращает пусто. - Эффект: `PayByPhoneScript` (стр.178) и `PayByCardScript` (стр.164) падают на старте: «Кнопка 'Перевести' не найдена на домашнем экране». Аналогично «Пополнить» = `replenish-button`. - Фикс: тапать кнопку действия на главной по `content-desc` (`transfer-button-shared` / `replenish-button` / `qr-code-button`), либо расширить `findButtonNode` на `content-desc`. ## ПРИМЕНЁННЫЕ ПРАВКИ (собрано и проверено на дампах 19.19.1) Все детекторы сделаны обратносовместимыми (сначала `text`, затем fallback на `content-desc`) — старые сборки Ozon продолжают работать. 1. `ScreenXmlParser::findPinCodeNodes` (способ 1) — цифра матчится и в `text`, и в `content-desc` (`key N`). На дампе нашёл 10/10 цифр. 2. `ScreenXmlParser::isHomeScreen` — детект по `text` ИЛИ `content-desc` (`transfer-button-shared` / `replenish-button`). На дампе → true. 3. `PayByPhoneScript` + `PayByCardScript` — домашняя «Перевести»: fallback `findNodeByContentDesc("transfer-button-shared")` после пустого `findButtonNode`. ### Каркас версионности — `android/ozon/AppVersionTrack.h` (по образцу Dushanbe) - `enum AppVersionTrack { Legacy (<19.19.1), V19_19_1 (>=19.19.1, новейший по умолчанию) }`. - `trackForVersion(appVersion)` через `QVersionNumber`; неизвестная/новее порога → новейший трек. - `ScreenXmlParser`: `setVersionTrack()`/`versionTrack()`, член `m_track = V19_19_1`. - Во всех 6 скриптах: `xmlScreenParser.setVersionTrack(Ozon::trackForVersion(app.appVersion))` + лог `appVersion → track` сразу после `dumpScope`. - Веток по `m_track` пока НЕТ (детекторы обратносовместимы) — трек это явный шов под будущие расхождения и маркер в логах. Как добавлять новую версию — см. комментарий в AppVersionTrack.h. ## Проверено на 19.19.1 и РАБОТАЕТ без правок - `isProfileScreen()` — тексты «Аккаунт»+«Выйти» на месте. - `parseProfilePhone()` — режет склейку «+7 953 803 83 18 Номер телефона» по подстроке. - `parseProfileFullName()` — ФИО «Галина Терехина» берётся как TextView между «Аккаунт» и телефоном. - `findUserNameOnHomeScreen()` — «Галина Т.» в верхней зоне. - Карта: «Показать»/«Реквизиты карты»/`findFullCardNumber` — номер `2204 3210 8610 9865`, срок `12/35`, CVV `774` читаются. Тексты в `text`. - `isTransactionListScreen()` — WebView text=«Операции». - `findTransactionButtons()` — находит строки; поддерживает оба варианта (текст в Button и во вложенной View с ₽). - `parseTransactionDetail()` — дата `26.05.2026, 18:56`, телефон `+7 (950) 128-60-90`, имя над телефоном. ## Платёжный флоу — проверено реальными переводами (по скрипту) Сделаны 2 реальных перевода с устройства: СБП 50₽ на Альфа (+7 985 553-28-96) и по карте 100₽+45₽ комиссия на карту Альфа 2200 1545 1435 0684. - Старт «Перевести» на главной — см. расхождение 2b (content-desc). - Дальше всё на текстовых маркерах РАБОТАЕТ: «Платежи и переводы», «По номеру телефона», «По номеру карты», «Перевод по номеру карты», «Номер карты получателя», «Сумма от», «Продолжить», «Подтвердите перевод», «Перевести N ₽», «Успешно». - Выбор банка (СБП): список — кнопки с числовым `content-desc` (ID банка, напр. Альфа=100000000008), «Другой банк» = `content-desc="other-bank-item"`. Скрипт это уже поддерживает. - Ввод названия банка кириллицей — ТОЛЬКО через ADBKeyboard (`com.android.adbkeyboard`): `adb shell input text` кидает NullPointerException на кириллице. Скрипт использует `enableAdbIMEKeyboard`/`inputAdbIMEText` — корректно. - OCR ID операции: на СБП-чеке (Документы) есть «ID операции A6I5...» — `extractTransactionId` сработает. На внутреннем Ozon-чеке поля «ID операции» НЕТ (см. transaction_document). ## Снятые дампы (assets/ozon/19.19.1/) Корень: pin_code, home_page, profile, card_screen, card_screen_open, card_screen_hide, payments_page, last_transactions (+ баннер «Аналитика финансов» = transaction_banner inline), transaction_info, transaction_document. pay/: pay_buy_phone, pay_to_new_number, pay_buy_phone_select_bank, pay_buy_phone_select_bank_1, pay_buy_phone_enter_sum, confirm_payment (=pay_buy_phone_check_data), confirm_payment_success (=pay_buy_phone_sent_success), pay_by_card, pay_by_card_enter_sum, pay_by_card_success. ## Ещё не снято - account_requisites ⚠️ (флоу в коде закомментирован) — пропущено - transaction_info_spb — пропущено по решению (есть свежая СБП-операция, если понадобится) - pay_buy_phone_default_bank — пропущено (всегда вводим новый номер) - confirm_payment_error — экран ошибки, сложно воспроизвести - home_page_2, ask_biometry - Баннеры/оверлеи: home_ad_1, google_play, banner_ipoteka, card_banner, select_bank, onboarding ⚠️, security ⚠️, system_permission ⚠️ (всплывают ситуативно)