#pragma once #include #include "ScreenXmlParser.h" namespace Ozon { class CommonScript : public QObject { Q_OBJECT public: explicit CommonScript(QObject *parent = nullptr); ~CommonScript() override; protected: virtual void doStart() = 0; // static method static bool inputPinCode(const QString &deviceId, const QList &pincode); bool goToAllProducts( const QString &deviceId, int width, int height ); bool findAndTapOnAccount(const QString &deviceId, const QString &accountNumbers); void postAccountsData(const QList > &accounts); void postNewTransactionData(const MaterialInfo &account, const TransactionInfo &transaction); void updateTransactionData( const MaterialInfo &account, int transactionId, TransactionStatus status, const QString &oldDesc, const QString &newDesc ); Node swipeToButton( const QString &deviceId, const QString &text, int &counter, int width, int height ); bool runAppAndGoToHomeScreen( const QString &deviceId, const QString &packageName, const QString &pinCode, int width, int height ); bool tryToCloseAllBannersOnHomePage( const QString &deviceId, int width, int height ); // Если виден баннер Google Play "Доступно обновление" — закрывает его и перепарсивает XML. // Безопасно вызывать на любом экране; возвращает true если баннер был закрыт. bool closeGooglePlayBannerIfVisible( const QString &deviceId, int width, int height ); // Создаёт bank_profile на сервере если ещё не создан. // Возвращает пустую строку при успехе, текст ошибки при провале. QString createBankProfileIfNeeded(const QString &deviceId, const QString &appCode, double parsedBalance = -1.0); // Проверяет что приложение ещё запущено на устройстве static bool isAppRunning(const QString &deviceId, const QString &packageName); // Детектор зафризившегося экрана: считает подряд идущие байт-идентичные // дампы с реальным контентом. Бесполезные дампы (пустые из-за adb-сбоя // или WebView-shell-only без отрисованного Svelte-контента) пропускаются — // не обнуляют счётчик и не накручивают его. // // Использование в wait-loop: // FreezeDetector freezeCheck; // for (int attempt = 0; attempt < N; ++attempt) { // QString xml = AdbUtils::getScreenDumpAsXml(...); // xmlScreenParser.parseAndSaveXml(xml); // if (freezeCheck.noticeAndCheckFrozen(xml)) { // m_error = "Экран зафризился"; return; // } // ... existing logic // } class FreezeDetector { public: explicit FreezeDetector(int maxStreak = 3) : m_maxStreak(maxStreak) {} // True если получили (m_maxStreak + 1) подряд байт-идентичных полезных дампов. bool noticeAndCheckFrozen(const QString &xml); private: static bool isUsefulDump(const QString &xml); QString m_prev; int m_streak = 0; int m_maxStreak; }; bool m_running = true; ScreenXmlParser xmlScreenParser; int m_counter = 0; QByteArray m_resultScreenshot; signals: void finished(); void finishedWithResult(const QString &result); void screenshotReady(const QByteArray &screenshot); public slots: virtual void start() final; virtual void stop() final; private: Q_DISABLE_COPY(CommonScript); }; } // namespace Ozon