162 lines
6.8 KiB
C++
162 lines
6.8 KiB
C++
#pragma once
|
||
|
||
#include <QObject>
|
||
#include <QDomElement>
|
||
#include "android/xml/Node.h"
|
||
#include "db/MaterialInfo.h"
|
||
#include "db/TransactionInfo.h"
|
||
#include "AppVersionTrack.h"
|
||
|
||
namespace Ozon {
|
||
|
||
class ScreenXmlParser final : public QObject {
|
||
Q_OBJECT
|
||
|
||
public:
|
||
explicit ScreenXmlParser(QObject *parent = nullptr);
|
||
|
||
~ScreenXmlParser() override;
|
||
|
||
// Версионный трек приложения проставляется один раз в начале скрипта:
|
||
// parser.setVersionTrack(Ozon::trackForVersion(app.appVersion));
|
||
// Версионно-зависимые методы парсинга используют m_track как явный шов
|
||
// (см. AppVersionTrack.h). По умолчанию — новейший известный формат.
|
||
void setVersionTrack(AppVersionTrack track) { m_track = track; }
|
||
AppVersionTrack versionTrack() const { return m_track; }
|
||
|
||
Node tryToFindBannerOrDialog(int width, int height);
|
||
|
||
Node tryToFindSecurityBanner();
|
||
|
||
Node tryToFindSelectBottomSheet();
|
||
|
||
Node findTextNode(const QString &text);
|
||
|
||
Node findTextNode(const QString &text, int x1, int y1, int x2, int y2);
|
||
|
||
Node findFirstEditText();
|
||
|
||
Node findEditTextByHint(const QString &hintPrefix);
|
||
|
||
// Возвращает EditText внутри Ozon "movable-pan-iframe" — поле номера карты
|
||
// получателя на экране "Перевод по номеру карты". Нужно как fallback, когда
|
||
// WebView не отдаёт hint и на экране нет TextView-лейбла "Номер карты
|
||
// получателя" (лейбл — просто "КУДА").
|
||
Node findPanCardNumberInput();
|
||
|
||
Node findButtonNode(const QString &text, bool contains);
|
||
|
||
QList<Node> findAllButtons();
|
||
|
||
const QList<Node> &findAllNodes() const;
|
||
|
||
Node findNodeByContentDesc(const QString &contentDesc);
|
||
|
||
bool isHomeScreen();
|
||
|
||
Node tryToFindAdBanner();
|
||
|
||
Node tryToFindGooglePlayBanner(int screenWidth, int screenHeight);
|
||
|
||
// Онбординг-баннер "Обновили главную" (resource-id onboarding_viewpager),
|
||
// появляется поверх главного экрана Ozon. Возвращает кнопку "Пропустить"
|
||
// для тапа, либо пустой Node если баннер не виден.
|
||
Node tryToFindOnboardingBanner();
|
||
|
||
// Находит кнопку "ЗАПРЕТИТЬ" в системном диалоге запроса разрешения Android
|
||
// (com.google.android.permissioncontroller). Возвращает пустой Node если диалог не виден.
|
||
Node tryToFindSystemPermissionDenyButton();
|
||
|
||
// Returns a Button node whose text is exactly 4 digits (card last numbers)
|
||
Node findCardButtonOnHomeScreen();
|
||
|
||
// Finds a card button whose text ends with the given last 4 digits
|
||
Node findCardButtonByLastNumbers(const QString &lastNumbers);
|
||
|
||
// Экран "Карта": last4 активной карты из маски "•••• •••• •••• NNNN".
|
||
// Пусто, если маскированный номер не найден.
|
||
QString parseActiveCardLast4();
|
||
|
||
// Экран "Карта": плитка карты в карусели по последним 4 цифрам
|
||
// ("Bank Card Виртуальная карта •• NNNN"). Тап по ней делает карту активной.
|
||
Node findCardCarouselTile(const QString &lastNumbers);
|
||
|
||
// Экран "Основной счёт": отдельная кнопка карты "Bank Card NNNN" (text или
|
||
// content-desc). Тап по ней открывает экран именно этой карты (а не передней
|
||
// карты карусели). NNNN — последние 4 цифры.
|
||
Node findAccountCardButton(const QString &lastNumbers);
|
||
|
||
// Returns all cards visible on the home screen as MaterialInfo stubs
|
||
// (lastNumbers, description, amount filled; id=-1, cardNumber empty)
|
||
QList<MaterialInfo> parseCardsOnHomeScreen();
|
||
|
||
bool isProfileScreen();
|
||
|
||
Node findUserNameOnHomeScreen(int screenHeight);
|
||
|
||
QString parseProfileFullName();
|
||
|
||
QString parseProfilePhone();
|
||
|
||
QList<Node> tryToFindPinCode(const QString &pinCode, const QString &title);
|
||
|
||
QList<Node> getLast2DaysTransactions();
|
||
|
||
void parseAndSaveXml(const QString &xml);
|
||
|
||
TransactionInfo parseTransactionInfoHistory(int screenWidth, int screenHeight);
|
||
TransactionInfo parseTransactionInfo(int screenWidth, int screenHeight);
|
||
|
||
QList<TransactionInfo> parseTodayAndYesterdayReportHistory();
|
||
|
||
QList<TransactionInfo> parseTodayAndYesterdayHistory();
|
||
|
||
|
||
QList<QPair<MaterialInfo, Node> > parseAccountsInfo();
|
||
|
||
// Finds a TextView with full card number (format "XXXX XXXX XXXX XXXX")
|
||
QString findFullCardNumber();
|
||
|
||
// Кнопка "Основной счёт X ₽" на главном экране
|
||
Node findMainAccountButton();
|
||
|
||
// Кнопка/текст "Посмотреть реквизиты" на экране "Основной счёт"
|
||
Node findShowRequisitesButton();
|
||
|
||
// Экран "Реквизиты счёта" — заголовок text="Реквизиты счёта"
|
||
bool isAccountRequisitesScreen();
|
||
|
||
// Парсит "Номер счёта получателя <20 цифр>" из текстовой ноды
|
||
QString parseAccountNumberFromRequisites();
|
||
|
||
bool isTransactionListScreen();
|
||
|
||
// Возвращает кнопки транзакций на экране "Операции" (до maxCount штук)
|
||
QList<Node> findTransactionButtons(int maxCount);
|
||
|
||
// Ozon WebView рендерит tappable-Button только для видимых транзакций.
|
||
// Off-screen элементы остаются в accessibility-tree как android.view.View
|
||
// с "схлопнутыми" bounds (height == 0). Если такие View с ₽-знаком есть —
|
||
// значит в списке осталось что прокручивать. Используется для детекции
|
||
// того, что скролл не завершён.
|
||
bool hasCollapsedTransactionsBelow(int screenHeight);
|
||
|
||
// Парсит имя и сумму из текста кнопки: "NAME + 150 ₽ CATEGORY"
|
||
TransactionInfo parseTransactionButtonText(const QString &text);
|
||
|
||
// Парсит детали транзакции: дату, имя отправителя, телефон
|
||
TransactionInfo parseTransactionDetail();
|
||
|
||
void test();
|
||
|
||
[[nodiscard]] const QList<Node> &getNodes() const { return m_nodes; }
|
||
|
||
private:
|
||
QList<Node> m_nodes;
|
||
QDomElement m_xml;
|
||
AppVersionTrack m_track = AppVersionTrack::V19_19_1;
|
||
|
||
QList<Node> findPinCodeNodes(const QString &pinCode);
|
||
};
|
||
|
||
} // namespace Ozon
|