diff options
Diffstat (limited to 'tests/manual/x11vkbtest')
25 files changed, 2655 insertions, 0 deletions
diff --git a/tests/manual/x11vkbtest/colors.h b/tests/manual/x11vkbtest/colors.h new file mode 100644 index 00000000..ad1d5a0e --- /dev/null +++ b/tests/manual/x11vkbtest/colors.h @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef COLORS_H +#define COLORS_H + +namespace { +#define RST "\x1B[0m" +#define KRed "\x1B[31m" +#define KGreen "\x1B[32m" + +#define FRed(x) KRed x RST +#define FGreen(x) KGreen x RST +#define FBold(x) "\x1B[1m" x RST +}; + +#endif // COLORS_H diff --git a/tests/manual/x11vkbtest/filehelper.cpp b/tests/manual/x11vkbtest/filehelper.cpp new file mode 100644 index 00000000..f3a379af --- /dev/null +++ b/tests/manual/x11vkbtest/filehelper.cpp @@ -0,0 +1,94 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QFile> +#include <QTextStream> +#include <QLoggingCategory> +#include <QJsonDocument> +#include <QJsonObject> +#include <fstream> + +#include "filehelper.h" + +Q_LOGGING_CATEGORY(lcFileHelper, "qt.virtualkeyboard.tests.manual.x11vkbtest.filehelper") + +bool FileHelper::fileExists(const QString &fileName) +{ + std::ifstream stream(fileName.toLatin1()); + return stream.good(); +} + + +QString FileHelper::getFileContext(const QString &fileName) +{ + QString result = ""; + QFile file(fileName); + + if (!(!file.open(QFile::ReadOnly | QFile::Text))) { + QTextStream in(&file); + result = in.readAll(); + file.close(); + } + + return result; +} + +bool FileHelper::getJsonFromFile(const QString &fileName, std::map<QString, QVariant> &jsonMap) +{ + bool result = true; + + if (!fileExists(fileName)) { + qCDebug(lcFileHelper) << "File:" << fileName << "doesn't exist"; + result = false; + } else { + QString jsonString = FileHelper::getFileContext(fileName); + QByteArray jsonBytes = jsonString.toLocal8Bit(); + + auto jsonDoc = QJsonDocument::fromJson(jsonBytes); + + if (jsonDoc.isNull()) { + qCDebug(lcFileHelper) << "jsonDoc is Null"; + result = false; + } else if (!jsonDoc.isObject()) { + qCDebug(lcFileHelper) << "jsonDoc is NOT an object"; + result = false; + } else { + QJsonObject jsonObj = jsonDoc.object(); + + if (jsonObj.isEmpty()) { + qCDebug(lcFileHelper) << "jsonObj is Empty"; + result = false; + } else { + auto jsonIter = jsonObj.constBegin(); + jsonMap.insert({jsonIter.key(), jsonIter.value()}); + } + } + } + return result; +} diff --git a/tests/manual/x11vkbtest/filehelper.h b/tests/manual/x11vkbtest/filehelper.h new file mode 100644 index 00000000..cc65351c --- /dev/null +++ b/tests/manual/x11vkbtest/filehelper.h @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef FILEHELPER_H +#define FILEHELPER_H + +#include <map> + +class QString; +class QVariant; + +class FileHelper +{ +public: + static bool fileExists(const QString &fileName); + static QString getFileContext(const QString &fileName); + static bool getJsonFromFile(const QString &fileName, std::map<QString, QVariant> &jsonMap); +}; + +#endif // FILEHELPER_H diff --git a/tests/manual/x11vkbtest/main.cpp b/tests/manual/x11vkbtest/main.cpp new file mode 100644 index 00000000..f248bd53 --- /dev/null +++ b/tests/manual/x11vkbtest/main.cpp @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QApplication> +#include <QDebug> +#include <QCommandLineParser> +#include <QStateMachine> +#include <QtGui/QGuiApplication> +#include <QtCharts/QChartView> +#include <QtWidgets/QMainWindow> + +#include "processhandler.h" +#include "windowhelper.h" +#include "testenglishletters.h" +#include "startclose.h" +#include "memorymonitor.h" +#include "testlanguagechange.h" +#include "testthread.h" +#include "testreporter.h" + +int main(int argc, char *argv[]) +{ + QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling); + QApplication app(argc, argv); + + QCommandLineParser parser; + parser.setApplicationDescription("X11VKB Testing application"); + parser.addHelpOption(); + + parser.addOption({"exec", "Give absolute path to target <executable>. See README.md for usage instructions.", "directory"}); + + parser.addOption({"sc", "Give a number of how many times a start&close cycle is to be executed.", "number"}); + + parser.addOption({"ko", "Give a number of how many times a key operation test is to be executed.", "number"}); + + parser.addOption({"lc", "Give a number of how many times a language change test is to be executed.", "number"}); + + parser.process(app); + + QString x11vkbPath = parser.value("exec"); + if (x11vkbPath.isEmpty()) { + qWarning() << "Give absolute path to target executable, including the filename"; + qWarning() << "Example: --exec <path_to_executable>."; + qWarning() << "See README.md for detailed usage instructions."; + return 1; + } + + quint32 startCloseTest = static_cast<quint16>(parser.value("sc").toInt()); + quint32 keyOperationTest = static_cast<quint16>(parser.value("ko").toInt()); + quint32 langChangeTest = static_cast<quint16>(parser.value("lc").toInt()); + + QMainWindow window; + window.setWindowFlags(Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint); + auto memoryMonitor = new MemoryMonitor(window); + + memoryMonitor->legend()->hide(); + QChartView chartView(memoryMonitor); + chartView.setRenderHint(QPainter::Antialiasing); + + window.setCentralWidget(&chartView); + window.resize(900, 600); + window.show(); + memoryMonitor->init(); + + TestReporter reporter; + reporter.startMemoryReport(); + QObject::connect(memoryMonitor, &MemoryMonitor::memUsage, &reporter, &TestReporter::currentMemUsage); + + auto testThread = new TestThread(x11vkbPath, startCloseTest, keyOperationTest, langChangeTest, &app); + QObject::connect(testThread, &TestThread::startMemoryMonitor, memoryMonitor, &MemoryMonitor::start); + QObject::connect(testThread, &TestThread::processID, memoryMonitor, &MemoryMonitor::setProcID); + QObject::connect(testThread, &TestThread::finished, testThread, &QObject::deleteLater); + QObject::connect(testThread, &TestThread::finished, memoryMonitor, &MemoryMonitor::stopChart); + QObject::connect(memoryMonitor, &MemoryMonitor::minAndPeakReport, &reporter, &TestReporter::printMemoryResultToCSV); + QObject::connect(testThread, &TestThread::finished, &app, &QApplication::quit); + testThread->start(); + + return app.exec(); +} diff --git a/tests/manual/x11vkbtest/memorymonitor.cpp b/tests/manual/x11vkbtest/memorymonitor.cpp new file mode 100644 index 00000000..db1b53b9 --- /dev/null +++ b/tests/manual/x11vkbtest/memorymonitor.cpp @@ -0,0 +1,226 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "memorymonitor.h" + +#include <QtCharts/QAbstractAxis> +#include <QtCharts/QSplineSeries> +#include <QtCharts/QValueAxis> +#include <QtCore/QRandomGenerator> +#include <QLoggingCategory> + +#include <QMainWindow> +#include <QWindow> +#include <QScreen> +#include <QDir> + +#include <QTime> + +extern "C" { +#include <unistd.h> +#include <sys/resource.h> +} +#include <cstdio> + +namespace { +const QString KChartFileName = "MemoryUsageChart"; +const quint8 KYPosition = 15; +const quint8 KReadingMargin = 80; +const quint16 KToKilo = 1024; +} + +Q_LOGGING_CATEGORY(lcMemoryMonitor, "qt.virtualkeyboard.tests.manual.x11vkbtest.memorymonitor") + +MemoryMonitor::MemoryMonitor(QMainWindow &window, QGraphicsItem *parent, Qt::WindowFlags wFlags) : + QChart(QChart::ChartTypeCartesian, parent, wFlags), + m_series(nullptr), + m_axisX(new QValueAxis()), + m_axisY(new QValueAxis()), + m_x(0), + m_y(0), + m_peakMemory(0), + m_minMemory(0), + m_procID(0), + m_MainWindow(window), + m_screen(nullptr), + m_drawInterval(new QTimer()), + m_elapsedTime(0), + m_minMemReading(nullptr), + m_curMemReading(nullptr), + m_peakMemReading(nullptr), + m_elapsedTimeReading(nullptr) +{ + m_series = new QSplineSeries(this); + QPen red(Qt::red); + red.setWidth(3); + m_series->setPen(red); + + this->addSeries(m_series); + + this->addAxis(m_axisX,Qt::AlignBottom); + m_axisX->setTitleText("Time"); + this->addAxis(m_axisY,Qt::AlignLeft); + m_axisY->setTitleText("Memory KB"); + m_series->attachAxis(m_axisX); + m_series->attachAxis(m_axisY); + m_axisX->setTickCount(15); + m_axisX->setLabelFormat("%.1u"); + m_axisY->setTickCount(15); + m_axisY->setLabelFormat("%.1u"); + m_axisX->setRange(0, 500); + m_axisY->setRange(0, 100 * KToKilo); +} + +void MemoryMonitor::init() +{ + QWindow *win = m_MainWindow.windowHandle(); + m_screen = win->screen(); + + m_minMemReading = new QGraphicsSimpleTextItem(this); + m_minMemReading->setPen(QPen(QBrush("black"), 1)); + m_minMemReading->setText("Min mem ----- KB"); + m_minMemReading->setPos(KReadingMargin, KYPosition); + + m_curMemReading = new QGraphicsSimpleTextItem(this); + m_curMemReading->setPen(QPen(QBrush("black"), 1)); + m_curMemReading->setText("Current mem ----- KB"); + m_curMemReading->setPos((this->size().width() / 2) - KReadingMargin, KYPosition); + + m_peakMemReading = new QGraphicsSimpleTextItem(this); + m_peakMemReading->setPen(QPen(QBrush("black"), 1)); + m_peakMemReading->setText("Peak mem ----- KB"); + m_peakMemReading->setPos(this->size().width() - (KReadingMargin * 2), KYPosition); + + m_elapsedTimeReading = new QGraphicsSimpleTextItem(this); + m_elapsedTimeReading->setPen(QPen(QBrush("black"), 1)); + m_elapsedTimeReading->setText("-- s"); + m_elapsedTimeReading->setPos((this->size().width() / 2) + KReadingMargin, this->size().height() - KYPosition * 3); + + QObject::connect(this, &QChart::geometryChanged, [this]() { + m_minMemReading->setPos(KReadingMargin, KYPosition); + m_curMemReading->setPos((this->size().width() / 2) - KReadingMargin, KYPosition); + m_peakMemReading->setPos(this->size().width() - (KReadingMargin * 2), KYPosition); + m_elapsedTimeReading->setPos((this->size().width() / 2) + KReadingMargin, this->size().height() - KYPosition * 3); + }); +} + +void MemoryMonitor::setProcID(const qint64 procID) +{ + m_procID = procID; +} + +void MemoryMonitor::start() +{ + QObject::connect(m_drawInterval, &QTimer::timeout, [&]() { + ulong memUsed = currentMemUsage(); + this->drawMemUsage(memUsed); + this->storeMemValues(memUsed); + }); + m_drawInterval->setInterval(1000); + m_drawInterval->start(); +} + +/** + * @brief currentMemUsage + * @param procID + * @return current memory by procID in kB + * Getting memory usage of a given process using + * Linux proc filesystem. + */ +ulong MemoryMonitor::currentMemUsage() +{ + ulong memSize = 0UL; + QString str = QString("/proc/" + QString::number(m_procID) + "/statm"); + QFile procFile(str); + + if (procFile.open(QIODevice::ReadOnly)) { + QTextStream procStream(&procFile); + ulong mem = procStream.readLine().split(" ").at(1).toULong(); + memSize = mem * static_cast<ulong>(sysconf(_SC_PAGESIZE)); + procFile.close(); + } + auto result = memSize / KToKilo; + qCDebug(lcMemoryMonitor).noquote() << QTime::currentTime().toString() << "memory usage:" << result; + + emit memUsage(m_elapsedTime, result); + + return result; +} + +MemoryMonitor::~MemoryMonitor() +{ + qCDebug(lcMemoryMonitor) << "Destroying MemoryChart"; +} + +void MemoryMonitor::saveChart() +{ + QPixmap pix = m_screen->grabWindow(m_MainWindow.winId()); + + const QString format = "png"; + QString path = QDir::currentPath(); + path += "/" + KChartFileName + "." + format; + pix.save(path); +} + +void MemoryMonitor::stopChart() +{ + this->saveChart(); + m_drawInterval->stop(); + + emit minAndPeakReport(QString("Min process memory: %1 KB\nPeak process memory: %2 KB") + .arg(QString::number(m_minMemory)) + .arg(QString::number(m_peakMemory))); +} + +void MemoryMonitor::storeMemValues(const ulong memValue) +{ + if ((m_minMemory == 0 || m_minMemory > memValue)) { + m_minMemory = memValue; + } + if (m_peakMemory < memValue) { + m_peakMemory = memValue; + } + m_minMemReading->setText(QString("Min mem %1 KB").arg(QString::number(m_minMemory))); + m_curMemReading->setText(QString("Current mem %1 KB").arg(QString::number(memValue))); + m_peakMemReading->setText(QString("Peak mem %1 KB").arg(QString::number(m_peakMemory))); + m_elapsedTimeReading->setText(QString("%1 s").arg(m_elapsedTime += 1)); +} + +void MemoryMonitor::drawMemUsage(const ulong memUsed) +{ + m_x += 1; + m_y = memUsed; + if (m_y >= m_axisY->max()) { + m_axisY->setRange(0, (m_axisY->max() * 2)); + } + if (m_x >= m_axisX->max()) { + m_axisX->setRange(0, (m_axisX->max() * 2)); + } + m_series->append(m_x, m_y); +} diff --git a/tests/manual/x11vkbtest/memorymonitor.h b/tests/manual/x11vkbtest/memorymonitor.h new file mode 100644 index 00000000..01239383 --- /dev/null +++ b/tests/manual/x11vkbtest/memorymonitor.h @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MEMORYMONITOR_H +#define MEMORYMONITOR_H + +#include <QtCharts/QChart> +#include <QtCore/QTimer> + +QT_CHARTS_BEGIN_NAMESPACE +class QSplineSeries; +class QValueAxis; +QT_CHARTS_END_NAMESPACE + +QT_CHARTS_USE_NAMESPACE + +class QMainWindow; + +class MemoryMonitor : public QChart +{ + Q_OBJECT +public: + explicit MemoryMonitor(QMainWindow &window, QGraphicsItem *parent = nullptr, Qt::WindowFlags wFlags = nullptr); + ~MemoryMonitor(); + +public: + void init(); + void start(); + void drawMemUsage(const ulong memUsed); + void setProcID(const qint64 procID); + +signals: + void memUsage(const quint64 timeElapsed, const ulong memSize); + void minAndPeakReport(const QString minPeakMemoryReport); + +public slots: + void saveChart(); + void stopChart(); + +private: + ulong currentMemUsage(); + void storeMemValues(const ulong memValue); + +private: + QSplineSeries *m_series; + QStringList m_titles; + QValueAxis *m_axisX; + QValueAxis *m_axisY; + ulong m_x; + ulong m_y; + ulong m_peakMemory; + ulong m_minMemory; + qint64 m_procID; + QMainWindow &m_MainWindow; + QScreen *m_screen; + QTimer *m_drawInterval; + quint64 m_elapsedTime; + QGraphicsSimpleTextItem *m_minMemReading; + QGraphicsSimpleTextItem *m_curMemReading; + QGraphicsSimpleTextItem *m_peakMemReading; + QGraphicsSimpleTextItem *m_elapsedTimeReading; +}; + +#endif // MEMORYMONITOR_H diff --git a/tests/manual/x11vkbtest/mousesimulator.cpp b/tests/manual/x11vkbtest/mousesimulator.cpp new file mode 100644 index 00000000..f49a91ef --- /dev/null +++ b/tests/manual/x11vkbtest/mousesimulator.cpp @@ -0,0 +1,367 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QTextStream> + +#include "mousesimulator.h" + +extern "C" { +#include <xdo.h> +#include <X11/X.h> +#include <X11/extensions/XTest.h> +#include <X11/keysym.h> +#include <X11/XF86keysym.h> +} +#include <unistd.h> + +namespace { +const quint16 KTime_Wait_After_Click = 50000; +const quint16 KMultiply_Time_Wait_For_Shift_Key = 12; +const quint16 KWidth_Parts = 24; +const quint16 KHeight_Parts = 11; +const quint16 KTotal_Lang_Rows = 5; +} + +MouseSimulator::MouseSimulator(QObject *parent, Window x11vkbWinId, quint16 x11vkbWidth, quint16 x11vkbHeight) : + QObject(parent), + m_xdo(xdo_new(nullptr)), + m_x11vkbWinId(x11vkbWinId), + m_x11vkbWidth(x11vkbWidth), + m_x11vkbHeight(x11vkbHeight) +{ +} + +/** + * @brief MouseSimulator::~MouseSimulator + */ +MouseSimulator::~MouseSimulator() +{ + xdo_free(m_xdo); +} + +void MouseSimulator::mouseLeftClickOnVkb(QPair<quint16, quint16> coordinates) const +{ + xdo_move_mouse_relative_to_window(m_xdo, m_x11vkbWinId, 0, 0); + Display *dpy = m_xdo->xdpy; + XEvent event; + + XQueryPointer(dpy, RootWindow(dpy,0), &event.xbutton.root, + &event.xbutton.window, &event.xbutton.x_root, + &event.xbutton.y_root, &event.xbutton.x, &event.xbutton.y, + &event.xbutton.state); + + XTestFakeMotionEvent (dpy, 0, event.xbutton.x + coordinates.first, + event.xbutton.y + coordinates.second, CurrentTime); + XSync(dpy, 0); + + XTestFakeButtonEvent(dpy, Button1, True, CurrentTime); + XTestFakeButtonEvent(dpy, Button1, False, CurrentTime); + XFlush(dpy); + usleep(KTime_Wait_After_Click); +} + +void MouseSimulator::setWidthHeight(QPair<quint16, quint16> pairWidthHeight) +{ + m_x11vkbWidth = pairWidthHeight.first; + m_x11vkbHeight = pairWidthHeight.first; +} + +void MouseSimulator::clickCtrlPlusSToSave(const Window winId) const +{ + xdo_move_mouse_relative_to_window(m_xdo, winId, 5, 5); + Display *dpy = m_xdo->xdpy; + XTestFakeKeyEvent(dpy, XKeysymToKeycode( dpy, XK_Control_L ), true, CurrentTime); + XTestFakeKeyEvent(dpy, XKeysymToKeycode( dpy, XK_S ), true, CurrentTime); + XTestFakeKeyEvent(dpy, XKeysymToKeycode( dpy, XK_S ), false, CurrentTime); + XTestFakeKeyEvent(dpy, XKeysymToKeycode( dpy, XK_Control_L ), false, CurrentTime); + XFlush(dpy); +} + +void MouseSimulator::clickLangKey(const quint16 layoutEnglish) const +{ + if (layoutEnglish == 2) { + mouseLeftClickOnVkb(getPositionOfNotEngLayout(4,2)); + } else { + mouseLeftClickOnVkb(getPosition(4,2)); + } +} + +void MouseSimulator::clickLangLine(const LanguageLines langLine) const +{ + quint16 width = m_x11vkbWidth/KTotal_Lang_Rows; + quint16 height = m_x11vkbHeight/KHeight_Parts; + switch (langLine) { + case LanguageLines::FirstLine: + height = height*4; + break; + case LanguageLines::SecondLine: + height = height*5; + break; + case LanguageLines::ThirdLine: + height = height*6; + break; + case LanguageLines::FourthLine: + height = height*7; + break; + case LanguageLines::FifthLine: + height = height*8; + break; + } + mouseLeftClickOnVkb({width, height}); +} + +void MouseSimulator::clickHideKeyboard() const +{ + mouseLeftClickOnVkb(getPosition(4,6)); +} + +QPair<quint16, quint16> MouseSimulator::getPosition(const quint16 rowNum, const quint16 keyNum) const +{ + QPair<quint16, quint16> coordinates(0,0); + + if (0 < rowNum && rowNum <= 4) { + coordinates.second = this->vkbPositionOfRow(rowNum); + switch (rowNum) + { + case 1: + case 3: + if (0 < keyNum && keyNum <= 11) { + coordinates.first = m_x11vkbWidth/KWidth_Parts*(keyNum*2); + } + break; + case 2: + if (0 < keyNum && keyNum <= 10) { + coordinates.first = m_x11vkbWidth/KWidth_Parts*(keyNum*2+1); + } + break; + case 4: + switch (keyNum) { + case 1: + coordinates.first = m_x11vkbWidth/KWidth_Parts*(keyNum*2); + break; + case 2: + coordinates.first = m_x11vkbWidth/KWidth_Parts*5; + break; + case 3: + coordinates.first = m_x11vkbWidth/2; + break; + case 4: + coordinates.first = m_x11vkbWidth/KWidth_Parts*18; + break; + case 5: + coordinates.first = m_x11vkbWidth/KWidth_Parts*20; + break; + case 6: + coordinates.first = m_x11vkbWidth/KWidth_Parts*(KWidth_Parts-2); + break; + default: + break; + } + break; + default: + break; + } + } + return coordinates; +} + +QPair<quint16, quint16> MouseSimulator::getPositionOfNotEngLayout(const quint16 rowNum, const quint16 keyNum) const +{ + QPair<quint16, quint16> coordinates(0, vkbPositionOfRow(rowNum)); + if (rowNum == 4 && keyNum == 2) { + coordinates.first = m_x11vkbWidth/KWidth_Parts*4; + } + return coordinates; +} + +void MouseSimulator::clickLetter(const QChar &letter) const +{ + switch (letter.toLower().unicode()) + { + case 'a': + mouseLeftClickOnVkb(this->getPosition(2,1)); + break; + case 'b': + mouseLeftClickOnVkb(this->getPosition(3,6)); + break; + case 'c': + mouseLeftClickOnVkb(this->getPosition(3,4)); + break; + case 'd': + mouseLeftClickOnVkb(this->getPosition(2,3)); + break; + case 'e': + mouseLeftClickOnVkb(this->getPosition(1,3)); + break; + case 'f': + mouseLeftClickOnVkb(this->getPosition(2,4)); + break; + case 'g': + mouseLeftClickOnVkb(this->getPosition(2,5)); + break; + case 'h': + mouseLeftClickOnVkb(this->getPosition(2,6)); + break; + case 'i': + mouseLeftClickOnVkb(this->getPosition(1,8)); + break; + case 'j': + mouseLeftClickOnVkb(this->getPosition(2,7)); + break; + case 'k': + mouseLeftClickOnVkb(this->getPosition(2,8)); + break; + case 'l': + mouseLeftClickOnVkb(this->getPosition(2,9)); + break; + case 'm': + mouseLeftClickOnVkb(this->getPosition(3,8)); + break; + case 'n': + mouseLeftClickOnVkb(this->getPosition(3,7)); + break; + case 'o': + mouseLeftClickOnVkb(this->getPosition(1,9)); + break; + case 'p': + mouseLeftClickOnVkb(this->getPosition(1,10)); + break; + case 'q': + mouseLeftClickOnVkb(this->getPosition(1,1)); + break; + case 'r': + mouseLeftClickOnVkb(this->getPosition(1,4)); + break; + case 's': + mouseLeftClickOnVkb(this->getPosition(2,2)); + break; + case 't': + mouseLeftClickOnVkb(this->getPosition(1,5)); + break; + case 'u': + mouseLeftClickOnVkb(this->getPosition(1,7)); + break; + case 'v': + mouseLeftClickOnVkb(this->getPosition(3,5)); + break; + case 'w': + mouseLeftClickOnVkb(this->getPosition(1,2)); + break; + case 'x': + mouseLeftClickOnVkb(this->getPosition(3,3)); + break; + case 'y': + mouseLeftClickOnVkb(this->getPosition(1,6)); + break; + case 'z': + mouseLeftClickOnVkb(this->getPosition(3,2)); + break; + default: + break; + } + +} + +void MouseSimulator::clickEnglishLetter(QChar &letter) const +{ + this->clickExtraKeyIfNeeded(letter); + + if (letter.isLetter()) { + this->clickLetter(letter); + } else if (letter.isNumber()) { + quint16 number = static_cast<quint16>(letter.digitValue()); + mouseLeftClickOnVkb(this->getPosition(1, number == 0 ? 10 : static_cast<quint16>(number) )); + } else { + switch (letter.unicode()) + { + case ' ': + mouseLeftClickOnVkb(this->getPosition(4,3)); + break; + case ',': + mouseLeftClickOnVkb(this->getPosition(3,9)); + break; + case '.': + mouseLeftClickOnVkb(this->getPosition(3,10)); + break; + case '\'': + mouseLeftClickOnVkb(this->getPosition(4,4)); + break; + case '\b': + mouseLeftClickOnVkb(this->getPosition(1,11)); + break; + case QChar::CarriageReturn : + mouseLeftClickOnVkb(this->getPosition(2,10)); + break; + default: + break; + } + } + + this->clickExtraKeyIfNeeded(letter); +} + +void MouseSimulator::clickExtraKeyIfNeeded(QChar &letter) const +{ + bool clickIsNeeded = false; + if (letter.isUpper()) { + mouseLeftClickOnVkb(this->getPosition(3,1)); + clickIsNeeded = true; + } else if (letter.isNumber()) { + mouseLeftClickOnVkb(this->getPosition(4,1)); + clickIsNeeded = true; + } + + if (clickIsNeeded) { + usleep(KTime_Wait_After_Click*KMultiply_Time_Wait_For_Shift_Key); + } +} + +quint16 MouseSimulator::vkbPositionOfRow(const quint16 row) const +{ + quint16 heightSize = m_x11vkbHeight/KHeight_Parts; + switch (row) + { + case 1 : + heightSize = heightSize*3; + break; + case 2 : + heightSize = heightSize*5; + break; + case 3 : + heightSize = heightSize*7; + break; + case 4 : + heightSize = heightSize*9; + break; + default: + heightSize = 0; + break; + } + return heightSize; +} diff --git a/tests/manual/x11vkbtest/mousesimulator.h b/tests/manual/x11vkbtest/mousesimulator.h new file mode 100644 index 00000000..7fdff58c --- /dev/null +++ b/tests/manual/x11vkbtest/mousesimulator.h @@ -0,0 +1,73 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef MOUSESIMULATOR_H +#define MOUSESIMULATOR_H + +#include <QObject> + +extern "C" { +#include <xdo.h> +} + +class MouseSimulator : public QObject +{ + Q_OBJECT +public: + explicit MouseSimulator(QObject *parent, Window x11vkbWinId, quint16 x11vkbWidth, quint16 x11vkbHeight); + ~MouseSimulator() override; + +public: + enum LanguageLines {FirstLine, SecondLine, ThirdLine, FourthLine, FifthLine}; + void clickEnglishLetter(QChar &letter) const; + void clickExtraKeyIfNeeded(QChar &letter) const; + void clickCtrlPlusSToSave(const Window winId) const; + void clickLangKey(const quint16 layoutEnglish = 1) const; + void clickLangLine(const LanguageLines langLine) const; + void clickHideKeyboard() const; + void mouseLeftClickOnVkb(QPair<quint16, quint16> coordinates) const; + void setWidthHeight(QPair<quint16, quint16> pairWidthHeight); + QPair<quint16, quint16> getPosition(const quint16 rowNum, const quint16 keyNum) const; + QPair<quint16, quint16> getPositionOfNotEngLayout(const quint16 rowNum, const quint16 keyNum) const; + +private: + quint16 vkbPositionOfRow(const quint16 row) const; + void clickLetter(const QChar &letter) const; + +private: + /** Libxdo context. */ + xdo_t *m_xdo; + Window m_x11vkbWinId; + quint16 m_x11vkbWidth; + quint16 m_x11vkbHeight; +}; + + +#endif // MOUSESIMULATOR_H + diff --git a/tests/manual/x11vkbtest/processhandler.cpp b/tests/manual/x11vkbtest/processhandler.cpp new file mode 100644 index 00000000..ca9c82c6 --- /dev/null +++ b/tests/manual/x11vkbtest/processhandler.cpp @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QProcess> +#include <QTextStream> + +#include <unistd.h> + +#include "processhandler.h" + +ProcessHandler::ProcessHandler(QObject *parent, const QString &procPath, quint32 msec) : + QObject(parent), + m_process(new QProcess(this)), + m_procPath(procPath), + m_msec(msec) +{ + m_process->setProgram(m_procPath); + QObject::connect(m_process, &QProcess::started, this, &ProcessHandler::procStarted); +} + +ProcessHandler::~ProcessHandler() +{ + this->closeProcess(); +} + +qint64 ProcessHandler::getProcId() const +{ + return m_process->processId(); +} + +void ProcessHandler::closeProcess() +{ + m_process->close(); +} + +void ProcessHandler::procStarted() +{ + if (m_msec > 0) { + usleep(m_msec); + } + emit procReady(); +} + +void ProcessHandler::startProc() +{ + m_process->start(m_procPath); +} + +void ProcessHandler::startDetachedProc() const +{ + m_process->startDetached(m_procPath); +} + +QProcess* ProcessHandler::getPRocess() const { + return m_process; +} diff --git a/tests/manual/x11vkbtest/processhandler.h b/tests/manual/x11vkbtest/processhandler.h new file mode 100644 index 00000000..c1d14983 --- /dev/null +++ b/tests/manual/x11vkbtest/processhandler.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PROCESSHANDLER_H +#define PROCESSHANDLER_H + +#include <QObject> + +class QProcess; + +class ProcessHandler : public QObject +{ + Q_OBJECT +public: + explicit ProcessHandler(QObject *parent, const QString &procPath, quint32 msec = 0); + ~ProcessHandler(); + +public: + void startProc(); + qint64 getProcId() const; + QProcess *getPRocess() const; + void startDetachedProc() const; + +signals: + void procReady(); + +public slots: + void closeProcess(); + +private slots: + void procStarted(); + +private: + QProcess *m_process; + const QString &m_procPath; + quint32 m_msec; +}; + +#endif // PROCESSHANDLER_H diff --git a/tests/manual/x11vkbtest/startclose.cpp b/tests/manual/x11vkbtest/startclose.cpp new file mode 100644 index 00000000..2738dc26 --- /dev/null +++ b/tests/manual/x11vkbtest/startclose.cpp @@ -0,0 +1,121 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QProcess> +#include <QFile> +#include <QTextStream> +#include <QTimer> + +#include "startclose.h" + +namespace { +const QString KTest_Name = "Test start/close %1 times."; +const quint16 KTestCycles = 25; +const int KTestMultiplier = 2; +} + +StartClose::StartClose(QProcess &proc, quint32 numberOfTests, QObject *parent) + : TestBase (parent, KTest_Name, numberOfTests), + m_procToTest(proc), + m_results(QStringList()), + m_testCycleCount(0) +{ + this->setTestRepeats(KTestCycles); + this->setTestName(); + QObject::connect(&m_procToTest, &QProcess::started, this, &StartClose::runCycles); + QObject::connect(&m_procToTest, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), + this, &StartClose::runCycles); +} + +void StartClose::startTest() +{ + m_testTimer.start(); + m_procToTest.start(); +} + +void StartClose::runCycles() +{ + QTimer::singleShot(50, this, [&]() { + if (m_testCycleCount == 0) { + m_results << QString::number(this->currentTotalAvailableMemory()); + } + // The original number of tests will be multiplied by 2 because we always need to + // have even number of test cycles because one cycle consists off ON & OFF. + if (m_testCycleCount == (m_numberOfTests * KTestMultiplier)) { + m_results << QString::number(this->currentTotalAvailableMemory()); + QObject::disconnect(&m_procToTest, &QProcess::started, this, &StartClose::startTest); + QObject::disconnect(&m_procToTest, + static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), + this, &StartClose::startTest); + + m_passed = true; + m_timeElapsed = m_testTimer.elapsed(); + + emit endTest(); + return; + } + m_testCycleCount ++; + + if (m_procToTest.state() == QProcess::Running) { + m_procToTest.kill(); + } else { + m_procToTest.start(); + } + }); +} + +QString StartClose::reportResult() +{ + m_testResult = + QString("Total free system memory at start: %1 KB\nTotal free system memory at end: %2 KB\nDifference: %3 KB") + .arg(m_results.value(0).toInt()).arg(m_results.value(1).toInt()) + .arg(m_results.value(1).toInt() - m_results.value(0).toInt()); + return m_testResult; +} + +/** + * @brief StartClose::currentTotalAvailableMemory + * @return current free system memory by procID in kB + * Getting current free memory using Linux proc + * filesystem. + */ +ulong StartClose::currentTotalAvailableMemory() const +{ + ulong availableMemSize = 0UL; + QString str = QString("/proc/meminfo"); + QFile procFile(str); + + if (procFile.open(QIODevice::ReadOnly)) { + QTextStream procStream(&procFile); + procStream.readLine(); // "Read away" the first row + availableMemSize = procStream.readLine().split(QRegExp("\\s+")).at(1).toULong(); + procFile.close(); + } + return availableMemSize; +} diff --git a/tests/manual/x11vkbtest/startclose.h b/tests/manual/x11vkbtest/startclose.h new file mode 100644 index 00000000..434a95ad --- /dev/null +++ b/tests/manual/x11vkbtest/startclose.h @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef STARTCLOSE_H +#define STARTCLOSE_H + +#include "testbase.h" + +#include <QTime> + +class QProcess; + +class StartClose : public TestBase +{ + Q_OBJECT +public: + explicit StartClose(QProcess &proc, quint32 numberOfTests, QObject *parent = nullptr); + ~StartClose() {} + +public: + ulong currentTotalAvailableMemory() const; + QString reportResult() override; + +public slots: + void startTest() override; + void runCycles(); + +private: + QProcess &m_procToTest; + QStringList m_results; + quint32 m_testCycleCount; +}; + +#endif // STARTCLOSE_H diff --git a/tests/manual/x11vkbtest/testbase.cpp b/tests/manual/x11vkbtest/testbase.cpp new file mode 100644 index 00000000..ef08c8c6 --- /dev/null +++ b/tests/manual/x11vkbtest/testbase.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QTextStream> +#include "testbase.h" + +namespace { +const qint32 KMs_In_Sec = 1000; +} + +TestBase::TestBase(QObject *parent, QString testName, quint32 numberOfTests, qint64 x11vkbProcId): + QObject(parent), + m_x11vkbProcId(x11vkbProcId), + m_testTimer(QElapsedTimer()), + m_timeElapsed(0), + m_testName(testName), + m_numberOfTests(numberOfTests), + m_testResult(QString()), + m_passed(false) + +{} + +QString TestBase::reportResult() +{ + return m_testResult; +} + +void TestBase::setProcID(const qint64 procID) +{ + m_x11vkbProcId = procID; +} + +QString TestBase::testName() const +{ + return m_testName; +} + +void TestBase::setTestName() +{ + m_testName = m_testName.arg(m_numberOfTests); +} +void TestBase::printResult(QTextStream &stream) const +{ + stream << m_testResult; +} + +bool TestBase::passed() const +{ + return m_passed; +} + +qint64 TestBase::timeElapsed() const +{ + return m_timeElapsed/KMs_In_Sec; +} + +bool TestBase::shiftIsDown = false; + +void TestBase::setTestRepeats(const quint32 repeats) +{ + if (m_numberOfTests == 0) { + m_numberOfTests = repeats; + } +} diff --git a/tests/manual/x11vkbtest/testbase.h b/tests/manual/x11vkbtest/testbase.h new file mode 100644 index 00000000..0b5c107b --- /dev/null +++ b/tests/manual/x11vkbtest/testbase.h @@ -0,0 +1,74 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TESTBASE_H +#define TESTBASE_H + +#include <QObject> +#include <QElapsedTimer> + +class QTextStream; + +class TestBase : public QObject +{ + Q_OBJECT + +public: + explicit TestBase(QObject *parent, QString testName, quint32 numberOfTests, qint64 x11vkbProcId = 0); + virtual ~TestBase() {} + +public: + virtual QString reportResult(); + void setProcID(const qint64 procID); + QString testName() const; + void setTestName(); + void printResult(QTextStream &stream) const; + bool passed() const; + qint64 timeElapsed() const; + void setTestRepeats(const quint32 repeats); + +signals: + void endTest(); + +public slots: + virtual void startTest() = 0; + +protected: + static bool shiftIsDown; + qint64 m_x11vkbProcId; + QElapsedTimer m_testTimer; + + qint64 m_timeElapsed; + QString m_testName; + quint32 m_numberOfTests; + QString m_testResult; + bool m_passed; +}; + +#endif // TESTBASE_H diff --git a/tests/manual/x11vkbtest/testenglishletters.cpp b/tests/manual/x11vkbtest/testenglishletters.cpp new file mode 100644 index 00000000..c0f63e53 --- /dev/null +++ b/tests/manual/x11vkbtest/testenglishletters.cpp @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "filehelper.h" +#include "mousesimulator.h" +#include "processhandler.h" +#include "windowhelper.h" +#include "testenglishletters.h" + +namespace { +const QString KTest_Name = "Test %1 key operations."; + +const quint32 KTime_Wait_To_Start_Process = 350000; +const quint32 KTime_Wait_To_Close_Process = 100000; +const QString KTest_File_Name = "test_letters.txt"; +const QString KTest_String = "abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuv\n"; +const quint16 KMax_Key_Operations = 100; +} + +TestEnglishLetters::TestEnglishLetters(QObject *parent, WindowHelper &windowHelper, quint32 numberOfTests, qint64 x11vkbProcId) : + TestBase(parent, KTest_Name, numberOfTests, x11vkbProcId), + m_windowHelper(windowHelper), + m_otherProcHandler(nullptr), + m_letters(QString()) +{ + this->setTestRepeats(KMax_Key_Operations); + this->setTestName(); + this->setTestingString(); +} + +void TestEnglishLetters::startTest() +{ + m_testTimer.start(); + this->deleteTestFile(); + + QString geditProcessName = QString("gedit -s %1").arg(KTest_File_Name); + m_otherProcHandler = new ProcessHandler(this, geditProcessName, KTime_Wait_To_Start_Process); + + QObject::connect(m_otherProcHandler, &ProcessHandler::procReady, this, &TestEnglishLetters::doTestLettersInGedit); + + m_otherProcHandler->startProc(); +} + +void TestEnglishLetters::doTestLettersInGedit() +{ + auto x11vkbWin = m_windowHelper.findWindowByPid(m_x11vkbProcId); + auto otherWinId = m_windowHelper.findWindowByPid(m_otherProcHandler->getProcId()); + + auto bigDimension = m_windowHelper.getWindowDimension(x11vkbWin); + auto mouseSimulator = new MouseSimulator(this, x11vkbWin, bigDimension.first, bigDimension.second); + + QStringList lines = m_letters.split( QRegExp("[\n]") ); + QChar enterChar = QChar::CarriageReturn; + + // first click shiftKey to get it Down + if (!TestBase::shiftIsDown) { + mouseSimulator->mouseLeftClickOnVkb(mouseSimulator->getPosition(3,1)); + TestBase::shiftIsDown = true; + } + + for (auto line : lines) + { + for (auto letter : line) + { + mouseSimulator->clickEnglishLetter(letter); + } + if (line != lines.at(lines.size()-1)) { + mouseSimulator->clickEnglishLetter(enterChar); + } + } + + // close gedit process starts + usleep(KTime_Wait_To_Close_Process); + mouseSimulator->clickCtrlPlusSToSave(otherWinId); + usleep(KTime_Wait_To_Close_Process); + m_otherProcHandler->closeProcess(); + + this->verifyResult(); + this->deleteTestFile(); + + m_timeElapsed = m_testTimer.elapsed(); + + emit endTest(); +} + +void TestEnglishLetters::verifyResult() +{ + auto resultStr = FileHelper::getFileContext(KTest_File_Name); + if (QString::compare(m_letters, resultStr.trimmed() ) == 0) { + m_passed = true; + } else { + m_testResult = + QString("key operation amount expected: %1\nkey operation amount result: : %2") + .arg(m_letters.size()).arg(resultStr.size()); + } +} + +void TestEnglishLetters::deleteTestFile() const +{ + if (FileHelper::fileExists(KTest_File_Name)) { + std::remove(KTest_File_Name.toLatin1()); + } +} + +void TestEnglishLetters::setTestingString() +{ + QString testString = ""; + while (testString.trimmed().size() < static_cast<int>(m_numberOfTests)) { + testString = testString + KTest_String; + } + m_letters = testString.mid(0, static_cast<int>(m_numberOfTests)); +} diff --git a/tests/manual/x11vkbtest/testenglishletters.h b/tests/manual/x11vkbtest/testenglishletters.h new file mode 100644 index 00000000..f39086de --- /dev/null +++ b/tests/manual/x11vkbtest/testenglishletters.h @@ -0,0 +1,65 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TESTENGLISHLETTERS_H +#define TESTENGLISHLETTERS_H + +#include <QObject> +#include "testbase.h" + +class WindowHelper; +class ProcessHandler; + +class TestEnglishLetters : public TestBase +{ + Q_OBJECT +public: + explicit TestEnglishLetters(QObject *parent, WindowHelper &windowHelper, quint32 numberOfTests, qint64 x11vkbProcId = 0); + ~TestEnglishLetters() {} + +public: + void setTestingString(); + +public slots: + void startTest() override; + +private slots: + void doTestLettersInGedit(); + +private: + void verifyResult(); + void deleteTestFile() const; + +private: + WindowHelper &m_windowHelper; + ProcessHandler *m_otherProcHandler; + QString m_letters; +}; + +#endif // TESTENGLISHLETTERS_H diff --git a/tests/manual/x11vkbtest/testlanguagechange.cpp b/tests/manual/x11vkbtest/testlanguagechange.cpp new file mode 100644 index 00000000..082c00a2 --- /dev/null +++ b/tests/manual/x11vkbtest/testlanguagechange.cpp @@ -0,0 +1,267 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QJsonDocument> +#include <QJsonObject> +#include <QLoggingCategory> +#include <QFile> +#include <QVector> +#include <QTextStream> +#include <QDir> +#include <QElapsedTimer> + +#include "mousesimulator.h" +#include "windowhelper.h" +#include "testlanguagechange.h" +#include "filehelper.h" +#include "processhandler.h" + +namespace { +const QString KTest_Name = "Test %1 language change operations."; + +const QString KFile_Path = "/x11vkbwrapper_language/"; +const QString KFile_Path_Name = KFile_Path + "currentLang.json"; +const quint32 KTime_Wait_After_Click = 180000; +const quint32 KTime_Wait_To_Start_Process = 350000; +const quint32 KTestRepeats = 10; + +const QVector< QPair< QString, quint8 > > KLanguage_List = { + QPair< QString, quint8 >("العربية", 1), + QPair< QString, quint8 >("български", 1), + QPair< QString, quint8 >("čeština", 1), + QPair< QString, quint8 >("dansk", 1), + QPair< QString, quint8 >("Deutsch", 1), + QPair< QString, quint8 >("Ελληνικά", 1), + QPair< QString, quint8 >("British English", 1), + QPair< QString, quint8 >("American English", 1), + QPair< QString, quint8 >("español de España", 1), + QPair< QString, quint8 >("español de México", 1), + QPair< QString, quint8 >("eesti", 1), + QPair< QString, quint8 >("فارسی", 1), + QPair< QString, quint8 >("suomi", 1), + QPair< QString, quint8 >("français canadien", 1), + QPair< QString, quint8 >("français", 1), + QPair< QString, quint8 >("עברית", 1), + QPair< QString, quint8 >("हिन्दी", 1), + QPair< QString, quint8 >("hrvatski", 1), + QPair< QString, quint8 >("magyar", 1), + QPair< QString, quint8 >("Indonesia", 1), + QPair< QString, quint8 >("italiano", 1), + QPair< QString, quint8 >("日本語", 2), + QPair< QString, quint8 >("한국어", 1), + QPair< QString, quint8 >("Melayu", 1), + QPair< QString, quint8 >("norsk bokmål", 1), + QPair< QString, quint8 >("Nederlands", 1), + QPair< QString, quint8 >("polski", 1), + QPair< QString, quint8 >("português", 1), + QPair< QString, quint8 >("português europeu", 1), + QPair< QString, quint8 >("română", 1), + QPair< QString, quint8 >("русский", 1), + QPair< QString, quint8 >("slovenčina", 1), + QPair< QString, quint8 >("slovenščina", 1), + QPair< QString, quint8 >("shqip", 1), + QPair< QString, quint8 >("српски", 1), + QPair< QString, quint8 >("svenska", 1), + QPair< QString, quint8 >("ไทย", 1), + QPair< QString, quint8 >("Türkçe", 1), + QPair< QString, quint8 >("українська", 1), + QPair< QString, quint8 >("Tiếng Việt", 1), + QPair< QString, quint8 >("简体中文", 1), + QPair< QString, quint8 >("繁體中文", 1) +}; +} + +Q_LOGGING_CATEGORY(lcTestLanguageChange, "qt.virtualkeyboard.tests.manual.x11vkbtest.testlanguagechange") + +TestLanguageChange::TestLanguageChange(QObject *parent, WindowHelper &windowHelper, quint32 numberOfTests, qint64 x11vkbProcId) : + TestBase(parent, KTest_Name, numberOfTests, x11vkbProcId), + m_windowHelper(windowHelper), + m_otherProcHandler(nullptr), + m_currentLangNum(0) +{ + this->setTestRepeats(KTestRepeats); + this->setTestName(); +} + +void TestLanguageChange::startTest() +{ + m_testTimer.start(); + this->deleteTestFile(); + + QString geditProcessName = QString("gedit -s"); + m_otherProcHandler = new ProcessHandler(this, geditProcessName, KTime_Wait_To_Start_Process); + + QObject::connect(m_otherProcHandler, &ProcessHandler::procReady, this, &TestLanguageChange::doTest); + + m_otherProcHandler->startProc(); +} + +void TestLanguageChange::doTest() +{ + auto x11vkbWin = m_windowHelper.findWindowByPid(m_x11vkbProcId); + + auto currentDimension = m_windowHelper.getWindowDimension(x11vkbWin); + auto mouseSimulator = new MouseSimulator(this, x11vkbWin, currentDimension.first, currentDimension.second); + + // First click shiftKey to get it Down + if (!TestBase::shiftIsDown) { + mouseSimulator->mouseLeftClickOnVkb(mouseSimulator->getPosition(3,1)); + TestBase::shiftIsDown = true; + } + + quint32 count = 0; + quint8 langLayout = 0; + auto currentLangLine = MouseSimulator::LanguageLines::FourthLine; + + // Determine the current language --> + mouseSimulator->clickLangKey(langLayout); + usleep(KTime_Wait_After_Click); + mouseSimulator->clickLangLine(currentLangLine); + usleep(KTime_Wait_After_Click); + + langLayout = this->verifyLanguage(m_currentLangNum, false); + + m_currentLangNum++; + if (m_currentLangNum == KLanguage_List.size()-1) { + currentLangLine = MouseSimulator::LanguageLines::FifthLine; + } + // <-- Determine the current language + + bool indexIncreases = true; + + while (count < m_numberOfTests && langLayout != 0) { + mouseSimulator->clickLangKey(langLayout); + usleep(KTime_Wait_After_Click); + + mouseSimulator->clickLangLine(currentLangLine); + usleep(KTime_Wait_After_Click); + + langLayout = this->verifyLanguage(m_currentLangNum); + + count++; + + switch (currentLangLine) { + + case MouseSimulator::LanguageLines::FirstLine: + indexIncreases = true; + m_currentLangNum++; + currentLangLine = MouseSimulator::LanguageLines::SecondLine; + break; + + case MouseSimulator::LanguageLines::SecondLine: + if (indexIncreases) { + m_currentLangNum++; + currentLangLine = MouseSimulator::LanguageLines::ThirdLine; + } else { + m_currentLangNum--; + if (m_currentLangNum == 0) { + currentLangLine = MouseSimulator::LanguageLines::FirstLine; + } + } + break; + + case MouseSimulator::LanguageLines::ThirdLine: + if (indexIncreases) { + m_currentLangNum++; + currentLangLine = MouseSimulator::LanguageLines::FourthLine; + } else { + m_currentLangNum--; + currentLangLine = MouseSimulator::LanguageLines::SecondLine; + } + break; + + case MouseSimulator::LanguageLines::FourthLine: + if (indexIncreases) { + m_currentLangNum++; + if (m_currentLangNum == KLanguage_List.size()-1) { + currentLangLine = MouseSimulator::LanguageLines::FifthLine; + } + } else { + m_currentLangNum--; + currentLangLine = MouseSimulator::LanguageLines::ThirdLine; + } + break; + + case MouseSimulator::LanguageLines::FifthLine: + indexIncreases = false; + m_currentLangNum--; + currentLangLine = MouseSimulator::LanguageLines::FourthLine; + break; + } + } + + m_otherProcHandler->closeProcess(); + m_timeElapsed = m_testTimer.elapsed(); + + if (count == m_numberOfTests && langLayout != 0) { + m_passed = true; + } else { + m_testResult = + QString("repeats were expected: %1\nrepeats were verified: %2") + .arg(m_numberOfTests).arg(count); + } + + emit endTest(); +} + +quint8 TestLanguageChange::verifyLanguage(const quint16 num, const bool langLineInListIsKnown) +{ + quint8 result = 0; + std::map<QString, QVariant> langMap; + + if (FileHelper::getJsonFromFile(QDir::homePath() + KFile_Path_Name, langMap)) { + auto lang = langMap["language"].toString(); + + if (langLineInListIsKnown) { + qCDebug(lcTestLanguageChange) << "language from json:" << lang; + QString langFromList = KLanguage_List.at(num).first; + qCDebug(lcTestLanguageChange) << "language from list:" << langFromList; + if (lang == langFromList) { + result = KLanguage_List.at(num).second; + } + } else { + for (auto pair : KLanguage_List) { + if (lang == pair.first) { + result = pair.second; + qCDebug(lcTestLanguageChange) << "Starting language set:" << lang << "with language index:" << m_currentLangNum; + break; + } + m_currentLangNum++; + } + } + } + return result; +} + +void TestLanguageChange::deleteTestFile() +{ + if (FileHelper::fileExists(QDir::homePath() + KFile_Path_Name)) { + std::remove(QString(QDir::homePath() + KFile_Path_Name).toLatin1()); + } +} diff --git a/tests/manual/x11vkbtest/testlanguagechange.h b/tests/manual/x11vkbtest/testlanguagechange.h new file mode 100644 index 00000000..f49c9379 --- /dev/null +++ b/tests/manual/x11vkbtest/testlanguagechange.h @@ -0,0 +1,66 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TESTLANGUAGECHANGE_H +#define TESTLANGUAGECHANGE_H + +#include <QObject> +#include "testbase.h" + +class WindowHelper; +class MouseSimulator; +class ProcessHandler; + +class TestLanguageChange : public TestBase +{ + Q_OBJECT +public: + explicit TestLanguageChange(QObject *parent, WindowHelper &windowHelper, quint32 numberOfTests, qint64 x11vkbProcId = 0); + ~TestLanguageChange() {} + +public: + void setProcID(const qint64 procID) {m_x11vkbProcId = procID;} + +public slots: + void startTest() override; + +private slots: + void doTest(); + +private: + quint8 verifyLanguage(const quint16 num, const bool langLineInListIsKnown = true); + void deleteTestFile(); + +private: + WindowHelper &m_windowHelper; + ProcessHandler *m_otherProcHandler; + quint8 m_currentLangNum; +}; + +#endif // TESTLANGUAGECHANGE_H diff --git a/tests/manual/x11vkbtest/testreporter.cpp b/tests/manual/x11vkbtest/testreporter.cpp new file mode 100644 index 00000000..11e24524 --- /dev/null +++ b/tests/manual/x11vkbtest/testreporter.cpp @@ -0,0 +1,159 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QFile> +#include <QTextStream> +#include <QVectorIterator> +#include <QTextStream> +#include "testreporter.h" +#include "testbase.h" +#include "colors.h" +#include "startclose.h" + +namespace { +const QString KReport_CSV_File = "result.csv"; +const QString KCSV_Column_Separator = ";"; +} + +TestReporter::TestReporter(QObject *parent) : QObject(parent) +{ +} + +void TestReporter::startMemoryReport() +{ + QFile file(KReport_CSV_File); + if (file.open(QIODevice::WriteOnly)) { + QTextStream stream(&file); + stream << "Time" << KCSV_Column_Separator; + stream << "Process Memory size" << KCSV_Column_Separator << endl; + file.close(); + } +} + +void TestReporter::printTestResultsToCSV(const QVector<TestBase *> &tests) const +{ + QFile file(KReport_CSV_File); + if (file.open(QIODevice::WriteOnly | QIODevice::Append)) { + QTextStream stream(&file); + + stream << endl; + qint64 timeElapsed = 0; + quint8 passed = 0; + quint8 failed = 0; + bool currentTestIsStartClose = true; + + for (auto test : tests) { + if (nullptr == qobject_cast<StartClose*>(test)) { + currentTestIsStartClose = false; + if (test->passed()) { + stream << "PASS" << KCSV_Column_Separator; + passed++; + } else { + stream << "FAIL" << KCSV_Column_Separator; + failed++; + } + } + stream << test->testName() << KCSV_Column_Separator + << test->timeElapsed() << "s" << endl; + + QString extraInfo = test->reportResult(); + if (!extraInfo.isEmpty()) { + extraInfo.replace(QString(": "), QString(KCSV_Column_Separator)); + stream << extraInfo << endl; + } + timeElapsed = timeElapsed + test->timeElapsed(); + + if (currentTestIsStartClose) { + stream << endl; + } + } + + stream << endl; + stream << "Totals" << KCSV_Column_Separator << passed << " passed " + << KCSV_Column_Separator << failed << " failed" + << KCSV_Column_Separator << timeElapsed << "s"; + stream << endl; + file.close(); + } +} + +void TestReporter::printMemoryResultToCSV(QString minPeakMemoryReport) const +{ + QFile file(KReport_CSV_File); + + if (file.open(QIODevice::WriteOnly | QIODevice::Append)) { + QTextStream stream(&file); + minPeakMemoryReport.replace(QString(": "), QString(KCSV_Column_Separator)); + stream << minPeakMemoryReport << endl; + file.close(); + } +} + +void TestReporter::printTestResultToConsole(const QVector<TestBase *> &tests) const +{ + QTextStream stream(stdout); + + qint64 timeElapsed = 0; + quint8 passed = 0; + quint8 failed = 0; + + for (auto test : tests) { + if (nullptr == qobject_cast<StartClose*>(test)) { + if (test->passed()) { + stream << FBold(FGreen("PASS: ")); + passed++; + } else { + stream << FBold(FRed("FAIL:")); + failed++; + } + } + stream << test->testName() << " " << test->timeElapsed() << "s" << endl; + QString extraInfo = test->reportResult(); + if (!extraInfo.isEmpty()) { + stream << extraInfo << endl; + } + + timeElapsed = timeElapsed + test->timeElapsed(); + } + + stream << "Totals: " << passed << " passed, " << failed << " failed. " << timeElapsed << "s"; + stream << endl; +} + +void TestReporter::currentMemUsage(const quint64 timeElapsed, const ulong memSize) const +{ + QFile file(KReport_CSV_File); + + if (file.open(QIODevice::WriteOnly | QIODevice::Append)) { + QTextStream stream(&file); + stream << timeElapsed << "s" << KCSV_Column_Separator; + stream << memSize << " KB" << KCSV_Column_Separator << endl; + file.close(); + } +} diff --git a/tests/manual/x11vkbtest/testreporter.h b/tests/manual/x11vkbtest/testreporter.h new file mode 100644 index 00000000..2a6d2c5f --- /dev/null +++ b/tests/manual/x11vkbtest/testreporter.h @@ -0,0 +1,53 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef CSVPRINTER_H +#define CSVPRINTER_H + +#include <QObject> + +class TestBase; + +class TestReporter : public QObject +{ + Q_OBJECT +public: + explicit TestReporter(QObject *parent = nullptr); + +public: + void startMemoryReport(); + void printTestResultsToCSV(const QVector<TestBase*> &tests) const; + void printTestResultToConsole(const QVector<TestBase *> &tests) const; + +public slots: + void printMemoryResultToCSV(const QString minPeakMemoryReport) const; + void currentMemUsage(const quint64 timeElapsed, const ulong memSize) const; +}; + +#endif // CSVPRINTER_H diff --git a/tests/manual/x11vkbtest/testthread.cpp b/tests/manual/x11vkbtest/testthread.cpp new file mode 100644 index 00000000..8bf4556c --- /dev/null +++ b/tests/manual/x11vkbtest/testthread.cpp @@ -0,0 +1,135 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QEventLoop> +#include <QFile> +#include <QElapsedTimer> +#include <QLoggingCategory> + +#include "testreporter.h" +#include "processhandler.h" +#include "startclose.h" +#include "testenglishletters.h" +#include "testlanguagechange.h" +#include "testthread.h" +#include "windowhelper.h" + +namespace { +const quint32 KTime_Wait_To_Start_Test = 1000000; +} + +Q_LOGGING_CATEGORY(lcTestThread, "qt.virtualkeyboard.tests.manual.x11vkbtest.testthread") + +TestThread::TestThread(const QString &x11vkbPath, quint32 startCloseTest, quint32 keyOperationTest, quint32 langChangeTest, QObject *parent) : + QThread(parent), + m_x11vkbPath(x11vkbPath), + m_numberOfStartClose(startCloseTest), + m_numberOfKeyOperation(keyOperationTest), + m_numberOfLangChange(langChangeTest) +{ +} + +void TestThread::run() +{ + QElapsedTimer testTimer; + testTimer.start(); + + QVector<TestBase*> tests; + + TestReporter reporter; + WindowHelper windowHelper; + auto x11vkbProcHandler = new ProcessHandler(&windowHelper, m_x11vkbPath); + + if (m_numberOfStartClose > 0 || (m_numberOfKeyOperation == 0 && m_numberOfLangChange == 0)) { + auto startClose = new StartClose(*x11vkbProcHandler->getPRocess(), m_numberOfStartClose, &windowHelper); + tests.append(startClose); + } + + if (m_numberOfKeyOperation > 0 || (m_numberOfStartClose == 0 && m_numberOfLangChange == 0)) { + auto testEngLetters = new TestEnglishLetters(&windowHelper, windowHelper, m_numberOfKeyOperation); + tests.append(testEngLetters); + } + + if (m_numberOfLangChange > 0 || (m_numberOfStartClose == 0 && m_numberOfKeyOperation == 0)) { + auto testLang = new TestLanguageChange(&windowHelper, windowHelper, m_numberOfLangChange); + tests.append(testLang); + } + + bool startVKB = true; + if (tests.size() == 1 && nullptr != qobject_cast<StartClose*>(tests.first())) { + startVKB = false; + } + /* main loop to connect test each after another */ + for (int i = 0 ; i < tests.size() - 1 ; ++i) { + if (nullptr != qobject_cast<StartClose*>(tests.at(i))) { + QObject::connect(tests.at(i), &StartClose::endTest, [&]() { + + auto x11vkbProcId = x11vkbProcHandler->getProcId(); + + emit processID(x11vkbProcId); + + for (int i = 1 ; i < tests.size() ; ++i) { + tests.at(i)->setProcID(x11vkbProcId); + } + if (tests.size() > 1) { + emit startMemoryMonitor(); + usleep(KTime_Wait_To_Start_Test); + tests.at(1)->startTest(); + } + }); + startVKB = false; + } else { + QObject::connect(tests.at(i), &TestBase::endTest, tests.at(i+1), &TestBase::startTest); + } + } + + if (startVKB) { + emit startMemoryMonitor(); + x11vkbProcHandler->startProc(); + qCDebug(lcTestThread) << "Explicitly start process"; + auto x11vkbProcId = x11vkbProcHandler->getProcId(); + + emit processID(x11vkbProcId); + + for (auto test : tests) { + test->setProcID(x11vkbProcId); + } + usleep(KTime_Wait_To_Start_Test); + } + + QObject::connect(tests.last(), &TestBase::endTest, this, &QThread::quit); + + tests.first()->startTest(); + exec(); + + reporter.printTestResultsToCSV(tests); + reporter.printTestResultToConsole(tests); + + x11vkbProcHandler->closeProcess(); +} diff --git a/tests/manual/x11vkbtest/testthread.h b/tests/manual/x11vkbtest/testthread.h new file mode 100644 index 00000000..f10e1497 --- /dev/null +++ b/tests/manual/x11vkbtest/testthread.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef TESTTHREAD_H +#define TESTTHREAD_H + +#include <QThread> +#include "testbase.h" + +class TestBase; + +class TestThread : public QThread +{ + Q_OBJECT +public: + explicit TestThread(const QString &x11vkbPath, quint32 startCloseTest, quint32 keyOperationTest, quint32 langChangeTest, QObject *parent = nullptr); + +public: + void run() override; + +signals: + void resultReady(const QString &s); + void processID(const qint64 procID); + void startMemoryMonitor(); + +private: + const QString &m_x11vkbPath; + quint32 m_numberOfStartClose; + quint32 m_numberOfKeyOperation; + quint32 m_numberOfLangChange; +}; + +#endif // TESTTHREAD_H diff --git a/tests/manual/x11vkbtest/windowhelper.cpp b/tests/manual/x11vkbtest/windowhelper.cpp new file mode 100644 index 00000000..9223774b --- /dev/null +++ b/tests/manual/x11vkbtest/windowhelper.cpp @@ -0,0 +1,81 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QTextStream> +#include <cstdlib> + +extern "C" { +#include <xdo.h> +#include <X11/X.h> +} + +#include <cstdio> +#include <cstdlib> + +#include "windowhelper.h" + +WindowHelper::WindowHelper(QObject *parent) : + QObject(parent), + m_xdo(xdo_new(nullptr)) +{ +} + +WindowHelper::~WindowHelper() +{ + xdo_free(m_xdo); +} + +Window WindowHelper::findWindowByPid(const qint64 appPid) const +{ + xdo_search_t search; + memset(&search, 0, sizeof(xdo_search_t)); + + search.require = xdo_search::SEARCH_ANY; + search.searchmask = SEARCH_PID; + search.pid = static_cast<int>(appPid); + search.max_depth = -1; + + Window *list; + quint32 nwindows = 0; + + xdo_search_windows(m_xdo, &search, &list, &nwindows); + + return nwindows > 0 ? list[nwindows-1] : 0; +} + +QPair<quint16, quint16> WindowHelper::getWindowDimension(const Window winId) const +{ + Display *display = XOpenDisplay(nullptr); + XWindowAttributes winAttributes; + XGetWindowAttributes(display, winId, &winAttributes); + + XCloseDisplay(display); + + return {static_cast<quint16>(winAttributes.width), static_cast<quint16>(winAttributes.height)}; +} diff --git a/tests/manual/x11vkbtest/windowhelper.h b/tests/manual/x11vkbtest/windowhelper.h new file mode 100644 index 00000000..e9871737 --- /dev/null +++ b/tests/manual/x11vkbtest/windowhelper.h @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the Qt Virtual Keyboard module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 or (at your option) any later version +** approved by the KDE Free Qt Foundation. The licenses are as published by +** the Free Software Foundation and appearing in the file LICENSE.GPL3 +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef WINDOWHELPER_H +#define WINDOWHELPER_H + +#include <QObject> + +extern "C" { +#include <xdo.h> +} + +class WindowHelper : public QObject +{ + Q_OBJECT +public: + explicit WindowHelper(QObject *parent = nullptr); + ~WindowHelper(); + +public: + Window findWindowByPid(const qint64 appPid) const; + QPair<quint16, quint16> getWindowDimension(const Window winId) const; + +private: + /** Libxdo context. */ + xdo_t *m_xdo; +}; + +#endif // WINDOWHELPER_H diff --git a/tests/manual/x11vkbtest/x11vkbtest.pro b/tests/manual/x11vkbtest/x11vkbtest.pro new file mode 100644 index 00000000..74623f89 --- /dev/null +++ b/tests/manual/x11vkbtest/x11vkbtest.pro @@ -0,0 +1,41 @@ +TARGET = x11vkbtest + +QT += charts + +CONFIG += c++11 + +# The following define makes your compiler emit warnings if you use +# any Qt feature that has been marked deprecated (the exact warnings +# depend on your compiler). Please consult the documentation of the +# deprecated API in order to know how to port your code away from it. +DEFINES += QT_DEPRECATED_WARNINGS + +SOURCES += \ + filehelper.cpp \ + main.cpp \ + memorymonitor.cpp \ + mousesimulator.cpp \ + processhandler.cpp \ + startclose.cpp \ + testbase.cpp \ + testenglishletters.cpp \ + testlanguagechange.cpp \ + testreporter.cpp \ + testthread.cpp \ + windowhelper.cpp + +HEADERS += \ + colors.h \ + filehelper.h \ + memorymonitor.h \ + mousesimulator.h \ + processhandler.h \ + startclose.h \ + testbase.h \ + testenglishletters.h \ + testlanguagechange.h \ + testreporter.h \ + testthread.h \ + windowhelper.h + +LIBS += -lXtst -lX11 -lxdo |