Can create list of highest level sections.

This commit is contained in:
NissimHadar 2018-08-01 15:13:44 -07:00
parent 64f651a266
commit 9957fc9474
9 changed files with 139 additions and 84 deletions

View file

@ -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) {

View file

@ -227,8 +227,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()) {
@ -264,8 +263,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 +300,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);
@ -364,7 +358,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 +369,9 @@ void TestRailInterface::updateMilestonesComboData(int exitCode, QProcess::ExitSt
createAddTestCasesPythonScript(_testDirectory, _userGitHub, _branchGitHub); createAddTestCasesPythonScript(_testDirectory, _userGitHub, _branchGitHub);
} }
void TestRailInterface::updateSectionsComboData(int exitCode, QProcess::ExitStatus exitStatus) {
}
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 +405,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,7 +415,6 @@ 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;
@ -435,7 +428,8 @@ void TestRailInterface::createTestSuitePython(const QString& testDirectory,
} }
_pythonCommand = _pythonPath + "/" + pythonExe; _pythonCommand = _pythonPath + "/" + pythonExe;
} else { } else {
QMessageBox::critical(0, "PYTHON_PATH not defined", "Please set PYTHON_PATH to directory containing the Python executable"); QMessageBox::critical(0, "PYTHON_PATH not defined",
"Please set PYTHON_PATH to directory containing the Python executable");
return; return;
} }
@ -451,7 +445,6 @@ void TestRailInterface::createTestSuitePython(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'");
@ -464,7 +457,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
@ -478,7 +472,8 @@ void TestRailInterface::createTestSuitePython(const QString& testDirectory,
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);
} }
@ -551,7 +546,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 +591,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 +615,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 +628,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."));
@ -678,8 +677,8 @@ 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.");
@ -693,8 +692,11 @@ void TestRailInterface::processTestPython(const QString& fullDirectory,
<< "\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 "
"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"; << "}\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 +705,65 @@ void TestRailInterface::processTestPython(const QString& fullDirectory,
void TestRailInterface::requestTestRailRunDataFromUser() { void TestRailInterface::requestTestRailRunDataFromUser() {
_testRailRunSelectorWindow.reset(); _testRailRunSelectorWindow.reset();
_testRailRunSelectorWindow.exec(); _testRailRunSelectorWindow.exec();
if (_testRailRunSelectorWindow.getUserCancelled()) {
return;
} }
void TestRailInterface::getTestCasesFromTestRail() { _url = _testRailRunSelectorWindow.getURL() + "/";
_user = _testRailRunSelectorWindow.getUser();
_password = _testRailRunSelectorWindow.getPassword();
////_password = "tutKA76";
_projectID = QString::number(_testRailRunSelectorWindow.getProjectID());
_suiteID = QString::number(_testRailRunSelectorWindow.getSuiteID());
} }
void TestRailInterface::createTestRailRun() { 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(const QString& outputDirectory) {
_outputDirectory = outputDirectory;
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();
} }

View file

@ -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,9 @@ 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);
private: private:
// HighFidelity Interface project ID in TestRail // HighFidelity Interface project ID in TestRail

View file

@ -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();
} }

View file

@ -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();

View file

@ -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>

View file

@ -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();
} }

View file

@ -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:

View file

@ -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>