mirror of
https://github.com/overte-org/overte.git
synced 2025-04-19 13:43:49 +02:00
Merge mess...
This commit is contained in:
parent
e39012de6e
commit
e77e2b9583
24 changed files with 112 additions and 4593 deletions
|
@ -1,197 +1,75 @@
|
|||
set(TARGET_NAME nitpick)
|
||||
set (TARGET_NAME nitpick)
|
||||
project(${TARGET_NAME})
|
||||
|
||||
set(CUSTOM_NITPICK_QRC_PATHS "")
|
||||
# Automatically run UIC and MOC. This replaces the older WRAP macros
|
||||
SET (CMAKE_AUTOUIC ON)
|
||||
SET (CMAKE_AUTOMOC ON)
|
||||
|
||||
find_npm()
|
||||
setup_hifi_project (Core Widgets Network Xml)
|
||||
link_hifi_libraries ()
|
||||
|
||||
set(RESOURCES_QRC ${CMAKE_CURRENT_BINARY_DIR}/resources.qrc)
|
||||
set(RESOURCES_RCC ${CMAKE_CURRENT_SOURCE_DIR}/compiledResources/resources.rcc)
|
||||
generate_qrc(OUTPUT ${RESOURCES_QRC} PATH ${CMAKE_CURRENT_SOURCE_DIR}/resources CUSTOM_PATHS ${CUSTOM_NITPICK_QRC_PATHS} GLOBS *)
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${RESOURCES_RCC}
|
||||
DEPENDS ${RESOURCES_QRC} ${GENERATE_QRC_DEPENDS}
|
||||
COMMAND "${QT_DIR}/bin/rcc"
|
||||
ARGS ${RESOURCES_QRC} -binary -o ${RESOURCES_RCC}
|
||||
)
|
||||
|
||||
# grab the implementation and header files from src dirs
|
||||
file(GLOB_RECURSE NITPICK_SRCS "src/*.cpp" "src/*.h")
|
||||
GroupSources("src")
|
||||
list(APPEND NITPICK_SRCS ${RESOURCES_RCC})
|
||||
|
||||
find_package(Qt5 COMPONENTS Widgets)
|
||||
|
||||
# grab the ui files in ui
|
||||
file (GLOB_RECURSE QT_UI_FILES ui/*.ui)
|
||||
source_group("UI Files" FILES ${QT_UI_FILES})
|
||||
|
||||
# have qt5 wrap them and generate the appropriate header files
|
||||
qt5_wrap_ui(QT_UI_HEADERS "${QT_UI_FILES}")
|
||||
|
||||
# add them to the nitpick source files
|
||||
set(NITPICK_SRCS ${NITPICK_SRCS} "${QT_UI_HEADERS}" "${QT_RESOURCES}")
|
||||
|
||||
if (APPLE)
|
||||
# configure CMake to use a custom Info.plist
|
||||
set_target_properties(${this_target} PROPERTIES MACOSX_BUNDLE_INFO_PLIST MacOSXBundleInfo.plist.in)
|
||||
|
||||
if (PRODUCTION_BUILD)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER com.highfidelity.nitpick)
|
||||
else ()
|
||||
if (DEV_BUILD)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER com.highfidelity.nitpick-dev)
|
||||
elseif (PR_BUILD)
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER com.highfidelity.nitpick-pr)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# set how the icon shows up in the Info.plist file
|
||||
set(MACOSX_BUNDLE_ICON_FILE "${NITPICK_ICON_FILENAME}")
|
||||
|
||||
# set where in the bundle to put the resources file
|
||||
set_source_files_properties(${CMAKE_CURRENT_SOURCE_DIR}/icon/${NITPICK_ICON_FILENAME} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
|
||||
|
||||
# append the discovered resources to our list of nitpick sources
|
||||
list(APPEND NITPICK_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/icon/${NITPICK_ICON_FILENAME})
|
||||
# FIX: Qt was built with -reduce-relocations
|
||||
if (Qt5_POSITION_INDEPENDENT_CODE)
|
||||
SET (CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
endif()
|
||||
|
||||
# create the executable, make it a bundle on OS X
|
||||
if (APPLE)
|
||||
add_executable(${TARGET_NAME} MACOSX_BUNDLE ${NITPICK_SRCS} ${QM})
|
||||
# Qt includes
|
||||
include_directories (${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories (${Qt5Core_INCLUDE_DIRS})
|
||||
include_directories (${Qt5Widgets_INCLUDE_DIRS})
|
||||
|
||||
# make sure the output name for the .app bundle is correct
|
||||
# Fix up the rpath so macdeployqt works
|
||||
set_target_properties(${TARGET_NAME} PROPERTIES INSTALL_RPATH "@executable_path/../Frameworks")
|
||||
elseif (WIN32)
|
||||
# configure an rc file for the chosen icon
|
||||
set(CONFIGURE_ICON_PATH "${CMAKE_CURRENT_SOURCE_DIR}/icon/${NITPICK_ICON_FILENAME}")
|
||||
set(CONFIGURE_ICON_RC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/Icon.rc")
|
||||
configure_file("${HF_CMAKE_DIR}/templates/Icon.rc.in" ${CONFIGURE_ICON_RC_OUTPUT})
|
||||
set (QT_LIBRARIES Qt5::Core Qt5::Widgets QT::Gui Qt5::Xml)
|
||||
|
||||
set(APP_FULL_NAME "High Fidelity Nitpick")
|
||||
set(CONFIGURE_VERSION_INFO_RC_OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/VersionInfo.rc")
|
||||
configure_file("${HF_CMAKE_DIR}/templates/VersionInfo.rc.in" ${CONFIGURE_VERSION_INFO_RC_OUTPUT})
|
||||
if (WIN32)
|
||||
# Do not show Console
|
||||
set_property (TARGET nitpick PROPERTY WIN32_EXECUTABLE true)
|
||||
endif()
|
||||
|
||||
# add an executable that also has the icon itself and the configured rc file as resources
|
||||
add_executable(${TARGET_NAME} WIN32 ${NITPICK_SRCS} ${QM} ${CONFIGURE_ICON_RC_OUTPUT} ${CONFIGURE_VERSION_INFO_RC_OUTPUT})
|
||||
else ()
|
||||
add_executable(${TARGET_NAME} ${NITPICK_SRCS} ${QM})
|
||||
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})
|
||||
|
||||
package_libraries_for_deployment()
|
||||
|
||||
if (WIN32)
|
||||
add_paths_to_fixup_libs (${QUAZIP_DLL_PATH})
|
||||
|
||||
find_program(WINDEPLOYQT_COMMAND windeployqt PATHS ${QT_DIR}/bin NO_DEFAULT_PATH)
|
||||
|
||||
if (NOT WINDEPLOYQT_COMMAND)
|
||||
message(FATAL_ERROR "Could not find windeployqt at ${QT_DIR}/bin. windeployqt is required.")
|
||||
endif ()
|
||||
|
||||
# add a post-build command to call windeployqt to copy Qt plugins
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
POST_BUILD
|
||||
COMMAND CMD /C "SET PATH=%PATH%;${QT_DIR}/bin && ${WINDEPLOYQT_COMMAND} ${EXTRA_DEPLOY_OPTIONS} $<$<OR:$<CONFIG:Release>,$<CONFIG:MinSizeRel>,$<CONFIG:RelWithDebInfo>>:--release> \"$<TARGET_FILE:${TARGET_NAME}>\""
|
||||
)
|
||||
|
||||
# add a custom command to copy the empty Apps/Data High Fidelity folder (i.e. - a valid folder with no entities)
|
||||
# this also copied to the containing folder, to facilitate running from Visual Studio
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/AppDataHighFidelity" "$<TARGET_FILE_DIR:${TARGET_NAME}>/AppDataHighFidelity"
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/AppDataHighFidelity" "AppDataHighFidelity"
|
||||
)
|
||||
|
||||
# add a custom command to copy the SSL DLLs
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "$ENV{VCPKG_ROOT}/installed/x64-windows/bin" "$<TARGET_FILE_DIR:${TARGET_NAME}>"
|
||||
)
|
||||
elseif (APPLE)
|
||||
# add a custom command to copy the empty Apps/Data High Fidelity folder (i.e. - a valid folder with no entities)
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/AppDataHighFidelity" "$<TARGET_FILE_DIR:${TARGET_NAME}>/AppDataHighFidelity"
|
||||
)
|
||||
endif ()
|
||||
|
||||
add_dependencies(${TARGET_NAME} resources)
|
||||
|
||||
# disable /OPT:REF and /OPT:ICF for the Debug builds
|
||||
# This will prevent the following linker warnings
|
||||
# LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:ICF' specification
|
||||
if (WIN32)
|
||||
set_property(TARGET ${TARGET_NAME} APPEND_STRING PROPERTY LINK_FLAGS_DEBUG "/OPT:NOREF /OPT:NOICF")
|
||||
endif()
|
||||
|
||||
link_hifi_libraries(entities-renderer)
|
||||
|
||||
# perform standard include and linking for found externals
|
||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||
if (${${EXTERNAL}_UPPERCASE}_REQUIRED)
|
||||
find_package(${EXTERNAL} REQUIRED)
|
||||
else ()
|
||||
find_package(${EXTERNAL})
|
||||
endif ()
|
||||
|
||||
if (${${EXTERNAL}_UPPERCASE}_FOUND AND NOT DISABLE_${${EXTERNAL}_UPPERCASE})
|
||||
add_definitions(-DHAVE_${${EXTERNAL}_UPPERCASE})
|
||||
|
||||
# include the library directories (ignoring warnings)
|
||||
if (NOT ${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS)
|
||||
set(${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS ${${${EXTERNAL}_UPPERCASE}_INCLUDE_DIR})
|
||||
endif ()
|
||||
|
||||
include_directories(SYSTEM ${${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS})
|
||||
|
||||
# perform the system include hack for OS X to ignore warnings
|
||||
if (APPLE)
|
||||
foreach(EXTERNAL_INCLUDE_DIR ${${${EXTERNAL}_UPPERCASE}_INCLUDE_DIRS})
|
||||
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -isystem ${EXTERNAL_INCLUDE_DIR}")
|
||||
endforeach()
|
||||
endif ()
|
||||
|
||||
if (NOT ${${EXTERNAL}_UPPERCASE}_LIBRARIES)
|
||||
set(${${EXTERNAL}_UPPERCASE}_LIBRARIES ${${${EXTERNAL}_UPPERCASE}_LIBRARY})
|
||||
endif ()
|
||||
|
||||
if (NOT APPLE OR NOT ${${EXTERNAL}_UPPERCASE} MATCHES "SIXENSE")
|
||||
target_link_libraries(${TARGET_NAME} ${${${EXTERNAL}_UPPERCASE}_LIBRARIES})
|
||||
elseif (APPLE AND NOT INSTALLER_BUILD)
|
||||
add_definitions(-DSIXENSE_LIB_FILENAME=\"${${${EXTERNAL}_UPPERCASE}_LIBRARY_RELEASE}\")
|
||||
endif ()
|
||||
endif ()
|
||||
endforeach()
|
||||
|
||||
# include headers for nitpick and NitpickConfig.
|
||||
include_directories("${PROJECT_SOURCE_DIR}/src")
|
||||
|
||||
if (UNIX AND NOT ANDROID)
|
||||
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
|
||||
# Linux
|
||||
target_link_libraries(${TARGET_NAME} pthread atomic)
|
||||
else ()
|
||||
# OSX
|
||||
target_link_libraries(${TARGET_NAME} pthread)
|
||||
endif ()
|
||||
endif()
|
||||
|
||||
# add a custom command to copy the empty AppData High Fidelity folder (i.e. - a valid folder with no entities)
|
||||
if (WIN32)
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/AppDataHighFidelity" "$<TARGET_FILE_DIR:${TARGET_NAME}>/AppDataHighFidelity"
|
||||
)
|
||||
|
||||
if (RELEASE_TYPE STREQUAL "DEV")
|
||||
# This to enable running from the IDE
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/AppDataHighFidelity" "AppDataHighFidelity"
|
||||
)
|
||||
endif ()
|
||||
elseif (APPLE)
|
||||
add_custom_command(
|
||||
TARGET ${TARGET_NAME}
|
||||
POST_BUILD
|
||||
COMMAND "${CMAKE_COMMAND}" -E copy_directory "${CMAKE_CURRENT_SOURCE_DIR}/AppDataHighFidelity" "$<TARGET_FILE_DIR:${TARGET_NAME}>/AppDataHighFidelity"
|
||||
)
|
||||
endif()
|
||||
|
||||
if (APPLE)
|
||||
# setup install of OS X nitpick bundle
|
||||
install(TARGETS ${TARGET_NAME}
|
||||
BUNDLE DESTINATION ${NITPICK_INSTALL_DIR}
|
||||
COMPONENT ${CLIENT_COMPONENT}
|
||||
)
|
||||
|
||||
# call the fixup_nitpick macro to add required bundling commands for installation
|
||||
fixup_nitpick()
|
||||
elseif (WIN32)
|
||||
# link target to external libraries
|
||||
# setup install of executable and things copied by fixup/windeployqt
|
||||
install(
|
||||
DIRECTORY "$<TARGET_FILE_DIR:${TARGET_NAME}>/"
|
||||
DESTINATION ${NITPICK_INSTALL_DIR}
|
||||
COMPONENT ${CLIENT_COMPONENT}
|
||||
PATTERN "*.pdb" EXCLUDE
|
||||
PATTERN "*.lib" EXCLUDE
|
||||
PATTERN "*.exp" EXCLUDE
|
||||
)
|
||||
endif()
|
||||
|
||||
if (WIN32)
|
||||
set(EXTRA_DEPLOY_OPTIONS "--qmldir \"${PROJECT_SOURCE_DIR}/resources/qml\"")
|
||||
|
||||
set(TARGET_INSTALL_DIR ${NITPICK_INSTALL_DIR})
|
||||
set(TARGET_INSTALL_COMPONENT ${CLIENT_COMPONENT})
|
||||
|
||||
package_libraries_for_deployment()
|
||||
endif()
|
||||
|
|
|
@ -6,16 +6,42 @@ Nitpick is a stand alone application that provides a mechanism for regression te
|
|||
* The result, if any test failed, is a zipped folder describing the failure.
|
||||
|
||||
Nitpick has 5 functions, separated into separate tabs:
|
||||
|
||||
1. Creating tests, MD files and recursive scripts
|
||||
1. Windows task bar utility (Windows only)
|
||||
1. Running tests
|
||||
1. Evaluating the results of running tests
|
||||
1. Web interface
|
||||
|
||||
## Installation
|
||||
`nitpick` is packaged with High Fidelity PR and Development builds.
|
||||
### Windows
|
||||
## Build (for developers)
|
||||
Nitpick is built as part of the High Fidelity build.
|
||||
### Creating installers
|
||||
#### Windows
|
||||
1. Verify that 7Zip is installed.
|
||||
1. cd to the `build\tools\nitpick\Release` directory
|
||||
1. Delete any existing installers (named nitpick-installer-###.exe)
|
||||
1. Select all, right-click and select 7-Zip->Add to archive...
|
||||
1. Set Archive format to 7z
|
||||
1. Check "Create SFX archive
|
||||
1. Enter installer name (i.e. `nitpick-installer-v1.2.exe`)
|
||||
1. Click "OK"
|
||||
1. Copy created installer to https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.2.exe: aws s3 cp nitpick-installer-v1.2.exe s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.2.exe
|
||||
#### Mac
|
||||
These steps assume the hifi repository has been cloned to `~/hifi`.
|
||||
1. (first time) Install brew
|
||||
In a terminal: `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)`
|
||||
1. (First time) install create-dmg:
|
||||
In a terminal: `brew install create-dmg`
|
||||
1. In a terminal: cd to the `build/tools/nitpick/Release` folder
|
||||
1. Copy the quazip dynamic library (note final period):
|
||||
In a terminal: `cp ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib .`
|
||||
1. Change the loader instruction to find the dynamic library locally
|
||||
In a terminal: `install_name_tool -change ~/hifi/build/ext/Xcode/quazip/project/lib/libquazip5.1.dylib libquazip5.1.dylib nitpick`
|
||||
1. Delete any existing disk images. In a terminal: `rm *.dmg`
|
||||
1. Create installer (note final period).In a terminal: `create-dmg --volname nitpick-installer-v1.2 nitpick-installer-v1.2.dmg .`
|
||||
Make sure to wait for completion.
|
||||
1. Copy created installer to AWS: `~/Library/Python/3.7/bin/aws s3 cp nitpick-installer-v1.2.dmg s3://hifi-qa/nitpick/Mac/nitpick-installer-v1.2.dmg`
|
||||
### Installation
|
||||
#### Windows
|
||||
1. (First time) download and install vc_redist.x64.exe (available at https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.2.exe)
|
||||
1. (First time) download and install Python 3 from https://hifi-qa.s3.amazonaws.com/nitpick/Windows/python-3.7.0-amd64.exe (also located at https://www.python.org/downloads/)
|
||||
1. After installation - create an environment variable called PYTHON_PATH and set it to the folder containing the Python executable.
|
||||
|
@ -26,9 +52,12 @@ Nitpick has 5 functions, separated into separate tabs:
|
|||
1. Leave region name and ouput format as default [None]
|
||||
1. Install the latest release of Boto3 via pip: `pip install boto3`
|
||||
|
||||
1. (First time) Install adb (Android Debug Bridge) from `https://dl.google.com/android/repository/platform-tools-latest-windows.zip`
|
||||
1. Create and environment variable named ADB_PATH and set its value to the installation location (e.g. **C:\adb**)
|
||||
### Mac
|
||||
1. Download the installer by browsing to [here](<https://hifi-qa.s3.amazonaws.com/nitpick/Windows/nitpick-installer-v1.2.exe>)
|
||||
1. Double click on the installer and install to a convenient location
|
||||

|
||||
|
||||
1. __To run nitpick, double click **nitpick.exe**__
|
||||
#### Mac
|
||||
1. (first time) Install brew
|
||||
In a terminal: `/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)`
|
||||
1. (First time) install Qt:
|
||||
|
@ -46,8 +75,17 @@ In a terminal: `python3 get-pip.py --user`
|
|||
1. Enter the AWS account number
|
||||
1. Enter the secret key
|
||||
1. Leave region name and ouput format as default [None]
|
||||
1. Install the latest release of Boto3 via pip: pip3 install boto3
|
||||
1. (First time)Install adb (Android Debug Bridge) from `https://dl.google.com/android/repository/platform-tools-latest-darwin.zip`
|
||||
1. Install the latest release of Boto3 via pip: pip3 install boto3
|
||||
1. Download the installer by browsing to [here](<https://hifi-qa.s3.amazonaws.com/nitpick/Mac/nitpick-installer-v1.2.dmg>).
|
||||
1. Double-click on the downloaded image to mount it
|
||||
1. Create a folder for the nitpick files (e.g. ~/nitpick)
|
||||
If this folder exists then delete all it's contents.
|
||||
1. Copy the downloaded files to the folder
|
||||
In a terminal:
|
||||
`cd ~/nitpick`
|
||||
`cp -r /Volumes/nitpick-installer-v1.2/* .`
|
||||
|
||||
1. __To run nitpick, cd to the folder that you copied to and run `./nitpick`__
|
||||
# Usage
|
||||
## Create
|
||||

|
||||
|
@ -126,7 +164,7 @@ nitpick.runRecursive();
|
|||
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.
|
||||
## Windows (only)
|
||||
## Windows
|
||||

|
||||
|
||||
This tab is Windows-specific. It provides buttons to hide and show the task bar.
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
//
|
||||
// BusyWindow.cpp
|
||||
//
|
||||
// Created by Nissim Hadar on 26 Jul 2017.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "BusyWindow.h"
|
||||
|
||||
BusyWindow::BusyWindow(QWidget *parent) {
|
||||
setupUi(this);
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
//
|
||||
// BusyWindow.h
|
||||
//
|
||||
// Created by Nissim Hadar on 29 Jul 2017.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_BusyWindow_h
|
||||
#define hifi_BusyWindow_h
|
||||
|
||||
#include "ui_BusyWindow.h"
|
||||
|
||||
class BusyWindow : public QDialog, public Ui::BusyWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BusyWindow(QWidget* parent = Q_NULLPTR);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,101 +0,0 @@
|
|||
//
|
||||
// MismatchWindow.cpp
|
||||
//
|
||||
// Created by Nissim Hadar on 9 Nov 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 "MismatchWindow.h"
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
MismatchWindow::MismatchWindow(QWidget *parent) : QDialog(parent) {
|
||||
setupUi(this);
|
||||
|
||||
expectedImage->setScaledContents(true);
|
||||
resultImage->setScaledContents(true);
|
||||
diffImage->setScaledContents(true);
|
||||
}
|
||||
|
||||
QPixmap MismatchWindow::computeDiffPixmap(QImage expectedImage, QImage resultImage) {
|
||||
// Create an empty difference image if the images differ in size
|
||||
if (expectedImage.height() != resultImage.height() || expectedImage.width() != resultImage.width()) {
|
||||
return QPixmap();
|
||||
}
|
||||
|
||||
// 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::setTestResult(TestResult testResult) {
|
||||
errorLabel->setText("Similarity: " + QString::number(testResult._error));
|
||||
|
||||
imagePath->setText("Path to test: " + testResult._pathname);
|
||||
|
||||
expectedFilename->setText(testResult._expectedImageFilename);
|
||||
resultFilename->setText(testResult._actualImageFilename);
|
||||
|
||||
QPixmap expectedPixmap = QPixmap(testResult._pathname + testResult._expectedImageFilename);
|
||||
QPixmap actualPixmap = QPixmap(testResult._pathname + testResult._actualImageFilename);
|
||||
|
||||
_diffPixmap = computeDiffPixmap(
|
||||
QImage(testResult._pathname + testResult._expectedImageFilename),
|
||||
QImage(testResult._pathname + testResult._actualImageFilename)
|
||||
);
|
||||
|
||||
expectedImage->setPixmap(expectedPixmap);
|
||||
resultImage->setPixmap(actualPixmap);
|
||||
diffImage->setPixmap(_diffPixmap);
|
||||
}
|
||||
|
||||
void MismatchWindow::on_passTestButton_clicked() {
|
||||
_userResponse = USER_RESPONSE_PASS;
|
||||
close();
|
||||
}
|
||||
|
||||
void MismatchWindow::on_failTestButton_clicked() {
|
||||
_userResponse = USE_RESPONSE_FAIL;
|
||||
close();
|
||||
}
|
||||
|
||||
void MismatchWindow::on_abortTestsButton_clicked() {
|
||||
_userResponse = USER_RESPONSE_ABORT;
|
||||
close();
|
||||
}
|
||||
|
||||
QPixmap MismatchWindow::getComparisonImage() {
|
||||
return _diffPixmap;
|
||||
}
|
|
@ -1,42 +0,0 @@
|
|||
//
|
||||
// MismatchWindow.h
|
||||
//
|
||||
// Created by Nissim Hadar on 9 Nov 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_MismatchWindow_h
|
||||
#define hifi_MismatchWindow_h
|
||||
|
||||
#include "ui_MismatchWindow.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
class MismatchWindow : public QDialog, public Ui::MismatchWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
MismatchWindow(QWidget *parent = Q_NULLPTR);
|
||||
|
||||
void setTestResult(TestResult testResult);
|
||||
|
||||
UserResponse getUserResponse() { return _userResponse; }
|
||||
|
||||
QPixmap computeDiffPixmap(QImage expectedImage, QImage resultImage);
|
||||
QPixmap getComparisonImage();
|
||||
|
||||
private slots:
|
||||
void on_passTestButton_clicked();
|
||||
void on_failTestButton_clicked();
|
||||
void on_abortTestsButton_clicked();
|
||||
|
||||
private:
|
||||
UserResponse _userResponse{ USER_RESPONSE_INVALID };
|
||||
|
||||
QPixmap _diffPixmap;
|
||||
};
|
||||
|
||||
|
||||
#endif // hifi_MismatchWindow_h
|
|
@ -1,345 +0,0 @@
|
|||
//
|
||||
// Nitpick.cpp
|
||||
// zone/ambientLightInheritence
|
||||
//
|
||||
// Created by Nissim Hadar on 2 Nov 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 "Nitpick.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
#endif
|
||||
|
||||
#include <QDesktopServices>
|
||||
|
||||
Nitpick::Nitpick(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, &Nitpick::on_closePushbutton_clicked);
|
||||
connect(_ui.actionAbout, &QAction::triggered, this, &Nitpick::about);
|
||||
connect(_ui.actionContent, &QAction::triggered, this, &Nitpick::content);
|
||||
|
||||
// The second tab hides and shows the Windows task bar
|
||||
#ifndef Q_OS_WIN
|
||||
_ui.tabWidget->removeTab(1);
|
||||
#endif
|
||||
|
||||
_ui.statusLabel->setText("");
|
||||
_ui.plainTextEdit->setReadOnly(true);
|
||||
|
||||
setWindowTitle("Nitpick - v2.0.1");
|
||||
}
|
||||
|
||||
Nitpick::~Nitpick() {
|
||||
delete _signalMapper;
|
||||
|
||||
if (_test) {
|
||||
delete _test;
|
||||
}
|
||||
|
||||
if (_testRunnerDesktop) {
|
||||
delete _testRunnerDesktop;
|
||||
}
|
||||
|
||||
if (_testRunnerMobile) {
|
||||
delete _testRunnerMobile;
|
||||
}
|
||||
}
|
||||
|
||||
void Nitpick::setup() {
|
||||
if (_test) {
|
||||
delete _test;
|
||||
}
|
||||
_test = new Test(_ui.progressBar, _ui.checkBoxInteractiveMode);
|
||||
|
||||
std::vector<QCheckBox*> dayCheckboxes;
|
||||
dayCheckboxes.emplace_back(_ui.mondayCheckBox);
|
||||
dayCheckboxes.emplace_back(_ui.tuesdayCheckBox);
|
||||
dayCheckboxes.emplace_back(_ui.wednesdayCheckBox);
|
||||
dayCheckboxes.emplace_back(_ui.thursdayCheckBox);
|
||||
dayCheckboxes.emplace_back(_ui.fridayCheckBox);
|
||||
dayCheckboxes.emplace_back(_ui.saturdayCheckBox);
|
||||
dayCheckboxes.emplace_back(_ui.sundayCheckBox);
|
||||
|
||||
std::vector<QCheckBox*> timeEditCheckboxes;
|
||||
timeEditCheckboxes.emplace_back(_ui.timeEdit1checkBox);
|
||||
timeEditCheckboxes.emplace_back(_ui.timeEdit2checkBox);
|
||||
timeEditCheckboxes.emplace_back(_ui.timeEdit3checkBox);
|
||||
timeEditCheckboxes.emplace_back(_ui.timeEdit4checkBox);
|
||||
|
||||
std::vector<QTimeEdit*> timeEdits;
|
||||
timeEdits.emplace_back(_ui.timeEdit1);
|
||||
timeEdits.emplace_back(_ui.timeEdit2);
|
||||
timeEdits.emplace_back(_ui.timeEdit3);
|
||||
timeEdits.emplace_back(_ui.timeEdit4);
|
||||
|
||||
// Create the two test runners
|
||||
if (_testRunnerDesktop) {
|
||||
delete _testRunnerDesktop;
|
||||
}
|
||||
_testRunnerDesktop = new TestRunnerDesktop(dayCheckboxes, timeEditCheckboxes, timeEdits, _ui.workingFolderRunOnDesktopLabel, _ui.checkBoxServerless, _ui.runLatestOnDesktopCheckBox, _ui.urlOnDesktopLineEdit, _ui.runNowPushbutton);
|
||||
|
||||
if (_testRunnerMobile) {
|
||||
delete _testRunnerMobile;
|
||||
}
|
||||
_testRunnerMobile = new TestRunnerMobile(_ui.workingFolderRunOnMobileLabel, _ui.connectDevicePushbutton, _ui.pullFolderPushbutton, _ui.detectedDeviceLabel, _ui.folderLineEdit);
|
||||
}
|
||||
|
||||
void Nitpick::startTestsEvaluation(const bool isRunningFromCommandLine,
|
||||
const bool isRunningInAutomaticTestRun,
|
||||
const QString& snapshotDirectory,
|
||||
const QString& branch,
|
||||
const QString& user
|
||||
) {
|
||||
_test->startTestsEvaluation(isRunningFromCommandLine, isRunningInAutomaticTestRun, snapshotDirectory, branch, user);
|
||||
}
|
||||
|
||||
void Nitpick::on_tabWidget_currentChanged(int index) {
|
||||
// Enable the GitHub edit boxes as required
|
||||
#ifdef Q_OS_WIN
|
||||
if (index == 0 || index == 2 || index == 3 || index == 4) {
|
||||
#else
|
||||
if (index == 0 || index == 1 || index == 2 || index == 3) {
|
||||
#endif
|
||||
_ui.userLineEdit->setDisabled(false);
|
||||
_ui.branchLineEdit->setDisabled(false);
|
||||
} else {
|
||||
_ui.userLineEdit->setDisabled(true);
|
||||
_ui.branchLineEdit->setDisabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
void Nitpick::on_evaluateTestsPushbutton_clicked() {
|
||||
_test->startTestsEvaluation(false, false);
|
||||
}
|
||||
|
||||
void Nitpick::on_createRecursiveScriptPushbutton_clicked() {
|
||||
_test->createRecursiveScript();
|
||||
}
|
||||
|
||||
void Nitpick::on_createAllRecursiveScriptsPushbutton_clicked() {
|
||||
_test->createAllRecursiveScripts();
|
||||
}
|
||||
|
||||
void Nitpick::on_createTestsPushbutton_clicked() {
|
||||
_test->createTests();
|
||||
}
|
||||
|
||||
void Nitpick::on_createMDFilePushbutton_clicked() {
|
||||
_test->createMDFile();
|
||||
}
|
||||
|
||||
void Nitpick::on_createAllMDFilesPushbutton_clicked() {
|
||||
_test->createAllMDFiles();
|
||||
}
|
||||
|
||||
void Nitpick::on_createTestAutoScriptPushbutton_clicked() {
|
||||
_test->createTestAutoScript();
|
||||
}
|
||||
|
||||
void Nitpick::on_createAllTestAutoScriptsPushbutton_clicked() {
|
||||
_test->createAllTestAutoScripts();
|
||||
}
|
||||
|
||||
void Nitpick::on_createTestsOutlinePushbutton_clicked() {
|
||||
_test->createTestsOutline();
|
||||
}
|
||||
|
||||
void Nitpick::on_createTestRailTestCasesPushbutton_clicked() {
|
||||
_test->createTestRailTestCases();
|
||||
}
|
||||
|
||||
void Nitpick::on_createTestRailRunButton_clicked() {
|
||||
_test->createTestRailRun();
|
||||
}
|
||||
|
||||
void Nitpick::on_setWorkingFolderRunOnDesktopPushbutton_clicked() {
|
||||
_testRunnerDesktop->setWorkingFolderAndEnableControls();
|
||||
}
|
||||
|
||||
void Nitpick::enableRunTabControls() {
|
||||
_ui.runNowPushbutton->setEnabled(true);
|
||||
_ui.daysGroupBox->setEnabled(true);
|
||||
_ui.timesGroupBox->setEnabled(true);
|
||||
}
|
||||
|
||||
void Nitpick::on_runNowPushbutton_clicked() {
|
||||
_testRunnerDesktop->run();
|
||||
}
|
||||
|
||||
void Nitpick::on_runLatestOnDesktopCheckBox_clicked() {
|
||||
_ui.urlOnDesktopLineEdit->setEnabled(!_ui.runLatestOnDesktopCheckBox->isChecked());
|
||||
}
|
||||
|
||||
void Nitpick::automaticTestRunEvaluationComplete(QString zippedFolderName, int numberOfFailures) {
|
||||
_testRunnerDesktop->automaticTestRunEvaluationComplete(zippedFolderName, numberOfFailures);
|
||||
}
|
||||
|
||||
void Nitpick::on_updateTestRailRunResultsPushbutton_clicked() {
|
||||
_test->updateTestRailRunResult();
|
||||
}
|
||||
|
||||
// To toggle between show and hide
|
||||
// if (uState & ABS_AUTOHIDE) on_showTaskbarButton_clicked();
|
||||
// else on_hideTaskbarButton_clicked();
|
||||
//
|
||||
void Nitpick::on_hideTaskbarPushbutton_clicked() {
|
||||
#ifdef Q_OS_WIN
|
||||
APPBARDATA abd = { sizeof abd };
|
||||
UINT uState = (UINT)SHAppBarMessage(ABM_GETSTATE, &abd);
|
||||
LPARAM param = uState & ABS_ALWAYSONTOP;
|
||||
abd.lParam = ABS_AUTOHIDE | param;
|
||||
SHAppBarMessage(ABM_SETSTATE, &abd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Nitpick::on_showTaskbarPushbutton_clicked() {
|
||||
#ifdef Q_OS_WIN
|
||||
APPBARDATA abd = { sizeof abd };
|
||||
UINT uState = (UINT)SHAppBarMessage(ABM_GETSTATE, &abd);
|
||||
LPARAM param = uState & ABS_ALWAYSONTOP;
|
||||
abd.lParam = param;
|
||||
SHAppBarMessage(ABM_SETSTATE, &abd);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Nitpick::on_closePushbutton_clicked() {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
void Nitpick::on_createPythonScriptRadioButton_clicked() {
|
||||
_test->setTestRailCreateMode(PYTHON);
|
||||
}
|
||||
|
||||
void Nitpick::on_createXMLScriptRadioButton_clicked() {
|
||||
_test->setTestRailCreateMode(XML);
|
||||
}
|
||||
|
||||
void Nitpick::on_createWebPagePushbutton_clicked() {
|
||||
_test->createWebPage(_ui.updateAWSCheckBox, _ui.awsURLLineEdit);
|
||||
}
|
||||
|
||||
void Nitpick::downloadFile(const QUrl& url) {
|
||||
_downloaders.emplace_back(new Downloader(url, this));
|
||||
connect(_downloaders[_index], SIGNAL(downloaded()), _signalMapper, SLOT(map()));
|
||||
|
||||
_signalMapper->setMapping(_downloaders[_index], _index);
|
||||
|
||||
++_index;
|
||||
}
|
||||
|
||||
void Nitpick::downloadFiles(const QStringList& URLs, const QString& directoryName, const QStringList& filenames, void *caller) {
|
||||
connect(_signalMapper, SIGNAL(mapped(int)), this, SLOT(saveFile(int)));
|
||||
|
||||
_directoryName = directoryName;
|
||||
_filenames = filenames;
|
||||
_caller = caller;
|
||||
|
||||
_numberOfFilesToDownload = URLs.size();
|
||||
_numberOfFilesDownloaded = 0;
|
||||
_index = 0;
|
||||
|
||||
_ui.progressBar->setMinimum(0);
|
||||
_ui.progressBar->setMaximum(_numberOfFilesToDownload - 1);
|
||||
_ui.progressBar->setValue(0);
|
||||
_ui.progressBar->setVisible(true);
|
||||
|
||||
foreach (auto downloader, _downloaders) {
|
||||
delete downloader;
|
||||
}
|
||||
|
||||
_downloaders.clear();
|
||||
for (int i = 0; i < _numberOfFilesToDownload; ++i) {
|
||||
downloadFile(URLs[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void Nitpick::saveFile(int index) {
|
||||
try {
|
||||
QFile file(_directoryName + "/" + _filenames[index]);
|
||||
file.open(QIODevice::WriteOnly);
|
||||
file.write(_downloaders[index]->downloadedData());
|
||||
file.close();
|
||||
} catch (...) {
|
||||
QMessageBox::information(0, "Test Aborted", "Failed to save file: " + _filenames[index]);
|
||||
_ui.progressBar->setVisible(false);
|
||||
return;
|
||||
}
|
||||
|
||||
++_numberOfFilesDownloaded;
|
||||
|
||||
if (_numberOfFilesDownloaded == _numberOfFilesToDownload) {
|
||||
disconnect(_signalMapper, SIGNAL(mapped(int)), this, SLOT(saveFile(int)));
|
||||
if (_caller == _test) {
|
||||
_test->finishTestsEvaluation();
|
||||
} else if (_caller == _testRunnerDesktop) {
|
||||
_testRunnerDesktop->downloadComplete();
|
||||
}
|
||||
} else {
|
||||
_ui.progressBar->setValue(_numberOfFilesDownloaded);
|
||||
}
|
||||
}
|
||||
|
||||
void Nitpick::about() {
|
||||
QMessageBox::information(0, "About", QString("Built ") + __DATE__ + ", " + __TIME__);
|
||||
}
|
||||
|
||||
void Nitpick::content() {
|
||||
QDesktopServices::openUrl(QUrl("https://github.com/highfidelity/hifi/blob/master/tools/nitpick/README.md"));
|
||||
}
|
||||
|
||||
void Nitpick::setUserText(const QString& user) {
|
||||
_ui.userLineEdit->setText(user);
|
||||
}
|
||||
|
||||
QString Nitpick::getSelectedUser() {
|
||||
return _ui.userLineEdit->text();
|
||||
}
|
||||
|
||||
void Nitpick::setBranchText(const QString& branch) {
|
||||
_ui.branchLineEdit->setText(branch);
|
||||
}
|
||||
|
||||
QString Nitpick::getSelectedBranch() {
|
||||
return _ui.branchLineEdit->text();
|
||||
}
|
||||
|
||||
void Nitpick::updateStatusLabel(const QString& status) {
|
||||
_ui.statusLabel->setText(status);
|
||||
}
|
||||
|
||||
void Nitpick::appendLogWindow(const QString& message) {
|
||||
_ui.plainTextEdit->appendPlainText(message);
|
||||
}
|
||||
|
||||
// Test on Mobile
|
||||
void Nitpick::on_setWorkingFolderRunOnMobilePushbutton_clicked() {
|
||||
_testRunnerMobile->setWorkingFolderAndEnableControls();
|
||||
}
|
||||
|
||||
void Nitpick::on_connectDevicePushbutton_clicked() {
|
||||
_testRunnerMobile->connectDevice();
|
||||
}
|
||||
|
||||
void Nitpick::on_runLatestOnMobileCheckBox_clicked() {
|
||||
_ui.urlOnMobileLineEdit->setEnabled(!_ui.runLatestOnMobileCheckBox->isChecked());
|
||||
}
|
||||
|
||||
void Nitpick::on_downloadAPKPushbutton_clicked() {
|
||||
_testRunnerMobile->downloadAPK();
|
||||
}
|
||||
|
||||
void Nitpick::on_pullFolderPushbutton_clicked() {
|
||||
_testRunnerMobile->pullFolder();
|
||||
}
|
|
@ -1,132 +0,0 @@
|
|||
//
|
||||
// Nitpick.h
|
||||
//
|
||||
// Created by Nissim Hadar on 2 Nov 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_Nitpick_h
|
||||
#define hifi_Nitpick_h
|
||||
|
||||
#include <QtWidgets/QMainWindow>
|
||||
#include <QSignalMapper>
|
||||
#include <QTextEdit>
|
||||
#include "ui_Nitpick.h"
|
||||
|
||||
#include "Downloader.h"
|
||||
#include "Test.h"
|
||||
|
||||
#include "TestRunnerDesktop.h"
|
||||
#include "TestRunnerMobile.h"
|
||||
|
||||
#include "AWSInterface.h"
|
||||
|
||||
class Nitpick : public QMainWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
Nitpick(QWidget* parent = Q_NULLPTR);
|
||||
~Nitpick();
|
||||
|
||||
void setup();
|
||||
|
||||
void startTestsEvaluation(const bool isRunningFromCommandLine,
|
||||
const bool isRunningInAutomaticTestRun,
|
||||
const QString& snapshotDirectory,
|
||||
const QString& branch,
|
||||
const QString& user);
|
||||
|
||||
void automaticTestRunEvaluationComplete(QString zippedFolderName, int numberOfFailures);
|
||||
|
||||
void downloadFile(const QUrl& url);
|
||||
void downloadFiles(const QStringList& URLs, const QString& directoryName, const QStringList& filenames, void* caller);
|
||||
|
||||
void setUserText(const QString& user);
|
||||
QString getSelectedUser();
|
||||
|
||||
void setBranchText(const QString& branch);
|
||||
QString getSelectedBranch();
|
||||
|
||||
void enableRunTabControls();
|
||||
|
||||
void updateStatusLabel(const QString& status);
|
||||
void appendLogWindow(const QString& message);
|
||||
|
||||
private slots:
|
||||
void on_closePushbutton_clicked();
|
||||
|
||||
void on_tabWidget_currentChanged(int index);
|
||||
|
||||
void on_evaluateTestsPushbutton_clicked();
|
||||
void on_createRecursiveScriptPushbutton_clicked();
|
||||
void on_createAllRecursiveScriptsPushbutton_clicked();
|
||||
void on_createTestsPushbutton_clicked();
|
||||
|
||||
void on_createMDFilePushbutton_clicked();
|
||||
void on_createAllMDFilesPushbutton_clicked();
|
||||
|
||||
void on_createTestAutoScriptPushbutton_clicked();
|
||||
void on_createAllTestAutoScriptsPushbutton_clicked();
|
||||
|
||||
void on_createTestsOutlinePushbutton_clicked();
|
||||
|
||||
void on_createTestRailTestCasesPushbutton_clicked();
|
||||
void on_createTestRailRunButton_clicked();
|
||||
|
||||
void on_setWorkingFolderRunOnDesktopPushbutton_clicked();
|
||||
void on_runNowPushbutton_clicked();
|
||||
|
||||
void on_runLatestOnDesktopCheckBox_clicked();
|
||||
|
||||
void on_updateTestRailRunResultsPushbutton_clicked();
|
||||
|
||||
void on_hideTaskbarPushbutton_clicked();
|
||||
void on_showTaskbarPushbutton_clicked();
|
||||
|
||||
void on_createPythonScriptRadioButton_clicked();
|
||||
void on_createXMLScriptRadioButton_clicked();
|
||||
|
||||
void on_createWebPagePushbutton_clicked();
|
||||
|
||||
void saveFile(int index);
|
||||
|
||||
void about();
|
||||
void content();
|
||||
|
||||
// Run on Mobile controls
|
||||
void on_setWorkingFolderRunOnMobilePushbutton_clicked();
|
||||
void on_connectDevicePushbutton_clicked();
|
||||
void on_runLatestOnMobileCheckBox_clicked();
|
||||
void on_downloadAPKPushbutton_clicked();
|
||||
void on_pullFolderPushbutton_clicked();
|
||||
|
||||
private:
|
||||
Ui::NitpickClass _ui;
|
||||
Test* _test{ nullptr };
|
||||
|
||||
TestRunnerDesktop* _testRunnerDesktop{ nullptr };
|
||||
TestRunnerMobile* _testRunnerMobile{ nullptr };
|
||||
|
||||
AWSInterface _awsInterface;
|
||||
|
||||
std::vector<Downloader*> _downloaders;
|
||||
|
||||
// local storage for parameters - folder to store downloaded files in, and a list of their names
|
||||
QString _directoryName;
|
||||
QStringList _filenames;
|
||||
|
||||
// Used to enable passing a parameter to slots
|
||||
QSignalMapper* _signalMapper;
|
||||
|
||||
int _numberOfFilesToDownload{ 0 };
|
||||
int _numberOfFilesDownloaded{ 0 };
|
||||
int _index{ 0 };
|
||||
|
||||
bool _isRunningFromCommandline{ false };
|
||||
|
||||
void* _caller;
|
||||
};
|
||||
|
||||
#endif // hifi_Nitpick_h
|
|
@ -1,106 +0,0 @@
|
|||
//
|
||||
// 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);
|
||||
suiteIDLineEdit->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);
|
||||
suiteIDLineEdit->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();
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
//
|
||||
// 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
|
|
@ -1,101 +0,0 @@
|
|||
//
|
||||
// TestRailRunSelectorWindow.cpp
|
||||
//
|
||||
// Created by Nissim Hadar on 31 Jul 2017.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "TestRailRunSelectorWindow.h"
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
TestRailRunSelectorWindow::TestRailRunSelectorWindow(QWidget *parent) {
|
||||
setupUi(this);
|
||||
|
||||
projectIDLineEdit->setValidator(new QIntValidator(1, 999, this));
|
||||
}
|
||||
|
||||
void TestRailRunSelectorWindow::reset() {
|
||||
urlLineEdit->setDisabled(false);
|
||||
userLineEdit->setDisabled(false);
|
||||
passwordLineEdit->setDisabled(false);
|
||||
projectIDLineEdit->setDisabled(false);
|
||||
suiteIDLineEdit->setDisabled(false);
|
||||
|
||||
OKButton->setDisabled(true);
|
||||
sectionsComboBox->setDisabled(true);
|
||||
}
|
||||
|
||||
void TestRailRunSelectorWindow::on_acceptButton_clicked() {
|
||||
urlLineEdit->setDisabled(true);
|
||||
userLineEdit->setDisabled(true);
|
||||
passwordLineEdit->setDisabled(true);
|
||||
projectIDLineEdit->setDisabled(true);
|
||||
suiteIDLineEdit->setDisabled(true);
|
||||
|
||||
OKButton->setDisabled(false);
|
||||
sectionsComboBox->setDisabled(false);
|
||||
close();
|
||||
}
|
||||
|
||||
void TestRailRunSelectorWindow::on_OKButton_clicked() {
|
||||
userCancelled = false;
|
||||
close();
|
||||
}
|
||||
|
||||
void TestRailRunSelectorWindow::on_cancelButton_clicked() {
|
||||
userCancelled = true;
|
||||
close();
|
||||
}
|
||||
|
||||
bool TestRailRunSelectorWindow::getUserCancelled() {
|
||||
return userCancelled;
|
||||
}
|
||||
|
||||
void TestRailRunSelectorWindow::setURL(const QString& user) {
|
||||
urlLineEdit->setText(user);
|
||||
}
|
||||
|
||||
QString TestRailRunSelectorWindow::getURL() {
|
||||
return urlLineEdit->text();
|
||||
}
|
||||
|
||||
void TestRailRunSelectorWindow::setUser(const QString& user) {
|
||||
userLineEdit->setText(user);
|
||||
}
|
||||
|
||||
QString TestRailRunSelectorWindow::getUser() {
|
||||
return userLineEdit->text();
|
||||
}
|
||||
|
||||
QString TestRailRunSelectorWindow::getPassword() {
|
||||
return passwordLineEdit->text();
|
||||
}
|
||||
|
||||
void TestRailRunSelectorWindow::setProjectID(const int project) {
|
||||
projectIDLineEdit->setText(QString::number(project));
|
||||
}
|
||||
|
||||
int TestRailRunSelectorWindow::getProjectID() {
|
||||
return projectIDLineEdit->text().toInt();
|
||||
}
|
||||
|
||||
void TestRailRunSelectorWindow::setSuiteID(const int project) {
|
||||
suiteIDLineEdit->setText(QString::number(project));
|
||||
}
|
||||
|
||||
int TestRailRunSelectorWindow::getSuiteID() {
|
||||
return suiteIDLineEdit->text().toInt();
|
||||
}
|
||||
|
||||
void TestRailRunSelectorWindow::updateSectionsComboBoxData(QStringList data) {
|
||||
sectionsComboBox->insertItems(0, data);
|
||||
}
|
||||
|
||||
int TestRailRunSelectorWindow::getSectionID() {
|
||||
return sectionsComboBox->currentIndex();
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
//
|
||||
// TestRailRunSelectorWindow.h
|
||||
//
|
||||
// Created by Nissim Hadar on 31 Jul 2017.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_TestRailRunSelectorWindow_h
|
||||
#define hifi_TestRailRunSelectorWindow_h
|
||||
|
||||
#include "ui_TestRailRunSelectorWindow.h"
|
||||
|
||||
class TestRailRunSelectorWindow : public QDialog, public Ui::TestRailRunSelectorWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TestRailRunSelectorWindow(QWidget* parent = Q_NULLPTR);
|
||||
|
||||
void reset();
|
||||
|
||||
bool getUserCancelled();
|
||||
|
||||
void setURL(const QString& user);
|
||||
QString getURL();
|
||||
|
||||
void setUser(const QString& user);
|
||||
QString getUser();
|
||||
|
||||
QString getPassword();
|
||||
|
||||
void setProjectID(const int project);
|
||||
int getProjectID();
|
||||
|
||||
void setSuiteID(const int project);
|
||||
int getSuiteID();
|
||||
|
||||
bool userCancelled{ false };
|
||||
|
||||
void updateSectionsComboBoxData(QStringList data);
|
||||
int getSectionID();
|
||||
|
||||
private slots:
|
||||
void on_acceptButton_clicked();
|
||||
void on_OKButton_clicked();
|
||||
void on_cancelButton_clicked();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,106 +0,0 @@
|
|||
//
|
||||
// TestRailTestCasesSelectorWindow.cpp
|
||||
//
|
||||
// Created by Nissim Hadar on 26 Jul 2017.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "TestRailTestCasesSelectorWindow.h"
|
||||
|
||||
#include <QtCore/QFileInfo>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
TestRailTestCasesSelectorWindow::TestRailTestCasesSelectorWindow(QWidget *parent) {
|
||||
setupUi(this);
|
||||
|
||||
projectIDLineEdit->setValidator(new QIntValidator(1, 999, this));
|
||||
}
|
||||
|
||||
|
||||
void TestRailTestCasesSelectorWindow::reset() {
|
||||
urlLineEdit->setDisabled(false);
|
||||
userLineEdit->setDisabled(false);
|
||||
passwordLineEdit->setDisabled(false);
|
||||
projectIDLineEdit->setDisabled(false);
|
||||
suiteIDLineEdit->setDisabled(false);
|
||||
|
||||
OKButton->setDisabled(true);
|
||||
|
||||
releasesLabel->setDisabled(true);
|
||||
releasesComboBox->setDisabled(true);
|
||||
}
|
||||
|
||||
void TestRailTestCasesSelectorWindow::on_acceptButton_clicked() {
|
||||
urlLineEdit->setDisabled(true);
|
||||
userLineEdit->setDisabled(true);
|
||||
passwordLineEdit->setDisabled(true);
|
||||
projectIDLineEdit->setDisabled(true);
|
||||
suiteIDLineEdit->setDisabled(true);
|
||||
|
||||
OKButton->setDisabled(false);
|
||||
|
||||
releasesLabel->setDisabled(false);
|
||||
releasesComboBox->setDisabled(false);
|
||||
close();
|
||||
}
|
||||
|
||||
void TestRailTestCasesSelectorWindow::on_OKButton_clicked() {
|
||||
userCancelled = false;
|
||||
close();
|
||||
}
|
||||
|
||||
void TestRailTestCasesSelectorWindow::on_cancelButton_clicked() {
|
||||
userCancelled = true;
|
||||
close();
|
||||
}
|
||||
|
||||
bool TestRailTestCasesSelectorWindow::getUserCancelled() {
|
||||
return userCancelled;
|
||||
}
|
||||
|
||||
void TestRailTestCasesSelectorWindow::setURL(const QString& user) {
|
||||
urlLineEdit->setText(user);
|
||||
}
|
||||
|
||||
QString TestRailTestCasesSelectorWindow::getURL() {
|
||||
return urlLineEdit->text();
|
||||
}
|
||||
|
||||
void TestRailTestCasesSelectorWindow::setUser(const QString& user) {
|
||||
userLineEdit->setText(user);
|
||||
}
|
||||
|
||||
QString TestRailTestCasesSelectorWindow::getUser() {
|
||||
return userLineEdit->text();
|
||||
}
|
||||
|
||||
QString TestRailTestCasesSelectorWindow::getPassword() {
|
||||
return passwordLineEdit->text();
|
||||
}
|
||||
|
||||
void TestRailTestCasesSelectorWindow::setProjectID(const int project) {
|
||||
projectIDLineEdit->setText(QString::number(project));
|
||||
}
|
||||
|
||||
int TestRailTestCasesSelectorWindow::getProjectID() {
|
||||
return projectIDLineEdit->text().toInt();
|
||||
}
|
||||
|
||||
void TestRailTestCasesSelectorWindow::setSuiteID(const int project) {
|
||||
suiteIDLineEdit->setText(QString::number(project));
|
||||
}
|
||||
|
||||
int TestRailTestCasesSelectorWindow::getSuiteID() {
|
||||
return suiteIDLineEdit->text().toInt();
|
||||
}
|
||||
|
||||
void TestRailTestCasesSelectorWindow::updateReleasesComboBoxData(QStringList data) {
|
||||
releasesComboBox->insertItems(0, data);
|
||||
}
|
||||
|
||||
int TestRailTestCasesSelectorWindow::getReleaseID() {
|
||||
return releasesComboBox->currentIndex();
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
//
|
||||
// TestRailTestCasesSelectorWindow.h
|
||||
//
|
||||
// Created by Nissim Hadar on 26 Jul 2017.
|
||||
// Copyright 2013 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#ifndef hifi_TestRailTestCasesSelectorWindow_h
|
||||
#define hifi_TestRailTestCasesSelectorWindow_h
|
||||
|
||||
#include "ui_TestRailTestCasesSelectorWindow.h"
|
||||
|
||||
class TestRailTestCasesSelectorWindow : public QDialog, public Ui::TestRailTestCasesSelectorWindow {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
TestRailTestCasesSelectorWindow(QWidget* parent = Q_NULLPTR);
|
||||
|
||||
void reset();
|
||||
|
||||
bool getUserCancelled();
|
||||
|
||||
void setURL(const QString& user);
|
||||
QString getURL();
|
||||
|
||||
void setUser(const QString& user);
|
||||
QString getUser();
|
||||
|
||||
QString getPassword();
|
||||
|
||||
void setProjectID(const int project);
|
||||
int getProjectID();
|
||||
|
||||
void setSuiteID(const int project);
|
||||
int getSuiteID();
|
||||
|
||||
bool userCancelled{ false };
|
||||
|
||||
void updateReleasesComboBoxData(QStringList data);
|
||||
int getReleaseID();
|
||||
|
||||
private slots:
|
||||
void on_acceptButton_clicked();
|
||||
void on_OKButton_clicked();
|
||||
void on_cancelButton_clicked();
|
||||
};
|
||||
|
||||
#endif
|
|
@ -1,805 +0,0 @@
|
|||
//
|
||||
// TestRunnerDesktop.cpp
|
||||
//
|
||||
// Created by Nissim Hadar on 1 Sept 2018.
|
||||
// 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 "TestRunnerDesktop.h"
|
||||
|
||||
#include <QThread>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
|
||||
#include "Nitpick.h"
|
||||
extern Nitpick* nitpick;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <windows.h>
|
||||
#include <tlhelp32.h>
|
||||
#endif
|
||||
|
||||
TestRunnerDesktop::TestRunnerDesktop(std::vector<QCheckBox*> dayCheckboxes,
|
||||
std::vector<QCheckBox*> timeEditCheckboxes,
|
||||
std::vector<QTimeEdit*> timeEdits,
|
||||
QLabel* workingFolderLabel,
|
||||
QCheckBox* runServerless,
|
||||
QCheckBox* runLatest,
|
||||
QLineEdit* url,
|
||||
QPushButton* runNow,
|
||||
QObject* parent) :
|
||||
QObject(parent) {
|
||||
_dayCheckboxes = dayCheckboxes;
|
||||
_timeEditCheckboxes = timeEditCheckboxes;
|
||||
_timeEdits = timeEdits;
|
||||
_workingFolderLabel = workingFolderLabel;
|
||||
_runServerless = runServerless;
|
||||
_runLatest = runLatest;
|
||||
_url = url;
|
||||
_runNow = runNow;
|
||||
|
||||
_installerThread = new QThread();
|
||||
_installerWorker = new InstallerWorker();
|
||||
|
||||
_installerWorker->moveToThread(_installerThread);
|
||||
_installerThread->start();
|
||||
connect(this, SIGNAL(startInstaller()), _installerWorker, SLOT(runCommand()));
|
||||
connect(_installerWorker, SIGNAL(commandComplete()), this, SLOT(installationComplete()));
|
||||
|
||||
_interfaceThread = new QThread();
|
||||
_interfaceWorker = new InterfaceWorker();
|
||||
|
||||
_interfaceThread->start();
|
||||
_interfaceWorker->moveToThread(_interfaceThread);
|
||||
connect(this, SIGNAL(startInterface()), _interfaceWorker, SLOT(runCommand()));
|
||||
connect(_interfaceWorker, SIGNAL(commandComplete()), this, SLOT(interfaceExecutionComplete()));
|
||||
}
|
||||
|
||||
TestRunnerDesktop::~TestRunnerDesktop() {
|
||||
delete _installerThread;
|
||||
delete _installerWorker;
|
||||
|
||||
delete _interfaceThread;
|
||||
delete _interfaceWorker;
|
||||
|
||||
if (_timer) {
|
||||
delete _timer;
|
||||
}
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::setWorkingFolderAndEnableControls() {
|
||||
setWorkingFolder(_workingFolderLabel);
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
_installationFolder = _workingFolder + "/High Fidelity";
|
||||
#elif defined Q_OS_MAC
|
||||
_installationFolder = _workingFolder + "/High_Fidelity";
|
||||
#endif
|
||||
|
||||
_logFile.setFileName(_workingFolder + "/log.txt");
|
||||
|
||||
nitpick->enableRunTabControls();
|
||||
|
||||
_timer = new QTimer(this);
|
||||
connect(_timer, SIGNAL(timeout()), this, SLOT(checkTime()));
|
||||
_timer->start(30 * 1000); //time specified in ms
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
// Create MAC shell scripts
|
||||
QFile script;
|
||||
|
||||
// This script waits for a process to start
|
||||
script.setFileName(_workingFolder + "/waitForStart.sh");
|
||||
if (!script.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not open 'waitForStart.sh'");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
script.write("#!/bin/sh\n\n");
|
||||
script.write("PROCESS=\"$1\"\n");
|
||||
script.write("until (pgrep -x $PROCESS >nul)\n");
|
||||
script.write("do\n");
|
||||
script.write("\techo waiting for \"$1\" to start\n");
|
||||
script.write("\tsleep 2\n");
|
||||
script.write("done\n");
|
||||
script.write("echo \"$1\" \"started\"\n");
|
||||
script.close();
|
||||
script.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner);
|
||||
|
||||
// The Mac shell command returns immediately. This little script waits for a process to finish
|
||||
script.setFileName(_workingFolder + "/waitForFinish.sh");
|
||||
if (!script.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not open 'waitForFinish.sh'");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
script.write("#!/bin/sh\n\n");
|
||||
script.write("PROCESS=\"$1\"\n");
|
||||
script.write("while (pgrep -x $PROCESS >nul)\n");
|
||||
script.write("do\n");
|
||||
script.write("\techo waiting for \"$1\" to finish\n");
|
||||
script.write("\tsleep 2\n");
|
||||
script.write("done\n");
|
||||
script.write("echo \"$1\" \"finished\"\n");
|
||||
script.close();
|
||||
script.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner);
|
||||
|
||||
// Create an AppleScript to resize Interface. This is needed so that snapshots taken
|
||||
// with the primary camera will be the correct size.
|
||||
// This will be run from a normal shell script
|
||||
script.setFileName(_workingFolder + "/setInterfaceSizeAndPosition.scpt");
|
||||
if (!script.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not open 'setInterfaceSizeAndPosition.scpt'");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
script.write("set width to 960\n");
|
||||
script.write("set height to 540\n");
|
||||
script.write("set x to 100\n");
|
||||
script.write("set y to 100\n\n");
|
||||
script.write("tell application \"System Events\" to tell application process \"interface\" to tell window 1 to set {size, position} to {{width, height}, {x, y}}\n");
|
||||
|
||||
script.close();
|
||||
script.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner);
|
||||
|
||||
script.setFileName(_workingFolder + "/setInterfaceSizeAndPosition.sh");
|
||||
if (!script.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not open 'setInterfaceSizeAndPosition.sh'");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
script.write("#!/bin/sh\n\n");
|
||||
script.write("echo resizing interface\n");
|
||||
script.write(("osascript " + _workingFolder + "/setInterfaceSizeAndPosition.scpt\n").toStdString().c_str());
|
||||
script.write("echo resize complete\n");
|
||||
script.close();
|
||||
script.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner);
|
||||
#endif
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::run() {
|
||||
_runNow->setEnabled(false);
|
||||
|
||||
_testStartDateTime = QDateTime::currentDateTime();
|
||||
_automatedTestIsRunning = true;
|
||||
|
||||
// Initial setup
|
||||
_branch = nitpick->getSelectedBranch();
|
||||
_user = nitpick->getSelectedUser();
|
||||
|
||||
// This will be restored at the end of the tests
|
||||
saveExistingHighFidelityAppDataFolder();
|
||||
|
||||
// Download the latest High Fidelity build XML.
|
||||
// Note that this is not needed for PR builds (or whenever `Run Latest` is unchecked)
|
||||
// It is still downloaded, to simplify the flow
|
||||
QStringList urls;
|
||||
QStringList filenames;
|
||||
|
||||
urls << DEV_BUILD_XML_URL;
|
||||
filenames << DEV_BUILD_XML_FILENAME;
|
||||
|
||||
updateStatusLabel("Downloading Build XML");
|
||||
|
||||
buildXMLDownloaded = false;
|
||||
nitpick->downloadFiles(urls, _workingFolder, filenames, (void*)this);
|
||||
|
||||
// `downloadComplete` will run after download has completed
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::downloadComplete() {
|
||||
if (!buildXMLDownloaded) {
|
||||
// Download of Build XML has completed
|
||||
buildXMLDownloaded = true;
|
||||
|
||||
// Download the High Fidelity installer
|
||||
QStringList urls;
|
||||
QStringList filenames;
|
||||
if (_runLatest->isChecked()) {
|
||||
parseBuildInformation();
|
||||
|
||||
_installerFilename = INSTALLER_FILENAME_LATEST;
|
||||
|
||||
urls << _buildInformation.url;
|
||||
filenames << _installerFilename;
|
||||
} else {
|
||||
QString urlText = _url->text();
|
||||
urls << urlText;
|
||||
_installerFilename = getInstallerNameFromURL(urlText);
|
||||
filenames << _installerFilename;
|
||||
}
|
||||
|
||||
updateStatusLabel("Downloading installer");
|
||||
|
||||
nitpick->downloadFiles(urls, _workingFolder, filenames, (void*)this);
|
||||
|
||||
// `downloadComplete` will run again after download has completed
|
||||
|
||||
} else {
|
||||
// Download of Installer has completed
|
||||
appendLog(QString("Tests started at ") + QString::number(_testStartDateTime.time().hour()) + ":" +
|
||||
QString("%1").arg(_testStartDateTime.time().minute(), 2, 10, QChar('0')) + ", on " +
|
||||
_testStartDateTime.date().toString("ddd, MMM d, yyyy"));
|
||||
|
||||
updateStatusLabel("Installing");
|
||||
|
||||
// Kill any existing processes that would interfere with installation
|
||||
killProcesses();
|
||||
|
||||
runInstaller();
|
||||
}
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::runInstaller() {
|
||||
// Qt cannot start an installation process using QProcess::start (Qt Bug 9761)
|
||||
// To allow installation, the installer is run using the `system` command
|
||||
|
||||
QStringList arguments{ QStringList() << QString("/S") << QString("/D=") + QDir::toNativeSeparators(_installationFolder) };
|
||||
|
||||
QString installerFullPath = _workingFolder + "/" + _installerFilename;
|
||||
|
||||
QString commandLine;
|
||||
#ifdef Q_OS_WIN
|
||||
commandLine = "\"" + QDir::toNativeSeparators(installerFullPath) + "\"" + " /S /D=" + QDir::toNativeSeparators(_installationFolder);
|
||||
#elif defined Q_OS_MAC
|
||||
// Create installation shell script
|
||||
QFile script;
|
||||
script.setFileName(_workingFolder + "/install_app.sh");
|
||||
if (!script.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not open 'install_app.sh'");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (!QDir().exists(_installationFolder)) {
|
||||
QDir().mkdir(_installationFolder);
|
||||
}
|
||||
|
||||
// This script installs High Fidelity. It is run as "yes | install_app.sh... so "yes" is killed at the end
|
||||
script.write("#!/bin/sh\n\n");
|
||||
script.write("VOLUME=`hdiutil attach \"$1\" | grep Volumes | awk '{print $3}'`\n");
|
||||
|
||||
QString folderName {"High Fidelity"};
|
||||
if (!_runLatest->isChecked()) {
|
||||
folderName += QString(" - ") + getPRNumberFromURL(_url->text());
|
||||
}
|
||||
|
||||
script.write((QString("cp -rf \"$VOLUME/") + folderName + "/interface.app\" \"" + _workingFolder + "/High_Fidelity/\"\n").toStdString().c_str());
|
||||
script.write((QString("cp -rf \"$VOLUME/") + folderName + "/Sandbox.app\" \"" + _workingFolder + "/High_Fidelity/\"\n").toStdString().c_str());
|
||||
|
||||
script.write("hdiutil detach \"$VOLUME\"\n");
|
||||
script.write("killall yes\n");
|
||||
script.close();
|
||||
script.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner);
|
||||
commandLine = "yes | " + _workingFolder + "/install_app.sh " + installerFullPath;
|
||||
#endif
|
||||
appendLog(commandLine);
|
||||
_installerWorker->setCommandLine(commandLine);
|
||||
emit startInstaller();
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::installationComplete() {
|
||||
verifyInstallationSucceeded();
|
||||
|
||||
createSnapshotFolder();
|
||||
|
||||
updateStatusLabel("Running tests");
|
||||
|
||||
if (!_runServerless->isChecked()) {
|
||||
startLocalServerProcesses();
|
||||
}
|
||||
|
||||
runInterfaceWithTestScript();
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::verifyInstallationSucceeded() {
|
||||
// Exit if the executables are missing.
|
||||
// On Windows, the reason is probably that UAC has blocked the installation. This is treated as a critical error
|
||||
#ifdef Q_OS_WIN
|
||||
QFileInfo interfaceExe(QDir::toNativeSeparators(_installationFolder) + "\\interface.exe");
|
||||
QFileInfo assignmentClientExe(QDir::toNativeSeparators(_installationFolder) + "\\assignment-client.exe");
|
||||
QFileInfo domainServerExe(QDir::toNativeSeparators(_installationFolder) + "\\domain-server.exe");
|
||||
|
||||
if (!interfaceExe.exists() || !assignmentClientExe.exists() || !domainServerExe.exists()) {
|
||||
QMessageBox::critical(0, "Installation of High Fidelity has failed", "Please verify that UAC has been disabled");
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::saveExistingHighFidelityAppDataFolder() {
|
||||
QString dataDirectory{ "NOT FOUND" };
|
||||
#ifdef Q_OS_WIN
|
||||
dataDirectory = qgetenv("USERPROFILE") + "\\AppData\\Roaming";
|
||||
#elif defined Q_OS_MAC
|
||||
dataDirectory = QDir::homePath() + "/Library/Application Support";
|
||||
#endif
|
||||
if (_runLatest->isChecked()) {
|
||||
_appDataFolder = dataDirectory + "/High Fidelity";
|
||||
} else {
|
||||
// We are running a PR build
|
||||
_appDataFolder = dataDirectory + "/High Fidelity - " + getPRNumberFromURL(_url->text());
|
||||
}
|
||||
|
||||
_savedAppDataFolder = dataDirectory + "/" + UNIQUE_FOLDER_NAME;
|
||||
if (QDir(_savedAppDataFolder).exists()) {
|
||||
_savedAppDataFolder.removeRecursively();
|
||||
}
|
||||
if (_appDataFolder.exists()) {
|
||||
// The original folder is saved in a unique name
|
||||
_appDataFolder.rename(_appDataFolder.path(), _savedAppDataFolder.path());
|
||||
}
|
||||
|
||||
// Copy an "empty" AppData folder (i.e. no entities)
|
||||
QDir canonicalAppDataFolder;
|
||||
#ifdef Q_OS_WIN
|
||||
canonicalAppDataFolder = QDir::currentPath() + "/AppDataHighFidelity";
|
||||
#elif defined Q_OS_MAC
|
||||
canonicalAppDataFolder = QCoreApplication::applicationDirPath() + "/AppDataHighFidelity";
|
||||
#endif
|
||||
if (canonicalAppDataFolder.exists()) {
|
||||
copyFolder(canonicalAppDataFolder.path(), _appDataFolder.path());
|
||||
} else {
|
||||
QMessageBox::critical(0, "Internal error", "The nitpick AppData folder cannot be found at:\n" + canonicalAppDataFolder.path());
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::createSnapshotFolder() {
|
||||
_snapshotFolder = _workingFolder + "/" + SNAPSHOT_FOLDER_NAME;
|
||||
|
||||
// Just delete all PNGs from the folder if it already exists
|
||||
if (QDir(_snapshotFolder).exists()) {
|
||||
// Note that we cannot use just a `png` filter, as the filenames include periods
|
||||
// Also, delete any `jpg` and `txt` files
|
||||
// The idea is to leave only previous zipped result folders
|
||||
QDirIterator it(_snapshotFolder);
|
||||
while (it.hasNext()) {
|
||||
QString filename = it.next();
|
||||
if (filename.right(4) == ".png" || filename.right(4) == ".jpg" || filename.right(4) == ".txt") {
|
||||
QFile::remove(filename);
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
QDir().mkdir(_snapshotFolder);
|
||||
}
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::killProcesses() {
|
||||
#ifdef Q_OS_WIN
|
||||
try {
|
||||
QStringList processesToKill = QStringList() << "interface.exe"
|
||||
<< "assignment-client.exe"
|
||||
<< "domain-server.exe"
|
||||
<< "server-console.exe";
|
||||
|
||||
// Loop until all pending processes to kill have actually died
|
||||
QStringList pendingProcessesToKill;
|
||||
do {
|
||||
pendingProcessesToKill.clear();
|
||||
|
||||
// Get list of running tasks
|
||||
HANDLE processSnapHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
|
||||
if (processSnapHandle == INVALID_HANDLE_VALUE) {
|
||||
throw("Process snapshot creation failure");
|
||||
}
|
||||
|
||||
PROCESSENTRY32 processEntry32;
|
||||
processEntry32.dwSize = sizeof(PROCESSENTRY32);
|
||||
if (!Process32First(processSnapHandle, &processEntry32)) {
|
||||
CloseHandle(processSnapHandle);
|
||||
throw("Process32First failed");
|
||||
}
|
||||
|
||||
// Kill any task in the list
|
||||
do {
|
||||
foreach (QString process, processesToKill)
|
||||
if (QString(processEntry32.szExeFile) == process) {
|
||||
QString commandLine = "taskkill /im " + process + " /f >nul";
|
||||
system(commandLine.toStdString().c_str());
|
||||
pendingProcessesToKill << process;
|
||||
}
|
||||
} while (Process32Next(processSnapHandle, &processEntry32));
|
||||
|
||||
QThread::sleep(2);
|
||||
} while (!pendingProcessesToKill.isEmpty());
|
||||
|
||||
} catch (QString errorMessage) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), errorMessage);
|
||||
exit(-1);
|
||||
} catch (...) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "unknown error");
|
||||
exit(-1);
|
||||
}
|
||||
#elif defined Q_OS_MAC
|
||||
QString commandLine;
|
||||
|
||||
commandLine = QString("killall interface") + "; " + _workingFolder +"/waitForFinish.sh interface";
|
||||
system(commandLine.toStdString().c_str());
|
||||
|
||||
commandLine = QString("killall Sandbox") + "; " + _workingFolder +"/waitForFinish.sh Sandbox";
|
||||
system(commandLine.toStdString().c_str());
|
||||
|
||||
commandLine = QString("killall Console") + "; " + _workingFolder +"/waitForFinish.sh Console";
|
||||
system(commandLine.toStdString().c_str());
|
||||
#endif
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::startLocalServerProcesses() {
|
||||
QString commandLine;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
commandLine =
|
||||
"start \"domain-server.exe\" \"" + QDir::toNativeSeparators(_installationFolder) + "\\domain-server.exe\"";
|
||||
system(commandLine.toStdString().c_str());
|
||||
|
||||
commandLine =
|
||||
"start \"assignment-client.exe\" \"" + QDir::toNativeSeparators(_installationFolder) + "\\assignment-client.exe\" -n 6";
|
||||
system(commandLine.toStdString().c_str());
|
||||
|
||||
#elif defined Q_OS_MAC
|
||||
commandLine = "open \"" +_installationFolder + "/Sandbox.app\"";
|
||||
system(commandLine.toStdString().c_str());
|
||||
#endif
|
||||
|
||||
// Give server processes time to stabilize
|
||||
QThread::sleep(20);
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::runInterfaceWithTestScript() {
|
||||
QString url = QString("hifi://localhost");
|
||||
if (_runServerless->isChecked()) {
|
||||
// Move to an empty area
|
||||
url = "file:///~serverless/tutorial.json";
|
||||
} else {
|
||||
url = "hifi://localhost";
|
||||
}
|
||||
|
||||
QString deleteScript =
|
||||
QString("https://raw.githubusercontent.com/") + _user + "/hifi_tests/" + _branch + "/tests/utils/deleteNearbyEntities.js";
|
||||
|
||||
QString testScript =
|
||||
QString("https://raw.githubusercontent.com/") + _user + "/hifi_tests/" + _branch + "/tests/testRecursive.js";
|
||||
|
||||
QString commandLine;
|
||||
#ifdef Q_OS_WIN
|
||||
QString exeFile;
|
||||
// First, run script to delete any entities in test area
|
||||
// Note that this will run to completion before continuing
|
||||
exeFile = QString("\"") + QDir::toNativeSeparators(_installationFolder) + "\\interface.exe\"";
|
||||
commandLine = "start /wait \"\" " + exeFile +
|
||||
" --url " + url +
|
||||
" --no-updater" +
|
||||
" --no-login-suggestion"
|
||||
" --testScript " + deleteScript + " quitWhenFinished";
|
||||
|
||||
system(commandLine.toStdString().c_str());
|
||||
|
||||
// Now run the test suite
|
||||
exeFile = QString("\"") + QDir::toNativeSeparators(_installationFolder) + "\\interface.exe\"";
|
||||
commandLine = exeFile +
|
||||
" --url " + url +
|
||||
" --no-updater" +
|
||||
" --no-login-suggestion"
|
||||
" --testScript " + testScript + " quitWhenFinished" +
|
||||
" --testResultsLocation " + _snapshotFolder;
|
||||
|
||||
_interfaceWorker->setCommandLine(commandLine);
|
||||
emit startInterface();
|
||||
#elif defined Q_OS_MAC
|
||||
QFile script;
|
||||
script.setFileName(_workingFolder + "/runInterfaceTests.sh");
|
||||
if (!script.open(QIODevice::WriteOnly | QIODevice::Text)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not open 'runInterfaceTests.sh'");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
script.write("#!/bin/sh\n\n");
|
||||
|
||||
// First, run script to delete any entities in test area
|
||||
commandLine =
|
||||
"open -W \"" +_installationFolder + "/interface.app\" --args" +
|
||||
" --url " + url +
|
||||
" --no-updater" +
|
||||
" --no-login-suggestion"
|
||||
" --testScript " + deleteScript + " quitWhenFinished\n";
|
||||
|
||||
script.write(commandLine.toStdString().c_str());
|
||||
|
||||
// On The Mac, we need to resize Interface. The Interface window opens a few seconds after the process
|
||||
// has started.
|
||||
// Before starting interface, start a process that will resize interface 10s after it opens
|
||||
commandLine = _workingFolder +"/waitForStart.sh interface && sleep 10 && " + _workingFolder +"/setInterfaceSizeAndPosition.sh &\n";
|
||||
script.write(commandLine.toStdString().c_str());
|
||||
|
||||
commandLine =
|
||||
"open \"" +_installationFolder + "/interface.app\" --args" +
|
||||
" --url " + url +
|
||||
" --no-updater" +
|
||||
" --no-login-suggestion"
|
||||
" --testScript " + testScript + " quitWhenFinished" +
|
||||
" --testResultsLocation " + _snapshotFolder +
|
||||
" && " + _workingFolder +"/waitForFinish.sh interface\n";
|
||||
|
||||
script.write(commandLine.toStdString().c_str());
|
||||
|
||||
script.close();
|
||||
script.setPermissions(QFile::ReadOwner | QFile::WriteOwner | QFile::ExeOwner);
|
||||
|
||||
commandLine = _workingFolder + "/runInterfaceTests.sh";
|
||||
_interfaceWorker->setCommandLine(commandLine);
|
||||
|
||||
emit startInterface();
|
||||
#endif
|
||||
|
||||
// Helpful for debugging
|
||||
appendLog(commandLine);
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::interfaceExecutionComplete() {
|
||||
QFileInfo testCompleted(QDir::toNativeSeparators(_snapshotFolder) +"/tests_completed.txt");
|
||||
if (!testCompleted.exists()) {
|
||||
QMessageBox::critical(0, "Tests not completed", "Interface seems to have crashed before completion of the test scripts\nExisting images will be evaluated");
|
||||
}
|
||||
|
||||
evaluateResults();
|
||||
|
||||
killProcesses();
|
||||
|
||||
// The High Fidelity AppData folder will be restored after evaluation has completed
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::evaluateResults() {
|
||||
updateStatusLabel("Evaluating results");
|
||||
nitpick->startTestsEvaluation(false, true, _snapshotFolder, _branch, _user);
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::automaticTestRunEvaluationComplete(QString zippedFolder, int numberOfFailures) {
|
||||
addBuildNumberToResults(zippedFolder);
|
||||
restoreHighFidelityAppDataFolder();
|
||||
|
||||
updateStatusLabel("Testing complete");
|
||||
|
||||
QDateTime currentDateTime = QDateTime::currentDateTime();
|
||||
|
||||
QString completionText = QString("Tests completed at ") + QString::number(currentDateTime.time().hour()) + ":" +
|
||||
QString("%1").arg(currentDateTime.time().minute(), 2, 10, QChar('0')) + ", on " +
|
||||
currentDateTime.date().toString("ddd, MMM d, yyyy");
|
||||
|
||||
if (numberOfFailures == 0) {
|
||||
completionText += "; no failures";
|
||||
} else if (numberOfFailures == 1) {
|
||||
completionText += "; 1 failure";
|
||||
} else {
|
||||
completionText += QString("; ") + QString::number(numberOfFailures) + " failures";
|
||||
}
|
||||
appendLog(completionText);
|
||||
|
||||
_automatedTestIsRunning = false;
|
||||
|
||||
_runNow->setEnabled(true);
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::addBuildNumberToResults(QString zippedFolderName) {
|
||||
QString augmentedFilename;
|
||||
if (!_runLatest->isChecked()) {
|
||||
augmentedFilename = zippedFolderName.replace("local", getPRNumberFromURL(_url->text()));
|
||||
} else {
|
||||
augmentedFilename = zippedFolderName.replace("local", _buildInformation.build);
|
||||
}
|
||||
QFile::rename(zippedFolderName, augmentedFilename);
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::restoreHighFidelityAppDataFolder() {
|
||||
_appDataFolder.removeRecursively();
|
||||
|
||||
if (_savedAppDataFolder != QDir()) {
|
||||
_appDataFolder.rename(_savedAppDataFolder.path(), _appDataFolder.path());
|
||||
}
|
||||
}
|
||||
|
||||
// Copies a folder recursively
|
||||
void TestRunnerDesktop::copyFolder(const QString& source, const QString& destination) {
|
||||
try {
|
||||
if (!QFileInfo(source).isDir()) {
|
||||
// just a file copy
|
||||
QFile::copy(source, destination);
|
||||
} else {
|
||||
QDir destinationDir(destination);
|
||||
if (!destinationDir.cdUp()) {
|
||||
throw("'source '" + source + "'seems to be a root folder");
|
||||
}
|
||||
|
||||
if (!destinationDir.mkdir(QFileInfo(destination).fileName())) {
|
||||
throw("Could not create destination folder '" + destination + "'");
|
||||
}
|
||||
|
||||
QStringList fileNames =
|
||||
QDir(source).entryList(QDir::Files | QDir::Dirs | QDir::NoDotAndDotDot | QDir::Hidden | QDir::System);
|
||||
|
||||
foreach (const QString& fileName, fileNames) {
|
||||
copyFolder(QString(source + "/" + fileName), QString(destination + "/" + fileName));
|
||||
}
|
||||
}
|
||||
} catch (QString errorMessage) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), errorMessage);
|
||||
exit(-1);
|
||||
} catch (...) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "unknown error");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::checkTime() {
|
||||
// No processing is done if a test is running
|
||||
if (_automatedTestIsRunning) {
|
||||
return;
|
||||
}
|
||||
|
||||
QDateTime now = QDateTime::currentDateTime();
|
||||
|
||||
// Check day of week
|
||||
if (!_dayCheckboxes.at(now.date().dayOfWeek() - 1)->isChecked()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Check the time
|
||||
bool timeToRun{ false };
|
||||
|
||||
for (size_t i = 0; i < std::min(_timeEditCheckboxes.size(), _timeEdits.size()); ++i) {
|
||||
if (_timeEditCheckboxes[i]->isChecked() && (_timeEdits[i]->time().hour() == now.time().hour()) &&
|
||||
(_timeEdits[i]->time().minute() == now.time().minute())) {
|
||||
timeToRun = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (timeToRun) {
|
||||
run();
|
||||
}
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::updateStatusLabel(const QString& message) {
|
||||
nitpick->updateStatusLabel(message);
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::appendLog(const QString& message) {
|
||||
if (!_logFile.open(QIODevice::Append | QIODevice::Text)) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__),
|
||||
"Could not open the log file");
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
_logFile.write(message.toStdString().c_str());
|
||||
_logFile.write("\n");
|
||||
_logFile.close();
|
||||
|
||||
nitpick->appendLogWindow(message);
|
||||
}
|
||||
|
||||
QString TestRunnerDesktop::getInstallerNameFromURL(const QString& url) {
|
||||
// An example URL: https://deployment.highfidelity.com/jobs/pr-build/label%3Dwindows/13023/HighFidelity-Beta-Interface-PR14006-be76c43.exe
|
||||
// On Mac, replace `exe` with `dmg`
|
||||
try {
|
||||
QStringList urlParts = url.split("/");
|
||||
return urlParts[urlParts.size() - 1];
|
||||
} catch (QString errorMessage) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), errorMessage);
|
||||
exit(-1);
|
||||
} catch (...) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "unknown error");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
QString TestRunnerDesktop::getPRNumberFromURL(const QString& url) {
|
||||
try {
|
||||
QStringList urlParts = url.split("/");
|
||||
QStringList filenameParts = urlParts[urlParts.size() - 1].split("-");
|
||||
if (filenameParts.size() <= 3) {
|
||||
#ifdef Q_OS_WIN
|
||||
throw "URL not in expected format, should look like `https://deployment.highfidelity.com/jobs/pr-build/label%3Dwindows/13023/HighFidelity-Beta-Interface-PR14006-be76c43.exe`";
|
||||
#elif defined Q_OS_MAC
|
||||
throw "URL not in expected format, should look like `https://deployment.highfidelity.com/jobs/pr-build/label%3Dwindows/13023/HighFidelity-Beta-Interface-PR14006-be76c43.dmg`";
|
||||
#endif
|
||||
}
|
||||
return filenameParts[filenameParts.size() - 2];
|
||||
} catch (QString errorMessage) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), errorMessage);
|
||||
exit(-1);
|
||||
} catch (...) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "unknown error");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
void TestRunnerDesktop::parseBuildInformation() {
|
||||
try {
|
||||
QDomDocument domDocument;
|
||||
QString filename{ _workingFolder + "/" + DEV_BUILD_XML_FILENAME };
|
||||
QFile file(filename);
|
||||
if (!file.open(QIODevice::ReadOnly) || !domDocument.setContent(&file)) {
|
||||
throw QString("Could not open " + filename);
|
||||
}
|
||||
|
||||
QString platformOfInterest;
|
||||
#ifdef Q_OS_WIN
|
||||
platformOfInterest = "windows";
|
||||
#elif defined(Q_OS_MAC)
|
||||
platformOfInterest = "mac";
|
||||
#endif
|
||||
|
||||
QDomElement element = domDocument.documentElement();
|
||||
|
||||
// Verify first element is "projects"
|
||||
if (element.tagName() != "projects") {
|
||||
throw("File seems to be in wrong format");
|
||||
}
|
||||
|
||||
element = element.firstChild().toElement();
|
||||
if (element.tagName() != "project") {
|
||||
throw("File seems to be in wrong format");
|
||||
}
|
||||
|
||||
if (element.attribute("name") != "interface") {
|
||||
throw("File is not from 'interface' build");
|
||||
}
|
||||
|
||||
// Now loop over the platforms, looking for ours
|
||||
bool platformFound{ false };
|
||||
element = element.firstChild().toElement();
|
||||
while (!element.isNull()) {
|
||||
if (element.attribute("name") == platformOfInterest) {
|
||||
platformFound = true;
|
||||
break;
|
||||
}
|
||||
element = element.nextSibling().toElement();
|
||||
}
|
||||
|
||||
if (!platformFound) {
|
||||
throw("File seems to be in wrong format - platform " + platformOfInterest + " not found");
|
||||
}
|
||||
|
||||
element = element.firstChild().toElement();
|
||||
if (element.tagName() != "build") {
|
||||
throw("File seems to be in wrong format");
|
||||
}
|
||||
|
||||
// Next element should be the version
|
||||
element = element.firstChild().toElement();
|
||||
if (element.tagName() != "version") {
|
||||
throw("File seems to be in wrong format");
|
||||
}
|
||||
|
||||
// Add the build number to the end of the filename
|
||||
_buildInformation.build = element.text();
|
||||
|
||||
// First sibling should be stable_version
|
||||
element = element.nextSibling().toElement();
|
||||
if (element.tagName() != "stable_version") {
|
||||
throw("File seems to be in wrong format");
|
||||
}
|
||||
|
||||
// Next sibling should be url
|
||||
element = element.nextSibling().toElement();
|
||||
if (element.tagName() != "url") {
|
||||
throw("File seems to be in wrong format");
|
||||
}
|
||||
_buildInformation.url = element.text();
|
||||
|
||||
} catch (QString errorMessage) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), errorMessage);
|
||||
exit(-1);
|
||||
} catch (...) {
|
||||
QMessageBox::critical(0, "Internal error: " + QString(__FILE__) + ":" + QString::number(__LINE__), "unknown error");
|
||||
exit(-1);
|
||||
}
|
||||
}
|
|
@ -1,156 +0,0 @@
|
|||
//
|
||||
// TestRunnerDesktop.h
|
||||
//
|
||||
// Created by Nissim Hadar on 1 Sept 2018.
|
||||
// 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_testRunnerDesktop_h
|
||||
#define hifi_testRunnerDesktop_h
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QDir>
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QObject>
|
||||
#include <QPushButton>
|
||||
#include <QThread>
|
||||
#include <QTimeEdit>
|
||||
#include <QTimer>
|
||||
|
||||
#include "TestRunner.h"
|
||||
|
||||
class BuildInformation {
|
||||
public:
|
||||
QString build;
|
||||
QString url;
|
||||
};
|
||||
|
||||
class InterfaceWorker;
|
||||
class InstallerWorker;
|
||||
|
||||
class TestRunnerDesktop : public QObject, public TestRunner {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TestRunnerDesktop(std::vector<QCheckBox*> dayCheckboxes,
|
||||
std::vector<QCheckBox*> timeEditCheckboxes,
|
||||
std::vector<QTimeEdit*> timeEdits,
|
||||
QLabel* workingFolderLabel,
|
||||
QCheckBox* runServerless,
|
||||
QCheckBox* runLatest,
|
||||
QLineEdit* url,
|
||||
QPushButton* runNow,
|
||||
QObject* parent = 0);
|
||||
|
||||
~TestRunnerDesktop();
|
||||
|
||||
void setWorkingFolderAndEnableControls();
|
||||
|
||||
void run();
|
||||
|
||||
void downloadComplete();
|
||||
void runInstaller();
|
||||
void verifyInstallationSucceeded();
|
||||
|
||||
void saveExistingHighFidelityAppDataFolder();
|
||||
void restoreHighFidelityAppDataFolder();
|
||||
|
||||
void createSnapshotFolder();
|
||||
|
||||
void killProcesses();
|
||||
void startLocalServerProcesses();
|
||||
|
||||
void runInterfaceWithTestScript();
|
||||
|
||||
void evaluateResults();
|
||||
void automaticTestRunEvaluationComplete(QString zippedFolderName, int numberOfFailures);
|
||||
void addBuildNumberToResults(QString zippedFolderName);
|
||||
|
||||
void copyFolder(const QString& source, const QString& destination);
|
||||
|
||||
void updateStatusLabel(const QString& message);
|
||||
void appendLog(const QString& message);
|
||||
|
||||
QString getInstallerNameFromURL(const QString& url);
|
||||
QString getPRNumberFromURL(const QString& url);
|
||||
|
||||
void parseBuildInformation();
|
||||
|
||||
private slots:
|
||||
void checkTime();
|
||||
void installationComplete();
|
||||
void interfaceExecutionComplete();
|
||||
|
||||
signals:
|
||||
void startInstaller();
|
||||
void startInterface();
|
||||
void startResize();
|
||||
|
||||
private:
|
||||
bool _automatedTestIsRunning{ false };
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
const QString INSTALLER_FILENAME_LATEST{ "HighFidelity-Beta-latest-dev.exe" };
|
||||
#elif defined(Q_OS_MAC)
|
||||
const QString INSTALLER_FILENAME_LATEST{ "HighFidelity-Beta-latest-dev.dmg" };
|
||||
#else
|
||||
const QString INSTALLER_FILENAME_LATEST{ "" };
|
||||
#endif
|
||||
|
||||
QString _installerURL;
|
||||
QString _installerFilename;
|
||||
const QString DEV_BUILD_XML_URL{ "https://highfidelity.com/dev-builds.xml" };
|
||||
const QString DEV_BUILD_XML_FILENAME{ "dev-builds.xml" };
|
||||
|
||||
bool buildXMLDownloaded;
|
||||
|
||||
QDir _appDataFolder;
|
||||
QDir _savedAppDataFolder;
|
||||
|
||||
QString _installationFolder;
|
||||
QString _snapshotFolder;
|
||||
|
||||
const QString UNIQUE_FOLDER_NAME{ "fgadhcUDHSFaidsfh3478JJJFSDFIUSOEIrf" };
|
||||
const QString SNAPSHOT_FOLDER_NAME{ "snapshots" };
|
||||
|
||||
QString _branch;
|
||||
QString _user;
|
||||
|
||||
std::vector<QCheckBox*> _dayCheckboxes;
|
||||
std::vector<QCheckBox*> _timeEditCheckboxes;
|
||||
std::vector<QTimeEdit*> _timeEdits;
|
||||
QLabel* _workingFolderLabel;
|
||||
QCheckBox* _runServerless;
|
||||
QCheckBox* _runLatest;
|
||||
QLineEdit* _url;
|
||||
QPushButton* _runNow;
|
||||
QTimer* _timer;
|
||||
|
||||
QFile _logFile;
|
||||
|
||||
QDateTime _testStartDateTime;
|
||||
|
||||
QThread* _installerThread;
|
||||
QThread* _interfaceThread;
|
||||
|
||||
InstallerWorker* _installerWorker;
|
||||
InterfaceWorker* _interfaceWorker;
|
||||
|
||||
BuildInformation _buildInformation;
|
||||
};
|
||||
|
||||
class InstallerWorker : public Worker {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void startInstaller();
|
||||
};
|
||||
|
||||
class InterfaceWorker : public Worker {
|
||||
Q_OBJECT
|
||||
signals:
|
||||
void startInterface();
|
||||
};
|
||||
#endif
|
|
@ -1,107 +0,0 @@
|
|||
//
|
||||
// TestRunnerMobile.cpp
|
||||
//
|
||||
// Created by Nissim Hadar on 22 Jan 2019.
|
||||
// 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 "TestRunnerMobile.h"
|
||||
|
||||
#include <QThread>
|
||||
#include <QtWidgets/QMessageBox>
|
||||
#include <QtWidgets/QFileDialog>
|
||||
|
||||
#include "Nitpick.h"
|
||||
extern Nitpick* nitpick;
|
||||
|
||||
TestRunnerMobile::TestRunnerMobile(
|
||||
QLabel* workingFolderLabel,
|
||||
QPushButton *connectDeviceButton,
|
||||
QPushButton *pullFolderButton,
|
||||
QLabel* detectedDeviceLabel,
|
||||
QLineEdit *folderLineEdit,
|
||||
QObject* parent
|
||||
) : QObject(parent)
|
||||
{
|
||||
_workingFolderLabel = workingFolderLabel;
|
||||
_connectDeviceButton = connectDeviceButton;
|
||||
_pullFolderButton = pullFolderButton;
|
||||
_detectedDeviceLabel = detectedDeviceLabel;
|
||||
_folderLineEdit = folderLineEdit;
|
||||
|
||||
folderLineEdit->setText("/sdcard/DCIM/TEST");
|
||||
}
|
||||
|
||||
TestRunnerMobile::~TestRunnerMobile() {
|
||||
}
|
||||
|
||||
void TestRunnerMobile::setWorkingFolderAndEnableControls() {
|
||||
setWorkingFolder(_workingFolderLabel);
|
||||
|
||||
_connectDeviceButton->setEnabled(true);
|
||||
|
||||
// Find ADB (Android Debugging Bridge) before continuing
|
||||
#ifdef Q_OS_WIN
|
||||
if (QProcessEnvironment::systemEnvironment().contains("ADB_PATH")) {
|
||||
QString adbExePath = QProcessEnvironment::systemEnvironment().value("ADB_PATH") + "/platform-tools";
|
||||
if (!QFile::exists(adbExePath + "/" + _adbExe)) {
|
||||
QMessageBox::critical(0, _adbExe, QString("Python executable not found in ") + adbExePath);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
_adbCommand = adbExePath + "/" + _adbExe;
|
||||
} else {
|
||||
QMessageBox::critical(0, "PYTHON_PATH not defined",
|
||||
"Please set PYTHON_PATH to directory containing the Python executable");
|
||||
exit(-1);
|
||||
}
|
||||
#elif defined Q_OS_MAC
|
||||
_adbCommand = "/usr/local/bin/adb";
|
||||
if (!QFile::exists(_adbCommand)) {
|
||||
QMessageBox::critical(0, "adb not found",
|
||||
"python3 not found at " + _adbCommand);
|
||||
exit(-1);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void TestRunnerMobile::connectDevice() {
|
||||
QString devicesFullFilename{ _workingFolder + "/devices.txt" };
|
||||
QString command = _adbCommand + " devices > " + devicesFullFilename;
|
||||
system(command.toStdString().c_str());
|
||||
|
||||
if (!QFile::exists(devicesFullFilename)) {
|
||||
QMessageBox::critical(0, "Internal error", "devicesFullFilename not found");
|
||||
exit (-1);
|
||||
}
|
||||
|
||||
// Device should be in second line
|
||||
QFile devicesFile(devicesFullFilename);
|
||||
devicesFile.open(QIODevice::ReadOnly | QIODevice::Text);
|
||||
QString line1 = devicesFile.readLine();
|
||||
QString line2 = devicesFile.readLine();
|
||||
|
||||
const QString DEVICE{ "device" };
|
||||
if (line2.contains(DEVICE)) {
|
||||
// Make sure only 1 device
|
||||
QString line3 = devicesFile.readLine();
|
||||
if (line3.contains(DEVICE)) {
|
||||
QMessageBox::critical(0, "Too many devices detected", "Tests will run only if a single device is attached");
|
||||
|
||||
} else {
|
||||
_detectedDeviceLabel->setText(line2.remove(DEVICE));
|
||||
_pullFolderButton->setEnabled(true);
|
||||
_folderLineEdit->setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TestRunnerMobile::downloadAPK() {
|
||||
}
|
||||
|
||||
void TestRunnerMobile::pullFolder() {
|
||||
QString command = _adbCommand + " pull " + _folderLineEdit->text() + " " + _workingFolder + " >" + _workingFolder + "/pullOutput.txt";
|
||||
system(command.toStdString().c_str());
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
//
|
||||
// TestRunnerMobile.h
|
||||
//
|
||||
// Created by Nissim Hadar on 22 Jan 2019.
|
||||
// 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_testRunnerMobile_h
|
||||
#define hifi_testRunnerMobile_h
|
||||
|
||||
#include <QLabel>
|
||||
#include <QLineEdit>
|
||||
#include <QObject>
|
||||
#include <QPushButton>
|
||||
|
||||
#include "TestRunner.h"
|
||||
|
||||
class TestRunnerMobile : public QObject, public TestRunner {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit TestRunnerMobile(
|
||||
QLabel* workingFolderLabel,
|
||||
QPushButton *connectDeviceButton,
|
||||
QPushButton *pullFolderButton,
|
||||
QLabel* detectedDeviceLabel,
|
||||
QLineEdit *folderLineEdit,
|
||||
QObject* parent = 0
|
||||
);
|
||||
~TestRunnerMobile();
|
||||
|
||||
void setWorkingFolderAndEnableControls();
|
||||
void connectDevice();
|
||||
void downloadAPK();
|
||||
void pullFolder();
|
||||
|
||||
private:
|
||||
QLabel* _workingFolderLabel;
|
||||
QPushButton* _connectDeviceButton;
|
||||
QPushButton* _pullFolderButton;
|
||||
QLabel* _detectedDeviceLabel;
|
||||
QLineEdit* _folderLineEdit;
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
const QString _adbExe{ "adb.exe" };
|
||||
#else
|
||||
// Both Mac and Linux use "adb"
|
||||
const QString _adbExe{ "adb" };
|
||||
#endif
|
||||
|
||||
QString _adbCommand;
|
||||
|
||||
};
|
||||
#endif
|
|
@ -1,75 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>BusyWindow</class>
|
||||
<widget class="QDialog" name="BusyWindow">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>542</width>
|
||||
<height>189</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Updating TestRail - please wait</string>
|
||||
</property>
|
||||
<widget class="QLabel" name="errorLabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>850</y>
|
||||
<width>500</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>similarity</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>40</x>
|
||||
<y>40</y>
|
||||
<width>481</width>
|
||||
<height>101</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>50</x>
|
||||
<y>60</y>
|
||||
<width>431</width>
|
||||
<height>61</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>20</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Please wait for this window to close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -1,199 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>MismatchWindow</class>
|
||||
<widget class="QDialog" name="MismatchWindow">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>1782</width>
|
||||
<height>942</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>MismatchWindow</string>
|
||||
</property>
|
||||
<widget class="QLabel" name="expectedImage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>10</x>
|
||||
<y>25</y>
|
||||
<width>800</width>
|
||||
<height>450</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>expected image</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="resultImage">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>900</x>
|
||||
<y>25</y>
|
||||
<width>800</width>
|
||||
<height>450</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>result image</string>
|
||||
</property>
|
||||
</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">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>660</y>
|
||||
<width>480</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>result image filename</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="expectedFilename">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>60</x>
|
||||
<y>630</y>
|
||||
<width>480</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>expected image filename</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="imagePath">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>600</y>
|
||||
<width>1200</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>image path</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="passTestButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>790</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Pass</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="failTestButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>120</x>
|
||||
<y>790</y>
|
||||
<width>75</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Fail</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="abortTestsButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>210</x>
|
||||
<y>790</y>
|
||||
<width>121</width>
|
||||
<height>23</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Abort current test</string>
|
||||
</property>
|
||||
</widget>
|
||||
<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>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>
|
||||
<layoutdefault spacing="6" margin="11"/>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
File diff suppressed because it is too large
Load diff
|
@ -1,280 +0,0 @@
|
|||
<?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>
|
|
@ -1,283 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TestRailRunSelectorWindow</class>
|
||||
<widget class="QDialog" name="TestRailRunSelectorWindow">
|
||||
<property name="windowModality">
|
||||
<enum>Qt::ApplicationModal</enum>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>489</width>
|
||||
<height>474</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>TestRail Run Selector Window</string>
|
||||
</property>
|
||||
<widget class="QLabel" name="errorLabel">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>30</x>
|
||||
<y>850</y>
|
||||
<width>500</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>12</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>similarity</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>125</y>
|
||||
<width>121</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TestRail Password</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>25</y>
|
||||
<width>121</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TestRail URL</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="OKButton">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>120</x>
|
||||
<y>420</y>
|
||||
<width>93</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>OK</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="cancelButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>280</x>
|
||||
<y>420</y>
|
||||
<width>93</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Cancel</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="passwordLineEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>120</y>
|
||||
<width>231</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Password</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>75</y>
|
||||
<width>121</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TestRail User</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLineEdit" name="projectIDLineEdit">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>170</y>
|
||||
<width>231</width>
|
||||
<height>24</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="echoMode">
|
||||
<enum>QLineEdit::Normal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>70</x>
|
||||
<y>175</y>
|
||||
<width>121</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TestRail Project ID</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QPushButton" name="acceptButton">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>200</x>
|
||||
<y>270</y>
|
||||
<width>231</width>
|
||||
<height>28</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Accept</string>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QComboBox" name="sectionsComboBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>140</x>
|
||||
<y>350</y>
|
||||
<width>311</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="milestoneLabel">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>20</x>
|
||||
<y>350</y>
|
||||
<width>121</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TestRail Sections</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>sectionsComboBox</tabstop>
|
||||
<tabstop>OKButton</tabstop>
|
||||
<tabstop>cancelButton</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -1,280 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TestRailTestCasesSelectorWindow</class>
|
||||
<widget class="QDialog" name="TestRailTestCasesSelectorWindow">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>489</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="releasesComboBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>270</x>
|
||||
<y>350</y>
|
||||
<width>161</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QLabel" name="releasesLabel">
|
||||
<property name="enabled">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>80</x>
|
||||
<y>350</y>
|
||||
<width>181</width>
|
||||
<height>20</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>10</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>TestRail Added for Release</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>releasesComboBox</tabstop>
|
||||
<tabstop>OKButton</tabstop>
|
||||
<tabstop>cancelButton</tabstop>
|
||||
</tabstops>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
Loading…
Reference in a new issue