mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 04:37:48 +02:00
Merge branch 'exportToTestRail' of github.com:NissimHadar/hifi into exportToTestRail
This commit is contained in:
commit
a66bef1218
9 changed files with 221 additions and 92 deletions
|
@ -838,7 +838,7 @@ void Test::createTestRailTestCases() {
|
||||||
}
|
}
|
||||||
|
|
||||||
QString outputDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select a folder to store generated files in",
|
QString outputDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select a folder to store generated files in",
|
||||||
parent, QFileDialog::ShowDirsOnly);
|
nullptr, QFileDialog::ShowDirsOnly);
|
||||||
|
|
||||||
// If user cancelled then return
|
// If user cancelled then return
|
||||||
if (outputDirectory == "") {
|
if (outputDirectory == "") {
|
||||||
|
@ -855,7 +855,9 @@ void Test::createTestRailTestCases() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Test::createTestRailRun() {
|
void Test::createTestRailRun() {
|
||||||
_testRailInterface.createTestRailRun();
|
QString outputDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select a folder to store generated files in",
|
||||||
|
nullptr, QFileDialog::ShowDirsOnly);
|
||||||
|
_testRailInterface.createTestRailRun(outputDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList Test::createListOfAll_imagesInDirectory(const QString& imageFormat, const QString& pathToImageDirectory) {
|
QStringList Test::createListOfAll_imagesInDirectory(const QString& imageFormat, const QString& pathToImageDirectory) {
|
||||||
|
|
|
@ -42,6 +42,24 @@ QString TestRailInterface::getObject(const QString& path) {
|
||||||
return path.right(path.length() - path.lastIndexOf("/") - 1);
|
return path.right(path.length() - path.lastIndexOf("/") - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool TestRailInterface::setPythonCommand() {
|
||||||
|
if (QProcessEnvironment::systemEnvironment().contains("PYTHON_PATH")) {
|
||||||
|
QString _pythonPath = QProcessEnvironment::systemEnvironment().value("PYTHON_PATH");
|
||||||
|
if (!QFile::exists(_pythonPath + "/" + pythonExe)) {
|
||||||
|
QMessageBox::critical(0, pythonExe, QString("Python executable not found in ") + _pythonPath);
|
||||||
|
}
|
||||||
|
_pythonCommand = _pythonPath + "/" + pythonExe;
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
QMessageBox::critical(0, "PYTHON_PATH not defined",
|
||||||
|
"Please set PYTHON_PATH to directory containing the Python executable");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Creates the testrail.py script
|
// Creates the testrail.py script
|
||||||
// This is the file linked to from http://docs.gurock.com/testrail-api2/bindings-python
|
// This is the file linked to from http://docs.gurock.com/testrail-api2/bindings-python
|
||||||
void TestRailInterface::createTestRailDotPyScript() {
|
void TestRailInterface::createTestRailDotPyScript() {
|
||||||
|
@ -227,8 +245,7 @@ bool TestRailInterface::isAValidTestDirectory(const QString& directory) {
|
||||||
void TestRailInterface::processDirectoryPython(const QString& directory,
|
void TestRailInterface::processDirectoryPython(const QString& directory,
|
||||||
QTextStream& stream,
|
QTextStream& stream,
|
||||||
const QString& userGitHub,
|
const QString& userGitHub,
|
||||||
const QString& branchGitHub
|
const QString& branchGitHub) {
|
||||||
) {
|
|
||||||
// Loop over all entries in directory
|
// Loop over all entries in directory
|
||||||
QDirIterator it(directory.toStdString().c_str());
|
QDirIterator it(directory.toStdString().c_str());
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
|
@ -255,7 +272,7 @@ void TestRailInterface::processDirectoryPython(const QString& directory,
|
||||||
stream << "parent_ids.pop()\n\n";
|
stream << "parent_ids.pop()\n\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
// A suite of TestRail test cases contains trees.
|
// A suite of TestRail test cases contains trees.
|
||||||
// The nodes of the trees are sections
|
// The nodes of the trees are sections
|
||||||
// The leaves are the test cases
|
// The leaves are the test cases
|
||||||
//
|
//
|
||||||
|
@ -264,8 +281,7 @@ void TestRailInterface::processDirectoryPython(const QString& directory,
|
||||||
//
|
//
|
||||||
void TestRailInterface::createAddTestCasesPythonScript(const QString& testDirectory,
|
void TestRailInterface::createAddTestCasesPythonScript(const QString& testDirectory,
|
||||||
const QString& userGitHub,
|
const QString& userGitHub,
|
||||||
const QString& branchGitHub
|
const QString& branchGitHub) {
|
||||||
) {
|
|
||||||
QString filename = _outputDirectory + "/addTestCases.py";
|
QString filename = _outputDirectory + "/addTestCases.py";
|
||||||
if (QFile::exists(filename)) {
|
if (QFile::exists(filename)) {
|
||||||
QFile::remove(filename);
|
QFile::remove(filename);
|
||||||
|
@ -302,19 +318,15 @@ void TestRailInterface::createAddTestCasesPythonScript(const QString& testDirect
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
if (QMessageBox::Yes == QMessageBox(QMessageBox::Information, "Python script has been created", "Do you want to run the script and update TestRail?", QMessageBox::Yes | QMessageBox::No).exec()) {
|
if (QMessageBox::Yes == QMessageBox(QMessageBox::Information, "Python script has been created",
|
||||||
|
"Do you want to run the script and update TestRail?",
|
||||||
|
QMessageBox::Yes | QMessageBox::No)
|
||||||
|
.exec()) {
|
||||||
QProcess* process = new QProcess();
|
QProcess* process = new QProcess();
|
||||||
connect(process, &QProcess::started, this,
|
connect(process, &QProcess::started, this, [=]() { _busyWindow.exec(); });
|
||||||
[=]() {
|
|
||||||
_busyWindow.exec();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
connect(process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this,
|
connect(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this,
|
||||||
[=](int exitCode, QProcess::ExitStatus exitStatus) {
|
[=](int exitCode, QProcess::ExitStatus exitStatus) { _busyWindow.hide(); });
|
||||||
_busyWindow.hide();
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
QStringList parameters = QStringList() << _outputDirectory + "/addTestCases.py";
|
QStringList parameters = QStringList() << _outputDirectory + "/addTestCases.py";
|
||||||
process->start(_pythonCommand, parameters);
|
process->start(_pythonCommand, parameters);
|
||||||
|
@ -331,7 +343,7 @@ void TestRailInterface::updateMilestonesComboData(int exitCode, QProcess::ExitSt
|
||||||
if (exitStatus != QProcess::NormalExit) {
|
if (exitStatus != QProcess::NormalExit) {
|
||||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||||
"Could not get milestones from TestRail");
|
"Could not get milestones from TestRail");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create map of milestones from the file created by the process
|
// Create map of milestones from the file created by the process
|
||||||
|
@ -347,7 +359,7 @@ void TestRailInterface::updateMilestonesComboData(int exitCode, QProcess::ExitSt
|
||||||
QFile file(filename);
|
QFile file(filename);
|
||||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||||
"Could not open " + _outputDirectory + "/milestones.txt");
|
"Could not open " + _outputDirectory + "/milestones.txt");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,7 +376,7 @@ void TestRailInterface::updateMilestonesComboData(int exitCode, QProcess::ExitSt
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
// Update the combo
|
// Update the combo
|
||||||
_testRailTestCasesSelectorWindow.updateMilestoneComboBoxData(_milestoneNames);
|
_testRailTestCasesSelectorWindow.updateMilestonesComboBoxData(_milestoneNames);
|
||||||
|
|
||||||
_testRailTestCasesSelectorWindow.exec();
|
_testRailTestCasesSelectorWindow.exec();
|
||||||
|
|
||||||
|
@ -375,6 +387,64 @@ void TestRailInterface::updateMilestonesComboData(int exitCode, QProcess::ExitSt
|
||||||
createAddTestCasesPythonScript(_testDirectory, _userGitHub, _branchGitHub);
|
createAddTestCasesPythonScript(_testDirectory, _userGitHub, _branchGitHub);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TestRailInterface::updateSectionsComboData(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 sections from TestRail");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create map of sections from the file created by the process
|
||||||
|
_sectionNames.clear();
|
||||||
|
|
||||||
|
QString filename = _outputDirectory + "/sections.txt";
|
||||||
|
if (!QFile::exists(filename)) {
|
||||||
|
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||||
|
"Could not find sections.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 " + _outputDirectory + "/sections.txt");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QTextStream in(&file);
|
||||||
|
QString line = in.readLine();
|
||||||
|
while (!line.isNull()) {
|
||||||
|
// The section 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);
|
||||||
|
|
||||||
|
_sections[section] = id.toInt();
|
||||||
|
_sectionNames << section;
|
||||||
|
|
||||||
|
line = in.readLine();
|
||||||
|
}
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
// Update the combo
|
||||||
|
_testRailRunSelectorWindow.updateSectionsComboBoxData(_sectionNames);
|
||||||
|
|
||||||
|
_testRailRunSelectorWindow.exec();
|
||||||
|
|
||||||
|
if (_testRailRunSelectorWindow.getUserCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
////createAddTestCasesPythonScript(_testDirectory, _userGitHub, _branchGitHub);
|
||||||
|
}
|
||||||
|
|
||||||
void TestRailInterface::getMilestonesFromTestRail() {
|
void TestRailInterface::getMilestonesFromTestRail() {
|
||||||
QString filename = _outputDirectory + "/getMilestones.py";
|
QString filename = _outputDirectory + "/getMilestones.py";
|
||||||
if (QFile::exists(filename)) {
|
if (QFile::exists(filename)) {
|
||||||
|
@ -408,10 +478,7 @@ void TestRailInterface::getMilestonesFromTestRail() {
|
||||||
|
|
||||||
QProcess* process = new QProcess();
|
QProcess* process = new QProcess();
|
||||||
connect(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this,
|
connect(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this,
|
||||||
[=](int exitCode, QProcess::ExitStatus exitStatus) {
|
[=](int exitCode, QProcess::ExitStatus exitStatus) { updateMilestonesComboData(exitCode, exitStatus); });
|
||||||
updateMilestonesComboData(exitCode, exitStatus);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
QStringList parameters = QStringList() << _outputDirectory + "/getMilestones.py ";
|
QStringList parameters = QStringList() << _outputDirectory + "/getMilestones.py ";
|
||||||
process->start(_pythonCommand, parameters);
|
process->start(_pythonCommand, parameters);
|
||||||
|
@ -421,21 +488,12 @@ void TestRailInterface::createTestSuitePython(const QString& testDirectory,
|
||||||
const QString& outputDirectory,
|
const QString& outputDirectory,
|
||||||
const QString& userGitHub,
|
const QString& userGitHub,
|
||||||
const QString& branchGitHub) {
|
const QString& branchGitHub) {
|
||||||
|
|
||||||
_testDirectory = testDirectory;
|
_testDirectory = testDirectory;
|
||||||
_outputDirectory = outputDirectory;
|
_outputDirectory = outputDirectory;
|
||||||
_userGitHub = userGitHub;
|
_userGitHub = userGitHub;
|
||||||
_branchGitHub = branchGitHub;
|
_branchGitHub = branchGitHub;
|
||||||
|
|
||||||
// First check that Python is available
|
if (!setPythonCommand()) {
|
||||||
if (QProcessEnvironment::systemEnvironment().contains("PYTHON_PATH")) {
|
|
||||||
QString _pythonPath = QProcessEnvironment::systemEnvironment().value("PYTHON_PATH");
|
|
||||||
if (!QFile::exists(_pythonPath + "/" + pythonExe)) {
|
|
||||||
QMessageBox::critical(0, pythonExe, QString("Python executable not found in ") + _pythonPath);
|
|
||||||
}
|
|
||||||
_pythonCommand = _pythonPath + "/" + pythonExe;
|
|
||||||
} else {
|
|
||||||
QMessageBox::critical(0, "PYTHON_PATH not defined", "Please set PYTHON_PATH to directory containing the Python executable");
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -447,12 +505,11 @@ void TestRailInterface::createTestSuitePython(const QString& testDirectory,
|
||||||
getMilestonesFromTestRail();
|
getMilestonesFromTestRail();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRailInterface::createTestSuiteXML(const QString& testDirectory,
|
void TestRailInterface::createTestSuiteXML(const QString& testDirectory,
|
||||||
const QString& outputDirectory,
|
const QString& outputDirectory,
|
||||||
const QString& userGitHub,
|
const QString& userGitHub,
|
||||||
const QString& branchGitHub) {
|
const QString& branchGitHub) {
|
||||||
|
_outputDirectory = outputDirectory;
|
||||||
_outputDirectory = outputDirectory;
|
|
||||||
|
|
||||||
QDomProcessingInstruction instruction = _document.createProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
|
QDomProcessingInstruction instruction = _document.createProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
|
||||||
_document.appendChild(instruction);
|
_document.appendChild(instruction);
|
||||||
|
@ -464,7 +521,8 @@ void TestRailInterface::createTestSuitePython(const QString& testDirectory,
|
||||||
QDomElement topLevelSection = _document.createElement("section");
|
QDomElement topLevelSection = _document.createElement("section");
|
||||||
|
|
||||||
QDomElement suiteName = _document.createElement("name");
|
QDomElement suiteName = _document.createElement("name");
|
||||||
suiteName.appendChild(_document.createTextNode("Test Suite - " + QDateTime::currentDateTime().toString("yyyy-MM-ddTHH:mm")));
|
suiteName.appendChild(
|
||||||
|
_document.createTextNode("Test Suite - " + QDateTime::currentDateTime().toString("yyyy-MM-ddTHH:mm")));
|
||||||
topLevelSection.appendChild(suiteName);
|
topLevelSection.appendChild(suiteName);
|
||||||
|
|
||||||
// This is the first call to 'process'. This is then called recursively to build the full XML tree
|
// This is the first call to 'process'. This is then called recursively to build the full XML tree
|
||||||
|
@ -475,10 +533,11 @@ void TestRailInterface::createTestSuitePython(const QString& testDirectory,
|
||||||
root.appendChild(topLevelSection);
|
root.appendChild(topLevelSection);
|
||||||
|
|
||||||
// Write to file
|
// Write to file
|
||||||
const QString testRailsFilename{ _outputDirectory + "/TestRailSuite.xml" };
|
const QString testRailsFilename{ _outputDirectory + "/TestRailSuite.xml" };
|
||||||
QFile file(testRailsFilename);
|
QFile file(testRailsFilename);
|
||||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Could not create XML file");
|
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||||
|
"Could not create XML file");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,10 +558,10 @@ QDomElement TestRailInterface::processDirectoryXML(const QString& directory,
|
||||||
// Loop over all entries in directory
|
// Loop over all entries in directory
|
||||||
QDirIterator it(directory.toStdString().c_str());
|
QDirIterator it(directory.toStdString().c_str());
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
QString nextDirectory = it.next();
|
QString nextDirectory = it.next();
|
||||||
|
|
||||||
// The object name appears after the last slash (we are assured there is at least 1).
|
// The object name appears after the last slash (we are assured there is at least 1).
|
||||||
QString objectName = getObject(nextDirectory);
|
QString objectName = getObject(nextDirectory);
|
||||||
|
|
||||||
// Only process directories
|
// Only process directories
|
||||||
if (isAValidTestDirectory(nextDirectory)) {
|
if (isAValidTestDirectory(nextDirectory)) {
|
||||||
|
@ -538,7 +597,7 @@ QDomElement TestRailInterface::processTestXML(const QString& fullDirectory,
|
||||||
const QString& branchGitHub,
|
const QString& branchGitHub,
|
||||||
const QDomElement& element) {
|
const QDomElement& element) {
|
||||||
QDomElement result = element;
|
QDomElement result = element;
|
||||||
|
|
||||||
QDomElement caseElement = _document.createElement("case");
|
QDomElement caseElement = _document.createElement("case");
|
||||||
|
|
||||||
caseElement.appendChild(_document.createElement("id"));
|
caseElement.appendChild(_document.createElement("id"));
|
||||||
|
@ -551,7 +610,8 @@ QDomElement TestRailInterface::processTestXML(const QString& fullDirectory,
|
||||||
while (words[i] != "tests") {
|
while (words[i] != "tests") {
|
||||||
++i;
|
++i;
|
||||||
if (i >= words.length() - 1) {
|
if (i >= words.length() - 1) {
|
||||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Folder \"tests\" not found in " + fullDirectory);
|
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||||
|
"Folder \"tests\" not found in " + fullDirectory);
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -595,7 +655,8 @@ QDomElement TestRailInterface::processTestXML(const QString& fullDirectory,
|
||||||
domain_bot_loadElementId.appendChild(_document.createTextNode("1"));
|
domain_bot_loadElementId.appendChild(_document.createTextNode("1"));
|
||||||
domain_bot_loadElement.appendChild(domain_bot_loadElementId);
|
domain_bot_loadElement.appendChild(domain_bot_loadElementId);
|
||||||
QDomElement domain_bot_loadElementValue = _document.createElement("value");
|
QDomElement domain_bot_loadElementValue = _document.createElement("value");
|
||||||
domain_bot_loadElementValue.appendChild(_document.createTextNode(" Without Bots (hifiqa-rc / hifi-qa-stable / hifiqa-master)"));
|
domain_bot_loadElementValue.appendChild(
|
||||||
|
_document.createTextNode(" Without Bots (hifiqa-rc / hifi-qa-stable / hifiqa-master)"));
|
||||||
domain_bot_loadElement.appendChild(domain_bot_loadElementValue);
|
domain_bot_loadElement.appendChild(domain_bot_loadElementValue);
|
||||||
customElement.appendChild(domain_bot_loadElement);
|
customElement.appendChild(domain_bot_loadElement);
|
||||||
|
|
||||||
|
@ -618,7 +679,8 @@ QDomElement TestRailInterface::processTestXML(const QString& fullDirectory,
|
||||||
customElement.appendChild(added_to_releaseElement);
|
customElement.appendChild(added_to_releaseElement);
|
||||||
|
|
||||||
QDomElement precondsElement = _document.createElement("preconds");
|
QDomElement precondsElement = _document.createElement("preconds");
|
||||||
precondsElement.appendChild(_document.createTextNode("Tester is in an empty region of a domain in which they have edit rights\n\n*Note: Press 'n' to advance test script"));
|
precondsElement.appendChild(_document.createTextNode(
|
||||||
|
"Tester is in an empty region of a domain in which they have edit rights\n\n*Note: Press 'n' to advance test script"));
|
||||||
customElement.appendChild(precondsElement);
|
customElement.appendChild(precondsElement);
|
||||||
|
|
||||||
QString testMDName = QString("https://github.com/") + userGitHub + "/hifi_tests/blob/" + branchGitHub +
|
QString testMDName = QString("https://github.com/") + userGitHub + "/hifi_tests/blob/" + branchGitHub +
|
||||||
|
@ -630,7 +692,8 @@ QDomElement TestRailInterface::processTestXML(const QString& fullDirectory,
|
||||||
stepIndexElement.appendChild(_document.createTextNode("1"));
|
stepIndexElement.appendChild(_document.createTextNode("1"));
|
||||||
stepElement.appendChild(stepIndexElement);
|
stepElement.appendChild(stepIndexElement);
|
||||||
QDomElement stepContentElement = _document.createElement("content");
|
QDomElement stepContentElement = _document.createElement("content");
|
||||||
stepContentElement.appendChild(_document.createTextNode(QString("Execute instructions in [THIS TEST](") + testMDName + ")"));
|
stepContentElement.appendChild(
|
||||||
|
_document.createTextNode(QString("Execute instructions in [THIS TEST](") + testMDName + ")"));
|
||||||
stepElement.appendChild(stepContentElement);
|
stepElement.appendChild(stepContentElement);
|
||||||
QDomElement stepExpectedElement = _document.createElement("expected");
|
QDomElement stepExpectedElement = _document.createElement("expected");
|
||||||
stepExpectedElement.appendChild(_document.createTextNode("Refer to the expected result in the linked description."));
|
stepExpectedElement.appendChild(_document.createTextNode("Refer to the expected result in the linked description."));
|
||||||
|
@ -645,7 +708,7 @@ QDomElement TestRailInterface::processTestXML(const QString& fullDirectory,
|
||||||
caseElement.appendChild(customElement);
|
caseElement.appendChild(customElement);
|
||||||
|
|
||||||
result.appendChild(caseElement);
|
result.appendChild(caseElement);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,24 +741,27 @@ void TestRailInterface::processTestPython(const QString& fullDirectory,
|
||||||
|
|
||||||
stream << "section_id = parent_ids.peek()\n";
|
stream << "section_id = parent_ids.peek()\n";
|
||||||
|
|
||||||
QString testMDName = QString("https://github.com/") + userGitHub + "/hifi_tests/blob/" + branchGitHub +
|
QString testMDName =
|
||||||
pathToTestMD + "/test.md ";
|
QString("https://github.com/") + userGitHub + "/hifi_tests/blob/" + branchGitHub + pathToTestMD + "/test.md ";
|
||||||
|
|
||||||
QString testContent = QString("Execute instructions in [THIS TEST](") + testMDName + ")";
|
QString testContent = QString("Execute instructions in [THIS TEST](") + testMDName + ")";
|
||||||
QString testExpected = QString("Refer to the expected result in the linked description.");
|
QString testExpected = QString("Refer to the expected result in the linked description.");
|
||||||
|
|
||||||
int milestone_id = _milestones[_milestoneNames[_testRailTestCasesSelectorWindow.getMilestoneID()]];
|
int milestone_id = _milestones[_milestoneNames[_testRailTestCasesSelectorWindow.getMilestoneID()]];
|
||||||
|
|
||||||
stream << "data = {\n"
|
stream << "data = {\n"
|
||||||
<< "\t'title': '" << title << "',\n"
|
<< "\t'title': '" << title << "',\n"
|
||||||
<< "\t'template_id': 2,\n"
|
<< "\t'template_id': 2,\n"
|
||||||
<< "\t'milestone_id': " << milestone_id << ",\n"
|
<< "\t'milestone_id': " << milestone_id << ",\n"
|
||||||
<< "\t'custom_tester_count': 1,\n"
|
<< "\t'custom_tester_count': 1,\n"
|
||||||
<< "\t'custom_domain_bot_load': 1,\n"
|
<< "\t'custom_domain_bot_load': 1,\n"
|
||||||
<< "\t'custom_added_to_release': 4,\n"
|
<< "\t'custom_added_to_release': 4,\n"
|
||||||
<< "\t'custom_preconds': " << "'Tester is in an empty region of a domain in which they have edit rights\\n\\n*Note: Press \\'n\\' to advance test script',\n"
|
<< "\t'custom_preconds': "
|
||||||
<< "\t'custom_steps_separated': " << "[\n\t\t{\n\t\t\t'content': '" << testContent << "',\n\t\t\t'expected': '" << testExpected << "'\n\t\t}\n\t]\n"
|
<< "'Tester is in an empty region of a domain in which they have edit rights\\n\\n*Note: Press \\'n\\' to advance "
|
||||||
<< "}\n";
|
"test script',\n"
|
||||||
|
<< "\t'custom_steps_separated': "
|
||||||
|
<< "[\n\t\t{\n\t\t\t'content': '" << testContent << "',\n\t\t\t'expected': '" << testExpected << "'\n\t\t}\n\t]\n"
|
||||||
|
<< "}\n";
|
||||||
|
|
||||||
stream << "case = client.send_post('add_case/' + str(section_id), data)\n";
|
stream << "case = client.send_post('add_case/' + str(section_id), data)\n";
|
||||||
}
|
}
|
||||||
|
@ -703,16 +769,69 @@ void TestRailInterface::processTestPython(const QString& fullDirectory,
|
||||||
void TestRailInterface::requestTestRailRunDataFromUser() {
|
void TestRailInterface::requestTestRailRunDataFromUser() {
|
||||||
_testRailRunSelectorWindow.reset();
|
_testRailRunSelectorWindow.reset();
|
||||||
_testRailRunSelectorWindow.exec();
|
_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::getTestCasesFromTestRail() {
|
void TestRailInterface::getTestSectionsFromTestRail() {
|
||||||
|
QString filename = _outputDirectory + "/getSections.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 'getSections.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 sections without parents
|
||||||
|
stream << "sections = client.send_get('get_sections/" + _projectID + "&suite_id=" + _suiteID + "')\n\n";
|
||||||
|
stream << "file = open('" + _outputDirectory + "/sections.txt', 'w')\n\n";
|
||||||
|
stream << "for section in sections:\n";
|
||||||
|
stream << "\tif section['parent_id'] == None:\n";
|
||||||
|
stream << "\t\tfile.write(section['name'] + ' ' + str(section['id']) + '\\n')\n\n";
|
||||||
|
stream << "file.close()\n";
|
||||||
|
|
||||||
|
file.close();
|
||||||
|
|
||||||
|
QProcess* process = new QProcess();
|
||||||
|
connect(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this,
|
||||||
|
[=](int exitCode, QProcess::ExitStatus exitStatus) { updateSectionsComboData(exitCode, exitStatus); });
|
||||||
|
|
||||||
|
QStringList parameters = QStringList() << _outputDirectory + "/getSections.py ";
|
||||||
|
process->start(_pythonCommand, parameters);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRailInterface::createTestRailRun() {
|
void TestRailInterface::createTestRailRun(const QString& outputDirectory) {
|
||||||
|
_outputDirectory = outputDirectory;
|
||||||
|
|
||||||
|
if (!setPythonCommand()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
requestTestRailRunDataFromUser();
|
requestTestRailRunDataFromUser();
|
||||||
createTestRailDotPyScript();
|
createTestRailDotPyScript();
|
||||||
createStackDotPyScript();
|
createStackDotPyScript();
|
||||||
|
|
||||||
// TestRail will be updated after the process initiated by getTestCasesFromTestRail has completed
|
// TestRail will be updated after the process initiated by getTestCasesFromTestRail has completed
|
||||||
getTestCasesFromTestRail();
|
getTestSectionsFromTestRail();
|
||||||
}
|
}
|
|
@ -54,7 +54,7 @@ public:
|
||||||
const QString& branchGitHub);
|
const QString& branchGitHub);
|
||||||
|
|
||||||
void getMilestonesFromTestRail();
|
void getMilestonesFromTestRail();
|
||||||
void getTestCasesFromTestRail();
|
void getTestSectionsFromTestRail();
|
||||||
|
|
||||||
void createTestRailDotPyScript();
|
void createTestRailDotPyScript();
|
||||||
void createStackDotPyScript();
|
void createStackDotPyScript();
|
||||||
|
@ -76,8 +76,11 @@ public:
|
||||||
QString getObject(const QString& path);
|
QString getObject(const QString& path);
|
||||||
|
|
||||||
void updateMilestonesComboData(int exitCode, QProcess::ExitStatus exitStatus);
|
void updateMilestonesComboData(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
|
void updateSectionsComboData(int exitCode, QProcess::ExitStatus exitStatus);
|
||||||
|
|
||||||
void createTestRailRun();
|
void createTestRailRun(const QString& outputDirectory);
|
||||||
|
|
||||||
|
bool setPythonCommand();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// HighFidelity Interface project ID in TestRail
|
// HighFidelity Interface project ID in TestRail
|
||||||
|
@ -105,8 +108,12 @@ private:
|
||||||
|
|
||||||
const QString pythonExe{ "python.exe" };
|
const QString pythonExe{ "python.exe" };
|
||||||
QString _pythonCommand;
|
QString _pythonCommand;
|
||||||
|
|
||||||
std::map<QString, int> _milestones;
|
std::map<QString, int> _milestones;
|
||||||
QStringList _milestoneNames;
|
QStringList _milestoneNames;
|
||||||
|
|
||||||
|
std::map<QString, int> _sections;
|
||||||
|
QStringList _sectionNames;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
|
@ -27,7 +27,7 @@ void TestRailRunSelectorWindow::reset() {
|
||||||
projectIDLineEdit->setDisabled(false);
|
projectIDLineEdit->setDisabled(false);
|
||||||
|
|
||||||
OKButton->setDisabled(true);
|
OKButton->setDisabled(true);
|
||||||
milestoneComboBox->setDisabled(true);
|
sectionsComboBox->setDisabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRailRunSelectorWindow::on_acceptButton_clicked() {
|
void TestRailRunSelectorWindow::on_acceptButton_clicked() {
|
||||||
|
@ -37,7 +37,7 @@ void TestRailRunSelectorWindow::on_acceptButton_clicked() {
|
||||||
projectIDLineEdit->setDisabled(true);
|
projectIDLineEdit->setDisabled(true);
|
||||||
|
|
||||||
OKButton->setDisabled(false);
|
OKButton->setDisabled(false);
|
||||||
milestoneComboBox->setDisabled(false);
|
sectionsComboBox->setDisabled(false);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,10 +91,11 @@ int TestRailRunSelectorWindow::getSuiteID() {
|
||||||
return suiteIDLineEdit->text().toInt();
|
return suiteIDLineEdit->text().toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRailRunSelectorWindow::updateMilestoneComboBoxData(QStringList data) {
|
void TestRailRunSelectorWindow::updateSectionsComboBoxData(QStringList data) {
|
||||||
milestoneComboBox->insertItems(0, data);
|
sectionsComboBox->insertItems(0, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TestRailRunSelectorWindow::getMilestoneID() {
|
int TestRailRunSelectorWindow::getSectionID() {
|
||||||
return milestoneComboBox->currentIndex();
|
return 0;
|
||||||
|
sectionsComboBox->currentIndex();
|
||||||
}
|
}
|
|
@ -38,8 +38,8 @@ public:
|
||||||
|
|
||||||
bool userCancelled{ false };
|
bool userCancelled{ false };
|
||||||
|
|
||||||
void updateMilestoneComboBoxData(QStringList data);
|
void updateSectionsComboBoxData(QStringList data);
|
||||||
int getMilestoneID();
|
int getSectionID();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_acceptButton_clicked();
|
void on_acceptButton_clicked();
|
||||||
|
|
|
@ -174,15 +174,15 @@
|
||||||
<string>Accept</string>
|
<string>Accept</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QComboBox" name="milestoneComboBox">
|
<widget class="QComboBox" name="sectionsComboBox">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>270</x>
|
<x>140</x>
|
||||||
<y>350</y>
|
<y>350</y>
|
||||||
<width>161</width>
|
<width>311</width>
|
||||||
<height>22</height>
|
<height>22</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -193,7 +193,7 @@
|
||||||
</property>
|
</property>
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>140</x>
|
<x>20</x>
|
||||||
<y>350</y>
|
<y>350</y>
|
||||||
<width>121</width>
|
<width>121</width>
|
||||||
<height>20</height>
|
<height>20</height>
|
||||||
|
@ -205,7 +205,7 @@
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>TestRail Milestone</string>
|
<string>TestRail Sections</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLineEdit" name="urlLineEdit">
|
<widget class="QLineEdit" name="urlLineEdit">
|
||||||
|
@ -274,7 +274,7 @@
|
||||||
<tabstop>projectIDLineEdit</tabstop>
|
<tabstop>projectIDLineEdit</tabstop>
|
||||||
<tabstop>suiteIDLineEdit</tabstop>
|
<tabstop>suiteIDLineEdit</tabstop>
|
||||||
<tabstop>acceptButton</tabstop>
|
<tabstop>acceptButton</tabstop>
|
||||||
<tabstop>milestoneComboBox</tabstop>
|
<tabstop>sectionsComboBox</tabstop>
|
||||||
<tabstop>OKButton</tabstop>
|
<tabstop>OKButton</tabstop>
|
||||||
<tabstop>cancelButton</tabstop>
|
<tabstop>cancelButton</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
|
|
|
@ -27,7 +27,7 @@ void TestRailTestCasesSelectorWindow::reset() {
|
||||||
projectIDLineEdit->setDisabled(false);
|
projectIDLineEdit->setDisabled(false);
|
||||||
|
|
||||||
OKButton->setDisabled(true);
|
OKButton->setDisabled(true);
|
||||||
milestoneComboBox->setDisabled(true);
|
milestonesComboBox->setDisabled(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRailTestCasesSelectorWindow::on_acceptButton_clicked() {
|
void TestRailTestCasesSelectorWindow::on_acceptButton_clicked() {
|
||||||
|
@ -37,7 +37,7 @@ void TestRailTestCasesSelectorWindow::on_acceptButton_clicked() {
|
||||||
projectIDLineEdit->setDisabled(true);
|
projectIDLineEdit->setDisabled(true);
|
||||||
|
|
||||||
OKButton->setDisabled(false);
|
OKButton->setDisabled(false);
|
||||||
milestoneComboBox->setDisabled(false);
|
milestonesComboBox->setDisabled(false);
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,10 +91,10 @@ int TestRailTestCasesSelectorWindow::getSuiteID() {
|
||||||
return suiteIDLineEdit->text().toInt();
|
return suiteIDLineEdit->text().toInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TestRailTestCasesSelectorWindow::updateMilestoneComboBoxData(QStringList data) {
|
void TestRailTestCasesSelectorWindow::updateMilestonesComboBoxData(QStringList data) {
|
||||||
milestoneComboBox->insertItems(0, data);
|
milestonesComboBox->insertItems(0, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
int TestRailTestCasesSelectorWindow::getMilestoneID() {
|
int TestRailTestCasesSelectorWindow::getMilestoneID() {
|
||||||
return milestoneComboBox->currentIndex();
|
return milestonesComboBox->currentIndex();
|
||||||
}
|
}
|
|
@ -38,7 +38,7 @@ public:
|
||||||
|
|
||||||
bool userCancelled{ false };
|
bool userCancelled{ false };
|
||||||
|
|
||||||
void updateMilestoneComboBoxData(QStringList data);
|
void updateMilestonesComboBoxData(QStringList data);
|
||||||
int getMilestoneID();
|
int getMilestoneID();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
|
|
|
@ -171,7 +171,7 @@
|
||||||
<string>Accept</string>
|
<string>Accept</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QComboBox" name="milestoneComboBox">
|
<widget class="QComboBox" name="milestonesComboBox">
|
||||||
<property name="enabled">
|
<property name="enabled">
|
||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
|
@ -271,7 +271,7 @@
|
||||||
<tabstop>projectIDLineEdit</tabstop>
|
<tabstop>projectIDLineEdit</tabstop>
|
||||||
<tabstop>suiteIDLineEdit</tabstop>
|
<tabstop>suiteIDLineEdit</tabstop>
|
||||||
<tabstop>acceptButton</tabstop>
|
<tabstop>acceptButton</tabstop>
|
||||||
<tabstop>milestoneComboBox</tabstop>
|
<tabstop>milestonesComboBox</tabstop>
|
||||||
<tabstop>OKButton</tabstop>
|
<tabstop>OKButton</tabstop>
|
||||||
<tabstop>cancelButton</tabstop>
|
<tabstop>cancelButton</tabstop>
|
||||||
</tabstops>
|
</tabstops>
|
||||||
|
|
Loading…
Reference in a new issue