Skip to content
Open
27 changes: 27 additions & 0 deletions .github/workflows/code_style.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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" \
'\<StackView[[:space:]]*{' \
app/qml/ || true)

if [ -n "$matches" ]; then
echo "ERROR: Direct StackView usage found. Use MMStackView instead:"
echo ""
echo "$matches"
exit 1
fi

echo "OK: No direct StackView usage found."
15 changes: 15 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,13 @@ set(MM_VERSION_CODE
CACHE STRING "Build version (for stores)"
)

if (DEFINED SQUISH_PATH)
set(SquishQtBuiltinHook_ROOT
${SQUISH_PATH}
CACHE PATH "Path to directory with Squish hook and libraries"
)
endif ()

mm_detect_version()
message(STATUS "Mergin Maps Mobile ${version_desc} - ${platform_desc}")

Expand Down Expand Up @@ -266,6 +273,10 @@ if (ENABLE_TESTS)
)
endif ()

if (SquishQtBuiltinHook_ROOT)
Comment thread
Withalion marked this conversation as resolved.
find_package(SquishQtBuiltinHook)
endif ()

# ########################################################################################
# GLOBAL SETUP
# ########################################################################################
Expand Down Expand Up @@ -370,6 +381,10 @@ if (ANDROID)
# Make sure the generator for android_deployment_settings.json can figure out the
# architecture
list(APPEND CMAKE_FIND_ROOT_PATH /)
# Make sure the generator for android_deployment_settings.json can find Squish libs
if (SquishQtBuiltinHook_ROOT)
list(APPEND CMAKE_FIND_ROOT_PATH ${SquishQtBuiltinHook_ROOT})
endif ()
endif ()

# ########################################################################################
Expand Down
43 changes: 43 additions & 0 deletions INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,7 @@ Once the project is opened, build it from Xcode.

# 9. Auto Testing <a name="auto-testing"></a>

## Mergin API tests
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are unit tests, not only mergin api 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.
Expand All @@ -645,3 +646,45 @@ TEST_API_PASSWORD=<your_password>

Build binary, and you can run tests either with `ctest` or you can run individual tests by adding `--test<TestName>`
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=/<path>/<to>/<squish-for-android-or-ios>/<directory>/
-DCMAKE_FIND_ROOT_PATH=/<path>/<to>/<squish-for-android-or-ios>/<directory>/
-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 \<No Application\>.
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")`
36 changes: 34 additions & 2 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -353,13 +353,28 @@ 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
QT_ANDROID_TARGET_SDK_VERSION ${MM_ANDROID_TARGET_SDK_VERSION}
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 ()

Expand Down Expand Up @@ -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 ()

Expand All @@ -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)
Expand Down
1 change: 1 addition & 0 deletions app/qml/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
19 changes: 19 additions & 0 deletions app/qml/components/MMStackView.qml
Original file line number Diff line number Diff line change
@@ -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
}
4 changes: 3 additions & 1 deletion app/qml/form/MMFormStackController.qml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
import QtQuick
import QtQuick.Controls

import "../components"

Item {
id: root

Expand Down Expand Up @@ -252,7 +254,7 @@ Item {
form.controllerToApply = null
}

StackView {
MMStackView {
Comment thread
Withalion marked this conversation as resolved.
id: formsStack

property bool syncWhenFormCloses: false
Expand Down
2 changes: 1 addition & 1 deletion app/qml/layers/MMLayersController.qml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Item {
}
}

StackView {
MMStackView {
id: pagesStackView

anchors.fill: parent
Expand Down
2 changes: 1 addition & 1 deletion app/qml/main.qml
Original file line number Diff line number Diff line change
Expand Up @@ -442,7 +442,7 @@ ApplicationWindow {
onClosed: stateManager.state = "map"
}

StackView {
MMStackView {
id: mapPanelsStackView

//
Expand Down
2 changes: 1 addition & 1 deletion app/qml/project/MMProjectController.qml
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Item {
stackView.focus = true
}

StackView {
MMStackView {
id: stackView

initialItem: workspaceProjectsPanelComp
Expand Down
2 changes: 1 addition & 1 deletion app/qml/settings/MMSettingsController.qml
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ Item {
}


StackView {
MMStackView {
id: stackview

width: ApplicationWindow.window?.width ?? 0
Expand Down
2 changes: 1 addition & 1 deletion gallery/qml/pages/OnboardingPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import "../../app/qml/account"
Page {
id: root

StackView {
MMStackView {
id: stackview

anchors.fill: parent
Expand Down
2 changes: 1 addition & 1 deletion gallery/qml/pages/PagesPage.qml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import "../../app/qml/account"
Page {
id: root

StackView {
MMStackView {
id: stackview

anchors.fill: parent
Expand Down
Loading