diff --git a/.github/workflows/code_style.yml b/.github/workflows/code_style.yml index 355591cc2..2ecfe2db1 100644 --- a/.github/workflows/code_style.yml +++ b/.github/workflows/code_style.yml @@ -73,3 +73,30 @@ jobs: - name: Run cppcheck test run: ./scripts/cppcheck.bash + + no_stackview: + name: No direct StackView usage in QML + if: ( github.repository == 'MerginMaps/mobile' ) && (!contains(github.event.head_commit.message, 'Translate ')) + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v6 + + - name: Check for direct StackView instantiation in QML files + run: | + # MMStackView.qml is the approved wrapper — exclude it from the search. + # Any other QML file with a bare "StackView" is using the raw Qt component + # instead of the wrapper, which breaks Squish test support. + matches=$(grep -rn --include="*.qml" \ + --exclude="MMStackView.qml" \ + '\ +## Unit tests You need to add cmake define `-DENABLE_TESTING=TRUE` on your cmake configure line. Also, you need to open Passbolt and check for password for user `test_mobileapp` on `app.dev.merginmaps.com`, or you need some user with unlimited projects limit. First workspace from list is taken. @@ -645,3 +646,45 @@ TEST_API_PASSWORD= Build binary, and you can run tests either with `ctest` or you can run individual tests by adding `--test` e.g. ` ./MerginMaps --testMerginApi` + +## Squish tests +### Prerequisites + - Squish for Qt for Android (ARMv8/ARMv7 depending on architecture you build for) + - Squish for Qt for iOS + - Squish for Qt (Windows/Mac/Linux), this should also include the Squish IDE + +### Android & iOS +After you unpack both (Qt & Qt for Android / iOS) and install Squish IDE, add these cmake arguments +```cmake +-DSQUISH_PATH=///// +-DCMAKE_FIND_ROOT_PATH=///// +-DCMAKE_FIND_ROOT_PATH_MODE_PACKAGE=BOTH +``` +This will build the app with squish hook inside. You can verify that squish is working by finding these lines in log after startup: + +##### Android log +```shell +I/Squish (26459): Setting SQUISH_PREFIX to '/data/data/uk.co.lutraconsulting' +I/Squish (26459): libMerginMaps_arm64-v8a.so[26459]: Loading Qt Wrapper configuration from ":/squish/etc/qtwrapper.ini" +I/Squish (26459): libMerginMaps_arm64-v8a.so[26459]: QObject lifetime tracking is disabled +I/Squish (26459): libMerginMaps_arm64-v8a.so[26459]: Listening on port 7757 for incoming connections +``` + +##### iOS log +```shell +MerginMaps[834]: Loading Qt Wrapper configuration from ":/squish/etc/qtwrapper.ini" +MerginMaps[834]: QObject lifetime tracking is disabled +MerginMaps[834]: Listening on port 7757 for incoming connections +``` + +### Squish +In the squish IDE it's necessary to follow these steps to finish setting it up and start testing the application. +1. In Squish IDE choose File, New Test Suite to create a new Test Suite and follow the wizard. When asked for the GUI Toolkit choose Qt. When asked for the Application Under Test choose \. +2. [Register attachable AUT](https://doc.qt.io/squish/attaching-to-running-applications.html#register-the-attachable-aut) + 1. As _Name_ set `MerginMaps`, _Host_ is the IP address of your phone (has to be on the same Wifi) and set _Port_ to `7757` + 2. You can also use USB cable to connect both devices. However, there is some further setup to do, first you need to forward the device port to your PC with: + ```shell + $ adb forward tcp:portnumber tcp:portnumber + ``` + After that the setup is the same as in point 1, just _Host_ will become `localhost`. +3. The test script should start with `attachToApplication("MerginMaps")` diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index b75d1b8e1..326147ed5 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -353,6 +353,20 @@ if (ANDROID) ${CMAKE_CURRENT_SOURCE_DIR}/android/build.gradle @ONLY ) + if (SquishQtBuiltinHook_FOUND) + list( + APPEND + SquishLibs + "${SquishQtBuiltinHook_ROOT}/lib/libsquishhook.so" + "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtquickcommon.so" + "${SquishQtBuiltinHook_ROOT}/lib/libsquishqtwrapper.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqgraphicsview.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtabwidget.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquick.so" + "${SquishQtBuiltinHook_ROOT}/lib/extensions/qt/libsquishqtquicktypes.so" + ) + endif () + set_target_properties( MerginMaps PROPERTIES QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android @@ -360,6 +374,7 @@ if (ANDROID) QT_ANDROID_MIN_SDK_VERSION ${MM_ANDROID_MIN_SDK_VERSION} QT_ANDROID_VERSION_CODE ${MM_VERSION_CODE} QT_ANDROID_VERSION_NAME ${MM_VERSION} + QT_ANDROID_EXTRA_LIBS "${SquishLibs}" ) endif () @@ -587,9 +602,14 @@ if (IOS) endif () if (ANDROID) + if (SquishQtBuiltinHook_FOUND) + squish_qt_add_builtin_hook(MerginMaps ATTACH_PORT 7757) + endif () + set_property( - TARGET MerginMaps PROPERTY QT_ANDROID_EXTRA_LIBS ${OpenSSL_SSL_LIBRARY} - ${OpenSSL_CRYPTO_LIBRARY} + TARGET MerginMaps + APPEND + PROPERTY QT_ANDROID_EXTRA_LIBS ${OpenSSL_SSL_LIBRARY} ${OpenSSL_CRYPTO_LIBRARY} ) endif () @@ -607,6 +627,18 @@ if (IOS) ) # TODO is this needed? this change requires cmake 3.28+ # qt_add_ios_ffmpeg_libraries(MerginMaps) # Qt Multimedia + if (SquishQtBuiltinHook_FOUND) + squish_qt_add_builtin_hook( + MerginMaps + ATTACH_PORT + 7757 + EXTENSIONS + QGraphicsView + QTabWidget + QtQuickTypes + QtQuick + ) + endif () endif () if (WIN) diff --git a/app/qml/CMakeLists.txt b/app/qml/CMakeLists.txt index 2413d008d..15c10bd25 100644 --- a/app/qml/CMakeLists.txt +++ b/app/qml/CMakeLists.txt @@ -58,6 +58,7 @@ set(MM_QML components/MMToolbarButton.qml components/MMSingleClickMouseArea.qml components/MMSegmentControl.qml + components/MMStackView.qml components/private/MMBaseInput.qml components/private/MMBaseSingleLineInput.qml components/private/MMToolbarLongButton.qml diff --git a/app/qml/components/MMStackView.qml b/app/qml/components/MMStackView.qml new file mode 100644 index 000000000..14e50556c --- /dev/null +++ b/app/qml/components/MMStackView.qml @@ -0,0 +1,19 @@ +/*************************************************************************** + * * + * 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 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +import QtQuick +import QtQuick.Controls + +// StackView wrapper, which improves Squish support. Should be used instead of pure QML StackView. + +StackView { + id: root + + visible: !empty +} diff --git a/app/qml/form/MMFormStackController.qml b/app/qml/form/MMFormStackController.qml index 9d8c4d1f3..b88533793 100644 --- a/app/qml/form/MMFormStackController.qml +++ b/app/qml/form/MMFormStackController.qml @@ -10,6 +10,8 @@ import QtQuick import QtQuick.Controls +import "../components" + Item { id: root @@ -252,7 +254,7 @@ Item { form.controllerToApply = null } - StackView { + MMStackView { id: formsStack property bool syncWhenFormCloses: false diff --git a/app/qml/layers/MMLayersController.qml b/app/qml/layers/MMLayersController.qml index 8b7d5487c..14fa79ff6 100644 --- a/app/qml/layers/MMLayersController.qml +++ b/app/qml/layers/MMLayersController.qml @@ -41,7 +41,7 @@ Item { } } - StackView { + MMStackView { id: pagesStackView anchors.fill: parent diff --git a/app/qml/main.qml b/app/qml/main.qml index cfeedeb51..f1f75837a 100644 --- a/app/qml/main.qml +++ b/app/qml/main.qml @@ -442,7 +442,7 @@ ApplicationWindow { onClosed: stateManager.state = "map" } - StackView { + MMStackView { id: mapPanelsStackView // diff --git a/app/qml/project/MMProjectController.qml b/app/qml/project/MMProjectController.qml index 9563972d4..51a978a3a 100644 --- a/app/qml/project/MMProjectController.qml +++ b/app/qml/project/MMProjectController.qml @@ -87,7 +87,7 @@ Item { stackView.focus = true } - StackView { + MMStackView { id: stackView initialItem: workspaceProjectsPanelComp diff --git a/app/qml/settings/MMSettingsController.qml b/app/qml/settings/MMSettingsController.qml index 938ca22e0..4b57758af 100644 --- a/app/qml/settings/MMSettingsController.qml +++ b/app/qml/settings/MMSettingsController.qml @@ -56,7 +56,7 @@ Item { } - StackView { + MMStackView { id: stackview width: ApplicationWindow.window?.width ?? 0 diff --git a/gallery/qml/pages/OnboardingPage.qml b/gallery/qml/pages/OnboardingPage.qml index e3c09b76d..d8748d9a5 100644 --- a/gallery/qml/pages/OnboardingPage.qml +++ b/gallery/qml/pages/OnboardingPage.qml @@ -17,7 +17,7 @@ import "../../app/qml/account" Page { id: root - StackView { + MMStackView { id: stackview anchors.fill: parent diff --git a/gallery/qml/pages/PagesPage.qml b/gallery/qml/pages/PagesPage.qml index 0effaf990..f06d94b0f 100644 --- a/gallery/qml/pages/PagesPage.qml +++ b/gallery/qml/pages/PagesPage.qml @@ -21,7 +21,7 @@ import "../../app/qml/account" Page { id: root - StackView { + MMStackView { id: stackview anchors.fill: parent