diff --git a/3rdparty/qtquickdesigner-components b/3rdparty/qtquickdesigner-components
index 5f115ed120adb58972ac3a0a2b80ec42cf3769a1..8be09977abbdb638bf483ea417b36091b409c54f 160000
--- a/3rdparty/qtquickdesigner-components
+++ b/3rdparty/qtquickdesigner-components
@@ -1 +1 @@
-Subproject commit 5f115ed120adb58972ac3a0a2b80ec42cf3769a1
+Subproject commit 8be09977abbdb638bf483ea417b36091b409c54f
diff --git a/README.md b/README.md
index 94c64199d13e3573c097a705341ddeac81f0768a..0aa72b4bd0791d893d8075016d7d733e149b6c0d 100644
--- a/README.md
+++ b/README.md
@@ -78,6 +78,19 @@ cmake --build build
 
 Upload the final APK file to your Android device and run. Then follow the instructions within the app.
 
+## Testing
+
+To run the tests a running emulator or a connected device is required. There's a helper script to run the tests under `tests/scripts/run-tests.sh`. To run the tests first copy the APK file to the device and then run the script. It'll extract the test results as `output.junit.xml` file.
+
+Test results can be viewed with any JUnit compatible viewer. For example, you can use `xunit-viewer` to view the results:
+
+```bash
+npm i -g xunit-viewer
+xunit-viewer -r output.junit.xml
+```
+
+It'll create a `report.html` file that can be opened in a web browser. For more information about `xunit-viewer` please visit the [GitHub repo](https://github.com/lukejpreston/xunit-viewer).
+
 ## 3rd Party Libraries/Components
 
 * [zxing-cpp](https://github.com/zxing-cpp/zxing-cpp.git)
diff --git a/src/backend/dsconnector.cpp b/src/backend/dsconnector.cpp
index a608535595d8f23866ee6275cf3f8b742e69a8cf..928c608a5e6b3c171edebfc9c3c4d96d68a5255e 100644
--- a/src/backend/dsconnector.cpp
+++ b/src/backend/dsconnector.cpp
@@ -27,8 +27,9 @@
 
 #include <QNetworkInterface>
 
-DesignStudioConnector::DesignStudioConnector(QObject *parent)
+DesignStudioConnector::DesignStudioConnector(const quint16 port, QObject *parent)
     : QObject(parent)
+    , m_tcpPort(port)
 {
     initTcpServer();
 }
@@ -71,31 +72,33 @@ void DesignStudioConnector::initTcpServer()
     }
 
     qDebug() << "Listening on port " << m_tcpPort;
-    connect(&m_tcpServer, &QTcpServer::newConnection, this, [this]() {
-        qDebug() << "New connection from Design Studio";
-        emit networkStatusUpdated("Qt Design Studio is connected.\n Waiting for project...");
-        m_tcpSocket.reset(m_tcpServer.nextPendingConnection());
-        m_ipUpdateTimer.stop();
-
-        connect(m_tcpSocket.data(), &QTcpSocket::disconnected, this, [this]() {
-            qDebug() << "Disconnected from Design Studio";
-            emit networkStatusUpdated("\nLocal IP: " + m_ipv4Addr
-                                      + "\nWaiting for Qt Design Studio to connect...");
-            m_projectData.clear();
-            m_ipUpdateTimer.start();
-        });
-
-        connect(m_tcpSocket.data(),
-                &QTcpSocket::readyRead,
-                this,
-                &DesignStudioConnector::receiveProject);
-    });
+    connect(&m_tcpServer, &QTcpServer::newConnection, this, &DesignStudioConnector::clientConnected);
 
     m_ipUpdateTimer.setInterval(5000);
     connect(&m_ipUpdateTimer, &QTimer::timeout, this, &DesignStudioConnector::updateIpv4Addr);
     m_ipUpdateTimer.start();
 }
 
