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

0001 /*
0002     KStars UI tests for alignment
0003 
0004     SPDX-FileCopyrightText: 2021 Wolfgang Reissenberger <sterne-jaeger@openfuture.de>
0005 
0006     SPDX-License-Identifier: GPL-2.0-or-later
0007 */
0008 
0009 #pragma once
0010 
0011 #include "config-kstars.h"
0012 #include "test_ekos.h"
0013 #include "test_ekos_capture_helper.h"
0014 
0015 #if defined(HAVE_INDI)
0016 
0017 #include <QObject>
0018 
0019 // Select the flat source from the flats calibration options.
0020 // Start with a delay of 1 sec a new thread that edits the calibration options:
0021 //    select the source widget
0022 //    set pre-mount and pre-dome park options
0023 //    select a manual flat ADU value
0024 //    klick OK
0025 // open the calibration dialog
0026 #define KTRY_SELECT_FLAT_METHOD(sourceWidget, preMountPark, preDomePark) do { \
0027 QTimer::singleShot(5000, capture, [&]() { \
0028     QDialog *calibrationOptions = nullptr; \
0029     if (! QTest::qWaitFor([&](){return ((calibrationOptions = Ekos::Manager::Instance()->findChild<QDialog*>("calibrationOptions")) != nullptr);}, 5000)) { \
0030         QFAIL(qPrintable("Calibrations options dialog not found!")); } \
0031     KTRY_GADGET(calibrationOptions, QAbstractButton, sourceWidget); \
0032     sourceWidget->setChecked(true); \
0033     KTRY_GADGET(calibrationOptions, QCheckBox, parkMountC);  \
0034     parkMountC->setChecked(preMountPark); \
0035     KTRY_GADGET(calibrationOptions, QCheckBox, parkDomeC);  \
0036     parkDomeC->setChecked(preDomePark); \
0037     KTRY_GADGET(calibrationOptions, QAbstractButton, manualDurationC);  \
0038     manualDurationC->setChecked(true); \
0039     QDialogButtonBox* buttons = calibrationOptions->findChild<QDialogButtonBox*>("buttonBox"); \
0040     QVERIFY(nullptr != buttons); \
0041     QTest::mouseClick(buttons->button(QDialogButtonBox::Ok), Qt::LeftButton); \
0042 }); \
0043 KTRY_CAPTURE_CLICK(calibrationB);  } while (false)
0044 
0045 #define KTRY_SELECT_FLAT_WALL(capture, azimuth, altitude) do { \
0046 QTimer::singleShot(1000, capture, [&]() { \
0047     QDialog *calibrationOptions = Ekos::Manager::Instance()->findChild<QDialog*>("calibrationOptions"); \
0048     KTRY_GADGET(calibrationOptions, QAbstractButton, gotoWallC); \
0049     gotoWallC->setChecked(true); \
0050     KTRY_SET_LINEEDIT(calibrationOptions, azBox, azimuth); \
0051     KTRY_SET_LINEEDIT(calibrationOptions, altBox, altitude); \
0052     KTRY_GADGET(calibrationOptions, QAbstractButton, manualDurationC);  \
0053     manualDurationC->setChecked(true); \
0054     QDialogButtonBox* buttons = calibrationOptions->findChild<QDialogButtonBox*>("buttonBox"); \
0055     QVERIFY(nullptr != buttons); \
0056     QTest::mouseClick(buttons->button(QDialogButtonBox::Ok), Qt::LeftButton); \
0057 }); \
0058 KTRY_CLICK(Ekos::Manager::Instance()->captureModule(), calibrationB);  } while (false)
0059 
0060 
0061 class TestEkosCaptureWorkflow : public QObject
0062 {
0063         Q_OBJECT
0064     public:
0065         explicit TestEkosCaptureWorkflow(QObject *parent = nullptr);
0066         explicit TestEkosCaptureWorkflow(QString guider, QObject *parent = nullptr);
0067 
0068     protected:
0069         // destination where images will be located
0070         QTemporaryDir *destination;
0071         QDir *imageLocation = nullptr;
0072 
0073     protected slots:
0074         void initTestCase();
0075         void cleanupTestCase();
0076 
0077         void init();
0078         void cleanup();
0079 
0080         bool prepareTestCase();
0081 
0082     private:
0083         // helper class
0084         TestEkosCaptureHelper *m_CaptureHelper = nullptr;
0085 
0086         QString target = "test";
0087 
0088         /**
0089          * @brief Setup capturing
0090          * @param refocusLimitTime time limit to trigger re-focusing
0091          * @param refocusHFR HFR limit to trigger re-focusing
0092          * @param refocusTemp temperature limit to trigger re-focusing
0093          * @param delay delay between frame captures
0094          * @return true iff preparation was successful
0095          */
0096         bool prepareCapture(int refocusLimitTime = 0.0, double refocusHFR = 0.0, double refocusTemp = 0.0, int delay = 0);
0097 
0098         /**
0099          * @brief initCaptureSetting Initialize Capture settings with a single bool/double pair
0100          * @param setting a single setting with an enabling checkbox and the value
0101          * @param checkboxName name of the QCheckBox widget
0102          * @param spinBoxName name of the QDoubleSpinBox widget
0103          */
0104         void initCaptureSetting(TestEkosCaptureHelper::OptDouble setting, const QString checkboxName, const QString dspinBoxName);
0105 
0106         /**
0107          * @brief Helper function translating simple QString input into QTest test data rows
0108          * @param exptime exposure time of the sequence
0109          * @param sequenceList List of sequences with filter and count as QString("<filter>:<count"), ... list
0110          */
0111         void prepareTestData(double exptime, QList<QString> sequenceList);
0112 
0113         /**
0114          * @brief verifyCalibrationSettings Verify if the flats calibration settings match the test data.
0115          */
0116         bool verifyCalibrationSettings();
0117 
0118         // counter for images taken in a single test run
0119         int image_count;
0120 
0121         QDir *getImageLocation();
0122 
0123 
0124     private slots:
0125         /** @brief Test if re-focusing is triggered after the configured delay. */
0126         void testCaptureRefocusDelay();
0127 
0128         /** @brief Test data for @see testCaptureRefocusDelay() */
0129         void testCaptureRefocusDelay_data();
0130 
0131         /** @brief Test if re-focusing is triggered when the HFR gets worse. */
0132         void testCaptureRefocusHFR();
0133 
0134         /** @brief Test data for @see testCaptureRefocusHFR() */
0135         void testCaptureRefocusHFR_data();
0136 
0137         /** @brief Test if re-focusing is triggered when the temperature changes. */
0138         void testCaptureRefocusTemperature();
0139 
0140         /** @brief Test data for @see testCaptureRefocusTemperature() */
0141         void testCaptureRefocusTemperature_data();
0142 
0143         /** @brief Test if re-focusing is aborted if capture is aborted. */
0144         void testCaptureRefocusAbort();
0145 
0146         /** @brief Test data for @see testCaptureRefocusAbort() */
0147         void testCaptureRefocusAbort_data();
0148 
0149         /** @brief Test whether a pre/post-job/capture scripts are executed as expected */
0150         void testCaptureScriptsExecution();
0151 
0152         /** @brief Test data for @see testCaptureScriptsExecution() */
0153         void testCaptureScriptsExecution_data();
0154 
0155         /**
0156          * @brief Test if capture continues where it had been suspended by a
0157          * guiding deviation as soon as guiding is back below the deviation threshold
0158          */
0159         void testGuidingDeviationSuspendingCapture();
0160 
0161         /**
0162          * @brief Test if aborting a job suspended due to a guiding deviation
0163          * remains aborted when the guiding deviation is below the configured threshold.
0164          */
0165         void testGuidingDeviationAbortCapture();
0166 
0167         /**
0168          * @brief Test if a guiding deviation beyond the configured limit blocks the start of
0169          * capturing until the guiding deviation is below the configured deviation threshold.
0170          */
0171         void testInitialGuidingLimitCapture();
0172 
0173         /** @brief Test data for @see testInitialGuidingLimitCapture() */
0174         void testInitialGuidingLimitCapture_data();
0175 
0176         /**
0177          * @brief Wait with start of capturing until the target temperature has been reached
0178          */
0179         void testCaptureWaitingForTemperature();
0180 
0181         /** @brief Test data for {@see testCaptureWaitingForTemperature()} */
0182         void testCaptureWaitingForTemperature_data();
0183 
0184         /**
0185          * @brief Wait with start of capturing until the target rotator position has been reached
0186          */
0187         void testCaptureWaitingForRotator();
0188 
0189         /**
0190          * @brief Test capturing flats with manual flat light
0191          */
0192         void testFlatManualSource();
0193 
0194         /** @brief Test data for {@see testFlatManualSource()} */
0195         void testFlatManualSource_data();
0196 
0197         /**
0198          * @brief Test capturing flats, darks and bias with a lights panel
0199          */
0200         void testLightPanelSource();
0201 
0202         /** @brief Test data for {@see testLightPanelSource()} */
0203         void testLightPanelSource_data();
0204 
0205         /**
0206          * @brief Test capturing flats or darks with a dust cap
0207          */
0208         void testDustcapSource();
0209 
0210         /** @brief Test data for {@see testFlatDustcapSource()} */
0211         void testDustcapSource_data();
0212 
0213         /**
0214          * @brief Test capturing flats with the wall as flat light source
0215          */
0216         void testWallSource();
0217 
0218         /** @brief Test data for {@see testWallSource()} */
0219         void testWallSource_data();
0220 
0221         /**
0222          * @brief Check mount and dome parking before capturing flats.
0223          */
0224         //void testPreMountAndDomePark();
0225 
0226         /** @brief Test data for {@see testFlatPreMountAndDomePark()} */
0227         //void testPreMountAndDomePark_data();
0228 
0229         /**
0230          * @brief Check the flat capture behavior if "same focus" is selectee
0231          *        in the filter settings when capturing flats. Before capturing
0232          *        flats, the focuser should move to the position last determined
0233          *        with an autofocus run for the selected filter.
0234          */
0235         void testFlatSyncFocus();
0236 
0237         /**
0238          * @brief Test capturing darks with manual scope covering
0239          */
0240         void testDarkManualCovering();
0241 
0242         /** @brief Test data for {@see testDarkManualCovering()} */
0243         void testDarkManualCovering_data();
0244 
0245         /**
0246          * @brief Test capturing a simple darks library
0247          */
0248         void testDarksLibrary();
0249 
0250         /**
0251          * @brief testLoadEsqFile Test for correctly loading a capture sequence file. This test case concentrates
0252          * upon the general values stored in the file, that are valid for all sequence jobs contained.
0253          */
0254         void testLoadEsqFileGeneral();
0255 
0256         /** @brief Test data for {@see testLoadEsqFileGeneral()} */
0257         void testLoadEsqFileGeneral_data();
0258 
0259         /**
0260          * @brief testLoadEsqFileBasicJobSettings Test for basic job settings when loading capture sequence file.
0261          */
0262         void testLoadEsqFileBasicJobSettings();
0263 
0264         /** @brief Test data for {@see testLoadEsqFileBasicJobSettings()} */
0265         void testLoadEsqFileBasicJobSettings_data();
0266 
0267         /**
0268          * @brief testLoadEsqFileFlatSettings Test for flat job settings when loading capture sequence file.
0269          */
0270         void testLoadEsqFileCalibrationSettings();
0271 
0272         /** @brief Test data for {@see testLoadEsqFileCalibrationSettings()} */
0273         void testLoadEsqFileCalibrationSettings_data();
0274 };
0275 
0276 #endif // HAVE_INDI