From 643f4c5942808eacf40d76de6dfbdcdbdca777c2 Mon Sep 17 00:00:00 2001 From: Julien Wadel Date: Tue, 24 Jan 2023 09:06:50 +0100 Subject: [PATCH] Proto tests[ci_skip] --- CMakeLists.txt | 1 + linphone-app/CMakeLists.txt | 38 +- linphone-app/src/app/App.cpp | 8 +- linphone-app/src/app/App.hpp | 2 + linphone-app/src/app/appMain.cpp | 102 ++++++ linphone-app/src/app/main.cpp | 85 +---- linphone-app/src/tester/utils_tester.cpp | 343 ++++++++++++++++++ linphone-app/src/tester/utils_tester.hpp | 44 +++ .../ui/modules/Common/Form/ActionButton.qml | 2 +- .../SmartSearchBar/SmartSearchBar.qml | 6 + .../Linphone/View/SipAddressesView.qml | 9 +- .../ui/views/App/Calls/CallsWindow.qml | 1 + linphone-app/ui/views/App/Calls/Incall.qml | 2 + linphone-app/ui/views/App/Main/MainWindow.qml | 2 + linphone-tester/CMakeLists.txt | 21 ++ linphone-tester/tst_utilstester.cpp | 48 +++ 16 files changed, 619 insertions(+), 95 deletions(-) create mode 100644 linphone-app/src/app/appMain.cpp create mode 100644 linphone-app/src/tester/utils_tester.cpp create mode 100644 linphone-app/src/tester/utils_tester.hpp create mode 100644 linphone-tester/CMakeLists.txt create mode 100644 linphone-tester/tst_utilstester.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d92707c5..a2eed7148 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -322,6 +322,7 @@ else() message("Adding Linphone Desktop in an IDE-friendly state") set(CMAKE_INSTALL_PREFIX "${APPLICATION_OUTPUT_DIR}") add_subdirectory(${CMAKE_SOURCE_DIR}/linphone-app) + add_subdirectory(${CMAKE_SOURCE_DIR}/linphone-tester) if(NOT LINPHONE_QT_ONLY) add_dependencies(app-library ${APP_DEPENDS}) endif() diff --git a/linphone-app/CMakeLists.txt b/linphone-app/CMakeLists.txt index 15c764637..bea3e7770 100644 --- a/linphone-app/CMakeLists.txt +++ b/linphone-app/CMakeLists.txt @@ -45,7 +45,7 @@ include(CheckCXXCompilerFlag) set(TARGET_NAME linphone-qt) set(LINPHONE_QML_DIR "WORK/qml_files/ui") set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS true) -set(CMAKE_CXX_STANDARD 14) +set(CMAKE_CXX_STANDARD 17) if(UNIX AND NOT APPLE) set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) @@ -60,6 +60,7 @@ list(APPEND CMAKE_PREFIX_PATH "${QTKEYCHAIN_OUTPUT_DIR}/lib/cmake") set(APP_LIBRARY app-library) set(APP_PLUGIN app-plugin) +#set(APP_TESTER app-tester) include(application_info.cmake) string(TIMESTAMP CURRENT_YEAR "%Y") if(NOT APPLICATION_START_LICENCE OR "${CURRENT_YEAR}" STREQUAL "${APPLICATION_START_LICENCE}") @@ -129,6 +130,8 @@ endif() if( WIN32) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -D_WINSOCKAPI_")#remove error from windows headers order add_definitions(-DNOMINMAX) +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread") endif() set(CMAKE_INCLUDE_CURRENT_DIR ON)#useful for config.h @@ -292,6 +295,8 @@ set(PLUGIN_SOURCES src/utils/plugins/PluginDataAPI.cpp src/utils/plugins/PluginNetworkHelper.cpp src/utils/plugins/LinphonePlugin.cpp ) +set(TESTER_SOURCES src/tester/utils_tester.cpp + ) set(HEADERS src/app/App.hpp @@ -432,9 +437,13 @@ set(HEADERS set(PLUGIN_HEADERS include/LinphoneApp/PluginDataAPI.hpp include/LinphoneApp/PluginNetworkHelper.hpp - include/LinphoneApp/LinphonePlugin.hpp) + include/LinphoneApp/LinphonePlugin.hpp + ) +set(TESTER_HEADERS src/tester/utils_tester.hpp + ) + list(APPEND SOURCES include/LinphoneApp/PluginExample.json) -set(MAIN_FILE src/app/main.cpp) +#set(MAIN_FILE src/app/main.cpp) if (APPLE) list(APPEND SOURCES @@ -511,6 +520,8 @@ PREPEND(SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/") PREPEND(HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/") PREPEND(PLUGIN_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/") PREPEND(PLUGIN_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/") +PREPEND(TESTER_SOURCES "${CMAKE_CURRENT_SOURCE_DIR}/") +PREPEND(TESTER_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/") # ------------------------------------------------------------------------------ # Compute QML files list. @@ -603,7 +614,8 @@ if(WIN32) endif() add_library(${APP_PLUGIN} SHARED ${PLUGIN_SOURCES} ${PLUGIN_HEADERS}) -add_library(${APP_LIBRARY} OBJECT ${SOURCES} ${HEADERS} ${QML_SOURCES} ${QRC_RESOURCES} ${QRC_WEBVIEW_RESOURCES} ${PLUGIN_HEADERS})#Need to add Headers to resolve moc Qt symbols +add_library(${APP_LIBRARY} OBJECT ${SOURCES} ${HEADERS} ${QML_SOURCES} ${QRC_RESOURCES} ${QRC_WEBVIEW_RESOURCES} ${TESTER_SOURCES} ${TESTER_HEADERS} ${PLUGIN_HEADERS})#Need to add Headers to resolve moc Qt symbols +##add_executable(${APP_TESTER} ${TESTER_SOURCES} ${TESTER_HEADERS}) if (WIN32) add_executable(${TARGET_NAME} WIN32 $ ${MAIN_FILE} ${QRC_BIG_RESOURCES} ${RC_FILE}) @@ -622,12 +634,14 @@ endif () set_property(TARGET ${APP_LIBRARY} PROPERTY POSITION_INDEPENDENT_CODE ON) #Need by Qt set_property(TARGET ${APP_PLUGIN} PROPERTY POSITION_INDEPENDENT_CODE ON) #Need by Qt +#set_property(TARGET ${APP_TESTER} PROPERTY POSITION_INDEPENDENT_CODE ON) #Need by Qt #Turn on automatic resources compilation by cmake #Instead of excplicitely calling qt5_add_resources set_property(TARGET ${APP_LIBRARY} PROPERTY AUTORCC ON) set_property(TARGET ${APP_PLUGIN} PROPERTY AUTORCC ON) +#set_property(TARGET ${APP_TESTER} PROPERTY AUTORCC ON) @@ -641,6 +655,10 @@ endif() target_compile_definitions(${APP_PLUGIN} PUBLIC "-DENABLE_APP_EXPORT_PLUGIN") set_target_properties(${APP_PLUGIN} PROPERTIES WINDOWS_EXPORT_ALL_SYMBOLS ON) +#set_target_properties(${APP_TESTER} PROPERTIES WIN32_EXECUTABLE TRUE) +#set_target_properties(${APP_TESTER} PROPERTIES MACOSX_BUNDLE TRUE) + + set(INCLUDED_DIRECTORIES "${LINPHONECXX_INCLUDE_DIRS}" "${MEDIASTREAMER2_INCLUDE_DIRS}") list(APPEND INCLUDED_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/include") @@ -676,6 +694,7 @@ foreach (package ${QT5_PACKAGES}) # list(APPEND LIBRARIES ${Qt5${package}_LIBRARIES}) target_link_libraries(${APP_LIBRARY} Qt5::${package}) target_link_libraries(${APP_PLUGIN} Qt5::${package}) + #target_link_libraries(${APP_TESTER} Qt5::${package}) target_link_libraries(${TARGET_NAME} Qt5::${package}) endif () endforeach () @@ -696,6 +715,7 @@ endforeach () if(ENABLE_QT_KEYCHAIN) target_link_libraries(${APP_LIBRARY} ${QTKEYCHAIN_TARGET_NAME}) target_link_libraries(${APP_PLUGIN} ${QTKEYCHAIN_TARGET_NAME}) + #target_link_libraries(${APP_TESTER} ${QTKEYCHAIN_TARGET_NAME}) target_link_libraries(${TARGET_NAME} ${QTKEYCHAIN_TARGET_NAME}) endif() @@ -707,6 +727,7 @@ endif () target_include_directories(${APP_LIBRARY} SYSTEM PUBLIC ${INCLUDED_DIRECTORIES}) target_include_directories(${APP_PLUGIN} SYSTEM PUBLIC ${INCLUDED_DIRECTORIES}) +#target_include_directories(${APP_TESTER} SYSTEM PUBLIC ${INCLUDED_DIRECTORIES}) target_include_directories(${TARGET_NAME} SYSTEM PUBLIC ${INCLUDED_DIRECTORIES}) target_link_libraries(${APP_LIBRARY} ${LIBRARIES}) @@ -714,6 +735,7 @@ target_link_libraries(${APP_PLUGIN} ${LIBRARIES}) target_link_libraries(${APP_LIBRARY} ${APP_PLUGIN}) target_link_libraries(${TARGET_NAME} ${LIBRARIES}) target_link_libraries(${TARGET_NAME} ${APP_PLUGIN}) +#target_link_libraries(${APP_TESTER} ${LIBRARIES}) if(WIN32) find_library(LDAP_LIBRARIES NAMES ldap libldap HINTS "${LINPHONE_OUTPUT_DIR}/${CMAKE_INSTALL_LIBDIR}") @@ -721,8 +743,11 @@ if(WIN32) target_link_libraries(${TARGET_NAME} wsock32 ws2_32 ${LDAP_LIBRARIES} ${LBER_LIBRARIES}) endif() +#target_link_libraries(${APP_TESTER} ${TARGET_NAME}) + add_dependencies(${APP_LIBRARY} update_translations ${TARGET_NAME}-git-version ${APP_PLUGIN}) add_dependencies(${TARGET_NAME} ${APP_LIBRARY} ${APP_PLUGIN}) +#add_dependencies(${APP_TESTER} ${TARGET_NAME} ${APP_LIBRARY}) # ------------------------------------------------------------------------------ @@ -738,11 +763,6 @@ add_custom_command(TARGET ${APP_PLUGIN} POST_BUILD COMMAND ${CMAKE_COMMAND} -E c #add_custom_command(TARGET ${TARGET_NAME} PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy "${CMAKE_CURRENT_SOURCE_DIR}/include/LinphoneApp/*" "${CMAKE_INSTALL_PREFIX}/include/LinphoneApp/") - - - - - #configure_file("${CMAKE_CURRENT_SOURCE_DIR}/include/*" "${CMAKE_INSTALL_PREFIX}/include/LinphoneApp/" COPYONLY) install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/include" DESTINATION ".") diff --git a/linphone-app/src/app/App.cpp b/linphone-app/src/app/App.cpp index faaa81f08..181b61b03 100644 --- a/linphone-app/src/app/App.cpp +++ b/linphone-app/src/app/App.cpp @@ -63,6 +63,7 @@ // ============================================================================= +#include "appMain.cpp" using namespace std; namespace { @@ -347,6 +348,8 @@ void App::initContentApp () { configPath = getConfigPathIfExists(*mParser); config = Utils::getConfigIfExists (QString::fromStdString(configPath)); initLocale(config); + // Init engine content. + mEngine = new QQmlApplicationEngine(this); } else { configPath = getConfigPathIfExists(*mParser); config = Utils::getConfigIfExists(QString::fromStdString(configPath)); @@ -367,6 +370,8 @@ void App::initContentApp () { #ifndef Q_OS_MACOS mustBeIconified = mParser->isSet("iconified"); #endif // ifndef Q_OS_MACOS + // Init engine content. + mEngine = new QQmlApplicationEngine(this); mColorListModel = new ColorListModel(); mImageListModel = new ImageListModel(); } @@ -382,8 +387,7 @@ void App::initContentApp () { CoreManager::init(this, Utils::coreStringToAppString(configPath)); - // Init engine content. - mEngine = new QQmlApplicationEngine(this); + // Provide `+custom` folders for custom components and `5.9` for old components. { diff --git a/linphone-app/src/app/App.hpp b/linphone-app/src/app/App.hpp index 7075c98ec..86fa85ef7 100644 --- a/linphone-app/src/app/App.hpp +++ b/linphone-app/src/app/App.hpp @@ -36,6 +36,7 @@ namespace linphone { class Config; } +class AppController; class ColorListModel; class DefaultTranslator; class ImageListModel; @@ -53,6 +54,7 @@ class App : public SingleApplication { Q_PROPERTY(bool autoStart READ getAutoStart WRITE setAutoStart NOTIFY autoStartChanged) public: + static int main(int argc, char *argv[]); App (int &argc, char *argv[]); ~App (); diff --git a/linphone-app/src/app/appMain.cpp b/linphone-app/src/app/appMain.cpp new file mode 100644 index 000000000..2440dfe09 --- /dev/null +++ b/linphone-app/src/app/appMain.cpp @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2010-2020 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "AppController.hpp" +#include +#ifdef QT_QML_DEBUG +#include +#endif +#include +#ifdef _WIN32 +#include +FILE * gStream = NULL; +#endif + +#include "components/core/CoreManager.hpp" +#include "utils/Utils.hpp" + +#ifdef ENABLE_QT_KEYCHAIN +#include "components/vfs/VfsUtils.hpp" +#endif + +// ============================================================================= + +void cleanStream(){ +#ifdef _WIN32 + if(gStream) { + fflush(stdout); + fflush(stderr); + fclose(gStream); + } +#endif +} + +int App::main (int argc, char *argv[]) { +#ifdef __APPLE__ + qputenv("QT_ENABLE_GLYPH_CACHE_WORKAROUND", "1"); // On Mac, set this workaround to avoid glitches on M1, because of https://bugreports.qt.io/browse/QTBUG-89379 +#elif defined _WIN32 + // log in console only if launched from console + if (AttachConsole(ATTACH_PARENT_PROCESS)) { + freopen_s(&gStream, "CONOUT$", "w", stdout); + freopen_s(&gStream, "CONOUT$", "w", stderr); + } +#endif + +#ifdef ENABLE_QT_KEYCHAIN + bool vfsEncrypted = VfsUtils::updateSDKWithKey(); +#else + bool vfsEncrypted = false; +#endif + + AppController controller(argc, argv); +#ifdef QT_QML_DEBUG + QQmlDebuggingEnabler enabler; +#endif + //QLoggingCategory::setFilterRules("*.debug=true;qml=false"); + App *app = controller.getApp(); +// if(vfsEncrypted) +// qInfo() << "Activation of VFS encryption."; + if (app->isSecondary()) + { + qInfo() << QStringLiteral("Running secondary app success. Kill it now."); + cleanStream(); + return EXIT_SUCCESS; + } + + qInfo() << QStringLiteral("Running app..."); + + int ret; + do { + app->initContentApp(); + ret = app->exec(); + } while (ret == App::RestartCode); + qWarning() << "Exiting app with the code : " << ret; + controller.stopApp(); // Stopping app before core to let time to GUI to process needed items from linphone. + if( CoreManager::getInstance()){ + auto core = CoreManager::getInstance()->getCore(); + if(core && core->getGlobalState() == linphone::GlobalState::On) + core->stop(); + } + cleanStream(); + if( ret == App::DeleteDataCode){ + Utils::deleteAllUserDataOffline(); + } + return ret; +} diff --git a/linphone-app/src/app/main.cpp b/linphone-app/src/app/main.cpp index ad26cf04d..1243d632f 100644 --- a/linphone-app/src/app/main.cpp +++ b/linphone-app/src/app/main.cpp @@ -17,88 +17,9 @@ * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ - -#include "AppController.hpp" -#include -#ifdef QT_QML_DEBUG -#include -#endif -#include -#ifdef _WIN32 -#include -FILE * gStream = NULL; -#endif - -#include "components/core/CoreManager.hpp" -#include "utils/Utils.hpp" - -#ifdef ENABLE_QT_KEYCHAIN -#include "components/vfs/VfsUtils.hpp" -#endif - -// ============================================================================= - -void cleanStream(){ -#ifdef _WIN32 - if(gStream) { - fflush(stdout); - fflush(stderr); - fclose(gStream); - } -#endif -} - - + #include "App.hpp" + int main (int argc, char *argv[]) { -#ifdef __APPLE__ - qputenv("QT_ENABLE_GLYPH_CACHE_WORKAROUND", "1"); // On Mac, set this workaround to avoid glitches on M1, because of https://bugreports.qt.io/browse/QTBUG-89379 -#elif defined _WIN32 - // log in console only if launched from console - if (AttachConsole(ATTACH_PARENT_PROCESS)) { - freopen_s(&gStream, "CONOUT$", "w", stdout); - freopen_s(&gStream, "CONOUT$", "w", stderr); - } -#endif - -#ifdef ENABLE_QT_KEYCHAIN - bool vfsEncrypted = VfsUtils::updateSDKWithKey(); -#else - bool vfsEncrypted = false; -#endif - - AppController controller(argc, argv); -#ifdef QT_QML_DEBUG - QQmlDebuggingEnabler enabler; -#endif - //QLoggingCategory::setFilterRules("*.debug=true;qml=false"); - App *app = controller.getApp(); - if(vfsEncrypted) - qInfo() << "Activation of VFS encryption."; - if (app->isSecondary()) - { - qInfo() << QStringLiteral("Running secondary app success. Kill it now."); - cleanStream(); - return EXIT_SUCCESS; - } - - qInfo() << QStringLiteral("Running app..."); - - int ret; - do { - app->initContentApp(); - ret = app->exec(); - } while (ret == App::RestartCode); - qWarning() << "Exiting app with the code : " << ret; - controller.stopApp(); // Stopping app before core to let time to GUI to process needed items from linphone. - if( CoreManager::getInstance()){ - auto core = CoreManager::getInstance()->getCore(); - if(core && core->getGlobalState() == linphone::GlobalState::On) - core->stop(); - } - cleanStream(); - if( ret == App::DeleteDataCode){ - Utils::deleteAllUserDataOffline(); - } - return ret; + return App::main(argc, argv); } diff --git a/linphone-app/src/tester/utils_tester.cpp b/linphone-app/src/tester/utils_tester.cpp new file mode 100644 index 000000000..c8888409d --- /dev/null +++ b/linphone-app/src/tester/utils_tester.cpp @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include "utils_tester.hpp" + +#include "app/App.hpp" +#include "app/AppController.hpp" +#include "components/core/CoreManager.hpp" +#include "utils/Utils.hpp" + +#include + +/* +#include + +#define L_QTEST_MAIN_IMPL(TestObject) \ + TESTLIB_SELFCOVERAGE_START(#TestObject) \ + QT_PREPEND_NAMESPACE(QTest::Internal::callInitMain)(); \ + AppController app(argc, argv); \ + TestObject tc(&app); \ + QTEST_SET_MAIN_SOURCE_PATH \ + return QTest::qExec(&tc, argc, argv); + +#define L_QTEST_MAIN(TestObject) \ +int main(int argc, char *argv[]) \ +{ \ + L_QTEST_MAIN_IMPL(TestObject) \ +} +L_QTEST_MAIN(UtilsTester) + +//QTEST_MAIN(UtilsTester) +//#include "utilstester.moc" // if hpp is in cpp +*/ + + +#include +#ifdef QT_QML_DEBUG +#include +#endif +#include +#ifdef _WIN32 +#include +FILE * gStream = NULL; +#endif + +#include "components/core/CoreManager.hpp" +#include "utils/Utils.hpp" + +#ifdef ENABLE_QT_KEYCHAIN +#include "components/vfs/VfsUtils.hpp" +#endif +#include +#include +#include +#include + +// ============================================================================= + +void _cleanStream(){ +#ifdef _WIN32 + if(gStream) { + fflush(stdout); + fflush(stderr); + fclose(gStream); + } +#endif +} + +class Test : public QThread{ +public: + Test(){ + } + virtual void run(); +}; +void Test::run(){ + UtilsTester tc(nullptr); + std::vector arguments = {"dummy", "-maxwarnings", "0"}; + std::vector argv; + for (const auto& arg : arguments) + argv.push_back((char*)arg.data()); + argv.push_back(nullptr); + + QTest::qExec(&tc, argv.size() - 1, argv.data()); +} +int main (int argc, char *argv[]) { +#ifdef __APPLE__ + qputenv("QT_ENABLE_GLYPH_CACHE_WORKAROUND", "1"); // On Mac, set this workaround to avoid glitches on M1, because of https://bugreports.qt.io/browse/QTBUG-89379 +#elif defined _WIN32 + // log in console only if launched from console + if (AttachConsole(ATTACH_PARENT_PROCESS)) { + freopen_s(&gStream, "CONOUT$", "w", stdout); + freopen_s(&gStream, "CONOUT$", "w", stderr); + } +#endif + +#ifdef ENABLE_QT_KEYCHAIN + bool vfsEncrypted = VfsUtils::updateSDKWithKey(); +#else + bool vfsEncrypted = false; +#endif + + AppController controller(argc, argv); +#ifdef QT_QML_DEBUG + QQmlDebuggingEnabler enabler; +#endif + //QLoggingCategory::setFilterRules("*.debug=true;qml=false"); + App *app = controller.getApp(); + // if(vfsEncrypted) + // qInfo() << "Activation of VFS encryption."; + if (app->isSecondary()) + { + qInfo() << QStringLiteral("Running secondary app success. Kill it now."); + _cleanStream(); + return EXIT_SUCCESS; + } + + qInfo() << QStringLiteral("Running app..."); + QThread * test; + int ret = 0; + do { + app->initContentApp(); + if(ret == 0){ + test = QThread::create([](){ + UtilsTester tc(nullptr); + std::vector arguments = {"dummy", "-maxwarnings", "0"}; + std::vector argv; + for (const auto& arg : arguments) + argv.push_back((char*)arg.data()); + argv.push_back(nullptr); + + QTest::qExec(&tc, argv.size() - 1, argv.data()); + }); + test->start(); + } + ret = app->exec(); + } while (ret == App::RestartCode); + qWarning() << "Exiting app with the code : " << ret; + controller.stopApp(); // Stopping app before core to let time to GUI to process needed items from linphone. + if( CoreManager::getInstance()){ + auto core = CoreManager::getInstance()->getCore(); + if(core && core->getGlobalState() == linphone::GlobalState::On) + core->stop(); + } + _cleanStream(); + if( ret == App::DeleteDataCode){ + Utils::deleteAllUserDataOffline(); + } + return ret; +} + +void debugNames(QQuickItem * item){ + if(!item) + return; + auto childs = item->childItems(); + QString name = item->objectName(); + QString qmlProperty = QQmlProperty::read(item, "objectName").toString(); + const QMetaObject* metaObject = item->metaObject(); + QStringList properties; + for(int i = metaObject->propertyOffset(); i < metaObject->propertyCount(); ++i) + properties << QString::fromLatin1(metaObject->property(i).name()); + + if(name != "" || qmlProperty != "") + qDebug() << name << " / " << qmlProperty << " / " << childs.size() << properties; + else{ + if(metaObject->propertyCount() > 0) + qDebug() << properties; + } + for(int i = 0 ; i < childs.size() ; ++i){ + debugNames(childs.at(i)); + } +} + +class ItemManager{ +public: + static void getItem(const QString& name, QQuickItem * item, QQuickItem ** found){ + if(*found || !item) + return; + auto childs = item->childItems(); + //QString itemName = item->objectName(); // not working on Repeater + if(QQmlProperty::read(item, "objectName").toString() == name){ + //if(name == itemName){ + *found = item; + return; + } + for(int i = 0 ; i < childs.size() ; ++i){ + ItemManager::getItem(name, childs.at(i), found); + } + } + static QQuickItem * getItem(QQuickItem * parent, const QString& name){ + QQuickItem * item = nullptr; + if(parent){ + ItemManager::getItem(name, parent, &item); + if(!item){ + qWarning() << "not found : " << name; + debugNames(parent); + //debugNames(engine); + } + } + return item; + } + static QQuickItem * getItem(const QString& name){ + auto engine = App::getInstance()->getEngine(); + QQuickItem * item = nullptr; + auto roots = engine->rootObjects(); + for(int i = 0 ; !item && i < roots.size() ; ++i){ + QObject * object = roots[i]; + auto childs = object->children(); + for(int j = 0 ; !item && j < childs.size() ; ++j) + ItemManager::getItem(name, qobject_cast(childs[j]), &item); + } + + if(!item){ + auto childs = App::getInstance()->getCallsWindow()->children(); + for(int j = 0 ; !item && j < childs.size() ; ++j) + ItemManager::getItem(name, qobject_cast(childs[j]), &item); + //ItemManager::getItem(qobject_cast(App::getInstance()->getCallsWindow()), name); + } + if(!item) { + //qWarning() << "not found : " << name << " / " << roots.size(); + //debugNames(qobject_cast(App::getInstance()->getCallsWindow())); + /* + auto roots = engine->rootObjects(); + for(int i = 0 ; !item && i < roots.size() ; ++i){ + QObject * object = roots[i]; + auto childs = object->children(); + for(int j = 0 ; j < childs.size() ; ++j) + debugNames(qobject_cast(childs[j])); + }*/ + } + return item; + //return qobject_cast(item); + } + + + static void clickItem( QQuickItem* pItem, QQuickWindow* pRootWindow ){ + QVERIFY(pItem != nullptr); + auto oPointF = pItem->mapToScene( QPoint( 0, 0 ) ); + auto oPoint = oPointF.toPoint(); + oPoint.rx() += pItem->width() / 2; + oPoint.ry() += pItem->height() / 2; + QTest::mouseClick( pRootWindow, Qt::LeftButton, Qt::NoModifier, oPoint ); + } + + static void clickItem(const QString& name){ + QQuickItem * item = nullptr; + QTRY_VERIFY_WITH_TIMEOUT( (item = ItemManager::getItem(name)) != nullptr, 5000); + clickItem(item, App::getInstance()->getMainWindow()); + //wrapperItem = view->findChild("__internalWrapper"); + } + + static void clickItem(const QString& parentName, const QString& name){ + QQuickItem * parentItem = nullptr; + QQuickItem * item = nullptr; + QTRY_VERIFY_WITH_TIMEOUT( (parentItem =ItemManager::getItem(parentName)) != nullptr, 5000); + QTRY_VERIFY_WITH_TIMEOUT( (item = ItemManager::getItem(parentItem, name)) != nullptr, 5000); + clickItem(item, App::getInstance()->getMainWindow()); + //wrapperItem = view->findChild("__internalWrapper"); + } + + static void keyItem(const QString& sequence){ + for(int i = 0 ; i < sequence.size() ; ++i) + QTest::keyClick(App::getInstance()->getMainWindow(), sequence[i].toLatin1() ); + } +}; + +UtilsTester::UtilsTester(AppController * controller){ + mController = controller; + QTRY_VERIFY_WITH_TIMEOUT(CoreManager::getInstance() != nullptr, 5000); + QTRY_VERIFY_WITH_TIMEOUT(CoreManager::getInstance()->isInitialized(), 5000); +} + +UtilsTester::~UtilsTester(){ + if(App::getInstance()) + App::getInstance()->exit(0); + delete mController; +} + +void UtilsTester::initTestCase(){ + QTRY_VERIFY_WITH_TIMEOUT(CoreManager::getInstance() != nullptr, 5000); + QTRY_VERIFY_WITH_TIMEOUT(CoreManager::getInstance()->isInitialized(), 5000); + //App::main(1, (char**)&appPtr); +} + +void UtilsTester::cleanupTestCase(){ + //App::getInstance()->exit(App::RestartCode); + App::getInstance()->exit(0); +} + +void UtilsTester::test_osProduct() { + QString product = Utils::getOsProduct(); + QVERIFY(!product.contains(' ')); +} + +void UtilsTester::test_register(){ + QTRY_VERIFY_WITH_TIMEOUT(CoreManager::getInstance()->getCore()->getDefaultAccount()->getState() == linphone::RegistrationState::Ok, 10000); +} + +void UtilsTester::test_call(){ + for(int i = 0 ; i < 100 ; ++i){ + ItemManager::clickItem("__mainSmartSearchBar"); + ItemManager::keyItem("julienw2@sip.linphone.org"); + ItemManager::clickItem("__ActionBar", "__audioCallButton"); + QQuickItem *item; + QTRY_VERIFY_WITH_TIMEOUT( (item = ItemManager::getItem("__hangupCallButton")) != nullptr, 5000); + QTest::qWait(2000); + ItemManager::clickItem(item, App::getInstance()->getCallsWindow()); + QTest::qWait(2000); + } +} + + +void UtilsTester::test_call2(){ + //for(int i = 0 ; i < 50 ; ++i){ + qWarning() << "A"; + ItemManager::clickItem("__mainSmartSearchBar"); + qWarning() << "B"; + ItemManager::keyItem("julienw2@sip.linphone.org"); + qWarning() << "C"; + ItemManager::clickItem("__ActionBar", "__audioCallButton"); + QQuickItem *item; + QTRY_VERIFY_WITH_TIMEOUT( (item = ItemManager::getItem("__hangupCallButton")) != nullptr, 5000); + QTest::qWait(1000);// Let 1 second and end of call + ItemManager::clickItem("__hangupCallButton"); + QTest::qWait(2000);// Let 1 second and end of call + //} +} \ No newline at end of file diff --git a/linphone-app/src/tester/utils_tester.hpp b/linphone-app/src/tester/utils_tester.hpp new file mode 100644 index 000000000..4d3681aef --- /dev/null +++ b/linphone-app/src/tester/utils_tester.hpp @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2010-2023 Belledonne Communications SARL. + * + * This file is part of linphone-desktop + * (see https://www.linphone.org). + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + #include + +class AppController; + +class UtilsTester: public QObject +{ + Q_OBJECT + std::string app; + char * appPtr; + int argc = 1; + QThread * mApplication; + AppController * mController; +public: + UtilsTester(AppController * controller); + ~UtilsTester(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void test_osProduct(); + void test_register(); + void test_call(); + void test_call2(); +}; \ No newline at end of file diff --git a/linphone-app/ui/modules/Common/Form/ActionButton.qml b/linphone-app/ui/modules/Common/Form/ActionButton.qml index 7abe0c588..49c98b2d6 100644 --- a/linphone-app/ui/modules/Common/Form/ActionButton.qml +++ b/linphone-app/ui/modules/Common/Form/ActionButton.qml @@ -11,7 +11,7 @@ import Common 1.0 Item { id: wrappedButton - objectName: '__internalActionButton' + //objectName: '__internalActionButton' property color defaultBackgroundColor: 'white' property color defaultForegroundColor: 'black' diff --git a/linphone-app/ui/modules/Linphone/SmartSearchBar/SmartSearchBar.qml b/linphone-app/ui/modules/Linphone/SmartSearchBar/SmartSearchBar.qml index 2c7a672c8..841422502 100644 --- a/linphone-app/ui/modules/Linphone/SmartSearchBar/SmartSearchBar.qml +++ b/linphone-app/ui/modules/Linphone/SmartSearchBar/SmartSearchBar.qml @@ -11,6 +11,7 @@ import Linphone.Styles 1.0 SearchBox { id: searchBox + objectName: '__SmartSearchBar' // --------------------------------------------------------------------------- @@ -61,8 +62,10 @@ SearchBox { SipAddressesView { id: view + objectName: '__SipAddressesView' actions: [{ + objectName: '__videoCallButton', colorSet: SipAddressesViewStyle.videoCall, secure: 0, visible: true, @@ -72,6 +75,7 @@ SearchBox { }, visible: SettingsModel.videoSupported && SettingsModel.outgoingCallsEnabled && SettingsModel.showStartVideoCallButton }, { + objectName: '__audioCallButton', colorSet: SipAddressesViewStyle.call, secure: 0, visible: true, @@ -81,6 +85,7 @@ SearchBox { }, visible: SettingsModel.outgoingCallsEnabled }, { + objectName: '__chatButton', colorSet: SettingsModel.getShowStartChatButton() ? SipAddressesViewStyle.chat : SipAddressesViewStyle.history, secure: 0, handler: function (entry) { @@ -90,6 +95,7 @@ SearchBox { visible: SettingsModel.standardChatEnabled, zz: 'toto' }, { + objectName: '__secureChatButton', colorSet: SettingsModel.getShowStartChatButton() ? SipAddressesViewStyle.chat : SipAddressesViewStyle.history, secure: 1, visible: SettingsModel.secureChatEnabled && AccountSettingsModel.conferenceUri != '', diff --git a/linphone-app/ui/modules/Linphone/View/SipAddressesView.qml b/linphone-app/ui/modules/Linphone/View/SipAddressesView.qml index c8d566e58..a74875bbf 100644 --- a/linphone-app/ui/modules/Linphone/View/SipAddressesView.qml +++ b/linphone-app/ui/modules/Linphone/View/SipAddressesView.qml @@ -53,6 +53,7 @@ ScrollableListView { // --------------------------------------------------------------------------- header: MouseArea { + objectName: '__MouseArea' height: { var height = headerButton.visible ? SipAddressesViewStyle.header.button.height : 0 if (defaultContact.visible) { @@ -78,6 +79,7 @@ ScrollableListView { Loader { id: defaultContact + objectName: '__DefaultContact' height: SipAddressesViewStyle.entry.height width: parent.width @@ -85,6 +87,7 @@ ScrollableListView { visible: sipAddressesView.interpretableSipAddress.length > 0 sourceComponent: Rectangle { + objectName: '__Rectangle' anchors.fill: parent color: SipAddressesViewStyle.entry.color.normal.color @@ -111,13 +114,16 @@ ScrollableListView { ActionBar { id: defaultContactActionBar + objectName: '__ActionBar' iconSize: SipAddressesViewStyle.entry.iconSize Repeater { model: sipAddressesView.actions - + objectName: '__Repeater' + delegate:Component{ ActionButton { + objectName: (sipAddressesView.actions[index].objectName ? sipAddressesView.actions[index].objectName : '') isCustom: true backgroundRadius: 90 colorSet: modelData.colorSet @@ -139,6 +145,7 @@ ScrollableListView { anchors.horizontalCenter: parent.right } } + } } } } diff --git a/linphone-app/ui/views/App/Calls/CallsWindow.qml b/linphone-app/ui/views/App/Calls/CallsWindow.qml index d66112701..f6c7982e9 100644 --- a/linphone-app/ui/views/App/Calls/CallsWindow.qml +++ b/linphone-app/ui/views/App/Calls/CallsWindow.qml @@ -13,6 +13,7 @@ import 'CallsWindow.js' as Logic Window { id: window + objectName: '__CallWindow' // --------------------------------------------------------------------------- diff --git a/linphone-app/ui/views/App/Calls/Incall.qml b/linphone-app/ui/views/App/Calls/Incall.qml index 487ff99b3..8d254fe55 100644 --- a/linphone-app/ui/views/App/Calls/Incall.qml +++ b/linphone-app/ui/views/App/Calls/Incall.qml @@ -21,6 +21,7 @@ import 'qrc:/ui/scripts/Utils/utils.js' as Utils Rectangle { id: mainItem + objectName: '__Incall' property CallModel callModel property ConferenceModel conferenceModel: callModel && callModel.conferenceModel @@ -571,6 +572,7 @@ Rectangle { onClicked: callModel.pausedByUser = !callModel.pausedByUser } ActionButton{ + objectName: '__hangupCallButton' isCustom: true backgroundRadius: width/2 colorSet: IncallStyle.buttons.hangup diff --git a/linphone-app/ui/views/App/Main/MainWindow.qml b/linphone-app/ui/views/App/Main/MainWindow.qml index 3ed5c75b6..01f647bc2 100644 --- a/linphone-app/ui/views/App/Main/MainWindow.qml +++ b/linphone-app/ui/views/App/Main/MainWindow.qml @@ -17,6 +17,7 @@ import 'qrc:/ui/scripts/Utils/utils.js' as Utils ApplicationWindow { id: window + objectName: "__MainWindow" property string _currentView property var _lockedInfo @@ -176,6 +177,7 @@ ApplicationWindow { SmartSearchBar { id: smartSearchBar + objectName: '__mainSmartSearchBar' Layout.fillWidth: true diff --git a/linphone-tester/CMakeLists.txt b/linphone-tester/CMakeLists.txt new file mode 100644 index 000000000..efe6f2e01 --- /dev/null +++ b/linphone-tester/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.5) + +project(UtilsTester LANGUAGES CXX) + +enable_testing() + +find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS Gui Test) +find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Gui Test) + +set(CMAKE_AUTOUIC ON) +set(CMAKE_AUTOMOC ON) +set(CMAKE_AUTORCC ON) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +add_executable(UtilsTester tst_utilstester.cpp) +add_test(NAME UtilsTester COMMAND UtilsTester) + +target_link_libraries(UtilsTester PRIVATE Qt${QT_VERSION_MAJOR}::Gui Qt${QT_VERSION_MAJOR}::Test) + diff --git a/linphone-tester/tst_utilstester.cpp b/linphone-tester/tst_utilstester.cpp new file mode 100644 index 000000000..d0880f90b --- /dev/null +++ b/linphone-tester/tst_utilstester.cpp @@ -0,0 +1,48 @@ +#include +#include + +// add necessary includes here + +class UtilsTester : public QObject +{ + Q_OBJECT + +public: + UtilsTester(); + ~UtilsTester(); + +private slots: + void initTestCase(); + void cleanupTestCase(); + void test_case1(); + +}; + +UtilsTester::UtilsTester() +{ + +} + +UtilsTester::~UtilsTester() +{ + +} + +void UtilsTester::initTestCase() +{ + +} + +void UtilsTester::cleanupTestCase() +{ + +} + +void UtilsTester::test_case1() +{ + +} + +QTEST_MAIN(UtilsTester) + +#include "tst_utilstester.moc"