+void DesignStudioConnector::clientConnected()
+{
+    qDebug() << "New connection from Design Studio";
+    emit networkStatusUpdated("Qt Design Studio is connected.\n Waiting for project...");
+    m_tcpSocket.reset(m_tcpServer.nextPendingConnection());
+    m_projectData.clear();
+    m_ipUpdateTimer.stop();
+
+    connect(m_tcpSocket.data(), &QTcpSocket::disconnected, this, [&]() {
+        qDebug() << "Disconnected from Design Studio";
+        emit networkStatusUpdated("\nLocal IP: " + m_ipv4Addr
+                                  + "\nWaiting for Qt Design Studio to connect...");
+    });
+
+    connect(m_tcpSocket.data(),
+            &QTcpSocket::readyRead,
+            this,
+            &DesignStudioConnector::receiveProject);
+}
+
 void DesignStudioConnector::updateIpv4Addr()
 {
     const QList<QHostAddress> list = QNetworkInterface::allAddresses();
diff --git a/src/backend/dsconnector.h b/src/backend/dsconnector.h
index 66e1ec5cf81be42c11752f6b8a211fa96b536e61..1068224b5932a7c93d6f0c949fb25c5f651a9141 100644
--- a/src/backend/dsconnector.h
+++ b/src/backend/dsconnector.h
@@ -36,7 +36,7 @@ class DesignStudioConnector : public QObject
 {
     Q_OBJECT
 public:
-    explicit DesignStudioConnector(QObject *parent = nullptr);
+    explicit DesignStudioConnector(const quint16 port = 40000, QObject *parent = nullptr);
 
 public slots:
     void sendProjectReceived();
@@ -45,7 +45,7 @@ private:
     // Tcp connection members
     QTcpServer m_tcpServer;
     QScopedPointer<QTcpSocket> m_tcpSocket;
-    const quint32 m_tcpPort = 40000;
+    const quint32 m_tcpPort;
 
     // Udp connection members
     QTimer m_ipUpdateTimer;
@@ -59,6 +59,7 @@ private:
     void initTcpServer();
     void receiveProject();
     void updateIpv4Addr();
+    void clientConnected();
 
 signals:
     void networkStatusUpdated(QString);
diff --git a/src/backend/projectmanager.cpp b/src/backend/projectmanager.cpp
index 629536f518307fb3192788b46995106aa40f12bf..ed795814da3dada736e4bd375b0f88cfadaa240d 100644
--- a/src/backend/projectmanager.cpp
+++ b/src/backend/projectmanager.cpp
@@ -534,9 +534,9 @@ void ProjectManager::orientateWindow(Qt::ScreenOrientation orientation)
     QQuickItem *childItem{contentItem->childItems().at(0)};
 
     const QRect screenGeometry = QGuiApplication::primaryScreen()->geometry();
-    const QString orientationString = (orientation == Qt::LandscapeOrientation ? "landscape"
-                                                                               : "portrait");
-    qDebug() << "Adapting orientation to " << orientationString << " mode"
+    const QString orientationString = (orientation == Qt::PortraitOrientation ? "portrait"
+                                                                              : "landscape");
+    qDebug() << "Adapting orientation to" << orientationString << "mode. enum_val:" << orientation
              << ". Initial sizing:" << Qt::endl
              << "-- Screen size: " << screenGeometry.height() << " x " << screenGeometry.width()
              << Qt::endl
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index e13567c9280fd89be3dbddbd818a2feb390fca58..e290b1706a39bf5ddd04c4bec43ffece7df45ecb 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -1,6 +1,6 @@
 set(TARGET_NAME ${PROJECT_NAME}_test)
 
-find_package(Qt6 REQUIRED COMPONENTS Test Core Quick Gui)
+find_package(Qt6 REQUIRED COMPONENTS Test Core Quick Gui Multimedia)
 
 enable_testing(true)
 qt_add_executable(${TARGET_NAME}
@@ -12,7 +12,7 @@ add_test(NAME ${TARGET_NAME} COMMAND qtuiviewer_test)
 target_link_libraries(
     ${TARGET_NAME}
     PRIVATE
-    Qt::Test Qt::Core Qt::Quick Qt::Gui
+    Qt::Test Qt::Core Qt::Quick Qt::Gui Qt::Multimedia
     qtuiviewerlib
 )
 
diff --git a/tests/scripts/run_test.sh b/tests/scripts/run_test.sh
index fd542e5bfc4d1a55db63c6efd8bdddca51f7e845..6015ffa87add2b82a7626001d5f3cf22df9f0171 100755
--- a/tests/scripts/run_test.sh
+++ b/tests/scripts/run_test.sh
@@ -3,7 +3,7 @@
 # Precondition: The device/emulator is connected/running and the test application is installed on it.
 
 adb shell "run-as io.qt.qtuiviewer.test rm -rf /data/data/io.qt.qtuiviewer.test/files/output.junitxml"
-adb shell am start -e applicationArguments "'-o output.junitxml,junitxml'" -n io.qt.qtuiviewer.test/org.qtproject.qt.android.bindings.QtActivity
+adb shell am start -e applicationArguments "'-o output.junitxml,junitxml -v2'" -n io.qt.qtuiviewer.test/org.qtproject.qt.android.bindings.QtActivity
 
 counter=0
 while [ -z "$(adb shell pidof -s io.qt.qtuiviewer.test)" ]; do
@@ -21,10 +21,10 @@ echo "PID of test: ${PID_OF_TEST}"
 
 counter=0
 while [ -n "$(adb shell pidof -s io.qt.qtuiviewer.test)" ]; do
-    echo "Waiting for test to finish"
-    sleep 0.1
+    echo "Waiting for test to finish. Elapsed time: $counter seconds"
+    sleep 1
     counter=$((counter + 1))
-    if [ $counter -gt 60 ]; then
+    if [ $counter -gt 300 ]; then
         echo "Test did not finish in time"
         exit 1
     fi
diff --git a/tests/tst_qtuiviewer.cpp b/tests/tst_qtuiviewer.cpp
index e0c111e0f7a10a5a4fd43661685c0c997df44d25..08499d8c8876a997c4b77181a206e2578280efac 100644
--- a/tests/tst_qtuiviewer.cpp
+++ b/tests/tst_qtuiviewer.cpp
@@ -170,7 +170,7 @@ void TestQtUiViewer::clearNonExistentUserProjectCache()
 
 void TestQtUiViewer::initDsConnector()
 {
-    DesignStudioConnector dsc;
+    DesignStudioConnector dsc(40000);
 
     QTcpSocket socket;
     socket.connectToHost("localhost", 40000);
@@ -178,47 +178,95 @@ void TestQtUiViewer::initDsConnector()
     QVERIFY(socket.waitForConnected(1000));
 }
 
-// void TestQtUiViewer::incomingProjectTrue()
-// {
-//     DesignStudioConnector dsc;
+void TestQtUiViewer::incomingProjectTrue()
+{
+    DesignStudioConnector dsc(40001);
+
+    QTcpSocket socket;
+    socket.connectToHost("localhost", 40001);
+
+    QVERIFY(socket.waitForConnected(1000));
+
+    // we'll write a sample project over the tcp connection
+    // and expect the DesignStudioConnector to emit the projectIncoming signal
+    QSignalSpy spy(&dsc, &DesignStudioConnector::projectIncoming);
+    QVERIFY(spy.isValid());
+
+    QByteArray projectData = "qres::qmlrc-start::";
+    socket.write(projectData);
+    QVERIFY(socket.waitForBytesWritten(1000));
+
+    QTRY_COMPARE(spy.count(), 1);
+}
 
-//     QTcpSocket socket;
-//     socket.connectToHost("localhost", 40000);
+void TestQtUiViewer::incomingProjectFalse()
+{
+    DesignStudioConnector dsc(40002);
 
-//     QVERIFY(socket.waitForConnected(1000));
+    QTcpSocket socket;
+    socket.connectToHost("localhost", 40002);
 
-//     // we'll write a sample project over the tcp connection
-//     // and expect the DesignStudioConnector to emit the projectIncoming signal
-//     QSignalSpy spy(&dsc, &DesignStudioConnector::projectIncoming);
-//     QVERIFY(spy.isValid());
+    QVERIFY(socket.waitForConnected(1000));
 
-//     QByteArray projectData = "qres::qmlrc-start::\n"
-//                              "qmlrc-end::";
-//     socket.write(projectData);
-//     QVERIFY(socket.waitForBytesWritten(1000));
-//     QThread::msleep(100);
-//     QCOMPARE(spy.count(), 1);
-// }
+    // we'll write a arbitrary data over the tcp connection
+    // and don't expect the DesignStudioConnector to emit the projectIncoming signal
+    QSignalSpy spy(&dsc, SIGNAL(projectIncoming()));
 
-// void TestQtUiViewer::incomingProjectFalse()
-// {
-//     DesignStudioConnector dsc;
+    QByteArray projectData = "some arbitrary data";
+    socket.write(projectData);
+    QVERIFY(socket.waitForBytesWritten(1000));
 
-//     QTcpSocket socket;
-//     socket.connectToHost("localhost", 40000);
+    QTRY_COMPARE(spy.count(), 0);
+}
 
-//     QVERIFY(socket.waitForConnected(1000));
+void TestQtUiViewer::receiveProject()
+{
+    DesignStudioConnector dsc(40003);
 
-//     // we'll write a sample project over the tcp connection
-//     // and expect the DesignStudioConnector to emit the projectIncoming signal
-//     QSignalSpy spy(&dsc, SIGNAL(projectIncoming()));
+    QTcpSocket socket;
+    socket.connectToHost("localhost", 40003);
 
-//     QByteArray projectData = "some arbitrary data";
-//     socket.write(projectData);
+    QVERIFY(socket.waitForConnected(1000));
 
-//     QVERIFY(socket.waitForBytesWritten(1000));
+    // we'll write a sample project over the tcp connection
+    // and expect the DesignStudioConnector to emit the projectReceived signal
+    QSignalSpy spy(&dsc, &DesignStudioConnector::projectReceived);
+    QVERIFY(spy.isValid());
 
-//     QCOMPARE(spy.count(), 0);
-// }
+    QByteArray projectData = "qres::qmlrc-start::";
+    socket.write(projectData);
+    QVERIFY(socket.waitForBytesWritten(1000));
+
+    spy.wait(1000);
+
+    projectData = "Hello World::qmlrc-end::";
+    socket.write(projectData);
+    QVERIFY(socket.waitForBytesWritten(1000));
+
+    QTRY_COMPARE(spy.count(), 1);
+}
+
+void TestQtUiViewer::networkStatusUpdated()
+{
+    DesignStudioConnector dsc(40004);
+
+    QTcpSocket socket;
+
+    QSignalSpy spy(&dsc, &DesignStudioConnector::networkStatusUpdated);
+    QVERIFY(spy.isValid());
+
+    socket.connectToHost("localhost", 40004);
+    QVERIFY(socket.waitForConnected(1000));
+
+    spy.wait(500);
+    QTRY_COMPARE(spy.count(), 1);
+
+    socket.disconnectFromHost();
+    socket.waitForDisconnected(1000);
+    QVERIFY(socket.state() == QAbstractSocket::UnconnectedState);
+
+    spy.wait(500);
+    QTRY_COMPARE(spy.count(), 2);
+}
 
 QTEST_MAIN(TestQtUiViewer);
diff --git a/tests/tst_qtuiviewer.h b/tests/tst_qtuiviewer.h
index a1dee3f0b420a9b608d8c5c614fe0853f29612f7..c158d378053baccfec8b52b34bb965ce015414a2 100644
--- a/tests/tst_qtuiviewer.h
+++ b/tests/tst_qtuiviewer.h
@@ -60,6 +60,8 @@ private slots:
 
     // ds connector tests
     void initDsConnector();
-    // void incomingProjectTrue();
-    // void incomingProjectFalse();
+    void incomingProjectTrue();
+    void incomingProjectFalse();
+    void receiveProject();
+    void networkStatusUpdated();
 };