#pragma once #include #include namespace Ozon { // «Трек» формата UI приложения Ozon Банк. Между версиями менялся способ, которым // uiautomator отдаёт интерактивные элементы: старый UI отдавал видимый text у кнопок // и вкладок, новый (Compose-семантика, наблюдается на 19.19.1) — пустой text и // стабильные тест-id в content-desc (например transfer-button-shared, replenish-button, // "key 1" у пин-пада, Главная|FINANCE_TAB1). Трек — нормализованный ярлык версии, по // которому код выбирает версионно-зависимую ветку парсинга (см. ScreenXmlParser::setVersionTrack). // // На момент введения каркаса детекторы уже сделаны обратносовместимыми (матч сначала по // text, затем fallback на content-desc), поэтому отдельных веток по треку ещё нет — трек // служит явным швом для будущих расхождений и читаемым маркером в логах/дампах. // // ───────────────────────────────────────────────────────────────────────── // КАК ДОБАВЛЯТЬ НОВУЮ ВЕРСИЮ ПРИЛОЖЕНИЯ // ───────────────────────────────────────────────────────────────────────── // Отдельные скрипты на каждую версию НЕ нужны — по умолчанию все версии обслуживает // один общий комплект скриптов. Выбирайте по объёму изменений: // // 1) Формат экранов не изменился (косметика, переименование в той же структуре). // → НИЧЕГО не делаем. Версия новее последнего порога автоматически трактуется как // новейший трек (см. trackForVersion). Опционально — эталонные дампы в // assets/ozon/<версия>/ для сверки. // // 2) Изменился один-два экрана. // → Добавляем элемент в enum (например V20_0) и НОВЫЙ порог в trackForVersion(). // В методе, который парсит изменившийся экран, ставим точечную ветку: // if (m_track >= AppVersionTrack::V20_0) { …новый формат… } // else { …существующий… } // Скрипты остаются ОБЩИМИ. Старые ветки (Legacy/19_19_1) не удаляем — в поле // могут оставаться старые версии. Версионно-зависимые точки сегодня: // ScreenXmlParser (isHomeScreen / findPinCodeNodes — кнопки и пин-пад в content-desc), // PayBy{Card,Phone}Script (домашняя «Перевести» = transfer-button-shared). // // 3) Версия разошлась радикально (другой флоу почти везде) — КРАЙНИЙ случай. // → Только тогда выносим версию в отдельный класс скрипта и выбираем его по треку // в EventHandler. Точка ветвления (app.appVersion → trackForVersion) уже есть. // // Значения enum упорядочены по возрастанию версии — можно сравнивать через <, <=, >, >=. enum class AppVersionTrack { Legacy, // < 19.19.1 — старый UI: подписи кнопок/вкладок в видимом text V19_19_1, // >= 19.19.1 — Compose-семантика: тест-id в content-desc (и новейший по умолчанию) }; // Резолвит трек из строки версии (например "19.19.1", полученной через // AdbUtils::getAppVersion → BankProfileInfo.appVersion). Сравнение — через // QVersionNumber, а не лексикографически по строке. // // Неизвестная/непарсящаяся версия, а также любая версия новее последнего известного // порога, трактуется как новейший известный трек (V19_19_1): свежие апдейты по умолчанию // идут по последнему формату, а не падают на Legacy. inline AppVersionTrack trackForVersion(const QString &appVersion) { static const QVersionNumber kV19_19_1(19, 19, 1); qsizetype suffixIndex = 0; const QVersionNumber v = QVersionNumber::fromString(appVersion.trimmed(), &suffixIndex); if (v.isNull()) { // Не смогли распарсить — считаем новейшим известным форматом. return AppVersionTrack::V19_19_1; } if (v < kV19_19_1) return AppVersionTrack::Legacy; return AppVersionTrack::V19_19_1; } // Человекочитаемое имя трека для логов. inline const char *trackName(AppVersionTrack track) { switch (track) { case AppVersionTrack::Legacy: return "Legacy(<19.19.1)"; case AppVersionTrack::V19_19_1: return "19.19.1"; } return "unknown"; } } // namespace Ozon