Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a Remote Screenshot #105

Merged
merged 6 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
# Qt v5.15.2
{name: 'qt-5.15.2 ubuntu', os: ubuntu-latest, build_type: Debug, qt_version: [5, 15, 2], shared_libs: 'OFF', tests: 'ON'},
{name: 'qt-5.15.2 windows', os: windows-latest, build_type: Debug, qt_version: [5, 15, 2], shared_libs: 'OFF', tests: 'ON', cmake_flags: '"-DAnyRPC_ROOT=C:/Program Files (x86)/AnyRPC" "-DGTest_ROOT=C:/Program Files (x86)/googletest-distribution"'},
{name: 'qt-5.15.2 macos', os: macos-latest, build_type: Debug, qt_version: [5, 15, 2], shared_libs: 'OFF', tests: 'ON'},
{name: 'qt-5.15.2 macos', os: macos-13, build_type: Debug, qt_version: [5, 15, 2], shared_libs: 'OFF', tests: 'ON'},
# Qt v6.2.3
{name: 'qt-6.2.3 ubuntu', os: ubuntu-latest, build_type: Debug, qt_version: [6, 2, 3], shared_libs: 'OFF', tests: 'ON'},
{name: 'qt-6.2.3 windows', os: windows-latest, build_type: Debug, qt_version: [6, 2, 3], shared_libs: 'OFF', tests: 'ON', cmake_flags: '"-DAnyRPC_ROOT=C:/Program Files (x86)/AnyRPC" "-DGTest_ROOT=C:/Program Files (x86)/googletest-distribution"'},
Expand All @@ -36,7 +36,7 @@ jobs:
]
steps:
- name: Check out repository code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Install Qt
uses: jurplel/install-qt-action@v3
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/clang-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Check out repository code
uses: actions/checkout@v3
uses: actions/checkout@v4
- uses: DoozyX/[email protected]
with:
source: '.'
Expand Down
20 changes: 12 additions & 8 deletions .github/workflows/run-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,15 @@ jobs:
# Qt v5.15.2
{name: 'qt-5.15.2 ubuntu', os: ubuntu-latest, build_type: Debug,qt_version: [5, 15, 2], shared_libs: 'OFF', tests: 'OFF'},
{name: 'qt-5.15.2 windows', os: windows-latest, build_type: Debug, qt_version: [5, 15, 2], shared_libs: 'OFF', tests: 'OFF', cmake_flags: '"-DAnyRPC_ROOT=C:/Program Files (x86)/AnyRPC" "-DGTest_ROOT=C:/Program Files (x86)/googletest-distribution"'},
{name: 'qt-5.15.2 macos', os: macos-latest, build_type: Debug, qt_version: [5, 15, 2], shared_libs: 'OFF', tests: 'OFF'},
{name: 'qt-5.15.2 macos', os: macos-13, build_type: Debug, qt_version: [5, 15, 2], shared_libs: 'OFF', tests: 'OFF'},
# Qt v6.2.3
{name: 'qt-6.2.3 ubuntu', os: ubuntu-latest, build_type: Debug, qt_version: [6, 2, 3], shared_libs: 'OFF', tests: 'OFF'},
{name: 'qt-6.2.3 windows', os: windows-latest, build_type: Debug, qt_version: [6, 2, 3], shared_libs: 'OFF', tests: 'OFF', cmake_flags: '"-DAnyRPC_ROOT=C:/Program Files (x86)/AnyRPC" "-DGTest_ROOT=C:/Program Files (x86)/googletest-distribution"'},

# Qt6 on GitHub Actions MacOS is currently bugged: https://bugreports.qt.io/browse/QTIFW-1592
# {name: 'qt-6.2.3 macos', os: macos-latest, build_type: Debug, qt_version: [6, 2, 3], shared_libs: 'OFF', tests: 'OFF'},
{name: 'qt-6.2.3 macos', os: macos-latest, build_type: Debug, qt_version: [6, 2, 3], shared_libs: 'OFF', tests: 'OFF'},
]
steps:
- name: Check out repository code
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Install Qt
uses: jurplel/install-qt-action@v3
Expand All @@ -42,9 +40,9 @@ jobs:

- name: "Build"
run: cmake --build build --config ${{ matrix.base.build_type }}
- name: "Test GTest Examples (*nix)"
if: ${{ !contains(matrix.base.os, 'windows') }}

