Thanks to visit codestin.com
Credit goes to github.com

Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
1 change: 1 addition & 0 deletions .github/workflows/run-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ jobs:
run: |
build/examples/GTest/SpixGTestExample -platform minimal
build/examples/RepeaterLoader/SpixRepeaterLoaderExampleGTest -platform minimal
build/examples/GTestPath/SpixGTestPath -platform minimal

- name: "Test GTest Examples (win)"
if: ${{ contains(matrix.base.os, 'windows') }}
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(GTestPath)
add_subdirectory(ListGridView)
add_subdirectory(RemoteCtrl)
add_subdirectory(RepeaterLoader)
14 changes: 14 additions & 0 deletions examples/GTestPath/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(SpixGTestPath "main.cpp" "qml.qrc")
target_compile_definitions(SpixGTestPath PRIVATE $<$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>:QT_QML_DEBUG>)
target_link_libraries(SpixGTestPath PRIVATE Qt${SPIX_QT_MAJOR}::Core Qt${SPIX_QT_MAJOR}::Quick GTest::GTest Spix)
43 changes: 43 additions & 0 deletions examples/GTestPath/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
}
}
}
Binary file added examples/GTestPath/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
120 changes: 120 additions & 0 deletions examples/GTestPath/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/***
* 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, ClickPictures)
{
#if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
srv->mouseClick(spix::ItemPath("mainWindow/(source=icon.png)"));
srv->wait(std::chrono::milliseconds(500));
srv->mouseClick(spix::ItemPath("mainWindow/(source=icon.png)"));
srv->wait(std::chrono::milliseconds(500));
#else
srv->mouseClick(spix::ItemPath("mainWindow/(source=qrc:/icon.png)"));
srv->wait(std::chrono::milliseconds(500));
srv->mouseClick(spix::ItemPath("mainWindow/(source=qrc:/icon.png)"));
srv->wait(std::chrono::milliseconds(500));
#endif

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

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

EXPECT_EQ(result, expected_result);
}

TEST(GTestExample, ClickWithIndex)
{
srv->setStringProperty("mainWindow/results", "text", "");
srv->wait(std::chrono::milliseconds(500));
srv->mouseClick(spix::ItemPath("mainWindow/\"Press Me\"#3"));
srv->wait(std::chrono::milliseconds(500));
srv->mouseClick(spix::ItemPath("mainWindow/\"Press Me\""));
srv->wait(std::chrono::milliseconds(500));
srv->mouseClick(spix::ItemPath("mainWindow/\"Press Me\"#2"));
srv->wait(std::chrono::milliseconds(500));

auto result = srv->getStringProperty("mainWindow/results", "text");
auto expected_result = R"RSLT(Button 4 clicked
Button 2 clicked
Button 3 clicked)RSLT";
EXPECT_EQ(result, expected_result);
}

TEST(GTestExample, TypeNumbers)
{
srv->setStringProperty("mainWindow/results", "text", "");
srv->mouseClick(spix::ItemPath("mainWindow/#Button#2"));
srv->wait(std::chrono::milliseconds(500));

auto result = srv->getStringProperty("mainWindow/results", "text");
auto expected_result = R"RSLT(Button 2 clicked)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();
}
106 changes: 106 additions & 0 deletions examples/GTestPath/main.qml
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
import QtQuick 2.11
import QtQuick.Window 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11

Window {
objectName: "mainWindow"
visible: true
width: 640
height: 480
title: qsTr("Spix Example")
color: "#111111"


GridLayout {
objectName: "Grid_1"
rowSpacing: 20
columnSpacing: 20
anchors {
top: parent.top
left: parent.left
right: parent.right
bottom: parent.verticalCenter
}
columns: 2

Button {
objectName: "Button_1"
Layout.fillHeight: true
Layout.fillWidth: true

Image {
source: "icon.png"
anchors.fill: parent
fillMode: Image.PreserveAspectFit
}


MouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons

onClicked:
{
resultsView.appendText("Button 1 clicked")
}
}
}
Button {
objectName: "Button_2"
text: "Press Me"
Layout.fillHeight: true
Layout.fillWidth: true
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons

onClicked:
{
resultsView.appendText("Button 2 clicked")
}
}
}
Button {
objectName: "Button_3"
text: "Press Me"
Layout.fillHeight: true
Layout.fillWidth: true
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons

onClicked:
{
resultsView.appendText("Button 3 clicked")
}
}
}
Button {
objectName: "Button_4"
text: "Press Me"
Layout.fillHeight: true
Layout.fillWidth: true
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.AllButtons

onClicked:
{
resultsView.appendText("Button 4 clicked")
}
}
}
}


ResultsView {
id: resultsView
anchors {
top: parent.verticalCenter
left: parent.left
right: parent.right
bottom: parent.bottom
}
}
}
7 changes: 7 additions & 0 deletions examples/GTestPath/qml.qrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<RCC>
<qresource prefix="/">
<file>main.qml</file>
<file>ResultsView.qml</file>
<file>icon.png</file>
</qresource>
</RCC>
4 changes: 3 additions & 1 deletion lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ set(SOURCES
src/Scene/Mock/MockScene.h
src/Scene/Mock/MockItem.cpp
src/Scene/Mock/MockItem.h
src/Scene/Qt/QtEventFilter.cpp
src/Scene/Qt/QtEventFilter.h
src/Scene/Qt/QtEvents.cpp
src/Scene/Qt/QtEvents.h
src/Scene/Qt/QtItem.cpp
Expand All @@ -110,7 +112,7 @@ source_group(TREE ${CMAKE_CURRENT_SOURCE_DIR} PREFIX source FILES ${SOURCES})
#
# Qt MOC Files
#
cmake_language(CALL "qt${SPIX_QT_MAJOR}_wrap_cpp" MOC_FILES "include/Spix/QtQmlBot.h")
cmake_language(CALL "qt${SPIX_QT_MAJOR}_wrap_cpp" MOC_FILES "include/Spix/QtQmlBot.h" "src/Scene/Qt/QtEventFilter.h")


#
Expand Down
40 changes: 40 additions & 0 deletions lib/src/Data/ItemPath.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,46 @@ ItemPath::ItemPath(const std::string& path)

while (pathss) {
std::string component;
if (pathss.peek() == '\"') {
getline(pathss, component, '\"');
getline(pathss, component, '\"');

if (pathss.peek() == '#') {
std::string number = "";
getline(pathss, number, '#');

char nextChar;
while (std::isdigit(pathss.peek())) {
pathss >> nextChar;
number += nextChar;
}
component = '\"' + component + '\"' + '#' + number;
} else {
component = '\"' + component + '\"';
}
m_components.push_back(std::move(component));
}

if (pathss.peek() == '(') {
getline(pathss, component, '(');
getline(pathss, component, ')');

if (pathss.peek() == '#') {
std::string number = "";
getline(pathss, number, '#');

char nextChar;
while (std::isdigit(pathss.peek())) {
pathss >> nextChar;
number += nextChar;
}
component = '(' + component + ')' + '#' + number;
} else {
component = '(' + component + ')';
}
m_components.push_back(std::move(component));
}

getline(pathss, component, '/');
if (component.length() > 0) {
m_components.push_back(std::move(component));
Expand Down
Loading