Merge branch 'exportToTestRail' of https://github.com/NissimHadar/hifi into exportToTestRail

This commit is contained in:
NissimHadar 2018-08-01 09:26:16 -07:00
commit 49821e37fb
20 changed files with 1343 additions and 222 deletions

View file

@ -821,7 +821,7 @@ void Test::createTestsOutline() {
QMessageBox::information(0, "Success", "Test outline file " + testsOutlineFilename + " has been created");
}
void Test::createTestRailTestSuite() {
void Test::createTestRailTestCases() {
QString previousSelection = _testDirectory;
QString parent = previousSelection.left(previousSelection.lastIndexOf('/'));
if (!parent.isNull() && parent.right(1) != "/") {
@ -854,6 +854,10 @@ void Test::createTestRailTestSuite() {
}
}
void Test::createTestRailRun() {
_testRailInterface.createTestRailRun();
}
QStringList Test::createListOfAll_imagesInDirectory(const QString& imageFormat, const QString& pathToImageDirectory) {
_imageDirectory = QDir(pathToImageDirectory);
QStringList nameFilters;

View file

@ -57,7 +57,8 @@ public:
void createTestsOutline();
void createTestRailTestSuite();
void createTestRailTestCases();
void createTestRailRun();
bool compareImageLists(bool isInteractiveMode, QProgressBar* progressBar);

View file

@ -11,27 +11,44 @@
#include "TestRailInterface.h"
#include "Test.h"
#include "ui/TestRailSelectorWindow.h"
#include <QDateTime>
#include <QFile>
#include <QMessageBox>
#include <QTextStream>
TestRailInterface::TestRailInterface() {
_testRailSelectorWindow.setModal(true);
_testRailTestCasesSelectorWindow.setURL("https://highfidelity.testrail.net");
////_testRailTestCasesSelectorWindow.setURL("https://nissimhadar.testrail.io");
_testRailTestCasesSelectorWindow.setUser("@highfidelity.io");
////_testRailSelectorWindow.setUser("nissim.hadar@gmail.com");
_testRailSelectorWindow.setURL("https://highfidelity.testrail.net/");
_testRailSelectorWindow.setUser("@highfidelity.io");
_testRailTestCasesSelectorWindow.setProjectID(INTERFACE_PROJECT_ID);
////_testRailSelectorWindow.setProject(1);
_testRailTestCasesSelectorWindow.setSuiteID(INTERFACE_SUITE_ID);
_testRailRunSelectorWindow.setURL("https://highfidelity.testrail.net");
////_testRailRunSelectorWindow.setURL("https://nissimhadar.testrail.io");
_testRailRunSelectorWindow.setUser("@highfidelity.io");
////_testRailSelectorWindow.setUser("nissim.hadar@gmail.com");
_testRailRunSelectorWindow.setProjectID(INTERFACE_PROJECT_ID);
////_testRailSelectorWindow.setProject(1);
_testRailRunSelectorWindow.setSuiteID(INTERFACE_SUITE_ID);
}
void TestRailInterface::createTestRailDotPyScript(const QString& outputDirectory) {
// Create the testrail.py script
// This is the file linked to from http://docs.gurock.com/testrail-api2/bindings-python
QFile file(outputDirectory + "/testrail.py");
QString TestRailInterface::getObject(const QString& path) {
return path.right(path.length() - path.lastIndexOf("/") - 1);
}
// Creates the testrail.py script
// This is the file linked to from http://docs.gurock.com/testrail-api2/bindings-python
void TestRailInterface::createTestRailDotPyScript() {
QFile file(_outputDirectory + "/testrail.py");
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
"Could not create \'testrail.py\'");
"Could not create 'testrail.py'");
exit(-1);
}
@ -118,10 +135,10 @@ void TestRailInterface::createTestRailDotPyScript(const QString& outputDirectory
stream << "\n";
stream << "\t\tif e != None:\n";
stream << "\t\t\tif result and 'error' in result:\n";
stream << "\t\t\t\terror = \'\"\' + result[\'error\'] + \'\"\'\n";
stream << "\t\t\t\terror = '\"' + result['error'] + '\"'\n";
stream << "\t\t\telse:\n";
stream << "\t\t\t\terror = \'No additional error message received\'\n";
stream << "\t\t\traise APIError(\'TestRail API returned HTTP %s (%s)\' % \n";
stream << "\t\t\t\terror = 'No additional error message received'\n";
stream << "\t\t\traise APIError('TestRail API returned HTTP %s (%s)' % \n";
stream << "\t\t\t\t(e.code, error))\n";
stream << "\n";
stream << "\t\treturn result\n";
@ -132,23 +149,132 @@ void TestRailInterface::createTestRailDotPyScript(const QString& outputDirectory
file.close();
}
void TestRailInterface::requestDataFromUser() {
_testRailSelectorWindow.exec();
// Creates a Stack class
void TestRailInterface::createStackDotPyScript() {
QString filename = _outputDirectory + "/stack.py";
if (QFile::exists(filename)) {
QFile::remove(filename);
}
QFile file(filename);
if (_testRailSelectorWindow.getUserCancelled()) {
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
"Could not create 'stack.py'");
exit(-1);
}
QTextStream stream(&file);
stream << "class Stack:\n";
stream << "\tdef __init__(self):\n";
stream << "\t\tself.items = []\n";
stream << "\n";
stream << "\tdef is_empty(self):\n";
stream << "\t\treturn self.items == []\n";
stream << "\n";
stream << "\tdef push(self, item):\n";
stream << "\t\tself.items.append(item)\n";
stream << "\n";
stream << "\tdef pop(self):\n";
stream << "\t\treturn self.items.pop()\n";
stream << "\n";
stream << "\tdef peek(self):\n";
stream << "\t\treturn self.items[len(self.items)-1]\n";
stream << "\n";
stream << "\tdef size(self):\n";
stream << "\t\treturn len(self.items)\n";
stream << "\n";
file.close();
}
void TestRailInterface::requestTestRailTestCasesDataFromUser() {
// Make sure correct fields are enabled before calling
_testRailTestCasesSelectorWindow.reset();
_testRailTestCasesSelectorWindow.exec();
if (_testRailTestCasesSelectorWindow.getUserCancelled()) {
return;
}
_url = _testRailSelectorWindow.getURL();
_user = _testRailSelectorWindow.getUser();
_password = _testRailSelectorWindow.getPassword();
_url = _testRailTestCasesSelectorWindow.getURL() + "/";
_user = _testRailTestCasesSelectorWindow.getUser();
_password = _testRailTestCasesSelectorWindow.getPassword();
////_password = "tutKA76";
_projectID = QString::number(_testRailTestCasesSelectorWindow.getProjectID());
_suiteID = QString::number(_testRailTestCasesSelectorWindow.getSuiteID());
}
void TestRailInterface::createAddSectionsPythonScript(const QString& outputDirectory) {
QFile file(outputDirectory + "/addSections.py");
bool TestRailInterface::isAValidTestDirectory(const QString& directory) {
if (Test::isAValidDirectory(directory)) {
// Ignore the utils and preformance directories
if (directory.right(QString("utils").length()) == "utils" ||
directory.right(QString("performance").length()) == "performance") {
return false;
}
return true;
}
return false;
}
void TestRailInterface::processDirectoryPython(const QString& directory,
QTextStream& stream,
const QString& userGitHub,
const QString& branchGitHub
) {
// Loop over all entries in directory
QDirIterator it(directory.toStdString().c_str());
while (it.hasNext()) {
QString nextDirectory = it.next();
QString objectName = getObject(nextDirectory);
if (isAValidTestDirectory(nextDirectory)) {
// The name of the section is the directory at the end of the path
stream << "parent_id = parent_ids.peek()\n";
stream << "data = { 'name': '" << objectName << "', 'suite_id': " + _suiteID + ", 'parent_id': parent_id }\n";
stream << "section = client.send_post('add_section/' + str(" << _projectID << "), data)\n";
// Now we push the parent_id, and recursively process each directory
stream << "parent_ids.push(section['id'])\n\n";
processDirectoryPython(nextDirectory, stream, userGitHub, branchGitHub);
} else if (objectName == "test.js") {
processTestPython(nextDirectory, stream, userGitHub, branchGitHub);
}
}
// pop the parent directory before leaving
stream << "parent_ids.pop()\n\n";
}
// A suite of TestRail test cases contains trees.
// The nodes of the trees are sections
// The leaves are the test cases
//
// Each node and leaf have an ID and a parent ID.
// Therefore, the tree is built top-down, using a stack to store the IDs of each node
//
void TestRailInterface::createAddTestCasesPythonScript(const QString& testDirectory,
const QString& userGitHub,
const QString& branchGitHub
) {
QString filename = _outputDirectory + "/addTestCases.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 \'addSections.py\'");
"Could not create 'addTestCases.py'");
exit(-1);
}
@ -156,31 +282,177 @@ void TestRailInterface::createAddSectionsPythonScript(const QString& outputDirec
// 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";
stream << "client = APIClient('" << _url.toStdString().c_str() << "')\n";
stream << "client.user = '" << _user << "'\n";
stream << "client.password = '" << _password << "'\n\n";
stream << "from stack import *\n";
stream << "parent_ids = Stack()\n\n";
// top-level section
stream << "data = { \'name\': \'"
<< "Test Suite - " << QDateTime::currentDateTime().toString("yyyy-MM-ddTHH:mm") << "\'}\n";
stream << "data = { 'name': '"
<< "Test Suite - " << QDateTime::currentDateTime().toString("yyyy-MM-ddTHH:mm") + "', "
<< "'suite_id': " + _suiteID + "}\n";
stream << "section = client.send_post('add_section/' + str(" << _projectID << "), data)\n";
// Now we push the parent_id, and recursively process each directory
stream << "parent_ids.push(section['id'])\n\n";
processDirectoryPython(testDirectory, stream, userGitHub, branchGitHub);
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()) {
QProcess* process = new QProcess();
connect(process, &QProcess::started, this,
[=]() {
_busyWindow.exec();
}
);
connect(process, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this,
[=](int exitCode, QProcess::ExitStatus exitStatus) {
_busyWindow.hide();
}
);
QStringList parameters = QStringList() << _outputDirectory + "/addTestCases.py";
process->start(_pythonCommand, parameters);
}
}
void TestRailInterface::updateMilestonesComboData(int exitCode, QProcess::ExitStatus exitStatus) {
// Quit if user has previously cancelled
if (_testRailTestCasesSelectorWindow.getUserCancelled()) {
return;
}
// Check if process completed successfully
if (exitStatus != QProcess::NormalExit) {
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
"Could not get milestones from TestRail");
exit(-1);
}
// Create map of milestones from the file created by the process
_milestoneNames.clear();
QString filename = _outputDirectory + "/milestones.txt";
if (!QFile::exists(filename)) {
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
"Could not find milestones.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 + "/milestones.txt");
exit(-1);
}
QTextStream in(&file);
QString line = in.readLine();
while (!line.isNull()) {
QStringList words = line.split(' ');
_milestones[words[0]] = words[1].toInt();
_milestoneNames << words[0];
line = in.readLine();
}
file.close();
// Update the combo
_testRailTestCasesSelectorWindow.updateMilestoneComboBoxData(_milestoneNames);
_testRailTestCasesSelectorWindow.exec();
if (_testRailTestCasesSelectorWindow.getUserCancelled()) {
return;
}
createAddTestCasesPythonScript(_testDirectory, _userGitHub, _branchGitHub);
}
void TestRailInterface::getMilestonesFromTestRail() {
QString filename = _outputDirectory + "/getMilestones.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 'getMilestones.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 uncompleted milestones
stream << "file = open('" + _outputDirectory + "/milestones.txt', 'w')\n\n";
stream << "milestones = client.send_get('get_milestones/" + _projectID + "')\n";
stream << "for milestone in milestones:\n";
stream << "\tif milestone['is_completed'] == False:\n";
stream << "\t\tfile.write(milestone['name'] + ' ' + str(milestone['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) {
updateMilestonesComboData(exitCode, exitStatus);
}
);
QStringList parameters = QStringList() << _outputDirectory + "/getMilestones.py ";
process->start(_pythonCommand, parameters);
}
void TestRailInterface::createTestSuitePython(const QString& testDirectory,
const QString& outputDirectory,
const QString& user,
const QString& branch) {
createTestRailDotPyScript(outputDirectory);
requestDataFromUser();
createAddSectionsPythonScript(outputDirectory);
}
const QString& userGitHub,
const QString& branchGitHub) {
_testDirectory = testDirectory;
_outputDirectory = outputDirectory;
_userGitHub = userGitHub;
_branchGitHub = branchGitHub;
// First check that Python is available
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;
}
requestTestRailTestCasesDataFromUser();
createTestRailDotPyScript();
createStackDotPyScript();
// TestRail will be updated after the process initiated by getMilestonesFromTestRail has completed
getMilestonesFromTestRail();
}
void TestRailInterface::createTestSuiteXML(const QString& testDirectory,
const QString& outputDirectory,
const QString& user,
const QString& branch) {
const QString& userGitHub,
const QString& branchGitHub) {
_outputDirectory = outputDirectory;
QDomProcessingInstruction instruction = _document.createProcessingInstruction("xml", "version='1.0' encoding='UTF-8'");
_document.appendChild(instruction);
@ -195,14 +467,15 @@ void TestRailInterface::createTestSuitePython(const QString& testDirectory,
suiteName.appendChild(_document.createTextNode("Test Suite - " + QDateTime::currentDateTime().toString("yyyy-MM-ddTHH:mm")));
topLevelSection.appendChild(suiteName);
// This is the first call to 'process'. This is then called recursively to build the full XML tree
QDomElement secondLevelSections = _document.createElement("sections");
topLevelSection.appendChild(processDirectory(testDirectory, user, branch, secondLevelSections));
topLevelSection.appendChild(processDirectoryXML(testDirectory, userGitHub, branchGitHub, secondLevelSections));
topLevelSection.appendChild(secondLevelSections);
root.appendChild(topLevelSection);
// Write to file
const QString testRailsFilename{ outputDirectory + "/TestRailSuite.xml" };
const QString testRailsFilename{ _outputDirectory + "/TestRailSuite.xml" };
QFile file(testRailsFilename);
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Could not create XML file");
@ -217,7 +490,10 @@ void TestRailInterface::createTestSuitePython(const QString& testDirectory,
QMessageBox::information(0, "Success", "TestRail XML file has been created");
}
QDomElement TestRailInterface::processDirectory(const QString& directory, const QString& user, const QString& branch, const QDomElement& element) {
QDomElement TestRailInterface::processDirectoryXML(const QString& directory,
const QString& userGitHub,
const QString& branchGitHub,
const QDomElement& element) {
QDomElement result = element;
// Loop over all entries in directory
@ -226,17 +502,11 @@ QDomElement TestRailInterface::processDirectory(const QString& directory, const
QString nextDirectory = it.next();
// The object name appears after the last slash (we are assured there is at least 1).
QString objectName = nextDirectory.right(nextDirectory.length() - nextDirectory.lastIndexOf("/") - 1);
QString objectName = getObject(nextDirectory);
// Only process directories
if (Test::isAValidDirectory(nextDirectory)) {
// Ignore the utils and preformance directories
if (nextDirectory.right(QString("utils").length()) == "utils" || nextDirectory.right(QString("performance").length()) == "performance") {
continue;
}
if (isAValidTestDirectory(nextDirectory)) {
// Create a section and process it
QDomElement sectionElement = _document.createElement("section");
QDomElement sectionElementName = _document.createElement("name");
@ -244,7 +514,7 @@ QDomElement TestRailInterface::processDirectory(const QString& directory, const
sectionElement.appendChild(sectionElementName);
QDomElement testsElement = _document.createElement("sections");
sectionElement.appendChild(processDirectory(nextDirectory, user, branch, testsElement));
sectionElement.appendChild(processDirectoryXML(nextDirectory, userGitHub, branchGitHub, testsElement));
result.appendChild(sectionElement);
} else if (objectName == "test.js" || objectName == "testStory.js") {
@ -252,7 +522,9 @@ QDomElement TestRailInterface::processDirectory(const QString& directory, const
QDomElement sectionElementName = _document.createElement("name");
sectionElementName.appendChild(_document.createTextNode("all"));
sectionElement.appendChild(sectionElementName);
sectionElement.appendChild(processTest(nextDirectory, objectName, user, branch, _document.createElement("cases")));
sectionElement.appendChild(
processTestXML(nextDirectory, objectName, userGitHub, branchGitHub, _document.createElement("cases")));
result.appendChild(sectionElement);
}
}
@ -260,7 +532,11 @@ QDomElement TestRailInterface::processDirectory(const QString& directory, const
return result;
}
QDomElement TestRailInterface::processTest(const QString& fullDirectory, const QString& test, const QString& user, const QString& branch, const QDomElement& element) {
QDomElement TestRailInterface::processTestXML(const QString& fullDirectory,
const QString& test,
const QString& userGitHub,
const QString& branchGitHub,
const QDomElement& element) {
QDomElement result = element;
QDomElement caseElement = _document.createElement("case");
@ -337,7 +613,7 @@ QDomElement TestRailInterface::processTest(const QString& fullDirectory, const Q
added_to_releaseElementId.appendChild(_document.createTextNode("4"));
added_to_releaseElement.appendChild(added_to_releaseElementId);
QDomElement added_to_releaseElementValue = _document.createElement("value");
added_to_releaseElementValue.appendChild(_document.createTextNode(branch));
added_to_releaseElementValue.appendChild(_document.createTextNode(branchGitHub));
added_to_releaseElement.appendChild(added_to_releaseElementValue);
customElement.appendChild(added_to_releaseElement);
@ -345,7 +621,8 @@ QDomElement TestRailInterface::processTest(const QString& fullDirectory, const Q
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);
QString testMDName = QString("https://github.com/") + user + "/hifi_tests/blob/" + branch + "/tests/content/entity/light/point/create/test.md";
QString testMDName = QString("https://github.com/") + userGitHub + "/hifi_tests/blob/" + branchGitHub +
"/tests/content/entity/light/point/create/test.md";
QDomElement steps_seperatedElement = _document.createElement("steps_separated");
QDomElement stepElement = _document.createElement("step");
@ -370,4 +647,72 @@ QDomElement TestRailInterface::processTest(const QString& fullDirectory, const Q
result.appendChild(caseElement);
return result;
}
void TestRailInterface::processTestPython(const QString& fullDirectory,
QTextStream& stream,
const QString& userGitHub,
const QString& branchGitHub) {
// The name of the test is derived from the full path.
// The first term is the first word after "tests"
// The last word is the penultimate word
QStringList words = fullDirectory.split('/');
int i = 0;
while (words[i] != "tests") {
++i;
if (i >= words.length() - 1) {
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
"Folder \"tests\" not found in " + fullDirectory);
exit(-1);
}
}
++i;
QString title{ words[i] };
for (++i; i < words.length() - 1; ++i) {
title += " / " + words[i];
}
// To create the path to test.md, prefix by tests, and remove blanks
QString pathToTestMD = QString("/tests/") + title.remove(" ");
stream << "section_id = parent_ids.peek()\n";
QString testMDName = QString("https://github.com/") + userGitHub + "/hifi_tests/blob/" + branchGitHub +
pathToTestMD + "/test.md ";
QString testContent = QString("Execute instructions in [THIS TEST](") + testMDName + ")";
QString testExpected = QString("Refer to the expected result in the linked description.");
int milestone_id = _milestones[_milestoneNames[_testRailTestCasesSelectorWindow.getMilestoneID()]];
stream << "data = {\n"
<< "\t'title': '" << title << "',\n"
<< "\t'template_id': 2,\n"
<< "\t'milestone_id': " << milestone_id << ",\n"
<< "\t'custom_tester_count': 1,\n"
<< "\t'custom_domain_bot_load': 1,\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_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";
}
void TestRailInterface::requestTestRailRunDataFromUser() {
_testRailRunSelectorWindow.reset();
_testRailRunSelectorWindow.exec();
}
void TestRailInterface::getTestCasesFromTestRail() {
}
void TestRailInterface::createTestRailRun() {
requestTestRailRunDataFromUser();
createTestRailDotPyScript();
createStackDotPyScript();
// TestRail will be updated after the process initiated by getTestCasesFromTestRail has completed
getTestCasesFromTestRail();
}

View file

@ -11,44 +11,102 @@
#ifndef hifi_test_testrail_interface_h
#define hifi_test_testrail_interface_h
#include "ui/TestRailSelectorWindow.h"
#include "ui/BusyWindow.h"
#include "ui/TestRailTestCasesSelectorWindow.h"
#include "ui/TestRailRunSelectorWindow.h"
#include <QDirIterator>
#include <QtXml/QDomDocument>
#include <QProcess>
#include <QString>
class TestRailInterface {
class TestRailInterface : public QObject{
Q_OBJECT
public:
TestRailInterface();
void createTestSuiteXML(const QString& testDirectory,
const QString& outputDirectory,
const QString& user,
const QString& branch);
const QString& userGitHub,
const QString& branchGitHub);
void createTestSuitePython(const QString& testDirectory,
const QString& outputDirectory,
const QString& user,
const QString& branch);
const QString& userGitHub,
const QString& branchGitHub);
QDomElement processDirectory(const QString& directory,
const QString& user,
const QString& branch,
const QDomElement& element);
QDomElement processDirectoryXML(const QString& directory,
const QString& useGitHubr,
const QString& branchGitHub,
const QDomElement& element);
QDomElement processTest(const QString& fullDirectory, const QString& test, const QString& user, const QString& branch, const QDomElement& element);
QDomElement processTestXML(const QString& fullDirectory,
const QString& test,
const QString& userGitHub,
const QString& branchGitHub,
const QDomElement& element);
void createTestRailDotPyScript(const QString& outputDirectory);
void requestDataFromUser();
void createAddSectionsPythonScript(const QString& outputDirectory);
void processTestPython(const QString& fullDirectory,
QTextStream& stream,
const QString& userGitHub,
const QString& branchGitHub);
void getMilestonesFromTestRail();
void getTestCasesFromTestRail();
void createTestRailDotPyScript();
void createStackDotPyScript();
void requestTestRailTestCasesDataFromUser();
void requestTestRailRunDataFromUser();
void createAddTestCasesPythonScript(const QString& testDirectory,
const QString& userGitHub,
const QString& branchGitHub);
void processDirectoryPython(const QString& directory,
QTextStream& stream,
const QString& userGitHub,
const QString& branchGitHub);
bool isAValidTestDirectory(const QString& directory);
QString getObject(const QString& path);
void updateMilestonesComboData(int exitCode, QProcess::ExitStatus exitStatus);
void createTestRailRun();
private:
// HighFidelity Interface project ID in TestRail
const int INTERFACE_PROJECT_ID{ 24 };
// Rendering suite ID
const int INTERFACE_SUITE_ID{ 1147 };
QDomDocument _document;
TestRailSelectorWindow _testRailSelectorWindow;
BusyWindow _busyWindow;
TestRailTestCasesSelectorWindow _testRailTestCasesSelectorWindow;
TestRailRunSelectorWindow _testRailRunSelectorWindow;
QString _url;
QString _user;
QString _password;
QString _projectID;
QString _suiteID;
QString _testDirectory;
QString _outputDirectory;
QString _userGitHub;
QString _branchGitHub;
const QString pythonExe{ "python.exe" };
QString _pythonCommand;
std::map<QString, int> _milestones;
QStringList _milestoneNames;
};
#endif

View file

@ -68,8 +68,12 @@ void AutoTester::on_createTestsOutlineButton_clicked() {
_test->createTestsOutline();
}
void AutoTester::on_createTestRailTestSuiteButton_clicked() {
_test->createTestRailTestSuite();
void AutoTester::on_createTestRailTestCasesButton_clicked() {
_test->createTestRailTestCases();
}
void AutoTester::on_createTestRailRunButton_clicked() {
_test->createTestRailRun();
}
// To toggle between show and hide

View file

@ -45,7 +45,8 @@ private slots:
void on_createMDFileButton_clicked();
void on_createAllMDFilesButton_clicked();
void on_createTestsOutlineButton_clicked();
void on_createTestRailTestSuiteButton_clicked();
void on_createTestRailTestCasesButton_clicked();
void on_createTestRailRunButton_clicked();
void on_hideTaskbarButton_clicked();
void on_showTaskbarButton_clicked();

View file

@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>645</width>
<height>570</height>
<height>814</height>
</rect>
</property>
<property name="windowTitle">
@ -18,7 +18,7 @@
<property name="geometry">
<rect>
<x>380</x>
<y>450</y>
<y>620</y>
<width>101</width>
<height>40</height>
</rect>
@ -44,7 +44,7 @@
<property name="geometry">
<rect>
<x>430</x>
<y>320</y>
<y>490</y>
<width>101</width>
<height>40</height>
</rect>
@ -57,7 +57,7 @@
<property name="geometry">
<rect>
<x>330</x>
<y>170</y>
<y>340</y>
<width>220</width>
<height>40</height>
</rect>
@ -70,7 +70,7 @@
<property name="geometry">
<rect>
<x>320</x>
<y>330</y>
<y>500</y>
<width>131</width>
<height>20</height>
</rect>
@ -86,7 +86,7 @@
<property name="geometry">
<rect>
<x>320</x>
<y>380</y>
<y>550</y>
<width>255</width>
<height>23</height>
</rect>
@ -99,7 +99,7 @@
<property name="geometry">
<rect>
<x>330</x>
<y>230</y>
<y>400</y>
<width>220</width>
<height>40</height>
</rect>
@ -229,17 +229,17 @@
</rect>
</property>
</widget>
<widget class="QPushButton" name="createTestRailTestSuiteButton">
<widget class="QPushButton" name="createTestRailTestCasesButton">
<property name="geometry">
<rect>
<x>409</x>
<x>410</x>
<y>100</y>
<width>141</width>
<width>140</width>
<height>40</height>
</rect>
</property>
<property name="text">
<string>Create TestRail Test Suite</string>
<string>Create TestRail Test Cases</string>
</property>
</widget>
<widget class="QRadioButton" name="createPythonScriptRadioButton">
@ -271,6 +271,19 @@
<string>XML</string>
</property>
</widget>
<widget class="QPushButton" name="createTestRailRunButton">
<property name="geometry">
<rect>
<x>410</x>
<y>180</y>
<width>140</width>
<height>40</height>
</rect>
</property>
<property name="text">
<string>Create TestRail Run</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menuBar">
<property name="geometry">

View file

@ -0,0 +1,18 @@
//
// BusyWindow.cpp
//
// Created by Nissim Hadar on 26 Jul 2017.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "BusyWindow.h"
#include <QtCore/QFileInfo>
#include <cmath>
BusyWindow::BusyWindow(QWidget *parent) {
setupUi(this);
}

View file

@ -0,0 +1,22 @@
//
// BusyWindow.h
//
// Created by Nissim Hadar on 29 Jul 2017.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_BusyWindow_h
#define hifi_BusyWindow_h
#include "ui_BusyWindow.h"
class BusyWindow : public QDialog, public Ui::BusyWindow {
Q_OBJECT
public:
BusyWindow(QWidget* parent = Q_NULLPTR);
};
#endif

View file

@ -0,0 +1,75 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>BusyWindow</class>
<widget class="QDialog" name="BusyWindow">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>542</width>
<height>189</height>
</rect>
</property>
<property name="windowTitle">
<string>Updating TestRail - please wait</string>
</property>
<widget class="QLabel" name="errorLabel">
<property name="geometry">
<rect>
<x>30</x>
<y>850</y>
<width>500</width>
<height>28</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>similarity</string>
</property>
</widget>
<widget class="QProgressBar" name="progressBar">
<property name="geometry">
<rect>
<x>40</x>
<y>40</y>
<width>481</width>
<height>101</height>
</rect>
</property>
<property name="maximum">
<number>0</number>
</property>
<property name="value">
<number>0</number>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>50</x>
<y>60</y>
<width>431</width>
<height>61</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
</font>
</property>
<property name="text">
<string>Please wait for this window to close</string>
</property>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>

View file

@ -14,8 +14,7 @@
#include "../common.h"
class MismatchWindow : public QDialog, public Ui::MismatchWindow
{
class MismatchWindow : public QDialog, public Ui::MismatchWindow {
Q_OBJECT
public:

View file

@ -2,6 +2,9 @@
<ui version="4.0">
<class>MismatchWindow</class>
<widget class="QDialog" name="MismatchWindow">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
@ -193,4 +196,4 @@
<layoutdefault spacing="6" margin="11"/>
<resources/>
<connections/>
</ui>
</ui>

View file

@ -0,0 +1,100 @@
//
// TestRailRunSelectorWindow.cpp
//
// Created by Nissim Hadar on 31 Jul 2017.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "TestRailRunSelectorWindow.h"
#include <QtCore/QFileInfo>
#include <cmath>
TestRailRunSelectorWindow::TestRailRunSelectorWindow(QWidget *parent) {
setupUi(this);
projectIDLineEdit->setValidator(new QIntValidator(1, 999, this));
}
void TestRailRunSelectorWindow::reset() {
urlLineEdit->setDisabled(false);
userLineEdit->setDisabled(false);
passwordLineEdit->setDisabled(false);
projectIDLineEdit->setDisabled(false);
OKButton->setDisabled(true);
milestoneComboBox->setDisabled(true);
}
void TestRailRunSelectorWindow::on_acceptButton_clicked() {
urlLineEdit->setDisabled(true);
userLineEdit->setDisabled(true);
passwordLineEdit->setDisabled(true);
projectIDLineEdit->setDisabled(true);
OKButton->setDisabled(false);
milestoneComboBox->setDisabled(false);
close();
}
void TestRailRunSelectorWindow::on_OKButton_clicked() {
userCancelled = false;
close();
}
void TestRailRunSelectorWindow::on_cancelButton_clicked() {
userCancelled = true;
close();
}
bool TestRailRunSelectorWindow::getUserCancelled() {
return userCancelled;
}
void TestRailRunSelectorWindow::setURL(const QString& user) {
urlLineEdit->setText(user);
}
QString TestRailRunSelectorWindow::getURL() {
return urlLineEdit->text();
}
void TestRailRunSelectorWindow::setUser(const QString& user) {
userLineEdit->setText(user);
}
QString TestRailRunSelectorWindow::getUser() {
return userLineEdit->text();
}
QString TestRailRunSelectorWindow::getPassword() {
return passwordLineEdit->text();
}
void TestRailRunSelectorWindow::setProjectID(const int project) {
projectIDLineEdit->setText(QString::number(project));
}
int TestRailRunSelectorWindow::getProjectID() {
return projectIDLineEdit->text().toInt();
}
void TestRailRunSelectorWindow::setSuiteID(const int project) {
suiteIDLineEdit->setText(QString::number(project));
}
int TestRailRunSelectorWindow::getSuiteID() {
return suiteIDLineEdit->text().toInt();
}
void TestRailRunSelectorWindow::updateMilestoneComboBoxData(QStringList data) {
milestoneComboBox->insertItems(0, data);
}
int TestRailRunSelectorWindow::getMilestoneID() {
return milestoneComboBox->currentIndex();
}

View file

@ -0,0 +1,50 @@
//
// TestRailRunSelectorWindow.h
//
// Created by Nissim Hadar on 31 Jul 2017.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_TestRailRunSelectorWindow_h
#define hifi_TestRailRunSelectorWindow_h
#include "ui_TestRailRunSelectorWindow.h"
class TestRailRunSelectorWindow : public QDialog, public Ui::TestRailRunSelectorWindow {
Q_OBJECT
public:
TestRailRunSelectorWindow(QWidget* parent = Q_NULLPTR);
void reset();
bool getUserCancelled();
void setURL(const QString& user);
QString getURL();
void setUser(const QString& user);
QString getUser();
QString getPassword();
void setProjectID(const int project);
int getProjectID();
void setSuiteID(const int project);
int getSuiteID();
bool userCancelled{ false };
void updateMilestoneComboBoxData(QStringList data);
int getMilestoneID();
private slots:
void on_acceptButton_clicked();
void on_OKButton_clicked();
void on_cancelButton_clicked();
};
#endif

View file

@ -0,0 +1,283 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TestRailRunSelectorWindow</class>
<widget class="QDialog" name="TestRailRunSelectorWindow">
<property name="windowModality">
<enum>Qt::ApplicationModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>489</width>
<height>474</height>
</rect>
</property>
<property name="windowTitle">
<string>TestRail Run Selector Window</string>
</property>
<widget class="QLabel" name="errorLabel">
<property name="geometry">
<rect>
<x>30</x>
<y>850</y>
<width>500</width>
<height>28</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>12</pointsize>
</font>
</property>
<property name="text">
<string>similarity</string>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>70</x>
<y>125</y>
<width>121</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>TestRail Password</string>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>70</x>
<y>25</y>
<width>121</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>TestRail URL</string>
</property>
</widget>
<widget class="QPushButton" name="OKButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>120</x>
<y>420</y>
<width>93</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>OK</string>
</property>
</widget>
<widget class="QPushButton" name="cancelButton">
<property name="geometry">
<rect>
<x>280</x>
<y>420</y>
<width>93</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>Cancel</string>
</property>
</widget>
<widget class="QLineEdit" name="passwordLineEdit">
<property name="geometry">
<rect>
<x>200</x>
<y>120</y>
<width>231</width>
<height>24</height>
</rect>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>70</x>
<y>75</y>
<width>121</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>TestRail User</string>
</property>
</widget>
<widget class="QLineEdit" name="projectIDLineEdit">
<property name="geometry">
<rect>
<x>200</x>
<y>170</y>
<width>231</width>
<height>24</height>
</rect>
</property>
<property name="echoMode">
<enum>QLineEdit::Normal</enum>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>70</x>
<y>175</y>
<width>121</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>TestRail Project ID</string>
</property>
</widget>
<widget class="QPushButton" name="acceptButton">
<property name="geometry">
<rect>
<x>200</x>
<y>270</y>
<width>231</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>Accept</string>
</property>
</widget>
<widget class="QComboBox" name="milestoneComboBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>270</x>
<y>350</y>
<width>161</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="milestoneLabel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>140</x>
<y>350</y>
<width>121</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>TestRail Milestone</string>
</property>
</widget>
<widget class="QLineEdit" name="urlLineEdit">
<property name="geometry">
<rect>
<x>200</x>
<y>20</y>
<width>231</width>
<height>24</height>
</rect>
</property>
<property name="echoMode">
<enum>QLineEdit::Normal</enum>
</property>
</widget>
<widget class="QLineEdit" name="userLineEdit">
<property name="geometry">
<rect>
<x>200</x>
<y>70</y>
<width>231</width>
<height>24</height>
</rect>
</property>
<property name="echoMode">
<enum>QLineEdit::Normal</enum>
</property>
</widget>
<widget class="QLineEdit" name="suiteIDLineEdit">
<property name="geometry">
<rect>
<x>200</x>
<y>215</y>
<width>231</width>
<height>24</height>
</rect>
</property>
<property name="echoMode">
<enum>QLineEdit::Normal</enum>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>70</x>
<y>220</y>
<width>121</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>TestRail Suite ID</string>
</property>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>
<tabstop>urlLineEdit</tabstop>
<tabstop>userLineEdit</tabstop>
<tabstop>passwordLineEdit</tabstop>
<tabstop>projectIDLineEdit</tabstop>
<tabstop>suiteIDLineEdit</tabstop>
<tabstop>acceptButton</tabstop>
<tabstop>milestoneComboBox</tabstop>
<tabstop>OKButton</tabstop>
<tabstop>cancelButton</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

View file

@ -1,62 +0,0 @@
//
// TestRailSelectorWindow.cpp
//
// Created by Nissim Hadar on 26 Jul 2017.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "TestRailSelectorWindow.h"
#include <QtCore/QFileInfo>
#include <cmath>
TestRailSelectorWindow::TestRailSelectorWindow(QWidget *parent) {
setupUi(this);
projectLineEdit->setValidator(new QIntValidator(1, 999, this));
}
void TestRailSelectorWindow::on_OKButton_clicked() {
userCancelled = false;
close();
}
void TestRailSelectorWindow::on_cancelButton_clicked() {
userCancelled = true;
close();
}
bool TestRailSelectorWindow::getUserCancelled() {
return userCancelled;
}
void TestRailSelectorWindow::setURL(const QString& user) {
URLTextEdit->setText(user);
}
QString TestRailSelectorWindow::getURL() {
return URLTextEdit->toPlainText();
}
void TestRailSelectorWindow::setUser(const QString& user) {
userTextEdit->setText(user);
}
QString TestRailSelectorWindow::getUser() {
return userTextEdit->toPlainText();
}
QString TestRailSelectorWindow::getPassword() {
return passwordLineEdit->text();
}
void TestRailSelectorWindow::setProject(const int project) {
projectLineEdit->setText(QString::number(project));
}
int TestRailSelectorWindow::getProject() {
return projectLineEdit->getText().toInt();
}

View file

@ -1,41 +0,0 @@
//
// TestRailSelectorWindow.h
//
// Created by Nissim Hadar on 26 Jul 2017.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_TestRailSelectorWindow_h
#define hifi_TestRailSelectorWindow_h
#include "ui_TestRailSelectorWindow.h"
class TestRailSelectorWindow : public QDialog, public Ui::TestRailSelectorWindow {
Q_OBJECT
public:
TestRailSelectorWindow(QWidget* parent = Q_NULLPTR);
bool getUserCancelled();
void setURL(const QString& user);
QString getURL();
void setUser(const QString& user);
QString getUser();
QString getPassword();
void setProject(const int project);
int getProject();
bool userCancelled{ false };
private slots:
void on_OKButton_clicked();
void on_cancelButton_clicked();
};
#endif

View file

@ -0,0 +1,100 @@
//
// TestRailTestCasesSelectorWindow.cpp
//
// Created by Nissim Hadar on 26 Jul 2017.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "TestRailTestCasesSelectorWindow.h"
#include <QtCore/QFileInfo>
#include <cmath>
TestRailTestCasesSelectorWindow::TestRailTestCasesSelectorWindow(QWidget *parent) {
setupUi(this);
projectIDLineEdit->setValidator(new QIntValidator(1, 999, this));
}
void TestRailTestCasesSelectorWindow::reset() {
urlLineEdit->setDisabled(false);
userLineEdit->setDisabled(false);
passwordLineEdit->setDisabled(false);
projectIDLineEdit->setDisabled(false);
OKButton->setDisabled(true);
milestoneComboBox->setDisabled(true);
}
void TestRailTestCasesSelectorWindow::on_acceptButton_clicked() {
urlLineEdit->setDisabled(true);
userLineEdit->setDisabled(true);
passwordLineEdit->setDisabled(true);
projectIDLineEdit->setDisabled(true);
OKButton->setDisabled(false);
milestoneComboBox->setDisabled(false);
close();
}
void TestRailTestCasesSelectorWindow::on_OKButton_clicked() {
userCancelled = false;
close();
}
void TestRailTestCasesSelectorWindow::on_cancelButton_clicked() {
userCancelled = true;
close();
}
bool TestRailTestCasesSelectorWindow::getUserCancelled() {
return userCancelled;
}
void TestRailTestCasesSelectorWindow::setURL(const QString& user) {
urlLineEdit->setText(user);
}
QString TestRailTestCasesSelectorWindow::getURL() {
return urlLineEdit->text();
}
void TestRailTestCasesSelectorWindow::setUser(const QString& user) {
userLineEdit->setText(user);
}
QString TestRailTestCasesSelectorWindow::getUser() {
return userLineEdit->text();
}
QString TestRailTestCasesSelectorWindow::getPassword() {
return passwordLineEdit->text();
}
void TestRailTestCasesSelectorWindow::setProjectID(const int project) {
projectIDLineEdit->setText(QString::number(project));
}
int TestRailTestCasesSelectorWindow::getProjectID() {
return projectIDLineEdit->text().toInt();
}
void TestRailTestCasesSelectorWindow::setSuiteID(const int project) {
suiteIDLineEdit->setText(QString::number(project));
}
int TestRailTestCasesSelectorWindow::getSuiteID() {
return suiteIDLineEdit->text().toInt();
}
void TestRailTestCasesSelectorWindow::updateMilestoneComboBoxData(QStringList data) {
milestoneComboBox->insertItems(0, data);
}
int TestRailTestCasesSelectorWindow::getMilestoneID() {
return milestoneComboBox->currentIndex();
}

View file

@ -0,0 +1,50 @@
//
// TestRailTestCasesSelectorWindow.h
//
// Created by Nissim Hadar on 26 Jul 2017.
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_TestRailTestCasesSelectorWindow_h
#define hifi_TestRailTestCasesSelectorWindow_h
#include "ui_TestRailTestCasesSelectorWindow.h"
class TestRailTestCasesSelectorWindow : public QDialog, public Ui::TestRailTestCasesSelectorWindow {
Q_OBJECT
public:
TestRailTestCasesSelectorWindow(QWidget* parent = Q_NULLPTR);
void reset();
bool getUserCancelled();
void setURL(const QString& user);
QString getURL();
void setUser(const QString& user);
QString getUser();
QString getPassword();
void setProjectID(const int project);
int getProjectID();
void setSuiteID(const int project);
int getSuiteID();
bool userCancelled{ false };
void updateMilestoneComboBoxData(QStringList data);
int getMilestoneID();
private slots:
void on_acceptButton_clicked();
void on_OKButton_clicked();
void on_cancelButton_clicked();
};
#endif

View file

@ -1,17 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>TestRailSelectorWindow</class>
<widget class="QDialog" name="TestRailSelectorWindow">
<class>TestRailTestCasesSelectorWindow</class>
<widget class="QDialog" name="TestRailTestCasesSelectorWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>489</width>
<height>312</height>
<height>474</height>
</rect>
</property>
<property name="windowTitle">
<string>MismatchWindow</string>
<string>TestRail Test Case Selector Window</string>
</property>
<widget class="QLabel" name="errorLabel">
<property name="geometry">
@ -35,7 +35,7 @@
<property name="geometry">
<rect>
<x>70</x>
<y>115</y>
<y>125</y>
<width>121</width>
<height>20</height>
</rect>
@ -67,21 +67,14 @@
<string>TestRail URL</string>
</property>
</widget>
<widget class="QTextEdit" name="URLTextEdit">
<property name="geometry">
<rect>
<x>200</x>
<y>25</y>
<width>231</width>
<height>24</height>
</rect>
</property>
</widget>
<widget class="QPushButton" name="OKButton">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>120</x>
<y>240</y>
<y>420</y>
<width>93</width>
<height>28</height>
</rect>
@ -94,7 +87,7 @@
<property name="geometry">
<rect>
<x>280</x>
<y>240</y>
<y>420</y>
<width>93</width>
<height>28</height>
</rect>
@ -107,7 +100,7 @@
<property name="geometry">
<rect>
<x>200</x>
<y>115</y>
<y>120</y>
<width>231</width>
<height>24</height>
</rect>
@ -116,21 +109,11 @@
<enum>QLineEdit::Password</enum>
</property>
</widget>
<widget class="QTextEdit" name="userTextEdit">
<property name="geometry">
<rect>
<x>200</x>
<y>70</y>
<width>231</width>
<height>24</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>70</x>
<y>70</y>
<y>75</y>
<width>121</width>
<height>20</height>
</rect>
@ -144,11 +127,11 @@
<string>TestRail User</string>
</property>
</widget>
<widget class="QLineEdit" name="projectLineEdit">
<widget class="QLineEdit" name="projectIDLineEdit">
<property name="geometry">
<rect>
<x>200</x>
<y>160</y>
<y>170</y>
<width>231</width>
<height>24</height>
</rect>
@ -161,7 +144,7 @@
<property name="geometry">
<rect>
<x>70</x>
<y>160</y>
<y>175</y>
<width>121</width>
<height>20</height>
</rect>
@ -172,11 +155,126 @@
</font>
</property>
<property name="text">
<string>TestRail Project</string>
<string>TestRail Project ID</string>
</property>
</widget>
<widget class="QPushButton" name="acceptButton">
<property name="geometry">
<rect>
<x>200</x>
<y>270</y>
<width>231</width>
<height>28</height>
</rect>
</property>
<property name="text">
<string>Accept</string>
</property>
</widget>
<widget class="QComboBox" name="milestoneComboBox">
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>270</x>
<y>350</y>
<width>161</width>
<height>22</height>
</rect>
</property>
</widget>
<widget class="QLabel" name="milestoneLabel">
<property name="enabled">
<bool>true</bool>
</property>
<property name="geometry">
<rect>
<x>140</x>
<y>350</y>
<width>121</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>TestRail Milestone</string>
</property>
</widget>
<widget class="QLineEdit" name="urlLineEdit">
<property name="geometry">
<rect>
<x>200</x>
<y>20</y>
<width>231</width>
<height>24</height>
</rect>
</property>
<property name="echoMode">
<enum>QLineEdit::Normal</enum>
</property>
</widget>
<widget class="QLineEdit" name="userLineEdit">
<property name="geometry">
<rect>
<x>200</x>
<y>70</y>
<width>231</width>
<height>24</height>
</rect>
</property>
<property name="echoMode">
<enum>QLineEdit::Normal</enum>
</property>
</widget>
<widget class="QLineEdit" name="suiteIDLineEdit">
<property name="geometry">
<rect>
<x>200</x>
<y>215</y>
<width>231</width>
<height>24</height>
</rect>
</property>
<property name="echoMode">
<enum>QLineEdit::Normal</enum>
</property>
</widget>
<widget class="QLabel" name="label_5">
<property name="geometry">
<rect>
<x>70</x>
<y>220</y>
<width>121</width>
<height>20</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>TestRail Suite ID</string>
</property>
</widget>
</widget>
<layoutdefault spacing="6" margin="11"/>
<tabstops>
<tabstop>urlLineEdit</tabstop>
<tabstop>userLineEdit</tabstop>
<tabstop>passwordLineEdit</tabstop>
<tabstop>projectIDLineEdit</tabstop>
<tabstop>suiteIDLineEdit</tabstop>
<tabstop>acceptButton</tabstop>
<tabstop>milestoneComboBox</tabstop>
<tabstop>OKButton</tabstop>
<tabstop>cancelButton</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>