- name: "Test GTest Examples (Linux)"
if: ${{ contains(matrix.base.os, 'ubuntu') }}
run: |
build/examples/GTest/SpixGTestExample -platform minimal
build/examples/RepeaterLoader/SpixRepeaterLoaderExampleGTest -platform minimal
Expand All @@ -54,3 +52,9 @@ jobs:
run: |
.\build\examples\GTest\${{ matrix.base.build_type }}\SpixGTestExample.exe -platform minimal
.\build\examples\RepeaterLoader\${{ matrix.base.build_type }}\SpixRepeaterLoaderExampleGTest.exe -platform minimal

- name: "Test GTest Examples (mac)"
if: ${{ contains(matrix.base.os, 'mac') }}
run: |
build/examples/GTest/SpixGTestExample
build/examples/RepeaterLoader/SpixRepeaterLoaderExampleGTest
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,27 @@ s.invokeMethod("root/item", "test", [34])
s.invokeMethod("root/item", "test", [{}])
```

### Using generic/custom command
You can register your own commands in your C++ Application.
It could be useful for Example to reset your hole Application.

Register the Commands in your C++ Code:
```C++
...
spix::AnyRpcServer server;
server.setGenericCommandHandler([](std::string command, std::string payload) {
// do whatever needs to be done
});
...
```
Now you have all capabilities that the Application has.
The Payload handling must be done by your own.

You can call this in Python like this:
```python
s.command('reset', 'now')
```

## Two modes of operation
In general, Spix can be used in two ways, which are different in how events are generated and sent
to your application:
Expand Down
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
add_subdirectory(Basic)
add_subdirectory(GTest)
add_subdirectory(GTestMouseClickPosition)
add_subdirectory(ListGridView)
add_subdirectory(RemoteCtrl)
add_subdirectory(RepeaterLoader)
14 changes: 14 additions & 0 deletions examples/GTestMouseClickPosition/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(SPIX_QT_MAJOR "6" CACHE STRING "Major Qt version to build Spix against")

find_package(Qt${SPIX_QT_MAJOR} COMPONENTS Core Quick REQUIRED)
find_package(GTest REQUIRED)

add_executable(SpixGTestMouseClickPosition "main.cpp" "qml.qrc")
target_compile_definitions(SpixGTestMouseClickPosition PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_link_libraries(SpixGTestMouseClickPosition PRIVATE Qt${SPIX_QT_MAJOR}::Core Qt${SPIX_QT_MAJOR}::Quick GTest::GTest Spix)
43 changes: 43 additions & 0 deletions examples/GTestMouseClickPosition/ResultsView.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import QtQuick 2.11
import QtQuick.Controls 2.4

Rectangle {
id: resultsView
color: "#222222"

function appendText(text) {
resultsArea.append(text);
}

Text {
id: resultsTitle
text: "Result: "
color: "white"
font.bold: true

anchors {
top: resultsView.top
left: resultsView.left
right: resultsView.right

topMargin: 5
leftMargin: 2
bottomMargin: 2
}
}
TextEdit {
id: resultsArea
objectName: "results"
color: "white"
anchors {
top: resultsTitle.bottom
left: resultsView.left
right: resultsView.right
bottom: resultsView.bottom

leftMargin: 2
rightMargin: 2
bottomMargin: 2
}
}
}
153 changes: 153 additions & 0 deletions examples/GTestMouseClickPosition/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
/***
* Copyright (C) Falko Axmann. All rights reserved.
* Licensed under the MIT license.
* See LICENSE.txt file in the project root for full license information.
****/

/**
* This is a very basic example to demonstrate how to run your UI tests
* using GTest. It can be useful when you have to make sure that your
* UI tests work well in an existing, GTest based environment.
*
* Keep in mind that GTest is not designed for UI testing and that the
* order of the test execution is not guaranteed. Thus, you should only
* have one test per executable.
*/

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <Spix/Events/Identifiers.h>
#include <Spix/QtQmlBot.h>

#include <atomic>
#include <gtest/gtest.h>

class SpixGTest;
static SpixGTest* srv;

class SpixGTest : public spix::TestServer {
public:
SpixGTest(int argc, char* argv[])
{
m_argc = argc;
m_argv = argv;
}

int testResult() { return m_result.load(); }

protected:
int m_argc;
char** m_argv;
std::atomic<int> m_result {0};

void executeTest() override
{
srv = this;
::testing::InitGoogleTest(&m_argc, m_argv);
auto testResult = RUN_ALL_TESTS();
m_result.store(testResult);
}
};

TEST(GTestExample, ProportionAllButtons)
{
const auto upperLeft = spix::Point(0.25, 0.25);
const auto upperRigth = spix::Point(0.75, 0.25);
const auto lowerLeft = spix::Point(0.25, 0.75);
const auto lowerRigth = spix::Point(0.75, 0.75);

srv->mouseClick(spix::ItemPath("mainWindow/Grid_1"), upperLeft);
srv->wait(std::chrono::milliseconds(500));
srv->mouseClick(spix::ItemPath("mainWindow/Grid_1"), upperRigth);
srv->wait(std::chrono::milliseconds(500));
srv->mouseClick(spix::ItemPath("mainWindow/Grid_1"), lowerLeft);
srv->wait(std::chrono::milliseconds(500));
srv->mouseClick(spix::ItemPath("mainWindow/Grid_1"), lowerRigth);
srv->wait(std::chrono::milliseconds(500));
auto result = srv->getStringProperty("mainWindow/results", "text");

auto expected_result = R"RSLT(Button 1 clicked
Button 2 clicked
Button 3 clicked
Button 4 clicked)RSLT";

EXPECT_EQ(result, expected_result);
}

TEST(GTestExample, TooMuchProportion)
{
// This Test click 200% under the Button 1 => under the Button 1 is Button 3 which will trigger.
const auto upperLeft = spix::Point(0.25, 2);

srv->setStringProperty("mainWindow/results", "text", "");
srv->mouseClick(spix::ItemPath("mainWindow/Button_1"), upperLeft);
srv->wait(std::chrono::milliseconds(500));

auto result = srv->getStringProperty("mainWindow/results", "text");

auto expected_result = R"RSLT(Button 3 clicked)RSLT";

EXPECT_EQ(result, expected_result);
}

TEST(GTestExample, OffsetAllButtons)
{
const auto upperLeft = spix::Point(100, 100);
const auto upperRigth = spix::Point(400, 100);
const auto lowerLeft = spix::Point(100, 200);
const auto lowerRigth = spix::Point(400, 200);

srv->setStringProperty("mainWindow/results", "text", "");
srv->mouseClick(spix::ItemPath("mainWindow/Grid_1"), spix::Point(0, 0), upperLeft);
srv->wait(std::chrono::milliseconds(500));
srv->mouseClick(spix::ItemPath("mainWindow/Grid_1"), spix::Point(0, 0), upperRigth);
srv->wait(std::chrono::milliseconds(500));
srv->mouseClick(spix::ItemPath("mainWindow/Grid_1"), spix::Point(0, 0), lowerLeft);
srv->wait(std::chrono::milliseconds(500));
srv->mouseClick(spix::ItemPath("mainWindow/Grid_1"), spix::Point(0, 0), lowerRigth);
srv->wait(std::chrono::milliseconds(500));

auto result = srv->getStringProperty("mainWindow/results", "text");

auto expected_result = R"RSLT(Button 1 clicked
Button 2 clicked
Button 3 clicked
Button 4 clicked)RSLT";

EXPECT_EQ(result, expected_result);
}

TEST(GTestExample, OffsetOnPositionWithNoButton)
{
const auto centre = spix::Point(320, 120);

srv->setStringProperty("mainWindow/results", "text", "No Click");
srv->mouseClick(spix::ItemPath("mainWindow/Grid_1"), spix::Point(0, 0), centre);
srv->wait(std::chrono::milliseconds(500));

auto result = srv->getStringProperty("mainWindow/results", "text");

auto expected_result = R"RSLT(No Click)RSLT";

EXPECT_EQ(result, expected_result);

srv->quit();
}

int main(int argc, char* argv[])
{
// Init Qt Qml Application
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;

// Instantiate and run tests
SpixGTest tests(argc, argv);
auto bot = new spix::QtQmlBot();
bot->runTestServer(tests);

app.exec();
return tests.testResult();
}
Loading