8.8 KiB
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) — хрупко
(кнопка отпечатка
bioauth86×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 продолжают работать.
ScreenXmlParser::findPinCodeNodes(способ 1) — цифра матчится и вtext, и вcontent-desc(key N). На дампе нашёл 10/10 цифр.ScreenXmlParser::isHomeScreen— детект поtextИЛИcontent-desc(transfer-button-shared/replenish-button). На дампе → true.PayByPhoneScript+PayByCardScript— домашняя «Перевести»: fallbackfindNodeByContentDesc("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, CVV774читаются. Тексты в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 ⚠️ (всплывают ситуативно)