mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-07-22 22:44:45 +02:00
Added option to delete old snapshots.
This commit is contained in:
parent
92a80c500e
commit
0f4206d330
12 changed files with 459 additions and 135 deletions
|
@ -20,28 +20,22 @@ include_directories(${Qt5Widgets_INCLUDE_DIRS})
|
||||||
|
|
||||||
set (QT_LIBRARIES Qt5::Core Qt5::Widgets)
|
set (QT_LIBRARIES Qt5::Core Qt5::Widgets)
|
||||||
|
|
||||||
# Find all sources files
|
|
||||||
file (GLOB_RECURSE SOURCES src/*.cpp)
|
|
||||||
file (GLOB_RECURSE HEADERS src/*.h)
|
|
||||||
file (GLOB_RECURSE UIS src/ui/*.ui)
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
# Do not show Console
|
# Do not show Console
|
||||||
set_property (TARGET auto-tester PROPERTY WIN32_EXECUTABLE true)
|
set_property (TARGET auto-tester PROPERTY WIN32_EXECUTABLE true)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
add_executable(PROJECT_NAME ${SOURCES} ${HEADERS} ${UIS})
|
target_zlib()
|
||||||
|
add_dependency_external_projects (quazip)
|
||||||
|
find_package (QuaZip REQUIRED)
|
||||||
|
target_include_directories( ${TARGET_NAME} SYSTEM PUBLIC ${QUAZIP_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(${TARGET_NAME} ${QUAZIP_LIBRARIES})
|
||||||
|
|
||||||
target_link_libraries(PROJECT_NAME ${QT_LIBRARIES})
|
package_libraries_for_deployment()
|
||||||
|
|
||||||
# Copy required dll's.
|
|
||||||
add_custom_command(TARGET auto-tester POST_BUILD
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Core> $<TARGET_FILE_DIR:auto-tester>
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Gui> $<TARGET_FILE_DIR:auto-tester>
|
|
||||||
COMMAND ${CMAKE_COMMAND} -E copy_if_different $<TARGET_FILE:Qt5::Widgets> $<TARGET_FILE_DIR:auto-tester>
|
|
||||||
)
|
|
||||||
|
|
||||||
if (WIN32)
|
if (WIN32)
|
||||||
|
add_paths_to_fixup_libs (${QUAZIP_DLL_PATH})
|
||||||
|
|
||||||
find_program(WINDEPLOYQT_COMMAND windeployqt PATHS ${QT_DIR}/bin NO_DEFAULT_PATH)
|
find_program(WINDEPLOYQT_COMMAND windeployqt PATHS ${QT_DIR}/bin NO_DEFAULT_PATH)
|
||||||
|
|
||||||
if (NOT WINDEPLOYQT_COMMAND)
|
if (NOT WINDEPLOYQT_COMMAND)
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
#include "ImageComparer.h"
|
#include "ImageComparer.h"
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
||||||
|
@ -26,11 +27,6 @@ double ImageComparer::compareImages(QImage resultImage, QImage expectedImage) co
|
||||||
const double c1 = pow((K1 * L), 2);
|
const double c1 = pow((K1 * L), 2);
|
||||||
const double c2 = pow((K2 * L), 2);
|
const double c2 = pow((K2 * L), 2);
|
||||||
|
|
||||||
// Coefficients for luminosity calculation
|
|
||||||
const double R_Y = 0.212655f;
|
|
||||||
const double G_Y = 0.715158f;
|
|
||||||
const double B_Y = 0.072187f;
|
|
||||||
|
|
||||||
// First go over all full 8x8 blocks
|
// First go over all full 8x8 blocks
|
||||||
// This is done in 3 loops
|
// This is done in 3 loops
|
||||||
// 1) Read the pixels into a linear array (an optimization)
|
// 1) Read the pixels into a linear array (an optimization)
|
||||||
|
|
|
@ -13,15 +13,59 @@
|
||||||
#include <QtCore/QTextStream>
|
#include <QtCore/QTextStream>
|
||||||
#include <QDirIterator>
|
#include <QDirIterator>
|
||||||
|
|
||||||
|
#include <quazip5/quazip.h>
|
||||||
|
#include <quazip5/JlCompress.h>
|
||||||
|
|
||||||
Test::Test() {
|
Test::Test() {
|
||||||
snapshotFilenameFormat = QRegularExpression("hifi-snap-by-.+-on-\\d\\d\\d\\d-\\d\\d-\\d\\d_\\d\\d-\\d\\d-\\d\\d.jpg");
|
snapshotFilenameFormat = QRegularExpression("hifi-snap-by-.*-on-\\d\\d\\d\\d-\\d\\d-\\d\\d_\\d\\d-\\d\\d-\\d\\d.jpg");
|
||||||
|
|
||||||
expectedImageFilenameFormat = QRegularExpression("ExpectedImage_\\d+.jpg");
|
expectedImageFilenameFormat = QRegularExpression("ExpectedImage_\\d+.jpg");
|
||||||
|
|
||||||
mismatchWindow.setModal(true);
|
mismatchWindow.setModal(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Test::compareImageLists(QStringList expectedImages, QStringList resultImages) {
|
bool Test::createTestResultsFolderPathIfNeeded(QString directory) {
|
||||||
|
// The test results folder is located in the root of the tests (i.e. for recursive test evaluation)
|
||||||
|
if (testResultsFolderPath == "") {
|
||||||
|
testResultsFolderPath = directory + "/" + TEST_RESULTS_FOLDER;
|
||||||
|
QDir testResultsFolder(testResultsFolderPath);
|
||||||
|
|
||||||
|
if (testResultsFolder.exists()) {
|
||||||
|
testResultsFolder.removeRecursively();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a new test results folder
|
||||||
|
return QDir().mkdir(testResultsFolderPath);
|
||||||
|
} else {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Test::zipAndDeleteTestResultsFolder() {
|
||||||
|
QString zippedResultsFileName { testResultsFolderPath + ".zip" };
|
||||||
|
QFileInfo fileInfo(zippedResultsFileName);
|
||||||
|
if (!fileInfo.exists()) {
|
||||||
|
QFile::remove(zippedResultsFileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
QDir testResultsFolder(testResultsFolderPath);
|
||||||
|
if (!testResultsFolder.isEmpty()) {
|
||||||
|
JlCompress::compressDir(testResultsFolderPath + ".zip", testResultsFolderPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
testResultsFolder.removeRecursively();
|
||||||
|
|
||||||
|
//In all cases, for the next evaluation
|
||||||
|
testResultsFolderPath = "";
|
||||||
|
index = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Test::compareImageLists(QStringList expectedImages, QStringList resultImages, QString testDirectory, bool interactiveMode, QProgressBar* progressBar) {
|
||||||
|
progressBar->setMinimum(0);
|
||||||
|
progressBar->setMaximum(expectedImages.length() - 1);
|
||||||
|
progressBar->setValue(0);
|
||||||
|
progressBar->setVisible(true);
|
||||||
|
|
||||||
// Loop over both lists and compare each pair of images
|
// Loop over both lists and compare each pair of images
|
||||||
// Quit loop if user has aborted due to a failed test.
|
// Quit loop if user has aborted due to a failed test.
|
||||||
const double THRESHOLD { 0.999 };
|
const double THRESHOLD { 0.999 };
|
||||||
|
@ -45,19 +89,26 @@ bool Test::compareImageLists(QStringList expectedImages, QStringList resultImage
|
||||||
}
|
}
|
||||||
|
|
||||||
if (similarityIndex < THRESHOLD) {
|
if (similarityIndex < THRESHOLD) {
|
||||||
mismatchWindow.setTestFailure(TestFailure{
|
TestFailure testFailure = TestFailure{
|
||||||
(float)similarityIndex,
|
(float)similarityIndex,
|
||||||
expectedImages[i].left(expectedImages[i].lastIndexOf("/") + 1), // path to the test (including trailing /)
|
expectedImages[i].left(expectedImages[i].lastIndexOf("/") + 1), // path to the test (including trailing /)
|
||||||
QFileInfo(expectedImages[i].toStdString().c_str()).fileName(), // filename of expected image
|
QFileInfo(expectedImages[i].toStdString().c_str()).fileName(), // filename of expected image
|
||||||
QFileInfo(resultImages[i].toStdString().c_str()).fileName() // filename of result image
|
QFileInfo(resultImages[i].toStdString().c_str()).fileName() // filename of result image
|
||||||
});
|
};
|
||||||
|
|
||||||
|
mismatchWindow.setTestFailure(testFailure);
|
||||||
|
|
||||||
|
if (!interactiveMode) {
|
||||||
|
appendTestResultsToFile(testResultsFolderPath, testFailure, mismatchWindow.getComparisonImage());
|
||||||
|
success = false;
|
||||||
|
} else {
|
||||||
mismatchWindow.exec();
|
mismatchWindow.exec();
|
||||||
|
|
||||||
switch (mismatchWindow.getUserResponse()) {
|
switch (mismatchWindow.getUserResponse()) {
|
||||||
case USER_RESPONSE_PASS:
|
case USER_RESPONSE_PASS:
|
||||||
break;
|
break;
|
||||||
case USE_RESPONSE_FAIL:
|
case USE_RESPONSE_FAIL:
|
||||||
|
appendTestResultsToFile(testResultsFolderPath, testFailure, mismatchWindow.getComparisonImage());
|
||||||
success = false;
|
success = false;
|
||||||
break;
|
break;
|
||||||
case USER_RESPONSE_ABORT:
|
case USER_RESPONSE_ABORT:
|
||||||
|
@ -71,16 +122,74 @@ bool Test::compareImageLists(QStringList expectedImages, QStringList resultImage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progressBar->setValue(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
progressBar->setVisible(false);
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Test::evaluateTests() {
|
void Test::appendTestResultsToFile(QString testResultsFolderPath, TestFailure testFailure, QPixmap comparisonImage) {
|
||||||
|
if (!QDir().exists(testResultsFolderPath)) {
|
||||||
|
messageBox.critical(0, "Internal error", "Folder " + testResultsFolderPath + " not found");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
QString failureFolderPath { testResultsFolderPath + "/" + "Failure_" + QString::number(index) };
|
||||||
|
if (!QDir().mkdir(failureFolderPath)) {
|
||||||
|
messageBox.critical(0, "Internal error", "Failed to create folder " + failureFolderPath);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
++index;
|
||||||
|
|
||||||
|
QFile descriptionFile(failureFolderPath + "/" + TEST_RESULTS_FILENAME);
|
||||||
|
if (!descriptionFile.open(QIODevice::ReadWrite)) {
|
||||||
|
messageBox.critical(0, "Internal error", "Failed to create file " + TEST_RESULTS_FILENAME);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create text file describing the failure
|
||||||
|
QTextStream stream(&descriptionFile);
|
||||||
|
stream << "Test failed in folder " << testFailure._pathname.left(testFailure._pathname.length() - 1) << endl; // remove trailing '/'
|
||||||
|
stream << "Expected image was " << testFailure._expectedImageFilename << endl;
|
||||||
|
stream << "Actual image was " << testFailure._actualImageFilename << endl;
|
||||||
|
stream << "Similarity index was " << testFailure._error << endl;
|
||||||
|
|
||||||
|
descriptionFile.close();
|
||||||
|
|
||||||
|
// Copy expected and actual images, and save the difference image
|
||||||
|
QString sourceFile;
|
||||||
|
QString destinationFile;
|
||||||
|
|
||||||
|
sourceFile = testFailure._pathname + testFailure._expectedImageFilename;
|
||||||
|
destinationFile = failureFolderPath + "/" + "Expected Image.jpg";
|
||||||
|
if (!QFile::copy(sourceFile, destinationFile)) {
|
||||||
|
messageBox.critical(0, "Internal error", "Failed to copy " + sourceFile + " to " + destinationFile);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
sourceFile = testFailure._pathname + testFailure._actualImageFilename;
|
||||||
|
destinationFile = failureFolderPath + "/" + "Actual Image.jpg";
|
||||||
|
if (!QFile::copy(sourceFile, destinationFile)) {
|
||||||
|
messageBox.critical(0, "Internal error", "Failed to copy " + sourceFile + " to " + destinationFile);
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
comparisonImage.save(failureFolderPath + "/" + "Difference Image.jpg");
|
||||||
|
}
|
||||||
|
|
||||||
|
void Test::evaluateTests(bool interactiveMode, QProgressBar* progressBar) {
|
||||||
// Get list of JPEG images in folder, sorted by name
|
// Get list of JPEG images in folder, sorted by name
|
||||||
QString pathToImageDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test images", ".", QFileDialog::ShowDirsOnly);
|
QString pathToImageDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder containing the test images", ".", QFileDialog::ShowDirsOnly);
|
||||||
if (pathToImageDirectory == "") {
|
if (pathToImageDirectory == "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Leave if test results folder could not be created
|
||||||
|
if (!createTestResultsFolderPathIfNeeded(pathToImageDirectory)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
QStringList sortedImageFilenames = createListOfAllJPEGimagesInDirectory(pathToImageDirectory);
|
QStringList sortedImageFilenames = createListOfAllJPEGimagesInDirectory(pathToImageDirectory);
|
||||||
|
|
||||||
// Separate images into two lists. The first is the expected images, the second is the test results
|
// Separate images into two lists. The first is the expected images, the second is the test results
|
||||||
|
@ -107,36 +216,57 @@ void Test::evaluateTests() {
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool success = compareImageLists(expectedImages, resultImages);
|
bool success = compareImageLists(expectedImages, resultImages, pathToImageDirectory, interactiveMode, progressBar);
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
messageBox.information(0, "Success", "All images are as expected");
|
messageBox.information(0, "Success", "All images are as expected");
|
||||||
} else {
|
} else {
|
||||||
messageBox.information(0, "Failure", "One or more images are not as expected");
|
messageBox.information(0, "Failure", "One or more images are not as expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zipAndDeleteTestResultsFolder();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Test::isAValidDirectory(QString pathname) {
|
||||||
|
// Only process directories
|
||||||
|
QDir dir(pathname);
|
||||||
|
if (!dir.exists()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ignore '.', '..' directories
|
||||||
|
if (pathname[pathname.length() - 1] == '.') {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Two criteria are used to decide if a folder contains valid test results.
|
// Two criteria are used to decide if a folder contains valid test results.
|
||||||
// 1) a 'test'js' file exists in the folder
|
// 1) a 'test'js' file exists in the folder
|
||||||
// 2) the folder has the same number of actual and expected images
|
// 2) the folder has the same number of actual and expected images
|
||||||
void Test::evaluateTestsRecursively() {
|
void Test::evaluateTestsRecursively(bool interactiveMode, QProgressBar* progressBar) {
|
||||||
// Select folder to start recursing from
|
// Select folder to start recursing from
|
||||||
QString topLevelDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder that will contain the top level test script", ".", QFileDialog::ShowDirsOnly);
|
QString topLevelDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select folder that will contain the top level test script", ".", QFileDialog::ShowDirsOnly);
|
||||||
if (topLevelDirectory == "") {
|
if (topLevelDirectory == "") {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Leave if test results folder could not be created
|
||||||
|
if (!createTestResultsFolderPathIfNeeded(topLevelDirectory)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool success{ true };
|
bool success{ true };
|
||||||
QDirIterator it(topLevelDirectory.toStdString().c_str(), QDirIterator::Subdirectories);
|
QDirIterator it(topLevelDirectory.toStdString().c_str(), QDirIterator::Subdirectories);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
QString directory = it.next();
|
QString directory = it.next();
|
||||||
if (directory[directory.length() - 1] == '.') {
|
|
||||||
// ignore '.', '..' directories
|
if (!isAValidDirectory(directory)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
const QString testPathname{ directory + "/" + TEST_FILENAME };
|
||||||
const QString testPathname{ directory + "/" + testFilename };
|
|
||||||
QFileInfo fileInfo(testPathname);
|
QFileInfo fileInfo(testPathname);
|
||||||
if (!fileInfo.exists()) {
|
if (!fileInfo.exists()) {
|
||||||
// Folder does not contain 'test.js'
|
// Folder does not contain 'test.js'
|
||||||
|
@ -164,7 +294,7 @@ void Test::evaluateTestsRecursively() {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set success to false if any test has failed
|
// Set success to false if any test has failed
|
||||||
success &= compareImageLists(expectedImages, resultImages);
|
success &= compareImageLists(expectedImages, resultImages, directory, interactiveMode, progressBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (success) {
|
if (success) {
|
||||||
|
@ -172,6 +302,8 @@ void Test::evaluateTestsRecursively() {
|
||||||
} else {
|
} else {
|
||||||
messageBox.information(0, "Failure", "One or more images are not as expected");
|
messageBox.information(0, "Failure", "One or more images are not as expected");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
zipAndDeleteTestResultsFolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Test::importTest(QTextStream& textStream, const QString& testPathname, int testNumber) {
|
void Test::importTest(QTextStream& textStream, const QString& testPathname, int testNumber) {
|
||||||
|
@ -191,7 +323,8 @@ void Test::createRecursiveScript() {
|
||||||
if (!allTestsFilename.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
if (!allTestsFilename.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||||
messageBox.critical(0,
|
messageBox.critical(0,
|
||||||
"Internal Error",
|
"Internal Error",
|
||||||
"Failed to create \"allTests.js\" in directory \"" + topLevelDirectory + "\"");
|
"Failed to create \"allTests.js\" in directory \"" + topLevelDirectory + "\""
|
||||||
|
);
|
||||||
|
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
@ -206,7 +339,7 @@ void Test::createRecursiveScript() {
|
||||||
QVector<QString> testPathnames;
|
QVector<QString> testPathnames;
|
||||||
|
|
||||||
// First test if top-level folder has a test.js file
|
// First test if top-level folder has a test.js file
|
||||||
const QString testPathname{ topLevelDirectory + "/" + testFilename };
|
const QString testPathname{ topLevelDirectory + "/" + TEST_FILENAME };
|
||||||
QFileInfo fileInfo(testPathname);
|
QFileInfo fileInfo(testPathname);
|
||||||
if (fileInfo.exists()) {
|
if (fileInfo.exists()) {
|
||||||
// Current folder contains a test
|
// Current folder contains a test
|
||||||
|
@ -219,12 +352,14 @@ void Test::createRecursiveScript() {
|
||||||
QDirIterator it(topLevelDirectory.toStdString().c_str(), QDirIterator::Subdirectories);
|
QDirIterator it(topLevelDirectory.toStdString().c_str(), QDirIterator::Subdirectories);
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
QString directory = it.next();
|
QString directory = it.next();
|
||||||
if (directory[directory.length() - 1] == '.') {
|
|
||||||
// ignore '.', '..' directories
|
// Only process directories
|
||||||
|
QDir dir(directory);
|
||||||
|
if (!isAValidDirectory(directory)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString testPathname{ directory + "/" + testFilename };
|
const QString testPathname{ directory + "/" + TEST_FILENAME };
|
||||||
QFileInfo fileInfo(testPathname);
|
QFileInfo fileInfo(testPathname);
|
||||||
if (fileInfo.exists()) {
|
if (fileInfo.exists()) {
|
||||||
// Current folder contains a test
|
// Current folder contains a test
|
||||||
|
@ -264,7 +399,7 @@ void Test::createRecursiveScript() {
|
||||||
// The script produced will look as follows:
|
// The script produced will look as follows:
|
||||||
// if (test1HasNotStarted) {
|
// if (test1HasNotStarted) {
|
||||||
// test1HasNotStarted = false;
|
// test1HasNotStarted = false;
|
||||||
// test1.test();
|
// test1.test("auto");
|
||||||
// print("******started test 1******");
|
// print("******started test 1******");
|
||||||
// }
|
// }
|
||||||
// |
|
// |
|
||||||
|
@ -287,7 +422,7 @@ void Test::createRecursiveScript() {
|
||||||
textStream << tab << tab << "if (test" << i - 1 << ".complete && test" << i << "HasNotStarted) {" << endl;
|
textStream << tab << tab << "if (test" << i - 1 << ".complete && test" << i << "HasNotStarted) {" << endl;
|
||||||
}
|
}
|
||||||
textStream << tab << tab << tab << "test" << i << "HasNotStarted = false;" << endl;
|
textStream << tab << tab << tab << "test" << i << "HasNotStarted = false;" << endl;
|
||||||
textStream << tab << tab << tab << "test" << i << "." << testFunction << "();" << endl;
|
textStream << tab << tab << tab << "test" << i << "." << testFunction << "(\"auto\");" << endl;
|
||||||
textStream << tab << tab << tab << "print(\"******started test " << i << "******\");" << endl;
|
textStream << tab << tab << tab << "print(\"******started test " << i << "******\");" << endl;
|
||||||
|
|
||||||
textStream << tab << tab << "}" << endl << endl;
|
textStream << tab << tab << "}" << endl << endl;
|
||||||
|
@ -366,6 +501,41 @@ void Test::createTest() {
|
||||||
messageBox.information(0, "Success", "Test images have been created");
|
messageBox.information(0, "Success", "Test images have been created");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Test::deleteOldSnapshots() {
|
||||||
|
// Select folder to start recursing from
|
||||||
|
QString topLevelDirectory = QFileDialog::getExistingDirectory(nullptr, "Please select root folder for snapshot deletion", ".", QFileDialog::ShowDirsOnly);
|
||||||
|
if (topLevelDirectory == "") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Recurse over folders
|
||||||
|
QDirIterator it(topLevelDirectory.toStdString().c_str(), QDirIterator::Subdirectories);
|
||||||
|
while (it.hasNext()) {
|
||||||
|
QString directory = it.next();
|
||||||
|
|
||||||
|
// Only process directories
|
||||||
|
QDir dir(directory);
|
||||||
|
if (!isAValidDirectory(directory)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList sortedImageFilenames = createListOfAllJPEGimagesInDirectory(directory);
|
||||||
|
|
||||||
|
// Delete any file that is a snapshot (NOT the Expected Images)
|
||||||
|
QStringList expectedImages;
|
||||||
|
QStringList resultImages;
|
||||||
|
foreach(QString currentFilename, sortedImageFilenames) {
|
||||||
|
QString fullCurrentFilename = directory + "/" + currentFilename;
|
||||||
|
if (isInSnapshotFilenameFormat(currentFilename)) {
|
||||||
|
if (!QFile::remove(fullCurrentFilename)) {
|
||||||
|
messageBox.critical(0, "Error", "Could not delete existing file: " + currentFilename + "\nSnapshot deletion aborted");
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QStringList Test::createListOfAllJPEGimagesInDirectory(QString pathToImageDirectory) {
|
QStringList Test::createListOfAllJPEGimagesInDirectory(QString pathToImageDirectory) {
|
||||||
imageDirectory = QDir(pathToImageDirectory);
|
imageDirectory = QDir(pathToImageDirectory);
|
||||||
QStringList nameFilters;
|
QStringList nameFilters;
|
||||||
|
@ -374,6 +544,7 @@ QStringList Test::createListOfAllJPEGimagesInDirectory(QString pathToImageDirect
|
||||||
return imageDirectory.entryList(nameFilters, QDir::Files, QDir::Name);
|
return imageDirectory.entryList(nameFilters, QDir::Files, QDir::Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Use regular expressions to check if files are in specific format
|
||||||
bool Test::isInSnapshotFilenameFormat(QString filename) {
|
bool Test::isInSnapshotFilenameFormat(QString filename) {
|
||||||
return (snapshotFilenameFormat.match(filename).hasMatch());
|
return (snapshotFilenameFormat.match(filename).hasMatch());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
//
|
//
|
||||||
// Test.h
|
// Test.h
|
||||||
// zone/ambientLightInheritence
|
|
||||||
//
|
//
|
||||||
// Created by Nissim Hadar on 2 Nov 2017.
|
// Created by Nissim Hadar on 2 Nov 2017.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
|
@ -15,6 +14,7 @@
|
||||||
#include <QtWidgets/QFileDialog>
|
#include <QtWidgets/QFileDialog>
|
||||||
#include <QtWidgets/QMessageBox>
|
#include <QtWidgets/QMessageBox>
|
||||||
#include <QtCore/QRegularExpression>
|
#include <QtCore/QRegularExpression>
|
||||||
|
#include <QProgressBar>
|
||||||
|
|
||||||
#include "ImageComparer.h"
|
#include "ImageComparer.h"
|
||||||
#include "ui/MismatchWindow.h"
|
#include "ui/MismatchWindow.h"
|
||||||
|
@ -23,10 +23,13 @@ class Test {
|
||||||
public:
|
public:
|
||||||
Test();
|
Test();
|
||||||
|
|
||||||
void evaluateTests();
|
void evaluateTests(bool interactiveMode, QProgressBar* progressBar);
|
||||||
void evaluateTestsRecursively();
|
void evaluateTestsRecursively(bool interactiveMode, QProgressBar* progressBar);
|
||||||
void createRecursiveScript();
|
void createRecursiveScript();
|
||||||
void createTest();
|
void createTest();
|
||||||
|
void deleteOldSnapshots();
|
||||||
|
|
||||||
|
bool compareImageLists(QStringList expectedImages, QStringList resultImages, QString testDirectory, bool interactiveMode, QProgressBar* progressBar);
|
||||||
|
|
||||||
QStringList createListOfAllJPEGimagesInDirectory(QString pathToImageDirectory);
|
QStringList createListOfAllJPEGimagesInDirectory(QString pathToImageDirectory);
|
||||||
|
|
||||||
|
@ -35,8 +38,17 @@ public:
|
||||||
|
|
||||||
void importTest(QTextStream& textStream, const QString& testPathname, int testNumber);
|
void importTest(QTextStream& textStream, const QString& testPathname, int testNumber);
|
||||||
|
|
||||||
|
void appendTestResultsToFile(QString testResultsFolderPath, TestFailure testFailure, QPixmap comparisonImage);
|
||||||
|
|
||||||
|
bool createTestResultsFolderPathIfNeeded(QString directory);
|
||||||
|
void zipAndDeleteTestResultsFolder();
|
||||||
|
|
||||||
|
bool isAValidDirectory(QString pathname);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const QString testFilename{ "test.js" };
|
const QString TEST_FILENAME { "test.js" };
|
||||||
|
const QString TEST_RESULTS_FOLDER { "TestResults" };
|
||||||
|
const QString TEST_RESULTS_FILENAME { "TestResults.txt" };
|
||||||
|
|
||||||
QMessageBox messageBox;
|
QMessageBox messageBox;
|
||||||
|
|
||||||
|
@ -49,7 +61,9 @@ private:
|
||||||
|
|
||||||
ImageComparer imageComparer;
|
ImageComparer imageComparer;
|
||||||
|
|
||||||
bool compareImageLists(QStringList expectedImages, QStringList resultImages);
|
|
||||||
|
QString testResultsFolderPath { "" };
|
||||||
|
int index { 1 };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_test_h
|
#endif // hifi_test_h
|
|
@ -34,4 +34,9 @@ enum UserResponse {
|
||||||
USER_RESPONSE_ABORT
|
USER_RESPONSE_ABORT
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Coefficients for luminosity calculation
|
||||||
|
const double R_Y = 0.212655f;
|
||||||
|
const double G_Y = 0.715158f;
|
||||||
|
const double B_Y = 0.072187f;
|
||||||
|
|
||||||
#endif // hifi_common_h
|
#endif // hifi_common_h
|
|
@ -12,14 +12,18 @@
|
||||||
|
|
||||||
AutoTester::AutoTester(QWidget *parent) : QMainWindow(parent) {
|
AutoTester::AutoTester(QWidget *parent) : QMainWindow(parent) {
|
||||||
ui.setupUi(this);
|
ui.setupUi(this);
|
||||||
|
|
||||||
|
ui.checkBoxInteractiveMode->setChecked(true);
|
||||||
|
|
||||||
|
ui.progressBar->setVisible(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoTester::on_evaluateTestsButton_clicked() {
|
void AutoTester::on_evaluateTestsButton_clicked() {
|
||||||
test.evaluateTests();
|
test.evaluateTests(ui.checkBoxInteractiveMode->isChecked(), ui.progressBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoTester::on_evaluateTestsRecursivelyButton_clicked() {
|
void AutoTester::on_evaluateTestsRecursivelyButton_clicked() {
|
||||||
test.evaluateTestsRecursively();
|
test.evaluateTestsRecursively(ui.checkBoxInteractiveMode->isChecked(), ui.progressBar);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AutoTester::on_createRecursiveScriptButton_clicked() {
|
void AutoTester::on_createRecursiveScriptButton_clicked() {
|
||||||
|
@ -30,6 +34,10 @@ void AutoTester::on_createTestButton_clicked() {
|
||||||
test.createTest();
|
test.createTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AutoTester::on_deleteOldSnapshotsButton_clicked() {
|
||||||
|
test.deleteOldSnapshots();
|
||||||
|
}
|
||||||
|
|
||||||
void AutoTester::on_closeButton_clicked() {
|
void AutoTester::on_closeButton_clicked() {
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
|
@ -1,6 +1,5 @@
|
||||||
//
|
//
|
||||||
// AutoTester.h
|
// AutoTester.h
|
||||||
// zone/ambientLightInheritence
|
|
||||||
//
|
//
|
||||||
// Created by Nissim Hadar on 2 Nov 2017.
|
// Created by Nissim Hadar on 2 Nov 2017.
|
||||||
// Copyright 2013 High Fidelity, Inc.
|
// Copyright 2013 High Fidelity, Inc.
|
||||||
|
@ -26,6 +25,7 @@ void on_evaluateTestsButton_clicked();
|
||||||
void on_evaluateTestsRecursivelyButton_clicked();
|
void on_evaluateTestsRecursivelyButton_clicked();
|
||||||
void on_createRecursiveScriptButton_clicked();
|
void on_createRecursiveScriptButton_clicked();
|
||||||
void on_createTestButton_clicked();
|
void on_createTestButton_clicked();
|
||||||
|
void on_deleteOldSnapshotsButton_clicked();
|
||||||
void on_closeButton_clicked();
|
void on_closeButton_clicked();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>286</width>
|
<width>607</width>
|
||||||
<height>470</height>
|
<height>395</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -17,9 +17,9 @@
|
||||||
<widget class="QPushButton" name="closeButton">
|
<widget class="QPushButton" name="closeButton">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>60</x>
|
<x>190</x>
|
||||||
<y>360</y>
|
<y>300</y>
|
||||||
<width>160</width>
|
<width>220</width>
|
||||||
<height>40</height>
|
<height>40</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -30,9 +30,9 @@
|
||||||
<widget class="QPushButton" name="createTestButton">
|
<widget class="QPushButton" name="createTestButton">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>60</x>
|
<x>360</x>
|
||||||
<y>270</y>
|
<y>130</y>
|
||||||
<width>160</width>
|
<width>220</width>
|
||||||
<height>40</height>
|
<height>40</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -43,9 +43,9 @@
|
||||||
<widget class="QPushButton" name="evaluateTestsButton">
|
<widget class="QPushButton" name="evaluateTestsButton">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>60</x>
|
<x>20</x>
|
||||||
<y>20</y>
|
<y>75</y>
|
||||||
<width>160</width>
|
<width>220</width>
|
||||||
<height>40</height>
|
<height>40</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -56,9 +56,9 @@
|
||||||
<widget class="QPushButton" name="createRecursiveScriptButton">
|
<widget class="QPushButton" name="createRecursiveScriptButton">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>60</x>
|
<x>360</x>
|
||||||
<y>210</y>
|
<y>75</y>
|
||||||
<width>160</width>
|
<width>220</width>
|
||||||
<height>40</height>
|
<height>40</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -69,9 +69,9 @@
|
||||||
<widget class="QPushButton" name="evaluateTestsRecursivelyButton">
|
<widget class="QPushButton" name="evaluateTestsRecursivelyButton">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>60</x>
|
<x>20</x>
|
||||||
<y>75</y>
|
<y>130</y>
|
||||||
<width>160</width>
|
<width>220</width>
|
||||||
<height>40</height>
|
<height>40</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -79,13 +79,55 @@
|
||||||
<string>Evaluate Tests Recursively</string>
|
<string>Evaluate Tests Recursively</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QCheckBox" name="checkBoxInteractiveMode">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>23</x>
|
||||||
|
<y>40</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>20</x>
|
||||||
|
<y>190</y>
|
||||||
|
<width>255</width>
|
||||||
|
<height>23</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>24</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QPushButton" name="deleteOldSnapshotsButton">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>360</x>
|
||||||
|
<y>240</y>
|
||||||
|
<width>220</width>
|
||||||
|
<height>40</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Delete Old Snapshots</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QMenuBar" name="menuBar">
|
<widget class="QMenuBar" name="menuBar">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>286</width>
|
<width>607</width>
|
||||||
<height>21</height>
|
<height>21</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
|
|
@ -11,11 +11,48 @@
|
||||||
|
|
||||||
#include <QtCore/QFileInfo>
|
#include <QtCore/QFileInfo>
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
MismatchWindow::MismatchWindow(QWidget *parent) : QDialog(parent) {
|
MismatchWindow::MismatchWindow(QWidget *parent) : QDialog(parent) {
|
||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
expectedImage->setScaledContents(true);
|
expectedImage->setScaledContents(true);
|
||||||
resultImage->setScaledContents(true);
|
resultImage->setScaledContents(true);
|
||||||
|
diffImage->setScaledContents(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap MismatchWindow::computeDiffPixmap(QImage expectedImage, QImage resultImage) {
|
||||||
|
// This is an optimization, as QImage.setPixel() is embarrassingly slow
|
||||||
|
unsigned char* buffer = new unsigned char[expectedImage.height() * expectedImage.width() * 3];
|
||||||
|
|
||||||
|
// loop over each pixel
|
||||||
|
for (int y = 0; y < expectedImage.height(); ++y) {
|
||||||
|
for (int x = 0; x < expectedImage.width(); ++x) {
|
||||||
|
QRgb pixelP = expectedImage.pixel(QPoint(x, y));
|
||||||
|
QRgb pixelQ = resultImage.pixel(QPoint(x, y));
|
||||||
|
|
||||||
|
// Convert to luminance
|
||||||
|
double p = R_Y * qRed(pixelP) + G_Y * qGreen(pixelP) + B_Y * qBlue(pixelP);
|
||||||
|
double q = R_Y * qRed(pixelQ) + G_Y * qGreen(pixelQ) + B_Y * qBlue(pixelQ);
|
||||||
|
|
||||||
|
// The intensity value is modified to increase the brightness of the displayed image
|
||||||
|
double absoluteDifference = fabs(p - q) / 255.0;
|
||||||
|
double modifiedDifference = sqrt(absoluteDifference);
|
||||||
|
|
||||||
|
int difference = (int)(modifiedDifference * 255.0);
|
||||||
|
|
||||||
|
buffer[3 * (x + y * expectedImage.width()) + 0] = difference;
|
||||||
|
buffer[3 * (x + y * expectedImage.width()) + 1] = difference;
|
||||||
|
buffer[3 * (x + y * expectedImage.width()) + 2] = difference;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QImage diffImage(buffer, expectedImage.width(), expectedImage.height(), QImage::Format_RGB888);
|
||||||
|
QPixmap resultPixmap = QPixmap::fromImage(diffImage);
|
||||||
|
|
||||||
|
delete[] buffer;
|
||||||
|
|
||||||
|
return resultPixmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
void MismatchWindow::setTestFailure(TestFailure testFailure) {
|
void MismatchWindow::setTestFailure(TestFailure testFailure) {
|
||||||
|
@ -24,10 +61,19 @@ void MismatchWindow::setTestFailure(TestFailure testFailure) {
|
||||||
imagePath->setText("Path to test: " + testFailure._pathname);
|
imagePath->setText("Path to test: " + testFailure._pathname);
|
||||||
|
|
||||||
expectedFilename->setText(testFailure._expectedImageFilename);
|
expectedFilename->setText(testFailure._expectedImageFilename);
|
||||||
expectedImage->setPixmap(QPixmap(testFailure._pathname + testFailure._expectedImageFilename));
|
|
||||||
|
|
||||||
resultFilename->setText(testFailure._actualImageFilename);
|
resultFilename->setText(testFailure._actualImageFilename);
|
||||||
resultImage->setPixmap(QPixmap(testFailure._pathname + testFailure._actualImageFilename));
|
|
||||||
|
QPixmap expectedPixmap = QPixmap(testFailure._pathname + testFailure._expectedImageFilename);
|
||||||
|
QPixmap actualPixmap = QPixmap(testFailure._pathname + testFailure._actualImageFilename);
|
||||||
|
|
||||||
|
diffPixmap = computeDiffPixmap(
|
||||||
|
QImage(testFailure._pathname + testFailure._expectedImageFilename),
|
||||||
|
QImage(testFailure._pathname + testFailure._actualImageFilename)
|
||||||
|
);
|
||||||
|
|
||||||
|
expectedImage->setPixmap(expectedPixmap);
|
||||||
|
resultImage->setPixmap(actualPixmap);
|
||||||
|
diffImage->setPixmap(diffPixmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MismatchWindow::on_passTestButton_clicked() {
|
void MismatchWindow::on_passTestButton_clicked() {
|
||||||
|
@ -44,3 +90,7 @@ void MismatchWindow::on_abortTestsButton_clicked() {
|
||||||
_userResponse = USER_RESPONSE_ABORT;
|
_userResponse = USER_RESPONSE_ABORT;
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QPixmap MismatchWindow::getComparisonImage() {
|
||||||
|
return diffPixmap;
|
||||||
|
}
|
||||||
|
|
|
@ -25,6 +25,9 @@ public:
|
||||||
|
|
||||||
UserResponse getUserResponse() { return _userResponse; }
|
UserResponse getUserResponse() { return _userResponse; }
|
||||||
|
|
||||||
|
QPixmap computeDiffPixmap(QImage expectedImage, QImage resultImage);
|
||||||
|
QPixmap getComparisonImage();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void on_passTestButton_clicked();
|
void on_passTestButton_clicked();
|
||||||
void on_failTestButton_clicked();
|
void on_failTestButton_clicked();
|
||||||
|
@ -32,6 +35,8 @@ private slots:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
UserResponse _userResponse{ USER_RESPONSE_INVALID };
|
UserResponse _userResponse{ USER_RESPONSE_INVALID };
|
||||||
|
|
||||||
|
QPixmap diffPixmap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>1585</width>
|
<width>1782</width>
|
||||||
<height>694</height>
|
<height>942</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
|
@ -16,10 +16,10 @@
|
||||||
<widget class="QLabel" name="expectedImage">
|
<widget class="QLabel" name="expectedImage">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>20</x>
|
<x>10</x>
|
||||||
<y>170</y>
|
<y>25</y>
|
||||||
<width>720</width>
|
<width>800</width>
|
||||||
<height>362</height>
|
<height>450</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -29,28 +29,41 @@
|
||||||
<widget class="QLabel" name="resultImage">
|
<widget class="QLabel" name="resultImage">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>760</x>
|
<x>900</x>
|
||||||
<y>170</y>
|
<y>25</y>
|
||||||
<width>720</width>
|
<width>800</width>
|
||||||
<height>362</height>
|
<height>450</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>result image</string>
|
<string>result image</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QLabel" name="diffImage">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>540</x>
|
||||||
|
<y>480</y>
|
||||||
|
<width>800</width>
|
||||||
|
<height>450</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>diff image</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
<widget class="QLabel" name="resultFilename">
|
<widget class="QLabel" name="resultFilename">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>760</x>
|
<x>60</x>
|
||||||
<y>90</y>
|
<y>660</y>
|
||||||
<width>800</width>
|
<width>480</width>
|
||||||
<height>28</height>
|
<height>28</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<pointsize>16</pointsize>
|
<pointsize>12</pointsize>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -60,15 +73,15 @@
|
||||||
<widget class="QLabel" name="expectedFilename">
|
<widget class="QLabel" name="expectedFilename">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>40</x>
|
<x>60</x>
|
||||||
<y>90</y>
|
<y>630</y>
|
||||||
<width>700</width>
|
<width>480</width>
|
||||||
<height>28</height>
|
<height>28</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<pointsize>16</pointsize>
|
<pointsize>12</pointsize>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -78,15 +91,15 @@
|
||||||
<widget class="QLabel" name="imagePath">
|
<widget class="QLabel" name="imagePath">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>40</x>
|
<x>20</x>
|
||||||
<y>30</y>
|
<y>600</y>
|
||||||
<width>1200</width>
|
<width>1200</width>
|
||||||
<height>28</height>
|
<height>28</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<pointsize>16</pointsize>
|
<pointsize>12</pointsize>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -97,7 +110,7 @@
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>30</x>
|
<x>30</x>
|
||||||
<y>600</y>
|
<y>790</y>
|
||||||
<width>75</width>
|
<width>75</width>
|
||||||
<height>23</height>
|
<height>23</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
@ -109,8 +122,8 @@
|
||||||
<widget class="QPushButton" name="failTestButton">
|
<widget class="QPushButton" name="failTestButton">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>330</x>
|
<x>120</x>
|
||||||
<y>600</y>
|
<y>790</y>
|
||||||
<width>75</width>
|
<width>75</width>
|
||||||
<height>23</height>
|
<height>23</height>
|
||||||
</rect>
|
</rect>
|
||||||
|
@ -122,34 +135,60 @@
|
||||||
<widget class="QPushButton" name="abortTestsButton">
|
<widget class="QPushButton" name="abortTestsButton">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>630</x>
|
<x>210</x>
|
||||||
<y>600</y>
|
<y>790</y>
|
||||||
<width>75</width>
|
<width>121</width>
|
||||||
<height>23</height>
|
<height>23</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Abort Tests</string>
|
<string>Abort current test</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QLabel" name="errorLabel">
|
<widget class="QLabel" name="errorLabel">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>810</x>
|
<x>30</x>
|
||||||
<y>600</y>
|
<y>850</y>
|
||||||
<width>720</width>
|
<width>500</width>
|
||||||
<height>28</height>
|
<height>28</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<property name="font">
|
<property name="font">
|
||||||
<font>
|
<font>
|
||||||
<pointsize>16</pointsize>
|
<pointsize>12</pointsize>
|
||||||
</font>
|
</font>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>similarity</string>
|
<string>similarity</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
|
<widget class="QLabel" name="label">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>30</x>
|
||||||
|
<y>5</y>
|
||||||
|
<width>151</width>
|
||||||
|
<height>16</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Expected Image</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
<widget class="QLabel" name="label_2">
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>930</x>
|
||||||
|
<y>5</y>
|
||||||
|
<width>151</width>
|
||||||
|
<height>16</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="text">
|
||||||
|
<string>Actual Image</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
</widget>
|
</widget>
|
||||||
<layoutdefault spacing="6" margin="11"/>
|
<layoutdefault spacing="6" margin="11"/>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
|
Loading…
Reference in a new issue