Merge pull request #13805 from NissimHadar/exportToTestRail1
Auto-Tester export to TestRail
BIN
tools/auto-tester/Create.PNG
Normal file
After Width: | Height: | Size: 12 KiB |
BIN
tools/auto-tester/Evaluate.PNG
Normal file
After Width: | Height: | Size: 9.1 KiB |
197
tools/auto-tester/README.md
Normal file
|
@ -0,0 +1,197 @@
|
|||
# Auto Tester
|
||||
|
||||
The auto-tester is a stand alone application that provides a mechanism for regression testing. The general idea is simple:
|
||||
* Each test folder has a script that produces a set of snapshots.
|
||||
* The snapshots are compared to a 'canonical' set of images that have been produced beforehand.
|
||||
* The result, if any test failed, is a zipped folder describing the failure.
|
||||
|
||||
Auto-tester has 4 functions, separated into 4 tabs:
|
||||
1. Creating tests, MD files and recursive scripts
|
||||
2. Evaluating the results of running tests
|
||||
3. TestRail interface
|
||||
4. Windows task bar utility (Windows only)
|
||||
## Installation
|
||||
### Executable
|
||||
1. Download the installer by browsing to [here](<https://hifi-content.s3.amazonaws.com/nissim/autoTester/AutoTester-Installer.exe>).
|
||||
2. Double click on the installer and install to a convenient location
|
||||

|
||||
3. To run the auto-tester, double click **auto-tester.exe**.
|
||||
### Python
|
||||
The TestRail interface requires Python 3 to be installed. Auto-Tester has been tested with Python 3.7.0 but should work with newer versions.
|
||||
|
||||
Python 3 can be downloaded from:
|
||||
1. Windows installer <https://www.python.org/downloads/>
|
||||
2. Linux (source) <https://www.python.org/downloads/release/python-370/> (**Gzipped source tarball**)
|
||||
3. Mac <https://www.python.org/downloads/release/python-370/> (**macOS 64-bit/32-bit installer** or **macOS 64-bit/32-bit installer**)
|
||||
|
||||
After installation - create an environment variable called PYTHON_PATH and set it to the folder containing the Python executable.
|
||||
# Create
|
||||

|
||||
|
||||
The Create tab provides functions to create tests from snapshots, MD files, a test outline and recursive scripts.
|
||||
## Create Tests
|
||||
### Usage
|
||||
This function is used to create/update Expected Images after a successful run of a test, or multiple tests.
|
||||
|
||||
The user will be asked for the snapshot folder and then the tests root folder. All snapshots located in the snapshot folder will be used to create or update the expected images in the relevant tests.
|
||||
### Details
|
||||
As an example - if the snapshots folder contains an image named `tests.content.entity.zone.zoneOrientation.00003.png`, then this file will be copied to `tests/contente/enity/zone/zoneOrientation/ExpectedImage0003.png`.
|
||||
## Create MD file
|
||||
### Usage
|
||||
This function creates a file named `test.md` from a `test.js` script. The user will be asked for the folder containing the test script:
|
||||
### Details
|
||||
The process to produce the MD file is a simplistic parse of the test script.
|
||||
- The string in the `autoTester.perform(...)` function call will be the title of the file
|
||||
|
||||
- Instructions to run the script are then provided:
|
||||
|
||||
**Run this script URL: [Manual]() [Auto]()(from menu/Edit/Open and Run scripts from URL...).**
|
||||
|
||||
- The step description is the string in the addStep/addStepStepSnapshot commands
|
||||
|
||||
- Image links are provided where applicable to the local Expected Images files
|
||||
## Create all MD files
|
||||
### Usage
|
||||
This function creates all MD files recursively from the user-selected root folder. This can be any folder in the tests hierarchy (e.g. all engine\material tests).
|
||||
|
||||
The file provides a hierarchial list of all the tests
|
||||
## Create Tests Outline
|
||||
### Usage
|
||||
This function creates an MD file in the (user-selected) tests root folder. The file provides links to both the tests and the MD files.
|
||||
## Create Recursive Script
|
||||
### Usage
|
||||
After the user selects a folder within the tests hierarchy, a script is created, named `testRecursive.js`. This script calls all `test.js` scripts in the subfolders.
|
||||
### Details
|
||||
The various scripts are called in alphabetical order.
|
||||
|
||||
An example of a recursive script is as follows:
|
||||
```
|
||||
// This is an automatically generated file, created by auto-tester on Jul 5 2018, 10:19
|
||||
|
||||
PATH_TO_THE_REPO_PATH_UTILS_FILE = "https://raw.githubusercontent.com/highfidelity/hifi_tests/master/tests/utils/branchUtils.js";
|
||||
Script.include(PATH_TO_THE_REPO_PATH_UTILS_FILE);
|
||||
var autoTester = createAutoTester(Script.resolvePath("."));
|
||||
|
||||
var testsRootPath = autoTester.getTestsRootPath();
|
||||
|
||||
if (typeof Test !== 'undefined') {
|
||||
Test.wait(10000);
|
||||
};
|
||||
|
||||
autoTester.enableRecursive();
|
||||
autoTester.enableAuto();
|
||||
|
||||
Script.include(testsRootPath + "content/overlay/layer/drawInFront/shape/test.js");
|
||||
Script.include(testsRootPath + "content/overlay/layer/drawInFront/model/test.js");
|
||||
Script.include(testsRootPath + "content/overlay/layer/drawHUDLayer/test.js");
|
||||
|
||||
autoTester.runRecursive();
|
||||
```
|
||||
## Create all Recursive Scripts
|
||||
### Usage
|
||||
In this case all recursive scripts, from the selected folder down, are created.
|
||||
|
||||
Running this function in the tests root folder will create (or update) all the recursive scripts.
|
||||
# Evaluate
|
||||

|
||||
|
||||
The Evaluate tab provides a single function - evaluating the results of a test run.
|
||||
|
||||
A checkbox (defaulting to checked) runs the evaluation in interactive mode. In this mode - every failure is shown to the user, who can then decide whether to pass the test, fail it or abort the whole evaluation.
|
||||
|
||||
If any tests have failed, then a zipped folder will be created in the snapshots folder, with a description of each failed step in each test.
|
||||
### Usage
|
||||
Before starting the evaluation, make sure the GitHub user and branch are set correctly. The user should not normally be changed, but the branch may need to be set to the appropriate RC.
|
||||
|
||||
After setting the checkbox as required and pressing Evaluate - the user will be asked for the snapshots folder.
|
||||
### Details
|
||||
Evaluation proceeds in a number of steps:
|
||||
|
||||
1. A folder is created to store any failures
|
||||
|
||||
1. The expecetd images are download from GitHub. They are named slightly differently from the snapshots (e.g. `tests.engine.render.effect.highlight.coverage.00000.png` and `tests.engine.render.effect.highlight.coverage.00000_EI.png`).
|
||||
|
||||
1. The images are then pair-wise compared, using the SSIM algorithm. A fixed threshold is used to define a mismatch.
|
||||
|
||||
1. In interactive mode - a window is opened showing the expected image, actual image, difference image and error:
|
||||

|
||||
|
||||
1. If not in interactive mode, or the user has defined the results as an error, an error is written into the error folder. The error itself is a folder with the 3 images and a small text file containing details.
|
||||
|
||||
1. At the end of the test, the folder is zipped and the original folder is deleted. If there are no errors then the zipped folder will be empty.
|
||||
# TestRail
|
||||

|
||||
|
||||
Before updating TestRail, make sure the GitHub user and branch are set correctly. The user should not normally be changed, but the branch may need to be set to the appropriate RC.
|
||||
|
||||
Any access to TestRail will require the TestRail account (default is High Fidelity's account), a user-name and a password:
|
||||
|
||||

|
||||
|
||||
- The default test rail user is shown, and can be changed as needed.
|
||||
- The username is usually the user's email.
|
||||
- The Project ID defaults to 14 - Interface.
|
||||
- The Suite ID defaults to 1147 - Renderong.
|
||||
- The TestRail page provides 3 functions for writing to TestRail.
|
||||
## Create Test Cases
|
||||
### Usage
|
||||
This function can either create an XML file that can then be imported into TestRail through TestRail itself, or automatically create the appropriate TestRail Sections.
|
||||
|
||||
The user will be first asked for the tests root folder and a folder to store temporary files (this is the output folder).
|
||||
|
||||
If XML has been selected, then the XML file will be created in the output folder.
|
||||
|
||||
If Python is selected, the user will then be prompted for TestRail data. After pressing `Accept` - the Release combo will be populated (as it needs to be read from TestRail).
|
||||
|
||||
After selecting the appropriate Release, press OK. The Python script will be created in the output folder, and the user will be prompted to run it.
|
||||
|
||||
A busy window will appear until the process is complete.
|
||||
### Details
|
||||
A number of Python scripts are created:
|
||||
- `testrail.py` is the TestRail interface code.
|
||||
- `stack.py` is a simple stack class
|
||||
- `getReleases.py` reads the release names from TestRail
|
||||
- `addTestCases` is the script that writes to TestRail.
|
||||
|
||||
In addition - a file containing all the releases will be created - `releases.txt`
|
||||
## Create Run
|
||||
A Run is created from previously created Test Cases.
|
||||
|
||||
The user will first be prompted for a temporary folder (for the Python scripts).
|
||||
|
||||
After entering TestRail data and pressing `Accept` - the Sections combo will be populated (as it needs to be read from TestRail).
|
||||
|
||||
After selecting the appropriate Section, press OK. The Python script will be created in the output folder, and the user will be prompted to run it.
|
||||
|
||||
A busy window will appear until the process is complete.
|
||||
### Details
|
||||
A number of Python scripts are created:
|
||||
- `testrail.py` is the TestRail interface code.
|
||||
- `stack.py` is a simple stack class
|
||||
- `getSections.py` reads the release names from TestRail
|
||||
- `addRun` is the script that writes to TestRail.
|
||||
|
||||
In addition - a file containing all the releases will be created - `sections.txt`
|
||||
## Update Run Results
|
||||
This function updates a Run with the results of an automated test.
|
||||
|
||||
The user will first be prompted to enter the zipped results folder and a folder to store temporary files (this is the output folder).
|
||||
|
||||
After entering TestRail data and pressing `Accept` - the Run combo will be populated (as it needs to be read from TestRail).
|
||||
|
||||
After selecting the appropriate Run, press OK. The Python script will be created in the output folder, and the user will be prompted to run it.
|
||||
|
||||
A busy window will appear until the process is complete.
|
||||
### Details
|
||||
A number of Python scripts are created:
|
||||
- `testrail.py` is the TestRail interface code.
|
||||
- `getRuns.py` reads the release names from TestRail
|
||||
- `addRun` is the script that writes to TestRail.
|
||||
|
||||
In addition - a file containing all the releases will be created - `runs.txt`
|
||||
# Windows
|
||||

|
||||
|
||||
This tab is Windows-specific. It provides buttons to hide and show the task bar.
|
||||
|
||||
The task bar should be hidden for all tests that use the primary camera. This is required to ensure that the snapshots are the right size.
|
|
@ -1,7 +0,0 @@
|
|||
After building auto-tester, it needs to be deployed to Amazon SW
|
||||
|
||||
* In folder hifi/build/tools/auto-tester
|
||||
* Right click on the Release folder
|
||||
* Select 7-Zip -> Add to archive
|
||||
* Select Option ```Create SFX archive``` to create Release.exe
|
||||
* Use Cyberduck (or any other AWS S3 client) to copy Release.exe to hifi-content/nissim/autoTester/
|
BIN
tools/auto-tester/TestRail.PNG
Normal file
After Width: | Height: | Size: 11 KiB |
BIN
tools/auto-tester/TestRailSelector.PNG
Normal file
After Width: | Height: | Size: 10 KiB |
BIN
tools/auto-tester/Windows.PNG
Normal file
After Width: | Height: | Size: 9.6 KiB |
BIN
tools/auto-tester/autoTesterMismatchExample.PNG
Normal file
After Width: | Height: | Size: 476 KiB |
BIN
tools/auto-tester/setup_7z.PNG
Normal file
After Width: | Height: | Size: 4 KiB |
|
@ -27,8 +27,8 @@ Test::Test() {
|
|||
_mismatchWindow.setModal(true);
|
||||
|
||||
if (autoTester) {
|
||||
autoTester->setUserText("highfidelity");
|
||||
autoTester->setBranchText("master");
|
||||
autoTester->setUserText(GIT_HUB_DEFAULT_USER);
|
||||
autoTester->setBranchText(GIT_HUB_DEFAULT_BRANCH);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -49,9 +49,7 @@ void Test::zipAndDeleteTestResultsFolder() {
|
|||
}
|
||||
|
||||
QDir testResultsFolder(_testResultsFolderPath);
|
||||
if (!testResultsFolder.isEmpty()) {
|
||||
JlCompress::compressDir(_testResultsFolderPath + ".zip", _testResultsFolderPath);
|
||||
}
|
||||
JlCompress::compressDir(_testResultsFolderPath + ".zip", _testResultsFolderPath);
|
||||
|
||||
testResultsFolder.removeRecursively();
|
||||
|
||||
|
@ -132,9 +130,7 @@ void Test::appendTestResultsToFile(const QString& _testResultsFolderPath, TestFa
|
|||
exit(-1);
|
||||
}
|
||||
|
||||
QString err = QString::number(testFailure._error).left(6);
|
||||
|
||||
QString failureFolderPath { _testResultsFolderPath + "/" + err + "-Failure_" + QString::number(_index) + "--" + testFailure._actualImageFilename.left(testFailure._actualImageFilename.length() - 4) };
|
||||
QString failureFolderPath { _testResultsFolderPath + "/Failure_" + QString::number(_index) + "--" + testFailure._actualImageFilename.left(testFailure._actualImageFilename.length() - 4) };
|
||||
if (!QDir().mkdir(failureFolderPath)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "Failed to create folder " + failureFolderPath);
|
||||
exit(-1);
|
||||
|
@ -832,7 +828,7 @@ void Test::createTestRailTestCases() {
|
|||
QFileDialog::getExistingDirectory(nullptr, "Please select the tests root folder", parent, QFileDialog::ShowDirsOnly);
|
||||
|
||||
// If user cancelled then restore previous selection and return
|
||||
if (_testDirectory == "") {
|
||||
if (_testDirectory.isNull()) {
|
||||
_testDirectory = previousSelection;
|
||||
return;
|
||||
}
|
||||
|
@ -841,7 +837,7 @@ void Test::createTestRailTestCases() {
|
|||
nullptr, QFileDialog::ShowDirsOnly);
|
||||
|
||||
// If user cancelled then return
|
||||
if (outputDirectory == "") {
|
||||
if (outputDirectory.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -857,9 +853,30 @@ void Test::createTestRailTestCases() {
|
|||
void Test::createTestRailRun() {
|
||||
QString outputDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select a folder to store generated files in",
|
||||
nullptr, QFileDialog::ShowDirsOnly);
|
||||
|
||||
if (outputDirectory.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_testRailInterface.createTestRailRun(outputDirectory);
|
||||
}
|
||||
|
||||
void Test::updateTestRailRunResult() {
|
||||
QString testResults = QFileDialog::getOpenFileName(nullptr, "Please select the zipped test results to update from", nullptr,
|
||||
"Zipped Test Results (*.zip)");
|
||||
if (testResults.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
QString tempDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select a folder to store temporary files in",
|
||||
nullptr, QFileDialog::ShowDirsOnly);
|
||||
if (tempDirectory.isNull()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_testRailInterface.updateTestRailRunResults(testResults, tempDirectory);
|
||||
}
|
||||
|
||||
QStringList Test::createListOfAll_imagesInDirectory(const QString& imageFormat, const QString& pathToImageDirectory) {
|
||||
_imageDirectory = QDir(pathToImageDirectory);
|
||||
QStringList nameFilters;
|
||||
|
|
|
@ -51,14 +51,16 @@ public:
|
|||
void createRecursiveScript(const QString& topLevelDirectory, bool interactiveMode);
|
||||
|
||||
void createTests();
|
||||
|
||||
void createTestsOutline();
|
||||
|
||||
void createMDFile();
|
||||
void createAllMDFiles();
|
||||
void createMDFile(const QString& topLevelDirectory);
|
||||
|
||||
void createTestsOutline();
|
||||
|
||||
void createTestRailTestCases();
|
||||
void createTestRailRun();
|
||||
void updateTestRailRunResult();
|
||||
|
||||
bool compareImageLists(bool isInteractiveMode, QProgressBar* progressBar);
|
||||
|
||||
|
@ -115,6 +117,8 @@ private:
|
|||
QStringList _resultImagesFullFilenames;
|
||||
|
||||
// Used for accessing GitHub
|
||||
const QString GIT_HUB_DEFAULT_USER{ "highfidelity" };
|
||||
const QString GIT_HUB_DEFAULT_BRANCH{ "master" };
|
||||
const QString GIT_HUB_REPOSITORY{ "hifi_tests" };
|
||||
|
||||
const QString DATETIME_FORMAT{ "yyyy-MM-dd_hh-mm-ss" };
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
#include "TestRailInterface.h"
|
||||
#include "Test.h"
|
||||
|
||||
#include <quazip5/quazip.h>
|
||||
#include <quazip5/JlCompress.h>
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QFile>
|
||||
#include <QMessageBox>
|
||||
|
@ -20,22 +23,35 @@ TestRailInterface::TestRailInterface() {
|
|||
_testRailTestCasesSelectorWindow.setURL("https://highfidelity.testrail.net");
|
||||
////_testRailTestCasesSelectorWindow.setURL("https://nissimhadar.testrail.io");
|
||||
_testRailTestCasesSelectorWindow.setUser("@highfidelity.io");
|
||||
////_testRailSelectorWindow.setUser("nissim.hadar@gmail.com");
|
||||
////_testRailTestCasesSelectorWindow.setUser("nissim.hadar@gmail.com");
|
||||
|
||||
_testRailTestCasesSelectorWindow.setProjectID(INTERFACE_PROJECT_ID);
|
||||
////_testRailSelectorWindow.setProject(1);
|
||||
////_testRailTestCasesSelectorWindow.setProjectID(2);
|
||||
|
||||
_testRailTestCasesSelectorWindow.setSuiteID(INTERFACE_SUITE_ID);
|
||||
////_testRailTestCasesSelectorWindow.setSuiteID(2);
|
||||
|
||||
_testRailRunSelectorWindow.setURL("https://highfidelity.testrail.net");
|
||||
////_testRailRunSelectorWindow.setURL("https://nissimhadar.testrail.io");
|
||||
_testRailRunSelectorWindow.setUser("@highfidelity.io");
|
||||
////_testRailSelectorWindow.setUser("nissim.hadar@gmail.com");
|
||||
////_testRailRunSelectorWindow.setUser("nissim.hadar@gmail.com");
|
||||
|
||||
_testRailRunSelectorWindow.setProjectID(INTERFACE_PROJECT_ID);
|
||||
////_testRailSelectorWindow.setProject(1);
|
||||
////_testRailRunSelectorWindow.setProjectID(2);
|
||||
|
||||
_testRailRunSelectorWindow.setSuiteID(INTERFACE_SUITE_ID);
|
||||
////_testRailRunSelectorWindow.setSuiteID(2);
|
||||
|
||||
_testRailResultsSelectorWindow.setURL("https://highfidelity.testrail.net");
|
||||
////_testRailResultsSelectorWindow.setURL("https://nissimhadar.testrail.io");
|
||||
_testRailResultsSelectorWindow.setUser("@highfidelity.io");
|
||||
////_testRailResultsSelectorWindow.setUser("nissim.hadar@gmail.com");
|
||||
|
||||
_testRailResultsSelectorWindow.setProjectID(INTERFACE_PROJECT_ID);
|
||||
////_testRailResultsSelectorWindow.setProjectID(2);
|
||||
|
||||
_testRailResultsSelectorWindow.setSuiteID(INTERFACE_SUITE_ID);
|
||||
////_testRailResultsSelectorWindow.setSuiteID(2);
|
||||
}
|
||||
|
||||
QString TestRailInterface::getObject(const QString& path) {
|
||||
|
@ -212,21 +228,59 @@ void TestRailInterface::createStackDotPyScript() {
|
|||
file.close();
|
||||
}
|
||||
|
||||
void TestRailInterface::requestTestRailTestCasesDataFromUser() {
|
||||
bool TestRailInterface::requestTestRailTestCasesDataFromUser() {
|
||||
// Make sure correct fields are enabled before calling
|
||||
_testRailTestCasesSelectorWindow.reset();
|
||||
_testRailTestCasesSelectorWindow.exec();
|
||||
|
||||
if (_testRailTestCasesSelectorWindow.getUserCancelled()) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
_url = _testRailTestCasesSelectorWindow.getURL() + "/";
|
||||
_user = _testRailTestCasesSelectorWindow.getUser();
|
||||
_password = _testRailTestCasesSelectorWindow.getPassword();
|
||||
////_password = "tutKA76";
|
||||
////_password = "tutKA76";////
|
||||
_projectID = QString::number(_testRailTestCasesSelectorWindow.getProjectID());
|
||||
_suiteID = QString::number(_testRailTestCasesSelectorWindow.getSuiteID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestRailInterface::requestTestRailRunDataFromUser() {
|
||||
_testRailRunSelectorWindow.reset();
|
||||
_testRailRunSelectorWindow.exec();
|
||||
|
||||
if (_testRailRunSelectorWindow.getUserCancelled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_url = _testRailRunSelectorWindow.getURL() + "/";
|
||||
_user = _testRailRunSelectorWindow.getUser();
|
||||
_password = _testRailRunSelectorWindow.getPassword();
|
||||
////_password = "tutKA76";////
|
||||
_projectID = QString::number(_testRailRunSelectorWindow.getProjectID());
|
||||
_suiteID = QString::number(_testRailRunSelectorWindow.getSuiteID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestRailInterface::requestTestRailResultsDataFromUser() {
|
||||
_testRailResultsSelectorWindow.reset();
|
||||
_testRailResultsSelectorWindow.exec();
|
||||
|
||||
if (_testRailResultsSelectorWindow.getUserCancelled()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
_url = _testRailResultsSelectorWindow.getURL() + "/";
|
||||
_user = _testRailResultsSelectorWindow.getUser();
|
||||
_password = _testRailResultsSelectorWindow.getPassword();
|
||||
////_password = "tutKA76";////
|
||||
_projectID = QString::number(_testRailResultsSelectorWindow.getProjectID());
|
||||
_suiteID = QString::number(_testRailResultsSelectorWindow.getSuiteID());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TestRailInterface::isAValidTestDirectory(const QString& directory) {
|
||||
|
@ -307,7 +361,7 @@ void TestRailInterface::createAddTestCasesPythonScript(const QString& testDirect
|
|||
|
||||
// top-level section
|
||||
stream << "data = { 'name': '"
|
||||
<< "Test Suite - " << QDateTime::currentDateTime().toString("yyyy-MM-ddTHH:mm") + "', "
|
||||
<< "Test Section - " << QDateTime::currentDateTime().toString("yyyy-MM-ddTHH:mm") + "', "
|
||||
<< "'suite_id': " + _suiteID + "}\n";
|
||||
|
||||
stream << "section = client.send_post('add_section/' + str(" << _projectID << "), data)\n";
|
||||
|
@ -320,8 +374,8 @@ void TestRailInterface::createAddTestCasesPythonScript(const QString& testDirect
|
|||
|
||||
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()) {
|
||||
QMessageBox::Yes | QMessageBox::No).exec()
|
||||
) {
|
||||
QProcess* process = new QProcess();
|
||||
connect(process, &QProcess::started, this, [=]() { _busyWindow.exec(); });
|
||||
|
||||
|
@ -333,7 +387,7 @@ void TestRailInterface::createAddTestCasesPythonScript(const QString& testDirect
|
|||
}
|
||||
}
|
||||
|
||||
void TestRailInterface::updateMilestonesComboData(int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
void TestRailInterface::updateReleasesComboData(int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
// Quit if user has previously cancelled
|
||||
if (_testRailTestCasesSelectorWindow.getUserCancelled()) {
|
||||
return;
|
||||
|
@ -342,41 +396,38 @@ void TestRailInterface::updateMilestonesComboData(int exitCode, QProcess::ExitSt
|
|||
// 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");
|
||||
"Could not get 'added to release' data from TestRail");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Create map of milestones from the file created by the process
|
||||
_milestoneNames.clear();
|
||||
// Create map of releases from the file created by the process
|
||||
_releaseNames.clear();
|
||||
|
||||
QString filename = _outputDirectory + "/milestones.txt";
|
||||
QString filename = _outputDirectory + "/releases.txt";
|
||||
if (!QFile::exists(filename)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not find milestones.txt in " + _outputDirectory);
|
||||
"Could not find releases.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");
|
||||
"Could not open " + _outputDirectory + "/releases.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];
|
||||
|
||||
_releaseNames << line;
|
||||
line = in.readLine();
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
// Update the combo
|
||||
_testRailTestCasesSelectorWindow.updateMilestonesComboBoxData(_milestoneNames);
|
||||
_testRailTestCasesSelectorWindow.updateReleasesComboBoxData(_releaseNames);
|
||||
|
||||
_testRailTestCasesSelectorWindow.exec();
|
||||
|
||||
|
@ -387,6 +438,167 @@ void TestRailInterface::updateMilestonesComboData(int exitCode, QProcess::ExitSt
|
|||
createAddTestCasesPythonScript(_testDirectory, _userGitHub, _branchGitHub);
|
||||
}
|
||||
|
||||
void TestRailInterface::addRun() {
|
||||
QString filename = _outputDirectory + "/addRun.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 " + filename);
|
||||
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";
|
||||
|
||||
// A test suite is a forest. Each node is a section and leaves are either sections or test cases
|
||||
// The user has selected a root for the run
|
||||
// To find the cases in this tree we need all the sections in the tree
|
||||
// These are found by building a set of all relevant sections. The first section is the selected root
|
||||
// As the sections are in an ordered array we use the following snippet to find the relevant sections:
|
||||
// initialize section set with the root
|
||||
// for each section in the ordered array of sections in the suite
|
||||
// if the parent of the section is in the section set then
|
||||
// add this section to the section set
|
||||
//
|
||||
stream << "sections = client.send_get('get_sections/" + _projectID + "&suite_id=" + _suiteID + "')\n\n";
|
||||
|
||||
int sectionID = _sectionIDs[_testRailRunSelectorWindow.getSectionID()];
|
||||
|
||||
stream << "relevantSections = { " + QString::number(sectionID) + " }\n";
|
||||
stream << "for section in sections:\n";
|
||||
stream << "\tif section['parent_id'] in relevantSections:\n";
|
||||
stream << "\t\trelevantSections.add(section['id'])\n\n";
|
||||
|
||||
// We now loop over each section in the set and collect the cases into an array
|
||||
stream << "cases = []\n";
|
||||
stream << "for section_id in relevantSections:\n";
|
||||
stream << "\tcases = cases + client.send_get('get_cases/" + _projectID + "&suite_id=" + _suiteID + "§ion_id=' + str(section_id))\n\n";
|
||||
|
||||
// To create a run we need an array of the relevant case ids
|
||||
stream << "case_ids = []\n";
|
||||
stream << "for case in cases:\n";
|
||||
stream << "\tcase_ids.append(case['id'])\n\n";
|
||||
|
||||
// Now, we can create the run
|
||||
stream << "data = { 'name': '" + _sectionNames[_testRailRunSelectorWindow.getSectionID()].replace("Section", "Run") +
|
||||
"', 'suite_id': " + _suiteID +
|
||||
", 'include_all': False, 'case_ids': case_ids}\n";
|
||||
|
||||
stream << "run = client.send_post('add_run/" + _projectID + "', data)\n";
|
||||
|
||||
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 + "/addRun.py";
|
||||
process->start(_pythonCommand, parameters);
|
||||
}
|
||||
}
|
||||
void TestRailInterface::updateRunWithResults() {
|
||||
QString filename = _outputDirectory + "/updateRunWithResults.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 " + filename);
|
||||
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";
|
||||
|
||||
// It is assumed that all the tests that haven't failed have passed
|
||||
// The failed tests are read, formatted and inserted into a set
|
||||
// A failure named 'Failure_1--tests.content.entity.material.apply.avatars.00000' is formatted to 'content/entity/material/apply/avatars'
|
||||
// This is the name of the test in TestRail
|
||||
stream << "from os import listdir\n";
|
||||
|
||||
stream << "failed_tests = set()\n";
|
||||
|
||||
stream << "for entry in listdir('" + _outputDirectory + "/" + tempName + "'):\n";
|
||||
stream << "\tparts = entry.split('--tests.')[1].split('.')\n";
|
||||
stream << "\tfailed_test = parts[0]\n";
|
||||
stream << "\tfor i in range(1, len(parts) - 1):\n";
|
||||
stream << "\t\tfailed_test = failed_test + '/' + parts[i]\n";
|
||||
|
||||
stream << "\tfailed_tests.add(failed_test)\n\n";
|
||||
|
||||
// Initialize the array of results that will be eventually used to update TestRail
|
||||
stream << "status_ids = []\n";
|
||||
stream << "case_ids = []\n";
|
||||
|
||||
int runID = _runIDs[_testRailResultsSelectorWindow.getRunID()];
|
||||
stream << "tests = client.send_get('get_tests/" + QString::number(runID) + "')\n\n";
|
||||
stream << "for test in tests:\n";
|
||||
|
||||
// status_id's: 1 - Passed
|
||||
// 2 - Blocked
|
||||
// 3 - Untested
|
||||
// 4 - Retest
|
||||
// 5 - Failed
|
||||
stream << "\tstatus_id = 1\n";
|
||||
stream << "\tif test['title'] in failed_tests:\n";
|
||||
stream << "\t\tstatus_id = 5\n";
|
||||
stream << "\tcase_ids.append(test['case_id'])\n";
|
||||
stream << "\tstatus_ids.append(status_id)\n\n";
|
||||
|
||||
// We can now update the test (note that all tests need to be updated)
|
||||
// An example request is as follows:
|
||||
//
|
||||
// "results" : [
|
||||
// { 'case_id': 1, 'status_id': 5 },
|
||||
// { 'case_id': 2, 'status_id': 1 }
|
||||
// ]
|
||||
//
|
||||
stream << "results = []\n";
|
||||
stream << "for i in range(len(case_ids)):\n";
|
||||
stream << "\tresults.append({'case_id': case_ids[i], 'status_id': status_ids[i] })\n\n";
|
||||
|
||||
stream << "data = { 'results': results }\n";
|
||||
stream << "section = client.send_post('add_results_for_cases/' + str(" << runID << "), data)\n";
|
||||
|
||||
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 + "/updateRunWithResults.py";
|
||||
process->start(_pythonCommand, parameters);
|
||||
}
|
||||
}
|
||||
|
||||
void TestRailInterface::updateSectionsComboData(int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
// Quit if user has previously cancelled
|
||||
if (_testRailRunSelectorWindow.getUserCancelled()) {
|
||||
|
@ -413,7 +625,7 @@ void TestRailInterface::updateSectionsComboData(int exitCode, QProcess::ExitStat
|
|||
QFile file(filename);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not open " + _outputDirectory + "/sections.txt");
|
||||
"Could not open " + filename);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
@ -425,7 +637,7 @@ void TestRailInterface::updateSectionsComboData(int exitCode, QProcess::ExitStat
|
|||
QString section = line.left(line.lastIndexOf(" "));
|
||||
QString id = line.right(line.length() - line.lastIndexOf(" ") - 1);
|
||||
|
||||
_sections[section] = id.toInt();
|
||||
_sectionIDs.push_back(id.toInt());
|
||||
_sectionNames << section;
|
||||
|
||||
line = in.readLine();
|
||||
|
@ -442,11 +654,73 @@ void TestRailInterface::updateSectionsComboData(int exitCode, QProcess::ExitStat
|
|||
return;
|
||||
}
|
||||
|
||||
////createAddTestCasesPythonScript(_testDirectory, _userGitHub, _branchGitHub);
|
||||
// The test cases are now read from TestRail
|
||||
// When this is complete, the Run can be created
|
||||
addRun();
|
||||
}
|
||||
|
||||
void TestRailInterface::getMilestonesFromTestRail() {
|
||||
QString filename = _outputDirectory + "/getMilestones.py";
|
||||
void TestRailInterface::updateRunsComboData(int exitCode, QProcess::ExitStatus exitStatus) {
|
||||
// Quit if user has previously cancelled
|
||||
if (_testRailRunSelectorWindow.getUserCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check if process completed successfully
|
||||
if (exitStatus != QProcess::NormalExit) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not get runs from TestRail");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// Create map of sections from the file created by the process
|
||||
_runNames.clear();
|
||||
|
||||
QString filename = _outputDirectory + "/runs.txt";
|
||||
if (!QFile::exists(filename)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not find runs.txt in " + _outputDirectory);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
QFile file(filename);
|
||||
if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not open " + filename);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
QTextStream in(&file);
|
||||
QString line = in.readLine();
|
||||
while (!line.isNull()) {
|
||||
// The run name is all the words except for the last
|
||||
// The id is the last word
|
||||
QString section = line.left(line.lastIndexOf(" "));
|
||||
QString id = line.right(line.length() - line.lastIndexOf(" ") - 1);
|
||||
|
||||
_runIDs.push_back(id.toInt());
|
||||
_runNames << section;
|
||||
|
||||
line = in.readLine();
|
||||
}
|
||||
|
||||
file.close();
|
||||
|
||||
// Update the combo
|
||||
_testRailResultsSelectorWindow.updateRunsComboBoxData(_runNames);
|
||||
|
||||
_testRailResultsSelectorWindow.exec();
|
||||
|
||||
if (_testRailResultsSelectorWindow.getUserCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// The test cases are now read from TestRail
|
||||
// When this is complete, the Run can be updated
|
||||
updateRunWithResults();
|
||||
}
|
||||
|
||||
void TestRailInterface::getReleasesFromTestRail() {
|
||||
QString filename = _outputDirectory + "/getReleases.py";
|
||||
if (QFile::exists(filename)) {
|
||||
QFile::remove(filename);
|
||||
}
|
||||
|
@ -454,7 +728,7 @@ void TestRailInterface::getMilestonesFromTestRail() {
|
|||
|
||||
if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not create 'getMilestones.py'");
|
||||
"Could not create 'getReleases.py'");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
|
@ -466,21 +740,33 @@ void TestRailInterface::getMilestonesFromTestRail() {
|
|||
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";
|
||||
// Print the list of releases
|
||||
stream << "case_fields = client.send_get('get_case_fields/" + _projectID + "')\n";
|
||||
stream << "for case_field in case_fields:\n";
|
||||
stream << "\tif case_field['name'] == 'added_to_release':\n";
|
||||
stream << "\t\trelease_string = case_field['configs'][0]['options']['items']\n\n";
|
||||
|
||||
// The list read from TestRail looks like this:
|
||||
// '0,< RC65\n1,RC65\n2,RC66\n3,RC67\n4,RC68\n5,RC69\n6,v0.70.0\n7,v0.71.0\n8,v0.72.0\n9,v0.73.0\n10,v0.74.0\n11,v0.75.0\n12,v0.76.0\n13,v0.77.0\n14,v0.78.0\n15,v0.79.0'
|
||||
// Splitting on newline gives an array:
|
||||
// ['0,< RC65', '1,RC65', '2,RC66', '3,RC67', '4,RC68', '5,RC69', '6,v0.70.0', '7,v0.71.0', '8,v0.72.0', '9,v0.73.0', '10,v0.74.0', '11,v0.75.0', '12,v0.76.0', '13,v0.77.0', '14,v0.78.0', '15,v0.79.0']
|
||||
// Each element consists of an index and a string, separated by a comma.
|
||||
// We just need the strings
|
||||
stream << "file = open('" + _outputDirectory + "/releases.txt', 'w')\n\n";
|
||||
stream << "releases = release_string.split('\\n')\n";
|
||||
stream << "for release in releases:\n";
|
||||
stream << "\twords = release.split(',')\n";
|
||||
stream << "\tfile.write(words[1] + '\\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); });
|
||||
[=](int exitCode, QProcess::ExitStatus exitStatus) { updateReleasesComboData(exitCode, exitStatus); });
|
||||
|
||||
QStringList parameters = QStringList() << _outputDirectory + "/getMilestones.py ";
|
||||
QStringList parameters = QStringList() << filename;
|
||||
process->start(_pythonCommand, parameters);
|
||||
}
|
||||
|
||||
|
@ -497,12 +783,15 @@ void TestRailInterface::createTestSuitePython(const QString& testDirectory,
|
|||
return;
|
||||
}
|
||||
|
||||
requestTestRailTestCasesDataFromUser();
|
||||
if (!requestTestRailTestCasesDataFromUser()) {
|
||||
return;
|
||||
}
|
||||
|
||||
createTestRailDotPyScript();
|
||||
createStackDotPyScript();
|
||||
|
||||
// TestRail will be updated after the process initiated by getMilestonesFromTestRail has completed
|
||||
getMilestonesFromTestRail();
|
||||
// TestRail will be updated after the process initiated by getReleasesFromTestRail has completed
|
||||
getReleasesFromTestRail();
|
||||
}
|
||||
|
||||
void TestRailInterface::createTestSuiteXML(const QString& testDirectory,
|
||||
|
@ -747,15 +1036,13 @@ void TestRailInterface::processTestPython(const QString& fullDirectory,
|
|||
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_added_to_release': " << _testRailTestCasesSelectorWindow.getReleaseID() << ",\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"
|
||||
|
@ -766,22 +1053,6 @@ void TestRailInterface::processTestPython(const QString& fullDirectory,
|
|||
stream << "case = client.send_post('add_case/' + str(section_id), data)\n";
|
||||
}
|
||||
|
||||
void TestRailInterface::requestTestRailRunDataFromUser() {
|
||||
_testRailRunSelectorWindow.reset();
|
||||
_testRailRunSelectorWindow.exec();
|
||||
|
||||
if (_testRailRunSelectorWindow.getUserCancelled()) {
|
||||
return;
|
||||
}
|
||||
|
||||
_url = _testRailRunSelectorWindow.getURL() + "/";
|
||||
_user = _testRailRunSelectorWindow.getUser();
|
||||
_password = _testRailRunSelectorWindow.getPassword();
|
||||
////_password = "tutKA76";
|
||||
_projectID = QString::number(_testRailRunSelectorWindow.getProjectID());
|
||||
_suiteID = QString::number(_testRailRunSelectorWindow.getSuiteID());
|
||||
}
|
||||
|
||||
void TestRailInterface::getTestSectionsFromTestRail() {
|
||||
QString filename = _outputDirectory + "/getSections.py";
|
||||
if (QFile::exists(filename)) {
|
||||
|
@ -817,7 +1088,46 @@ void TestRailInterface::getTestSectionsFromTestRail() {
|
|||
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 ";
|
||||
QStringList parameters = QStringList() << filename;
|
||||
process->start(_pythonCommand, parameters);
|
||||
}
|
||||
|
||||
void TestRailInterface::getRunsFromTestRail() {
|
||||
QString filename = _outputDirectory + "/getRuns.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 " + filename);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
QTextStream stream(&file);
|
||||
|
||||
// Code to access TestRail
|
||||
stream << "from testrail import *\n";
|
||||
stream << "client = APIClient('" << _url.toStdString().c_str() << "')\n";
|
||||
stream << "client.user = '" << _user << "'\n";
|
||||
stream << "client.password = '" << _password << "'\n\n";
|
||||
|
||||
// Print the list of runs
|
||||
stream << "runs = client.send_get('get_runs/" + _projectID + "')\n\n";
|
||||
stream << "file = open('" + _outputDirectory + "/runs.txt', 'w')\n\n";
|
||||
stream << "for run in runs:\n";
|
||||
stream << "\tfile.write(run['name'] + ' ' + str(run['id']) + '\\n')\n\n";
|
||||
stream << "file.close()\n";
|
||||
|
||||
file.close();
|
||||
|
||||
QProcess* process = new QProcess();
|
||||
connect(process, static_cast<void (QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), this,
|
||||
[=](int exitCode, QProcess::ExitStatus exitStatus) { updateRunsComboData(exitCode, exitStatus); });
|
||||
|
||||
QStringList parameters = QStringList() << filename;
|
||||
|
||||
process->start(_pythonCommand, parameters);
|
||||
}
|
||||
|
||||
|
@ -828,10 +1138,37 @@ void TestRailInterface::createTestRailRun(const QString& outputDirectory) {
|
|||
return;
|
||||
}
|
||||
|
||||
requestTestRailRunDataFromUser();
|
||||
if (!requestTestRailRunDataFromUser()) {
|
||||
return;
|
||||
}
|
||||
|
||||
createTestRailDotPyScript();
|
||||
createStackDotPyScript();
|
||||
|
||||
// TestRail will be updated after the process initiated by getTestCasesFromTestRail has completed
|
||||
getTestSectionsFromTestRail();
|
||||
}
|
||||
|
||||
void TestRailInterface::updateTestRailRunResults(const QString& testResults, const QString& tempDirectory) {
|
||||
_outputDirectory = tempDirectory;
|
||||
|
||||
if (!setPythonCommand()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!requestTestRailResultsDataFromUser()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// This is needed to access TestRail
|
||||
createTestRailDotPyScript();
|
||||
|
||||
// Extract test failures from zipped folder
|
||||
QString tempSubDirectory = tempDirectory + "/" + tempName;
|
||||
QDir dir = tempSubDirectory;
|
||||
dir.mkdir(tempSubDirectory);
|
||||
JlCompress::extractDir(testResults, tempSubDirectory);
|
||||
|
||||
// TestRail will be updated after the process initiated by getTestRunFromTestRail has completed
|
||||
getRunsFromTestRail();
|
||||
}
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
#include "ui/TestRailTestCasesSelectorWindow.h"
|
||||
#include "ui/TestRailRunSelectorWindow.h"
|
||||
#include "ui/TestRailResultsSelectorWindow.h"
|
||||
|
||||
#include <QDirIterator>
|
||||
#include <QtXml/QDomDocument>
|
||||
|
@ -53,14 +54,16 @@ public:
|
|||
const QString& userGitHub,
|
||||
const QString& branchGitHub);
|
||||
|
||||
void getMilestonesFromTestRail();
|
||||
void getReleasesFromTestRail();
|
||||
void getTestSectionsFromTestRail();
|
||||
void getRunsFromTestRail();
|
||||
|
||||
void createTestRailDotPyScript();
|
||||
void createStackDotPyScript();
|
||||
|
||||
void requestTestRailTestCasesDataFromUser();
|
||||
void requestTestRailRunDataFromUser();
|
||||
bool requestTestRailTestCasesDataFromUser();
|
||||
bool requestTestRailRunDataFromUser();
|
||||
bool requestTestRailResultsDataFromUser();
|
||||
|
||||
void createAddTestCasesPythonScript(const QString& testDirectory,
|
||||
const QString& userGitHub,
|
||||
|
@ -75,10 +78,15 @@ public:
|
|||
|
||||
QString getObject(const QString& path);
|
||||
|
||||
void updateMilestonesComboData(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void updateReleasesComboData(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void updateSectionsComboData(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
void updateRunsComboData(int exitCode, QProcess::ExitStatus exitStatus);
|
||||
|
||||
void createTestRailRun(const QString& outputDirectory);
|
||||
void updateTestRailRunResults(const QString& testResults, const QString& tempDirectory);
|
||||
|
||||
void addRun();
|
||||
void updateRunWithResults();
|
||||
|
||||
bool setPythonCommand();
|
||||
|
||||
|
@ -94,6 +102,7 @@ private:
|
|||
BusyWindow _busyWindow;
|
||||
TestRailTestCasesSelectorWindow _testRailTestCasesSelectorWindow;
|
||||
TestRailRunSelectorWindow _testRailRunSelectorWindow;
|
||||
TestRailResultsSelectorWindow _testRailResultsSelectorWindow;
|
||||
|
||||
QString _url;
|
||||
QString _user;
|
||||
|
@ -109,11 +118,15 @@ private:
|
|||
const QString pythonExe{ "python.exe" };
|
||||
QString _pythonCommand;
|
||||
|
||||
std::map<QString, int> _milestones;
|
||||
QStringList _milestoneNames;
|
||||
QStringList _releaseNames;
|
||||
|
||||
std::map<QString, int> _sections;
|
||||
QStringList _sectionNames;
|
||||
std::vector<int> _sectionIDs;
|
||||
|
||||
QStringList _runNames;
|
||||
std::vector<int> _runIDs;
|
||||
|
||||
QString tempName{ "fgadhcUDHSFaidsfh3478JJJFSDFIUSOEIrf" };
|
||||
};
|
||||
|
||||
#endif
|
|
@ -15,20 +15,24 @@
|
|||
#include <shellapi.h>
|
||||
#endif
|
||||
|
||||
AutoTester::AutoTester(QWidget *parent) : QMainWindow(parent) {
|
||||
AutoTester::AutoTester(QWidget* parent) : QMainWindow(parent) {
|
||||
_ui.setupUi(this);
|
||||
|
||||
_ui.checkBoxInteractiveMode->setChecked(true);
|
||||
_ui.progressBar->setVisible(false);
|
||||
_ui.tabWidget->setCurrentIndex(0);
|
||||
|
||||
_signalMapper = new QSignalMapper();
|
||||
|
||||
connect(_ui.actionClose, &QAction::triggered, this, &AutoTester::on_closeButton_clicked);
|
||||
connect(_ui.actionAbout, &QAction::triggered, this, &AutoTester::about);
|
||||
connect(_ui.actionContent, &QAction::triggered, this, &AutoTester::content);
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
_ui.hideTaskbarButton->setVisible(false);
|
||||
_ui.showTaskbarButton->setVisible(false);
|
||||
_ui.tabWidget->setTabEnabled(3, false);
|
||||
#endif
|
||||
|
||||
// helpWindow.textBrowser->setText()
|
||||
}
|
||||
|
||||
void AutoTester::setup() {
|
||||
|
@ -40,6 +44,16 @@ void AutoTester::runFromCommandLine(const QString& testFolder, const QString& br
|
|||
_test->startTestsEvaluation(testFolder, branch, user);
|
||||
}
|
||||
|
||||
void AutoTester::on_tabWidget_currentChanged(int index) {
|
||||
if (index == 1 || index == 2) {
|
||||
_ui.userTextEdit->setDisabled(false);
|
||||
_ui.branchTextEdit->setDisabled(false);
|
||||
} else {
|
||||
_ui.userTextEdit->setDisabled(true);
|
||||
_ui.branchTextEdit->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void AutoTester::on_evaluateTestsButton_clicked() {
|
||||
_test->startTestsEvaluation();
|
||||
}
|
||||
|
@ -53,7 +67,7 @@ void AutoTester::on_createAllRecursiveScriptsButton_clicked() {
|
|||
}
|
||||
|
||||
void AutoTester::on_createTestsButton_clicked() {
|
||||
_test->createTests();
|
||||
_test->createTests();
|
||||
}
|
||||
|
||||
void AutoTester::on_createMDFileButton_clicked() {
|
||||
|
@ -76,6 +90,10 @@ void AutoTester::on_createTestRailRunButton_clicked() {
|
|||
_test->createTestRailRun();
|
||||
}
|
||||
|
||||
void AutoTester::on_updateTestRailRunResultsButton_clicked() {
|
||||
_test->updateTestRailRunResult();
|
||||
}
|
||||
|
||||
// To toggle between show and hide
|
||||
// if (uState & ABS_AUTOHIDE) on_showTaskbarButton_clicked();
|
||||
// else on_hideTaskbarButton_clicked();
|
||||
|
@ -114,7 +132,7 @@ void AutoTester::on_createXMLScriptRadioButton_clicked() {
|
|||
|
||||
void AutoTester::downloadImage(const QUrl& url) {
|
||||
_downloaders.emplace_back(new Downloader(url, this));
|
||||
connect(_downloaders[_index], SIGNAL (downloaded()), _signalMapper, SLOT (map()));
|
||||
connect(_downloaders[_index], SIGNAL(downloaded()), _signalMapper, SLOT(map()));
|
||||
|
||||
_signalMapper->setMapping(_downloaders[_index], _index);
|
||||
|
||||
|
@ -140,7 +158,7 @@ void AutoTester::downloadImages(const QStringList& URLs, const QString& director
|
|||
downloadImage(imageURL);
|
||||
}
|
||||
|
||||
connect(_signalMapper, SIGNAL (mapped(int)), this, SLOT (saveImage(int)));
|
||||
connect(_signalMapper, SIGNAL(mapped(int)), this, SLOT(saveImage(int)));
|
||||
}
|
||||
|
||||
void AutoTester::saveImage(int index) {
|
||||
|
@ -158,7 +176,7 @@ void AutoTester::saveImage(int index) {
|
|||
++_numberOfImagesDownloaded;
|
||||
|
||||
if (_numberOfImagesDownloaded == _numberOfImagesToDownload) {
|
||||
disconnect(_signalMapper, SIGNAL (mapped(int)), this, SLOT (saveImage(int)));
|
||||
disconnect(_signalMapper, SIGNAL(mapped(int)), this, SLOT(saveImage(int)));
|
||||
_test->finishTestsEvaluation(_isRunningFromCommandline, _ui.checkBoxInteractiveMode->isChecked(), _ui.progressBar);
|
||||
} else {
|
||||
_ui.progressBar->setValue(_numberOfImagesDownloaded);
|
||||
|
@ -169,12 +187,15 @@ void AutoTester::about() {
|
|||
QMessageBox::information(0, "About", QString("Built ") + __DATE__ + " : " + __TIME__);
|
||||
}
|
||||
|
||||
void AutoTester::content() {
|
||||
helpWindow.show();
|
||||
}
|
||||
|
||||
void AutoTester::setUserText(const QString& user) {
|
||||
_ui.userTextEdit->setText(user);
|
||||
}
|
||||
|
||||
QString AutoTester::getSelectedUser()
|
||||
{
|
||||
QString AutoTester::getSelectedUser() {
|
||||
return _ui.userTextEdit->toPlainText();
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,8 @@
|
|||
#include "../Downloader.h"
|
||||
#include "../Test.h"
|
||||
|
||||
#include "HelpWindow.h"
|
||||
|
||||
class AutoTester : public QMainWindow {
|
||||
Q_OBJECT
|
||||
|
||||
|
@ -38,15 +40,21 @@ public:
|
|||
QString getSelectedBranch();
|
||||
|
||||
private slots:
|
||||
void on_tabWidget_currentChanged(int index);
|
||||
|
||||
void on_evaluateTestsButton_clicked();
|
||||
void on_createRecursiveScriptButton_clicked();
|
||||
void on_createAllRecursiveScriptsButton_clicked();
|
||||
void on_createTestsButton_clicked();
|
||||
|
||||
void on_createMDFileButton_clicked();
|
||||
void on_createAllMDFilesButton_clicked();
|
||||
|
||||
void on_createTestsOutlineButton_clicked();
|
||||
|
||||
void on_createTestRailTestCasesButton_clicked();
|
||||
void on_createTestRailRunButton_clicked();
|
||||
void on_updateTestRailRunResultsButton_clicked();
|
||||
|
||||
void on_hideTaskbarButton_clicked();
|
||||
void on_showTaskbarButton_clicked();
|
||||
|
@ -59,6 +67,7 @@ private slots:
|
|||
void saveImage(int index);
|
||||
|
||||
void about();
|
||||
void content();
|
||||
|
||||
private:
|
||||
Ui::AutoTesterClass _ui;
|
||||
|
@ -78,6 +87,8 @@ private:
|
|||
int _index { 0 };
|
||||
|
||||
bool _isRunningFromCommandline { false };
|
||||
|
||||
HelpWindow helpWindow;
|
||||
};
|
||||
|
||||
#endif // hifi_AutoTester_h
|
|
@ -6,10 +6,16 @@
|
|||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>645</width>
|
||||
<height>814</height>
|
||||
<width>432</width>
|
||||
<height>734</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>AutoTester</string>
|
||||
</property>
|
||||
|
@ -17,9 +23,9 @@
|
|||
<widget class="QPushButton" name="closeButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>380</x>
|
||||
<y>620</y>
|
||||
<width>101</width>
|
||||
<x>166</x>
|
||||
<y>610</y>
|
||||
<width>100</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -27,157 +33,258 @@
|
|||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createTestsButton">
|
||||
<widget class="QTabWidget" name="tabWidget">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>30</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
<x>12</x>
|
||||
<y>140</y>
|
||||
<width>408</width>
|
||||
<height>461</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create Tests</string>
|
||||
<property name="currentIndex">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="tab_1">
|
||||
<attribute name="title">
|
||||
<string>Create</string>
|
||||
</attribute>
|
||||
<widget class="QPushButton" name="createTestsButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>96</x>
|
||||
<y>20</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create Tests</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createMDFileButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>96</x>
|
||||
<y>100</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create MD file</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createAllMDFilesButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>96</x>
|
||||
<y>150</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create all MD files</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createTestsOutlineButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>96</x>
|
||||
<y>230</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create Tests Outline</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createRecursiveScriptButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>96</x>
|
||||
<y>310</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create Recursive Script</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createAllRecursiveScriptsButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>96</x>
|
||||
<y>360</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create all Recursive Scripts</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_2">
|
||||
<attribute name="title">
|
||||
<string>Evaluate</string>
|
||||
</attribute>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>90</x>
|
||||
<y>100</y>
|
||||
<width>255</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="checkBoxInteractiveMode">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>90</x>
|
||||
<y>50</y>
|
||||
<width>131</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>If unchecked, will not show results during evaluation</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Interactive Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="evaluateTestsButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>40</y>
|
||||
<width>101</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Evaluate Test</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_3">
|
||||
<attribute name="title">
|
||||
<string>TestRail</string>
|
||||
</attribute>
|
||||
<widget class="QPushButton" name="updateTestRailRunResultsButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>180</x>
|
||||
<y>160</y>
|
||||
<width>161</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Update Run Results</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="createPythonScriptRadioButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>80</x>
|
||||
<y>40</y>
|
||||
<width>95</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Python</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createTestRailRunButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>180</x>
|
||||
<y>100</y>
|
||||
<width>161</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create Run</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createTestRailTestCasesButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>180</x>
|
||||
<y>40</y>
|
||||
<width>161</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create Test Cases</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="createXMLScriptRadioButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>80</x>
|
||||
<y>60</y>
|
||||
<width>95</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>XML</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tab_4">
|
||||
<attribute name="title">
|
||||
<string>Windows</string>
|
||||
</attribute>
|
||||
<widget class="QPushButton" name="hideTaskbarButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>100</y>
|
||||
<width>211</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Hide Windows Taskbar</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="showTaskbarButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>100</x>
|
||||
<y>170</y>
|
||||
<width>211</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show Windows Taskbar</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="evaluateTestsButton">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>430</x>
|
||||
<y>490</y>
|
||||
<width>101</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Evaluate Test</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createRecursiveScriptButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>330</x>
|
||||
<y>340</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create Recursive Script</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QCheckBox" name="checkBoxInteractiveMode">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>320</x>
|
||||
<y>500</y>
|
||||
<width>131</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>If unchecked, will not show results during evaluation</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Interactive Mode</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>320</x>
|
||||
<y>550</y>
|
||||
<width>255</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>24</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createAllRecursiveScriptsButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>330</x>
|
||||
<y>400</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create all Recursive Scripts</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createMDFileButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>110</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create MD file</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createAllMDFilesButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>160</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create all MD files</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createTestsOutlineButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>250</y>
|
||||
<width>220</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create Tests Outline</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="showTaskbarButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>440</y>
|
||||
<width>211</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Show Windows Taskbar</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="hideTaskbarButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>390</y>
|
||||
<width>211</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Hide Windows Taskbar</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>330</x>
|
||||
<y>55</y>
|
||||
<x>110</x>
|
||||
<y>90</y>
|
||||
<width>81</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
|
@ -191,11 +298,31 @@
|
|||
<string>GitHub Branch</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<widget class="QTextEdit" name="branchTextEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>330</x>
|
||||
<y>15</y>
|
||||
<x>200</x>
|
||||
<y>85</y>
|
||||
<width>140</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTextEdit" name="userTextEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>47</y>
|
||||
<width>140</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>110</x>
|
||||
<y>50</y>
|
||||
<width>81</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
|
@ -209,88 +336,13 @@
|
|||
<string>GitHub User</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTextEdit" name="userTextEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>420</x>
|
||||
<y>12</y>
|
||||
<width>140</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTextEdit" name="branchTextEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>420</x>
|
||||
<y>50</y>
|
||||
<width>140</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="createTestRailTestCasesButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>410</x>
|
||||
<y>100</y>
|
||||
<width>140</width>
|
||||
<height>40</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Create TestRail Test Cases</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="createPythonScriptRadioButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>100</y>
|
||||
<width>95</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Python</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QRadioButton" name="createXMLScriptRadioButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>310</x>
|
||||
<y>120</y>
|
||||
<width>95</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<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">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>645</width>
|
||||
<width>432</width>
|
||||
<height>21</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -305,6 +357,7 @@
|
|||
<string>Help</string>
|
||||
</property>
|
||||
<addaction name="actionAbout"/>
|
||||
<addaction name="actionContent"/>
|
||||
</widget>
|
||||
<addaction name="menuFile"/>
|
||||
<addaction name="menuHelp"/>
|
||||
|
@ -328,6 +381,11 @@
|
|||
<string>About</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionContent">
|
||||
<property name="text">
|
||||
<string>Content</string>
|
||||
</property>
|
||||
</action>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
|
|
|
@ -9,10 +9,6 @@
|
|||
//
|
||||
#include "BusyWindow.h"
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
BusyWindow::BusyWindow(QWidget *parent) {
|
||||
setupUi(this);
|
||||
}
|
||||
|
|
14
tools/auto-tester/src/ui/HelpWindow.cpp
Normal file
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// HelpWindow.cpp
|
||||
//
|
||||
// Created by Nissim Hadar on 8 Aug 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 "HelpWindow.h"
|
||||
|
||||
HelpWindow::HelpWindow(QWidget *parent) {
|
||||
setupUi(this);
|
||||
}
|
22
tools/auto-tester/src/ui/HelpWindow.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// HelpWindow.h
|
||||
//
|
||||
// Created by Nissim Hadar on 8 Aug 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_HelpWindow_h
|
||||
#define hifi_HelpWindow_h
|
||||
|
||||
#include "ui_HelpWindow.h"
|
||||
|
||||
class HelpWindow : public QDialog, public Ui::HelpWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
HelpWindow(QWidget* parent = Q_NULLPTR);
|
||||
};
|
||||
|
||||
#endif
|
46
tools/auto-tester/src/ui/HelpWindow.ui
Normal file
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>HelpWindow</class>
|
||||
<widget class="QDialog" name="HelpWindow">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>696</width>
|
||||
<height>546</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>AutoTester Help</string>
|
||||
</property>
|
||||
<widget class="QTextEdit" name="textEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>50</y>
|
||||
<width>581</width>
|
||||
<height>381</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="pushButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>300</x>
|
||||
<y>460</y>
|
||||
<width>93</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
104
tools/auto-tester/src/ui/TestRailResultsSelectorWindow.cpp
Normal file
|
@ -0,0 +1,104 @@
|
|||
//
|
||||
// TestRailResultsSelectorWindow.cpp
|
||||
//
|
||||
// Created by Nissim Hadar on 2 Aug 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 "TestRailResultsSelectorWindow.h"
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
TestRailResultsSelectorWindow::TestRailResultsSelectorWindow(QWidget *parent) {
|
||||
setupUi(this);
|
||||
|
||||
projectIDLineEdit->setValidator(new QIntValidator(1, 999, this));
|
||||
}
|
||||
|
||||
|
||||
void TestRailResultsSelectorWindow::reset() {
|
||||
urlLineEdit->setDisabled(false);
|
||||
userLineEdit->setDisabled(false);
|
||||
passwordLineEdit->setDisabled(false);
|
||||
projectIDLineEdit->setDisabled(false);
|
||||
|
||||
OKButton->setDisabled(true);
|
||||
|
||||
runsLabel->setDisabled(true);
|
||||
runsComboBox->setDisabled(true);
|
||||
}
|
||||
|
||||
void TestRailResultsSelectorWindow::on_acceptButton_clicked() {
|
||||
urlLineEdit->setDisabled(true);
|
||||
userLineEdit->setDisabled(true);
|
||||
passwordLineEdit->setDisabled(true);
|
||||
projectIDLineEdit->setDisabled(true);
|
||||
|
||||
OKButton->setDisabled(false);
|
||||
|
||||
runsLabel->setDisabled(false);
|
||||
runsComboBox->setDisabled(false);
|
||||
close();
|
||||
}
|
||||
|
||||
void TestRailResultsSelectorWindow::on_OKButton_clicked() {
|
||||
userCancelled = false;
|
||||
close();
|
||||
}
|
||||
|
||||
void TestRailResultsSelectorWindow::on_cancelButton_clicked() {
|
||||
userCancelled = true;
|
||||
close();
|
||||
}
|
||||
|
||||
bool TestRailResultsSelectorWindow::getUserCancelled() {
|
||||
return userCancelled;
|
||||
}
|
||||
|
||||
void TestRailResultsSelectorWindow::setURL(const QString& user) {
|
||||
urlLineEdit->setText(user);
|
||||
}
|
||||
|
||||
QString TestRailResultsSelectorWindow::getURL() {
|
||||
return urlLineEdit->text();
|
||||
}
|
||||
|
||||
void TestRailResultsSelectorWindow::setUser(const QString& user) {
|
||||
userLineEdit->setText(user);
|
||||
}
|
||||
|
||||
QString TestRailResultsSelectorWindow::getUser() {
|
||||
return userLineEdit->text();
|
||||
}
|
||||
|
||||
QString TestRailResultsSelectorWindow::getPassword() {
|
||||
return passwordLineEdit->text();
|
||||
}
|
||||
|
||||
void TestRailResultsSelectorWindow::setProjectID(const int project) {
|
||||
projectIDLineEdit->setText(QString::number(project));
|
||||
}
|
||||
|
||||
int TestRailResultsSelectorWindow::getProjectID() {
|
||||
return projectIDLineEdit->text().toInt();
|
||||
}
|
||||
|
||||
void TestRailResultsSelectorWindow::setSuiteID(const int project) {
|
||||
suiteIDLineEdit->setText(QString::number(project));
|
||||
}
|
||||
|
||||
int TestRailResultsSelectorWindow::getSuiteID() {
|
||||
return suiteIDLineEdit->text().toInt();
|
||||
}
|
||||
|
||||
void TestRailResultsSelectorWindow::updateRunsComboBoxData(QStringList data) {
|
||||
runsComboBox->insertItems(0, data);
|
||||
}
|
||||
|
||||
int TestRailResultsSelectorWindow::getRunID() {
|
||||
return runsComboBox->currentIndex();
|
||||
}
|
50
tools/auto-tester/src/ui/TestRailResultsSelectorWindow.h
Normal file
|
@ -0,0 +1,50 @@
|
|||
//
|
||||
// TestRailResultsSelectorWindow.h
|
||||
//
|
||||
// Created by Nissim Hadar on 2 Aug 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_TestRailResultsSelectorWindow_h
|
||||
#define hifi_TestRailResultsSelectorWindow_h
|
||||
|
||||
#include "ui_TestRailResultsSelectorWindow.h"
|
||||
|
||||
class TestRailResultsSelectorWindow : public QDialog, public Ui::TestRailResultsSelectorWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TestRailResultsSelectorWindow(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 updateRunsComboBoxData(QStringList data);
|
||||
int getRunID();
|
||||
|
||||
private slots:
|
||||
void on_acceptButton_clicked();
|
||||
void on_OKButton_clicked();
|
||||
void on_cancelButton_clicked();
|
||||
};
|
||||
|
||||
#endif
|
280
tools/auto-tester/src/ui/TestRailResultsSelectorWindow.ui
Normal file
|
@ -0,0 +1,280 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TestRailResultsSelectorWindow</class>
|
||||
<widget class="QDialog" name="TestRailResultsSelectorWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>533</width>
|
||||
<height>474</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>TestRail Test Case 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="runsComboBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>160</x>
|
||||
<y>350</y>
|
||||
<width>271</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="runsLabel">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>80</x>
|
||||
<y>350</y>
|
||||
<width>71</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TestRail Run</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>runsComboBox</tabstop>
|
||||
<tabstop>OKButton</tabstop>
|
||||
<tabstop>cancelButton</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -96,6 +96,5 @@ void TestRailRunSelectorWindow::updateSectionsComboBoxData(QStringList data) {
|
|||
}
|
||||
|
||||
int TestRailRunSelectorWindow::getSectionID() {
|
||||
return 0;
|
||||
sectionsComboBox->currentIndex();
|
||||
return sectionsComboBox->currentIndex();
|
||||
}
|
|
@ -27,7 +27,9 @@ void TestRailTestCasesSelectorWindow::reset() {
|
|||
projectIDLineEdit->setDisabled(false);
|
||||
|
||||
OKButton->setDisabled(true);
|
||||
milestonesComboBox->setDisabled(true);
|
||||
|
||||
releasesLabel->setDisabled(true);
|
||||
releasesComboBox->setDisabled(true);
|
||||
}
|
||||
|
||||
void TestRailTestCasesSelectorWindow::on_acceptButton_clicked() {
|
||||
|
@ -37,7 +39,9 @@ void TestRailTestCasesSelectorWindow::on_acceptButton_clicked() {
|
|||
projectIDLineEdit->setDisabled(true);
|
||||
|
||||
OKButton->setDisabled(false);
|
||||
milestonesComboBox->setDisabled(false);
|
||||
|
||||
releasesLabel->setDisabled(false);
|
||||
releasesComboBox->setDisabled(false);
|
||||
close();
|
||||
}
|
||||
|
||||
|
@ -91,10 +95,10 @@ int TestRailTestCasesSelectorWindow::getSuiteID() {
|
|||
return suiteIDLineEdit->text().toInt();
|
||||
}
|
||||
|
||||
void TestRailTestCasesSelectorWindow::updateMilestonesComboBoxData(QStringList data) {
|
||||
milestonesComboBox->insertItems(0, data);
|
||||
void TestRailTestCasesSelectorWindow::updateReleasesComboBoxData(QStringList data) {
|
||||
releasesComboBox->insertItems(0, data);
|
||||
}
|
||||
|
||||
int TestRailTestCasesSelectorWindow::getMilestoneID() {
|
||||
return milestonesComboBox->currentIndex();
|
||||
int TestRailTestCasesSelectorWindow::getReleaseID() {
|
||||
return releasesComboBox->currentIndex();
|
||||
}
|
|
@ -38,8 +38,8 @@ public:
|
|||
|
||||
bool userCancelled{ false };
|
||||
|
||||
void updateMilestonesComboBoxData(QStringList data);
|
||||
int getMilestoneID();
|
||||
void updateReleasesComboBoxData(QStringList data);
|
||||
int getReleaseID();
|
||||
|
||||
private slots:
|
||||
void on_acceptButton_clicked();
|
||||
|
|
|
@ -171,7 +171,7 @@
|
|||
<string>Accept</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="milestonesComboBox">
|
||||
<widget class="QComboBox" name="releasesComboBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
|
@ -184,15 +184,15 @@
|
|||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="milestoneLabel">
|
||||
<widget class="QLabel" name="releasesLabel">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>140</x>
|
||||
<x>80</x>
|
||||
<y>350</y>
|
||||
<width>121</width>
|
||||
<width>181</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
|
@ -202,7 +202,7 @@
|
|||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TestRail Milestone</string>
|
||||
<string>TestRail Added for Release</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="urlLineEdit">
|
||||
|
@ -271,7 +271,7 @@
|
|||
<tabstop>projectIDLineEdit</tabstop>
|
||||
<tabstop>suiteIDLineEdit</tabstop>
|
||||
<tabstop>acceptButton</tabstop>
|
||||
<tabstop>milestonesComboBox</tabstop>
|
||||
<tabstop>releasesComboBox</tabstop>
|
||||
<tabstop>OKButton</tabstop>
|
||||
<tabstop>cancelButton</tabstop>
|
||||
</tabstops>
|
||||
|
|