Qt 6.x
The Qt SDK
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
visualtestutils.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3
4#include "visualtestutils_p.h"
5
6#include <QtCore/QCoreApplication>
7#include <QtCore/private/qvariantanimation_p.h>
8#include <QtCore/QDebug>
9#include <QtQuick/QQuickItem>
10#if QT_CONFIG(quick_itemview)
11#include <QtQuick/private/qquickitemview_p.h>
12#endif
13#include <QtQuickTest/QtQuickTest>
14#include <QtQuickTestUtils/private/viewtestutils_p.h>
15
17
19{
20 QQuickItem *item = nullptr;
21 QList<QQuickItem*> items = parent->findChildren<QQuickItem*>(objectName);
22 for (int i = 0; i < items.size(); ++i) {
23 if (items.at(i)->isVisible() && !QQuickItemPrivate::get(items.at(i))->culled) {
24 item = items.at(i);
25 break;
26 }
27 }
28 return item;
29}
30
32{
33 static QString padding = QStringLiteral(" ");
34 for (int i = 0; i < parent->childItems().size(); ++i) {
35 QQuickItem *item = qobject_cast<QQuickItem*>(parent->childItems().at(i));
36 if (!item)
37 continue;
38 qDebug() << padding.left(depth*2) << item;
40 }
41}
42
44{
45#if QT_CONFIG(cursor) // Get the cursor out of the way.
46 // Using "bottomRight() + QPoint(100, 100)" was causing issues on Ubuntu,
47 // where the window was positioned at the bottom right corner of the window
48 // (even after centering the window on the screen), so we use another position.
49 QCursor::setPos(window->frameGeometry().bottomLeft() + QPoint(-10, 10));
50#endif
51
52 // make sure hover events from QQuickDeliveryAgentPrivate::flushFrameSynchronousEvents()
53 // do not interfere with the tests
56}
57
59{
60 const QRect screenGeometry = window->screen()->availableGeometry();
61 const QPoint offset = QPoint(window->width() / 2, window->height() / 2);
62 window->setFramePosition(screenGeometry.center() - offset);
63}
64
66{
67 return QPoint(_q_interpolate(point1.x(), point2.x(), t), _q_interpolate(point1.y(), point2.y(), t));
68};
69
87 : mWindow(window)
88 , mPointingDevice(pointingDevice)
89{
90}
91
100void QQuickVisualTestUtils::PointLerper::move(const QPoint &pos, int steps, int delayInMilliseconds)
101{
102 forEachStep(steps, [&](qreal progress) {
103 QQuickTest::pointerMove(mPointingDevice, mWindow, 0, lerpPoints(mFrom, pos, progress));
104 QTest::qWait(delayInMilliseconds);
105 });
106 mFrom = pos;
107};
108
109void QQuickVisualTestUtils::PointLerper::move(int x, int y, int steps, int delayInMilliseconds)
110{
111 move(QPoint(x, y), steps, delayInMilliseconds);
112};
113
115{
117}
118
132{
133 if (ia.size() != ib.size()) {
134 QDebug(errorMessage) << "Images are of different size:" << ia.size() << ib.size()
135 << "DPR:" << ia.devicePixelRatio() << ib.devicePixelRatio();
136 return false;
137 }
138 if (ia.format() != ib.format()) {
139 QDebug(errorMessage) << "Images are of different formats:" << ia.format() << ib.format();
140 return false;
141 }
142
143 int w = ia.width();
144 int h = ia.height();
145 const int tolerance = 5;
146 for (int y=0; y<h; ++y) {
147 const uint *as= (const uint *) ia.constScanLine(y);
148 const uint *bs= (const uint *) ib.constScanLine(y);
149 for (int x=0; x<w; ++x) {
150 uint a = as[x];
151 uint b = bs[x];
152
153 // No tolerance for error in the alpha.
154 if ((a & 0xff000000) != (b & 0xff000000)
155 || qAbs(qRed(a) - qRed(b)) > tolerance
156 || qAbs(qRed(a) - qRed(b)) > tolerance
157 || qAbs(qRed(a) - qRed(b)) > tolerance) {
158 QDebug(errorMessage) << "Mismatch at:" << x << y << ':'
159 << Qt::hex << Qt::showbase << a << b;
160 return false;
161 }
162 }
163 }
164 return true;
165}
166
167#if QT_CONFIG(quick_itemview)
176QQuickItem *QQuickVisualTestUtils::findViewDelegateItem(QQuickItemView *itemView, int index, FindViewDelegateItemFlags flags)
177{
178 if (QQuickTest::qIsPolishScheduled(itemView)) {
179 if (!QQuickTest::qWaitForPolish(itemView)) {
180 qWarning() << "failed to polish" << itemView;
181 return nullptr;
182 }
183 }
184
185 // Do this after the polish, just in case the count changes after a polish...
186 if (index <= -1 || index >= itemView->count()) {
187 qWarning() << "index" << index << "is out of bounds for" << itemView;
188 return nullptr;
189 }
190
193
194 return itemView->itemAtIndex(index);
195}
196#endif
197
199 const QString &testFilePath, const QVariantMap &initialProperties, const QStringList &qmlImportPaths)
200{
201 for (const auto &path : qmlImportPaths)
202 engine.addImportPath(path);
203
205
206 component.loadUrl(testCase->testFileUrl(testFilePath));
207 QVERIFY2(component.isReady(), qPrintable(component.errorString()));
208 QObject *rootObject = component.createWithInitialProperties(initialProperties);
209 cleanup.reset(rootObject);
210 if (component.isError() || !rootObject) {
211 errorMessage = QString::fromUtf8("Failed to create window: %1").arg(component.errorString()).toUtf8();
212 return;
213 }
214
215 window = qobject_cast<QQuickWindow*>(rootObject);
216 if (!window) {
217 errorMessage = QString::fromUtf8("Root object %1 must be a QQuickWindow subclass").arg(QDebug::toString(window)).toUtf8();
218 return;
219 }
220
221 if (window->isVisible()) {
222 errorMessage = QString::fromUtf8("Expected window not to be visible, but it is").toUtf8();
223 return;
224 }
225
226 ready = true;
227}
228
230 : m_window(window), m_modifiers(Qt::NoModifier)
231{
232}
233
235{
236 // QTest::keyPress() but not generating the press event for the modifier key.
237 if (key == Qt::Key_Alt)
238 m_modifiers |= Qt::AltModifier;
239 QTest::simulateEvent(m_window, true, key, m_modifiers, QString(), false);
240}
241
243{
244 // QTest::keyRelease() but not generating the release event for the modifier key.
245 if (key == Qt::Key_Alt)
246 m_modifiers &= ~Qt::AltModifier;
247 QTest::simulateEvent(m_window, false, key, m_modifiers, QString(), false);
248}
249
251{
252 press(key);
253 release(key);
254}
255
257{
258 return item->mapToScene(QPointF(item->width() / 2, item->height() / 2)).toPoint();
259}
260
262{
263 return item->mapToScene(QPointF(relativeX, relativeY)).toPoint();
264}
265
267{
268 return mapToWindow(item, relativePos.x(), relativePos.y());
269}
270
272
273#include "moc_visualtestutils_p.cpp"
static bool sendEvent(QObject *receiver, QEvent *event)
Sends event event directly to receiver receiver, using the notify() function.
static void setPos(int x, int y)
Moves the cursor (hot spot) of the primary screen to the global screen position (x,...
Definition qcursor.cpp:240
\inmodule QtCore
\inmodule QtCore
Definition qcoreevent.h:45
QPointF mapToScene(const QPointF &point) const
Maps the point point, which is in this item's coordinate system, to the scene's coordinate system,...
bool isVisible() const
Returns true if the item is visible; otherwise, false is returned.
\inmodule QtGui
Definition qimage.h:37
QSize size() const
Returns the size of the image, i.e.
int width() const
Returns the width of the image.
int height() const
Returns the height of the image.
Format format() const
Returns the format of the image.
Definition qimage.cpp:2146
const uchar * constScanLine(int) const
Returns a pointer to the pixel data at the scanline with index i.
Definition qimage.cpp:1657
qreal devicePixelRatio() const
Returns the device pixel ratio for the image.
Definition qimage.cpp:1460
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
\inmodule QtCore
Definition qobject.h:90
\inmodule QtCore\reentrant
Definition qpoint.h:214
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:333
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:338
constexpr QPoint toPoint() const
Rounds the coordinates of this point to the nearest integer, and returns a QPoint object with the rou...
Definition qpoint.h:394
\inmodule QtCore\reentrant
Definition qpoint.h:23
constexpr int x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:127
constexpr int y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:132
The QPointingDevice class describes a device from which mouse, touch or tablet events originate.
The QQmlComponent class encapsulates a QML component definition.
QUrl testFileUrl(const QString &fileName) const
Definition qmlutils_p.h:48
static QQuickItemPrivate * get(QQuickItem *item)
Q_INVOKABLE void positionViewAtIndex(int index, int mode)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:64
void move(const QPoint &pos, int steps=10, int delayInMilliseconds=1)
PointLerper(QQuickWindow *window, const QPointingDevice *pointingDevice=QPointingDevice::primaryPointingDevice())
QQuickApplicationHelper(QQmlDataTest *testCase, const QString &testFilePath, const QVariantMap &initialProperties={}, const QStringList &qmlImportPaths={})
\qmltype Window \instantiates QQuickWindow \inqmlmodule QtQuick
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr QPoint center() const noexcept
Returns the center point of the rectangle.
Definition qrect.h:232
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
static QString fromUtf8(QByteArrayView utf8)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Definition qstring.cpp:5857
QString arg(qlonglong a, int fieldwidth=0, int base=10, QChar fillChar=u' ') const
Definition qstring.cpp:8606
QString left(qsizetype n) const
Returns a substring that contains the n leftmost characters of the string.
Definition qstring.cpp:5161
QByteArray toUtf8() const &
Definition qstring.h:563
\inmodule QtGui
Definition qwindow.h:63
Q_QUICK_TEST_EXPORT bool qWaitForPolish(const QQuickItem *item, int timeout=defaultTimeout)
Q_QUICK_TEST_EXPORT bool qIsPolishScheduled(const QQuickItem *item)
Definition quicktest.cpp:73
void pointerMove(const QPointingDevice *dev, QQuickWindow *window, int pointId, const QPoint &p)
void centerOnScreen(QQuickWindow *window)
void dumpTree(QQuickItem *parent, int depth=0)
QPoint mapToWindow(const QQuickItem *item, qreal relativeX, qreal relativeY)
bool delegateVisible(QQuickItem *item)
QPoint mapCenterToWindow(const QQuickItem *item)
bool findViewDelegateItem(QQuickItemView *itemView, int index, T &delegateItem, FindViewDelegateItemFlags flags=FindViewDelegateItemFlag::PositionViewAtIndex)
QQuickItem * findVisibleChild(QQuickItem *parent, const QString &objectName)
void moveMouseAway(QQuickWindow *window)
bool compareImages(const QImage &ia, const QImage &ib, QString *errorMessage)
QPoint lerpPoints(const QPoint &point1, const QPoint &point2, qreal t)
void forEachStep(int steps, F &&func)
Combined button and popup list for selecting options.
Q_CORE_EXPORT void qWait(int ms)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static void simulateEvent(QWindow *window, bool press, int code, Qt::KeyboardModifiers modifier, QString text, bool repeat, int delay=-1)
QTextStream & hex(QTextStream &stream)
Calls QTextStream::setIntegerBase(16) on stream and returns stream.
QTextStream & showbase(QTextStream &stream)
Calls QTextStream::setNumberFlags(QTextStream::numberFlags() | QTextStream::ShowBase) on stream and r...
@ Key_Alt
Definition qnamespace.h:681
@ AltModifier
#define qDebug
[1]
Definition qlogging.h:160
#define qWarning
Definition qlogging.h:162
constexpr T qAbs(const T &t)
Definition qnumeric.h:328
GLboolean GLboolean GLboolean b
GLint GLint GLint GLint GLint x
[0]
GLint GLenum GLsizei GLsizei GLsizei depth
GLuint64 key
GLfloat GLfloat GLfloat w
[0]
GLboolean GLboolean GLboolean GLboolean a
[7]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLuint index
[2]
GLbitfield flags
GLenum GLuint GLintptr offset
GLint y
GLfloat GLfloat GLfloat GLfloat h
GLdouble GLdouble t
Definition qopenglext.h:243
GLsizei const GLchar *const * path
static qreal component(const QPointF &point, unsigned int i)
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
Definition qquickitem.h:483
constexpr int qRed(QRgb rgb)
Definition qrgb.h:18
#define qPrintable(string)
Definition qstring.h:1391
#define QStringLiteral(str)
#define QVERIFY2(statement, description)
Definition qtestcase.h:41
unsigned int uint
Definition qtypes.h:29
double qreal
Definition qtypes.h:92
static QString errorMessage(QUrlPrivate::ErrorCode errorCode, const QString &errorSource, qsizetype errorPosition)
Definition qurl.cpp:3503
#define leave(x)
Q_INLINE_TEMPLATE QRect _q_interpolate(const QRect &f, const QRect &t, qreal progress)
sem release()
QGraphicsItem * item
QList< QTreeWidgetItem * > items
aWidget window() -> setWindowTitle("New Window Title")
[2]
QJSEngine engine
[0]
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent