From 7ef3b274906de4d6693d7ca0ccc15258b81606ec Mon Sep 17 00:00:00 2001 From: NissimHadar Date: Fri, 3 Aug 2018 11:12:18 -0700 Subject: [PATCH] WIP - updating test results. --- tools/auto-tester/src/Test.cpp | 17 +- tools/auto-tester/src/TestRailInterface.cpp | 188 ++++++++++++++++-- tools/auto-tester/src/TestRailInterface.h | 12 +- .../src/ui/TestRailResultsSelectorWindow.cpp | 14 +- .../src/ui/TestRailResultsSelectorWindow.h | 2 +- .../src/ui/TestRailResultsSelectorWindow.ui | 8 +- .../src/ui/TestRailTestCasesSelectorWindow.ui | 2 +- 7 files changed, 203 insertions(+), 40 deletions(-) diff --git a/tools/auto-tester/src/Test.cpp b/tools/auto-tester/src/Test.cpp index 86e47be047..37d1f9ca0f 100644 --- a/tools/auto-tester/src/Test.cpp +++ b/tools/auto-tester/src/Test.cpp @@ -830,7 +830,7 @@ void Test::createTestRailTestCases() { QFileDialog::getExistingDirectory(nullptr, "Please select the tests root folder", parent, QFileDialog::ShowDirsOnly); // If user cancelled then restore previous selection and return - if (_testDirectory == "") { + if (_testDirectory.isNull()) { _testDirectory = previousSelection; return; } @@ -839,7 +839,7 @@ void Test::createTestRailTestCases() { nullptr, QFileDialog::ShowDirsOnly); // If user cancelled then return - if (outputDirectory == "") { + if (outputDirectory.isNull()) { return; } @@ -855,15 +855,26 @@ void Test::createTestRailTestCases() { void Test::createTestRailRun() { QString outputDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select a folder to store generated files in", nullptr, QFileDialog::ShowDirsOnly); + + if (outputDirectory.isNull()) { + return; + } + _testRailInterface.createTestRailRun(outputDirectory); } void Test::updateTestRailRunResult() { QString testResults = QFileDialog::getOpenFileName(nullptr, "Please select the zipped test results to update from", nullptr, - "Zipped Test Results (*.zip)"); + "Zipped Test Results (*.zip)"); + if (testResults.isNull()) { + return; + } QString tempDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select a folder to store temporary files in", nullptr, QFileDialog::ShowDirsOnly); + if (tempDirectory.isNull()) { + return; + } _testRailInterface.updateTestRailRunResults(testResults, tempDirectory); } diff --git a/tools/auto-tester/src/TestRailInterface.cpp b/tools/auto-tester/src/TestRailInterface.cpp index bedc8d2138..fbb6c81718 100644 --- a/tools/auto-tester/src/TestRailInterface.cpp +++ b/tools/auto-tester/src/TestRailInterface.cpp @@ -41,6 +41,17 @@ TestRailInterface::TestRailInterface() { _testRailRunSelectorWindow.setSuiteID(INTERFACE_SUITE_ID); ////_testRailRunSelectorWindow.setSuiteID(2); + + _testRailResultsSelectorWindow.setURL("https://highfidelity.testrail.net"); + ////_testRailResultsSelectorWindow.setURL("https://nissimhadar.testrail.io"); + _testRailResultsSelectorWindow.setUser("@highfidelity.io"); + ////_testRailResultsSelectorWindow.setUser("nissim.hadar@gmail.com"); + + _testRailResultsSelectorWindow.setProjectID(INTERFACE_PROJECT_ID); + ////_testRailResultsSelectorWindow.setProjectID(2); + + _testRailResultsSelectorWindow.setSuiteID(INTERFACE_SUITE_ID); + ////_testRailResultsSelectorWindow.setSuiteID(2); } QString TestRailInterface::getObject(const QString& path) { @@ -217,13 +228,13 @@ void TestRailInterface::createStackDotPyScript() { file.close(); } -void TestRailInterface::requestTestRailTestCasesDataFromUser() { +bool TestRailInterface::requestTestRailTestCasesDataFromUser() { // Make sure correct fields are enabled before calling _testRailTestCasesSelectorWindow.reset(); _testRailTestCasesSelectorWindow.exec(); if (_testRailTestCasesSelectorWindow.getUserCancelled()) { - return; + return false; } _url = _testRailTestCasesSelectorWindow.getURL() + "/"; @@ -232,6 +243,44 @@ void TestRailInterface::requestTestRailTestCasesDataFromUser() { ////_password = "tutKA76";//// _projectID = QString::number(_testRailTestCasesSelectorWindow.getProjectID()); _suiteID = QString::number(_testRailTestCasesSelectorWindow.getSuiteID()); + + return true; +} + +bool TestRailInterface::requestTestRailRunDataFromUser() { + _testRailRunSelectorWindow.reset(); + _testRailRunSelectorWindow.exec(); + + if (_testRailRunSelectorWindow.getUserCancelled()) { + return false; + } + + _url = _testRailRunSelectorWindow.getURL() + "/"; + _user = _testRailRunSelectorWindow.getUser(); + _password = _testRailRunSelectorWindow.getPassword(); + ////_password = "tutKA76";//// + _projectID = QString::number(_testRailRunSelectorWindow.getProjectID()); + _suiteID = QString::number(_testRailRunSelectorWindow.getSuiteID()); + + return true; +} + +bool TestRailInterface::requestTestRailResultsDataFromUser() { + _testRailResultsSelectorWindow.reset(); + _testRailResultsSelectorWindow.exec(); + + if (_testRailResultsSelectorWindow.getUserCancelled()) { + return false; + } + + _url = _testRailResultsSelectorWindow.getURL() + "/"; + _user = _testRailResultsSelectorWindow.getUser(); + _password = _testRailResultsSelectorWindow.getPassword(); + ////_password = "tutKA76";//// + _projectID = QString::number(_testRailResultsSelectorWindow.getProjectID()); + _suiteID = QString::number(_testRailResultsSelectorWindow.getSuiteID()); + + return true; } bool TestRailInterface::isAValidTestDirectory(const QString& directory) { @@ -489,7 +538,7 @@ void TestRailInterface::updateSectionsComboData(int exitCode, QProcess::ExitStat QFile file(filename); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), - "Could not open " + _outputDirectory + "/sections.txt"); + "Could not open " + filename); exit(-1); } @@ -523,6 +572,67 @@ void TestRailInterface::updateSectionsComboData(int exitCode, QProcess::ExitStat addRun(); } +void TestRailInterface::updateRunsComboData(int exitCode, QProcess::ExitStatus exitStatus) { + // Quit if user has previously cancelled + if (_testRailRunSelectorWindow.getUserCancelled()) { + return; + } + + // Check if process completed successfully + if (exitStatus != QProcess::NormalExit) { + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), + "Could not get runs from TestRail"); + exit(-1); + } + + // Create map of sections from the file created by the process + _runNames.clear(); + + QString filename = _outputDirectory + "/runs.txt"; + if (!QFile::exists(filename)) { + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), + "Could not find runs.txt in " + _outputDirectory); + exit(-1); + } + + QFile file(filename); + if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), + "Could not open " + filename); + exit(-1); + } + + QTextStream in(&file); + QString line = in.readLine(); + while (!line.isNull()) { + // The run name is all the words except for the last + // The id is the last word + QString section = line.left(line.lastIndexOf(" ")); + QString id = line.right(line.length() - line.lastIndexOf(" ") - 1); + + _runIDs.push_back(id.toInt()); + _runNames << section; + + line = in.readLine(); + } + + file.close(); + + // Update the combo + _testRailResultsSelectorWindow.updateRunsComboBoxData(_sectionNames); + + _testRailResultsSelectorWindow.exec(); + + if (_testRailResultsSelectorWindow.getUserCancelled()) { + return; + } + + // The test cases are now read from TestRail + // When this is complete, the Run can be created + int sfg = 456; + //addRun(); +} + void TestRailInterface::getReleasesFromTestRail() { QString filename = _outputDirectory + "/getReleases.py"; if (QFile::exists(filename)) { @@ -587,7 +697,10 @@ void TestRailInterface::createTestSuitePython(const QString& testDirectory, return; } - requestTestRailTestCasesDataFromUser(); + if (!requestTestRailTestCasesDataFromUser()) { + return; + } + createTestRailDotPyScript(); createStackDotPyScript(); @@ -854,22 +967,6 @@ void TestRailInterface::processTestPython(const QString& fullDirectory, stream << "case = client.send_post('add_case/' + str(section_id), data)\n"; } -void TestRailInterface::requestTestRailRunDataFromUser() { - _testRailRunSelectorWindow.reset(); - _testRailRunSelectorWindow.exec(); - - if (_testRailRunSelectorWindow.getUserCancelled()) { - return; - } - - _url = _testRailRunSelectorWindow.getURL() + "/"; - _user = _testRailRunSelectorWindow.getUser(); - _password = _testRailRunSelectorWindow.getPassword(); - ////_password = "tutKA76";//// - _projectID = QString::number(_testRailRunSelectorWindow.getProjectID()); - _suiteID = QString::number(_testRailRunSelectorWindow.getSuiteID()); -} - void TestRailInterface::getTestSectionsFromTestRail() { QString filename = _outputDirectory + "/getSections.py"; if (QFile::exists(filename)) { @@ -909,6 +1006,44 @@ void TestRailInterface::getTestSectionsFromTestRail() { process->start(_pythonCommand, parameters); } +void TestRailInterface::getRunFromTestRail() { + QString filename = _outputDirectory + "/getRun.py"; + if (QFile::exists(filename)) { + QFile::remove(filename); + } + QFile file(filename); + + if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), + "Could not create 'getRun.py'"); + exit(-1); + } + + QTextStream stream(&file); + + // Code to access TestRail + stream << "from testrail import *\n"; + stream << "client = APIClient('" << _url.toStdString().c_str() << "')\n"; + stream << "client.user = '" << _user << "'\n"; + stream << "client.password = '" << _password << "'\n\n"; + + // Print the list of runs + stream << "runs = client.send_get('get_runs/" + _projectID + "')\n\n"; + stream << "file = open('" + _outputDirectory + "/runs.txt', 'w')\n\n"; + stream << "for run in runs:\n"; + stream << "\tfile.write(run['name'] + ' ' + str(run['id']) + '\\n')\n\n"; + stream << "file.close()\n"; + + file.close(); + + QProcess* process = new QProcess(); + connect(process, static_cast(&QProcess::finished), this, + [=](int exitCode, QProcess::ExitStatus exitStatus) { updateRunsComboData(exitCode, exitStatus); }); + + QStringList parameters = QStringList() << filename; + process->start(_pythonCommand, parameters); +} + void TestRailInterface::createTestRailRun(const QString& outputDirectory) { _outputDirectory = outputDirectory; @@ -916,7 +1051,10 @@ void TestRailInterface::createTestRailRun(const QString& outputDirectory) { return; } - requestTestRailRunDataFromUser(); + if (!requestTestRailRunDataFromUser()) { + return; + } + createTestRailDotPyScript(); createStackDotPyScript(); @@ -924,8 +1062,14 @@ void TestRailInterface::createTestRailRun(const QString& outputDirectory) { getTestSectionsFromTestRail(); } - void TestRailInterface::updateTestRailRunResults(const QString& testResults, const QString& tempDirectory) { + if (requestTestRailResultsDataFromUser()) { + return; + } + + // TestRail will be updated after the process initiated by getTestRunFromTestRail has completed + getRunFromTestRail(); + // Extract test failures from zipped folder QString tempSubDirectory = tempDirectory + "/" + tempName; QDir dir = tempSubDirectory; diff --git a/tools/auto-tester/src/TestRailInterface.h b/tools/auto-tester/src/TestRailInterface.h index a4e18afad8..baf4ef5600 100644 --- a/tools/auto-tester/src/TestRailInterface.h +++ b/tools/auto-tester/src/TestRailInterface.h @@ -15,6 +15,7 @@ #include "ui/TestRailTestCasesSelectorWindow.h" #include "ui/TestRailRunSelectorWindow.h" +#include "ui/TestRailResultsSelectorWindow.h" #include #include @@ -55,12 +56,14 @@ public: void getReleasesFromTestRail(); void getTestSectionsFromTestRail(); + void getRunFromTestRail(); void createTestRailDotPyScript(); void createStackDotPyScript(); - void requestTestRailTestCasesDataFromUser(); - void requestTestRailRunDataFromUser(); + bool requestTestRailTestCasesDataFromUser(); + bool requestTestRailRunDataFromUser(); + bool requestTestRailResultsDataFromUser(); void createAddTestCasesPythonScript(const QString& testDirectory, const QString& userGitHub, @@ -77,6 +80,7 @@ public: void updateReleasesComboData(int exitCode, QProcess::ExitStatus exitStatus); void updateSectionsComboData(int exitCode, QProcess::ExitStatus exitStatus); + void updateRunsComboData(int exitCode, QProcess::ExitStatus exitStatus); void createTestRailRun(const QString& outputDirectory); void updateTestRailRunResults(const QString& testResults, const QString& tempDirectory); @@ -97,6 +101,7 @@ private: BusyWindow _busyWindow; TestRailTestCasesSelectorWindow _testRailTestCasesSelectorWindow; TestRailRunSelectorWindow _testRailRunSelectorWindow; + TestRailResultsSelectorWindow _testRailResultsSelectorWindow; QString _url; QString _user; @@ -117,6 +122,9 @@ private: QStringList _sectionNames; std::vector _sectionIDs; + QStringList _runNames; + std::vector _runIDs; + QString tempName{ "fgadhcUDHSFaidsfh3478JJJFSDFIUSOEIrf" }; }; diff --git a/tools/auto-tester/src/ui/TestRailResultsSelectorWindow.cpp b/tools/auto-tester/src/ui/TestRailResultsSelectorWindow.cpp index 65a136d13f..f9ed45cac8 100644 --- a/tools/auto-tester/src/ui/TestRailResultsSelectorWindow.cpp +++ b/tools/auto-tester/src/ui/TestRailResultsSelectorWindow.cpp @@ -28,8 +28,8 @@ void TestRailResultsSelectorWindow::reset() { OKButton->setDisabled(true); - releasesLabel->setDisabled(true); - releasesComboBox->setDisabled(true); + runsLabel->setDisabled(true); + runsComboBox->setDisabled(true); } void TestRailResultsSelectorWindow::on_acceptButton_clicked() { @@ -40,8 +40,8 @@ void TestRailResultsSelectorWindow::on_acceptButton_clicked() { OKButton->setDisabled(false); - releasesLabel->setDisabled(false); - releasesComboBox->setDisabled(false); + runsLabel->setDisabled(false); + runsComboBox->setDisabled(false); close(); } @@ -95,10 +95,10 @@ int TestRailResultsSelectorWindow::getSuiteID() { return suiteIDLineEdit->text().toInt(); } -void TestRailResultsSelectorWindow::updateReleasesComboBoxData(QStringList data) { - releasesComboBox->insertItems(0, data); +void TestRailResultsSelectorWindow::updateRunsComboBoxData(QStringList data) { + runsComboBox->insertItems(0, data); } int TestRailResultsSelectorWindow::getReleaseID() { - return releasesComboBox->currentIndex(); + return runsComboBox->currentIndex(); } \ No newline at end of file diff --git a/tools/auto-tester/src/ui/TestRailResultsSelectorWindow.h b/tools/auto-tester/src/ui/TestRailResultsSelectorWindow.h index 2c8f18034a..abe4e7b9a5 100644 --- a/tools/auto-tester/src/ui/TestRailResultsSelectorWindow.h +++ b/tools/auto-tester/src/ui/TestRailResultsSelectorWindow.h @@ -38,7 +38,7 @@ public: bool userCancelled{ false }; - void updateReleasesComboBoxData(QStringList data); + void updateRunsComboBoxData(QStringList data); int getReleaseID(); private slots: diff --git a/tools/auto-tester/src/ui/TestRailResultsSelectorWindow.ui b/tools/auto-tester/src/ui/TestRailResultsSelectorWindow.ui index c7664518b0..c15c86493f 100644 --- a/tools/auto-tester/src/ui/TestRailResultsSelectorWindow.ui +++ b/tools/auto-tester/src/ui/TestRailResultsSelectorWindow.ui @@ -171,7 +171,7 @@ Accept - + false @@ -184,7 +184,7 @@ - + true @@ -202,7 +202,7 @@ - TestRail Added for release + TestRail Run @@ -271,7 +271,7 @@ projectIDLineEdit suiteIDLineEdit acceptButton - releasesComboBox + runsComboBox OKButton cancelButton diff --git a/tools/auto-tester/src/ui/TestRailTestCasesSelectorWindow.ui b/tools/auto-tester/src/ui/TestRailTestCasesSelectorWindow.ui index f904339ff5..41ff2943d5 100644 --- a/tools/auto-tester/src/ui/TestRailTestCasesSelectorWindow.ui +++ b/tools/auto-tester/src/ui/TestRailTestCasesSelectorWindow.ui @@ -202,7 +202,7 @@ - TestRail Added for release + TestRail Added for Release