File indexing completed on 2024-04-21 14:47:24

0001 /*  KStars UI tests
0002     SPDX-FileCopyrightText: 2020 Eric Dejouhanet <eric.dejouhanet@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #ifndef TESTEKOSGUIDE_H
0008 #define TESTEKOSGUIDE_H
0009 
0010 #include "config-kstars.h"
0011 
0012 #if defined(HAVE_INDI) && HAVE_INDI
0013 
0014 #include <QObject>
0015 #include <QPushButton>
0016 #include <QComboBox>
0017 #include <QDoubleSpinBox>
0018 #include <QSpinBox>
0019 #include <QCheckBox>
0020 #include <QTest>
0021 
0022 /** @brief Helper to show the Guide tab
0023  */
0024 #define KTRY_GUIDE_SHOW() do { \
0025     QTRY_VERIFY_WITH_TIMEOUT(Ekos::Manager::Instance()->guideModule() != nullptr, 5000); \
0026     KTRY_EKOS_GADGET(QTabWidget, toolsWidget); \
0027     QTRY_VERIFY_WITH_TIMEOUT(-1 != toolsWidget->indexOf(Ekos::Manager::Instance()->guideModule()), 5000); \
0028     toolsWidget->setCurrentWidget(Ekos::Manager::Instance()->guideModule()); \
0029     QTRY_COMPARE_WITH_TIMEOUT(toolsWidget->currentWidget(), Ekos::Manager::Instance()->guideModule(), 5000); \
0030     QTRY_VERIFY_WITH_TIMEOUT(!Ekos::Manager::Instance()->guideModule()->camera().isEmpty(), 5000); } while (false)
0031 
0032 /** @brief Helper to retrieve a gadget in the Guide tab specifically.
0033  * @param klass is the class of the gadget to look for.
0034  * @param name is the gadget name to look for in the UI configuration.
0035  * @warning Fails the test if the gadget "name" of class "klass" does not exist in the Focus module
0036  */
0037 #define KTRY_GUIDE_GADGET(klass, name) klass * const name = Ekos::Manager::Instance()->guideModule()->findChild<klass*>(#name); \
0038     QVERIFY2(name != nullptr, QString(#klass " '%1' does not exist and cannot be used").arg(#name).toStdString().c_str())
0039 
0040 /** @brief Helper to click a button in the Guide tab specifically.
0041  * @param button is the gadget name of the button to look for in the UI configuration.
0042  * @warning Fails the test if the button is not currently enabled.
0043  */
0044 #define KTRY_GUIDE_CLICK(button) do { \
0045     QTimer::singleShot(100, Ekos::Manager::Instance(), []() { \
0046         KTRY_GUIDE_GADGET(QPushButton, button); \
0047         QVERIFY2(button->isEnabled(), QString("QPushButton '%1' is disabled and cannot be clicked").arg(#button).toStdString().c_str()); \
0048         QTest::mouseClick(button, Qt::LeftButton); }); \
0049     QTest::qWait(200); } while(false)
0050 
0051 /** @brief Helper to set a string text into a QComboBox in the Focus module.
0052  * @param combobox is the gadget name of the QComboBox to look for in the UI configuration.
0053  * @param text is the string text to set in the gadget.
0054  * @note This is a contrived method to set a text into a QComboBox programmatically *and* emit the "activated" message.
0055  * @warning Fails the test if the name does not exist in the Focus UI or if the text cannot be set in the gadget.
0056  */
0057 #define KTRY_GUIDE_COMBO_SET(combobox, text) do { \
0058     KTRY_GUIDE_GADGET(QComboBox, combobox); \
0059     int const cbIndex = combobox->findText(text); \
0060     QVERIFY(0 <= cbIndex); \
0061     combobox->setCurrentIndex(cbIndex); \
0062     combobox->activated(cbIndex); \
0063     QCOMPARE(combobox->currentText(), QString(text)); } while(false);
0064 
0065 /** @brief Helper for exposure.
0066  * @param exposure is the amount of seconds to expose for.
0067  * @param averaged is the number of frames the procedure should average before computation.
0068  * @note The Focus capture button is disabled during exposure.
0069  * @warning Fails the test if the exposure cannot be entered or if the capture button is
0070  * disabled or does not toggle during exposure or if the stop button is not the opposite of the capture button.
0071  */
0072 /** @{ */
0073 #define KTRY_GUIDE_DETECT(exposure, averaged) do { \
0074     KTRY_GUIDE_GADGET(QDoubleSpinBox, exposureIN); \
0075     exposureIN->setValue(exposure); \
0076     KTRY_GUIDE_GADGET(QSpinBox, focusFramesSpin); \
0077     focusFramesSpin->setValue(averaged); \
0078     KTRY_GUIDE_GADGET(QPushButton, captureB); \
0079     KTRY_GUIDE_GADGET(QPushButton, stopFocusB); \
0080     QTRY_VERIFY_WITH_TIMEOUT(captureB->isEnabled(), 1000); \
0081     QTRY_VERIFY_WITH_TIMEOUT(!stopFocusB->isEnabled(), 1000); \
0082     KTRY_GUIDE_CLICK(captureB); \
0083     QTRY_VERIFY_WITH_TIMEOUT(!captureB->isEnabled(), 1000); \
0084     QVERIFY(stopFocusB->isEnabled()); \
0085     QTest::qWait(exposure*averaged*1000); \
0086     QTRY_VERIFY_WITH_TIMEOUT(captureB->isEnabled(), 5000); \
0087     QVERIFY(!stopFocusB->isEnabled()); } while (false)
0088 /** @} */
0089 
0090 class TestEkosGuide : public QObject
0091 {
0092     Q_OBJECT
0093 
0094 public:
0095     explicit TestEkosGuide(QObject *parent = nullptr);
0096 
0097 protected:
0098     QProcess * phd2 { nullptr };
0099     QString testProfileName { "phd2_test_profile" };
0100     QString const guider_host { "localhost" };
0101     QString const guider_port { "4400" };
0102     void stopPHD2();
0103 
0104 private slots:
0105     void initTestCase();
0106     void cleanupTestCase();
0107 
0108     void init();
0109     void cleanup();
0110 
0111     void testPHD2ConnectionStability();
0112     void testPHD2CaptureStability();
0113     void testPHD2Calibration();
0114 };
0115 
0116 #endif // HAVE_INDI
0117 #endif // TESTEKOSGUIDE_H