blob: d7d8f98d1516826981f354c3d69dcdc81e1abf41 [file] [log] [blame]
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: http://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL3$
** 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 http://www.qt.io/terms-conditions. For further
** information use the contact form at http://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPLv3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or later as published by the Free
** Software Foundation and appearing in the file LICENSE.GPL included in
** the packaging of this file. Please review the following information to
** ensure the GNU General Public License version 2.0 requirements will be
** met: http://www.gnu.org/licenses/gpl-2.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtTest>
#include <QtQuick>
#include "gifrecorder.h"
#include "eventcapturer.h"
//#define GENERATE_EVENT_CODE
class tst_Gifs : public QObject
{
Q_OBJECT
private slots:
void initTestCase();
void tumblerWrap();
void slider();
void sliderSnap_data();
void sliderSnap();
void rangeSlider();
void busyIndicator();
void switchGif();
void button_data();
void button();
void tabBar();
void menu();
void swipeView();
void swipeDelegate_data();
void swipeDelegate();
void swipeDelegateBehind();
void delegates_data();
void delegates();
void dial_data();
void dial();
void scrollBar();
void scrollBarSnap_data();
void scrollBarSnap();
void scrollIndicator();
void progressBar_data();
void progressBar();
void triState_data();
void triState();
void checkables_data();
void checkables();
void comboBox();
void stackView_data();
void stackView();
void drawer();
void delayButton();
private:
void moveSmoothly(QQuickWindow *window, const QPoint &from, const QPoint &to, int movements,
QEasingCurve::Type easingCurveType = QEasingCurve::OutQuint, int movementDelay = 15);
void moveSmoothlyAlongArc(QQuickWindow *window, QPoint arcCenter, qreal distanceFromCenter,
qreal startAngleRadians, qreal endAngleRadians, QEasingCurve::Type easingCurveType = QEasingCurve::OutQuint);
QString dataDirPath;
QDir outputDir;
};
void tst_Gifs::initTestCase()
{
dataDirPath = QFINDTESTDATA("data");
QVERIFY(!dataDirPath.isEmpty());
qInfo() << "data directory:" << dataDirPath;
outputDir = QDir(QDir::current().filePath("gifs"));
QVERIFY(outputDir.exists() || QDir::current().mkpath("gifs"));
qInfo() << "output directory:" << outputDir.absolutePath();
}
void tst_Gifs::moveSmoothly(QQuickWindow *window, const QPoint &from, const QPoint &to,
int movements, QEasingCurve::Type easingCurveType, int movementDelay)
{
QEasingCurve curve(easingCurveType);
int xDifference = to.x() - from.x();
int yDifference = to.y() - from.y();
for (int movement = 0; movement < movements; ++movement) {
QPoint pos = QPoint(
from.x() + qRound(curve.valueForProgress(movement / qreal(qAbs(xDifference))) * xDifference),
from.y() + qRound(curve.valueForProgress(movement / qreal(qAbs(yDifference))) * yDifference));
QTest::mouseMove(window, pos, movementDelay);
}
}
QPoint posAlongArc(QPoint arcCenter, qreal startAngleRadians, qreal endAngleRadians,
qreal distanceFromCenter, qreal progress, QEasingCurve::Type easingCurveType)
{
QEasingCurve curve(easingCurveType);
const qreal angle = startAngleRadians + curve.valueForProgress(progress) * (endAngleRadians - startAngleRadians);
return (arcCenter - QTransform().rotateRadians(angle).map(QPointF(0, distanceFromCenter))).toPoint();
}
void tst_Gifs::moveSmoothlyAlongArc(QQuickWindow *window, QPoint arcCenter, qreal distanceFromCenter,
qreal startAngleRadians, qreal endAngleRadians, QEasingCurve::Type easingCurveType)
{
QEasingCurve curve(easingCurveType);
const qreal angleSpan = endAngleRadians - startAngleRadians;
const int movements = qAbs(angleSpan) * 20 + 20;
for (int movement = 0; movement < movements; ++movement) {
const qreal progress = movement / qreal(movements);
const QPoint pos = posAlongArc(arcCenter, startAngleRadians, endAngleRadians,
distanceFromCenter, progress, easingCurveType);
QTest::mouseMove(window, pos, 15);
}
}
void tst_Gifs::tumblerWrap()
{
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(5);
gifRecorder.setQmlFileName("qtquickcontrols2-tumbler-wrap.qml");
gifRecorder.start();
// Left as an example. Usually EventCapturer code would be removed after
// the GIF has been generated.
QQuickWindow *window = gifRecorder.window();
EventCapturer eventCapturer;
#ifdef GENERATE_EVENT_CODE
eventCapturer.setMoveEventTrimFlags(EventCapturer::TrimAll);
eventCapturer.startCapturing(window, 4000);
#else
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(89, 75), 326);
QTest::mouseMove(window, QPoint(89, 76), 31);
QTest::mouseMove(window, QPoint(89, 80), 10);
QTest::mouseMove(window, QPoint(93, 93), 10);
QTest::mouseMove(window, QPoint(95, 101), 10);
QTest::mouseMove(window, QPoint(97, 109), 11);
QTest::mouseMove(window, QPoint(101, 125), 10);
QTest::mouseMove(window, QPoint(103, 133), 11);
QTest::mouseMove(window, QPoint(103, 141), 11);
QTest::mouseMove(window, QPoint(105, 158), 10);
QTest::mouseMove(window, QPoint(105, 162), 13);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(105, 162), 0);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(154, 100), 1098);
QTest::mouseMove(window, QPoint(154, 99), 16);
QTest::mouseMove(window, QPoint(153, 98), 16);
QTest::mouseMove(window, QPoint(153, 95), 16);
QTest::mouseMove(window, QPoint(152, 91), 15);
QTest::mouseMove(window, QPoint(152, 87), 14);
QTest::mouseMove(window, QPoint(151, 83), 13);
QTest::mouseMove(window, QPoint(151, 86), 13);
QTest::mouseMove(window, QPoint(150, 79), 12);
QTest::mouseMove(window, QPoint(148, 73), 12);
QTest::mouseMove(window, QPoint(148, 68), 12);
QTest::mouseMove(window, QPoint(148, 60), 10);
QTest::mouseMove(window, QPoint(147, 50), 10);
QTest::mouseMove(window, QPoint(147, 40), 9);
QTest::mouseMove(window, QPoint(147, 30), 8);
QTest::mouseMove(window, QPoint(147, 20), 7);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(147, 20), 0);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(154, 100), 1000);
QTest::mouseMove(window, QPoint(147, 101), 16);
QTest::mouseMove(window, QPoint(147, 102), 16);
QTest::mouseMove(window, QPoint(147, 105), 16);
QTest::mouseMove(window, QPoint(148, 109), 15);
QTest::mouseMove(window, QPoint(148, 115), 14);
QTest::mouseMove(window, QPoint(148, 120), 13);
QTest::mouseMove(window, QPoint(150, 125), 13);
QTest::mouseMove(window, QPoint(151, 130), 12);
QTest::mouseMove(window, QPoint(151, 135), 12);
QTest::mouseMove(window, QPoint(153, 140), 12);
QTest::mouseMove(window, QPoint(153, 150), 10);
QTest::mouseMove(window, QPoint(153, 160), 10);
QTest::mouseMove(window, QPoint(153, 170), 9);
QTest::mouseMove(window, QPoint(155, 180), 8);
QTest::mouseMove(window, QPoint(155, 188), 7);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(20, 188), 0);
#endif
gifRecorder.waitForFinish();
const auto capturedEvents = eventCapturer.capturedEvents();
for (CapturedEvent event : capturedEvents)
qDebug().noquote() << event.cppCommand();
}
void tst_Gifs::slider()
{
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(5);
gifRecorder.setHighQuality(true);
gifRecorder.setQmlFileName("qtquickcontrols2-slider.qml");
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QQuickItem *slider = window->property("slider").value<QQuickItem*>();
QVERIFY(slider);
QQuickItem *handle = slider->property("handle").value<QQuickItem*>();
QVERIFY(handle);
const QPoint handleCenter = handle->mapToItem(window->contentItem(),
QPoint(handle->width() / 2, handle->height() / 2)).toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, handleCenter, 100);
QPoint pos1 = handleCenter + QPoint(slider->width() * 0.3, 0);
moveSmoothly(window, handleCenter, pos1, pos1.x() - handleCenter.x(), QEasingCurve::OutQuint, 10);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos1, 20);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, handleCenter, 100);
const QPoint pos2 = QPoint(slider->width() - handleCenter.x() + slider->property("rightPadding").toInt(), handleCenter.y());
moveSmoothly(window, pos1, pos2, pos2.x() - pos1.x(), QEasingCurve::OutQuint, 10);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos2, 20);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, pos2, 100);
moveSmoothly(window, pos2, handleCenter, qAbs(handleCenter.x() - pos2.x()), QEasingCurve::OutQuint, 10);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, handleCenter, 20);
gifRecorder.waitForFinish();
}
void tst_Gifs::sliderSnap_data()
{
QTest::addColumn<QString>("gifBaseName");
QTest::addColumn<int>("snapMode");
QTest::newRow("NoSnap") << "qtquickcontrols2-slider-nosnap" << 0;
QTest::newRow("SnapAlways") << "qtquickcontrols2-slider-snapalways" << 1;
QTest::newRow("SnapOnRelease") << "qtquickcontrols2-slider-snaponrelease" << 2;
}
void tst_Gifs::sliderSnap()
{
QFETCH(QString, gifBaseName);
QFETCH(int, snapMode);
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(8);
gifRecorder.setHighQuality(true);
gifRecorder.setQmlFileName("qtquickcontrols2-slider-snap.qml");
gifRecorder.setOutputFileBaseName(gifBaseName);
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QQuickItem *slider = window->property("slider").value<QQuickItem*>();
QVERIFY(slider);
QVERIFY(slider->setProperty("snapMode", QVariant(snapMode)));
QCOMPARE(slider->property("snapMode").toInt(), snapMode);
QQuickItem *handle = slider->property("handle").value<QQuickItem*>();
QVERIFY(handle);
const QPoint startPos(slider->property("leftPadding").toReal(), slider->height() / 2);
const int trackWidth = slider->property("availableWidth").toReal();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, startPos, 200);
QPoint pos1 = startPos + QPoint(trackWidth * 0.3, 0);
moveSmoothly(window, startPos, pos1, pos1.x() - startPos.x(), QEasingCurve::OutQuint, 30);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos1, 0);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, startPos, 400);
const QPoint pos2 = startPos + QPoint(trackWidth * 0.6, 0);
moveSmoothly(window, pos1, pos2, pos2.x() - pos1.x(), QEasingCurve::OutQuint, 30);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos2, 0);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, pos2, 400);
moveSmoothly(window, pos2, startPos, qAbs(startPos.x() - pos2.x()) / 2, QEasingCurve::OutQuint, 30);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, startPos, 0);
gifRecorder.waitForFinish();
}
void tst_Gifs::rangeSlider()
{
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(7);
gifRecorder.setHighQuality(true);
gifRecorder.setQmlFileName("qtquickcontrols2-rangeslider.qml");
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QQuickItem *slider = window->property("slider").value<QQuickItem*>();
QVERIFY(slider);
QObject *first = slider->property("first").value<QObject*>();
QVERIFY(first);
QQuickItem *firstHandle = first->property("handle").value<QQuickItem*>();
QVERIFY(firstHandle);
QObject *second = slider->property("second").value<QObject*>();
QVERIFY(second);
QQuickItem *secondHandle = second->property("handle").value<QQuickItem*>();
QVERIFY(secondHandle);
const QPoint firstCenter = firstHandle->mapToItem(slider,
QPoint(firstHandle->width() / 2, firstHandle->height() / 2)).toPoint();
const QPoint secondCenter = secondHandle->mapToItem(slider,
QPoint(secondHandle->width() / 2, secondHandle->height() / 2)).toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, firstCenter, 100);
const QPoint firstTarget = firstCenter + QPoint(slider->width() * 0.25, 0);
moveSmoothly(window, firstCenter, firstTarget, firstTarget.x() - firstCenter.x());
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, firstTarget, 20);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, secondCenter, 100);
const QPoint secondTarget = secondCenter - QPoint(slider->width() * 0.25, 0);
moveSmoothly(window, secondCenter, secondTarget, qAbs(secondTarget.x() - secondCenter.x()));
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, secondTarget, 20);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, secondTarget, 100);
moveSmoothly(window, secondTarget, secondCenter, qAbs(secondTarget.x() - secondCenter.x()));
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, secondCenter, 20);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, firstTarget, 100);
moveSmoothly(window, firstTarget, firstCenter, firstTarget.x() - firstCenter.x());
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, firstCenter, 20);
gifRecorder.waitForFinish();
}
void tst_Gifs::busyIndicator()
{
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(6);
gifRecorder.setHighQuality(true);
gifRecorder.setQmlFileName("qtquickcontrols2-busyindicator.qml");
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
// Record nothing for a bit to make it smoother.
QTest::qWait(800 * 2);
QQuickItem *busyIndicator = window->property("busyIndicator").value<QQuickItem*>();
QVERIFY(busyIndicator);
busyIndicator->setProperty("running", false);
// 800 ms is the duration of one rotation animation cycle for BusyIndicator.
QTest::qWait(800 * 2);
busyIndicator->setProperty("running", true);
gifRecorder.waitForFinish();
}
void tst_Gifs::switchGif()
{
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(3);
gifRecorder.setQmlFileName("qtquickcontrols2-switch.qml");
gifRecorder.setHighQuality(true);
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.8, window->height() / 2), 0);
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.2, window->height() / 2), 800);
gifRecorder.waitForFinish();
}
void tst_Gifs::button_data()
{
QTest::addColumn<QString>("qmlFileName");
QTest::newRow("button") << QString::fromLatin1("qtquickcontrols2-button.qml");
QTest::newRow("button-flat") << QString::fromLatin1("qtquickcontrols2-button-flat.qml");
QTest::newRow("button-highlighted") << QString::fromLatin1("qtquickcontrols2-button-highlighted.qml");
}
void tst_Gifs::button()
{
QFETCH(QString, qmlFileName);
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(3);
gifRecorder.setQmlFileName(qmlFileName);
// Seems to be necessary to show the Default button background.
gifRecorder.setHighQuality(true);
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 0);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 700);
gifRecorder.waitForFinish();
}
void tst_Gifs::tabBar()
{
const QString qmlFileName = QStringLiteral("qtquickcontrols2-tabbar.qml");
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(4);
gifRecorder.setQmlFileName(qmlFileName);
gifRecorder.setHighQuality(true);
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.6, window->height() / 2), 0);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.6, window->height() / 2), 50);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.9, window->height() / 2), 400);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.9, window->height() / 2), 50);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.6, window->height() / 2), 800);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.6, window->height() / 2), 50);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.3, window->height() / 2), 400);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() * 0.3, window->height() / 2), 50);
gifRecorder.waitForFinish();
}
void tst_Gifs::menu()
{
const QString qmlFileName = QStringLiteral("qtquickcontrols2-menu.qml");
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(3);
gifRecorder.setQmlFileName(qmlFileName);
gifRecorder.setHighQuality(true);
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
const QQuickItem *fileButton = window->property("fileButton").value<QQuickItem*>();
QVERIFY(fileButton);
const QPoint fileButtonCenter = fileButton->mapToScene(QPointF(fileButton->width() / 2, fileButton->height() / 2)).toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, fileButtonCenter, 0);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, fileButtonCenter, 200);
const QObject *menu = window->property("menu").value<QObject*>();
QVERIFY(menu);
const QQuickItem *menuContentItem = menu->property("contentItem").value<QQuickItem*>();
QVERIFY(menuContentItem);
const QPoint lastItemPos = menuContentItem->mapToScene(QPointF(menuContentItem->width() / 2, menuContentItem->height() - 10)).toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, lastItemPos, 1000);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, lastItemPos, 300);
gifRecorder.waitForFinish();
}
void tst_Gifs::swipeView()
{
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(8);
gifRecorder.setQmlFileName(QStringLiteral("qtquickcontrols2-swipeview.qml"));
gifRecorder.setHighQuality(true);
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QQuickItem *swipeView = window->property("swipeView").value<QQuickItem*>();
QVERIFY(swipeView);
QTest::qWait(1200);
swipeView->setProperty("currentIndex", 1);
QTest::qWait(2000);
swipeView->setProperty("currentIndex", 2);
QTest::qWait(2000);
swipeView->setProperty("currentIndex", 0);
gifRecorder.waitForFinish();
}
void tst_Gifs::swipeDelegate_data()
{
QTest::addColumn<QString>("qmlFileName");
QTest::newRow("qtquickcontrols2-swipedelegate.qml") << QString::fromLatin1("qtquickcontrols2-swipedelegate.qml");
QTest::newRow("qtquickcontrols2-swipedelegate-leading-trailing.qml") << QString::fromLatin1("qtquickcontrols2-swipedelegate-leading-trailing.qml");
}
void tst_Gifs::swipeDelegate()
{
QFETCH(QString, qmlFileName);
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(10);
gifRecorder.setQmlFileName(qmlFileName);
gifRecorder.setHighQuality(true);
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QQuickItem *swipeDelegate = window->property("swipeDelegate").value<QQuickItem*>();
QVERIFY(swipeDelegate);
// Show left item.
const QPoint leftTarget = QPoint(swipeDelegate->width() * 0.2, 0);
const QPoint rightTarget = QPoint(swipeDelegate->width() * 0.8, 0);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, leftTarget, 100);
const int movements = rightTarget.x() - leftTarget.x();
moveSmoothly(window, leftTarget, rightTarget, movements, QEasingCurve::OutQuint, 5);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, rightTarget, 20);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, rightTarget, 1000);
moveSmoothly(window, rightTarget, leftTarget, movements, QEasingCurve::OutQuint, 5);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, leftTarget, 20);
QTest::qWait(1000);
// Show right item.
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, rightTarget, 1000);
moveSmoothly(window, rightTarget, leftTarget, movements, QEasingCurve::OutQuint, 5);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, leftTarget, 20);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, leftTarget, 1000);
moveSmoothly(window, leftTarget, rightTarget, movements, QEasingCurve::OutQuint, 5);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, rightTarget, 20);
gifRecorder.waitForFinish();
}
void tst_Gifs::swipeDelegateBehind()
{
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(14);
gifRecorder.setQmlFileName(QStringLiteral("qtquickcontrols2-swipedelegate-behind.qml"));
gifRecorder.setHighQuality(true);
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QQuickItem *swipeDelegate = window->property("swipeDelegate").value<QQuickItem*>();
QVERIFY(swipeDelegate);
// Show wrapping around left item.
const QPoint leftTarget = QPoint(swipeDelegate->width() * 0.2, 0);
const QPoint rightTarget = QPoint(swipeDelegate->width() * 0.8, 0);
const int movements = rightTarget.x() - leftTarget.x();
for (int i = 0; i < 4; ++i) {
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, leftTarget, 100);
moveSmoothly(window, leftTarget, rightTarget, movements, QEasingCurve::OutQuint, 5);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, rightTarget, 20);
QTest::qWait(500);
}
QTest::qWait(1000);
// Show wrapping around right item.
for (int i = 0; i < 4; ++i) {
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, rightTarget, 100);
moveSmoothly(window, rightTarget, leftTarget, movements, QEasingCurve::OutQuint, 5);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, leftTarget, 20);
QTest::qWait(500);
}
gifRecorder.waitForFinish();
}
void tst_Gifs::delegates_data()
{
QTest::addColumn<QString>("name");
QTest::addColumn<QVector<int> >("pressIndices");
QTest::addColumn<int>("duration");
QTest::newRow("ItemDelegate") << "itemdelegate" << (QVector<int>() << 0 << 1 << 2) << 5;
QTest::newRow("CheckDelegate") << "checkdelegate" << (QVector<int>() << 0 << 0) << 5;
QTest::newRow("RadioDelegate") << "radiodelegate" << (QVector<int>() << 1 << 0) << 5;
QTest::newRow("SwitchDelegate") << "switchdelegate" << (QVector<int>() << 0 << 0) << 5;
}
void tst_Gifs::delegates()
{
QFETCH(QString, name);
QFETCH(QVector<int>, pressIndices);
QFETCH(int, duration);
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(duration);
gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-%1.qml").arg(name));
gifRecorder.setHighQuality(true);
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QQuickItem *delegate = window->property("delegate").value<QQuickItem*>();
QVERIFY(delegate);
for (int i = 0; i < pressIndices.size(); ++i) {
const int pressIndex = pressIndices.at(i);
const QPoint delegateCenter(delegate->mapToScene(QPointF(
delegate->width() / 2, delegate->height() / 2 + delegate->height() * pressIndex)).toPoint());
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, delegateCenter, i == 0 ? 200 : 1000);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, delegateCenter, 400);
}
gifRecorder.waitForFinish();
}
void tst_Gifs::dial_data()
{
QTest::addColumn<QString>("name");
QTest::newRow("dial-wrap") << "wrap";
QTest::newRow("dial-no-wrap") << "no-wrap";
}
void tst_Gifs::dial()
{
QFETCH(QString, name);
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(10);
gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-dial-%1.qml").arg(name));
gifRecorder.setHighQuality(false);
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QQuickItem *dial = window->property("dial").value<QQuickItem*>();
QVERIFY(dial);
const QPoint arcCenter = dial->mapToScene(QPoint(dial->width() / 2, dial->height() / 2)).toPoint();
const qreal distanceFromCenter = dial->height() * 0.25;
// Go a bit past the actual min/max to ensure that we get the full range.
const qreal minAngle = qDegreesToRadians(-170.0);
const qreal maxAngle = qDegreesToRadians(170.0);
// Drag from start to end.
qreal startAngle = minAngle;
qreal endAngle = maxAngle;
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, posAlongArc(
arcCenter, startAngle, endAngle, distanceFromCenter, 0, QEasingCurve::InOutQuad), 30);
moveSmoothlyAlongArc(window, arcCenter, distanceFromCenter, startAngle, endAngle, QEasingCurve::InOutQuad);
// Come back from the end a bit.
startAngle = endAngle;
endAngle -= qDegreesToRadians(50.0);
moveSmoothlyAlongArc(window, arcCenter, distanceFromCenter, startAngle, endAngle, QEasingCurve::InOutQuad);
// Try to drag over max to show what happens with different wrap settings.
startAngle = endAngle;
endAngle = qDegreesToRadians(270.0);
moveSmoothlyAlongArc(window, arcCenter, distanceFromCenter, startAngle, endAngle, QEasingCurve::InOutQuad);
// Go back to the start so that it loops nicely.
startAngle = endAngle;
endAngle = minAngle;
moveSmoothlyAlongArc(window, arcCenter, distanceFromCenter, startAngle, endAngle, QEasingCurve::InOutQuad);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, posAlongArc(
arcCenter, startAngle, endAngle, distanceFromCenter, 1, QEasingCurve::InOutQuad), 30);
gifRecorder.waitForFinish();
}
void tst_Gifs::checkables_data()
{
QTest::addColumn<QString>("name");
QTest::addColumn<QVector<int> >("pressIndices");
QTest::newRow("checkbox") << "checkbox" << (QVector<int>() << 1 << 2 << 2 << 1);
QTest::newRow("radiobutton") << "radiobutton" << (QVector<int>() << 1 << 2 << 1 << 0);
}
void tst_Gifs::checkables()
{
QFETCH(QString, name);
QFETCH(QVector<int>, pressIndices);
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(6);
gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-%1.qml").arg(name));
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
for (int i = 0; i < pressIndices.size(); ++i) {
const int pressIndex = pressIndices.at(i);
const QString controlId = QString::fromLatin1("control%1").arg(pressIndex + 1);
QQuickItem *control = window->property(qPrintable(controlId)).value<QQuickItem*>();
QVERIFY(control);
const QPoint pos = control->mapToScene(QPointF(control->width() / 2, control->height() / 2)).toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, pos, 800);
QTest::mouseClick(window, Qt::LeftButton, Qt::NoModifier, pos, 300);
}
gifRecorder.waitForFinish();
}
void tst_Gifs::comboBox()
{
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(6);
gifRecorder.setQmlFileName(QStringLiteral("qtquickcontrols2-combobox.qml"));
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QQuickItem *comboBox = window->property("comboBox").value<QQuickItem*>();
QVERIFY(comboBox);
// Open the popup.
const QPoint center = comboBox->mapToScene(
QPoint(comboBox->width() / 2, comboBox->height() / 2)).toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, center, 800);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, center, 80);
// Select the third item.
QObject *popup = comboBox->property("popup").value<QObject*>();
QVERIFY(popup);
QQuickItem *popupContent = popup->property("contentItem").value<QQuickItem*>();
QVERIFY(popupContent);
const QPoint lastItemPos = popupContent->mapToScene(
QPoint(popupContent->width() / 2, popupContent->height() * 0.8)).toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, lastItemPos, 600);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, lastItemPos, 200);
// Open the popup.
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, center, 1500);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, center, 80);
// Select the first item.
const QPoint firstItemPos = popupContent->mapToScene(
QPoint(popupContent->width() / 2, popupContent->height() * 0.2)).toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, firstItemPos, 600);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, firstItemPos, 200);
gifRecorder.waitForFinish();
}
void tst_Gifs::triState_data()
{
QTest::addColumn<QString>("name");
QTest::newRow("checkbox-tristate") << "checkbox-tristate";
QTest::newRow("checkdelegate-tristate") << "checkdelegate-tristate";
}
void tst_Gifs::triState()
{
QFETCH(QString, name);
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(6);
gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-%1.qml").arg(name));
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QQuickItem *english = window->property("english").value<QQuickItem*>();
QVERIFY(english);
QQuickItem *norwegian = window->property("norwegian").value<QQuickItem*>();
QVERIFY(norwegian);
const QPoint englishCenter = english->mapToScene(
QPointF(english->width() / 2, english->height() / 2)).toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, englishCenter, 1000);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, englishCenter, 300);
const QPoint norwegianCenter = norwegian->mapToScene(
QPointF(norwegian->width() / 2, norwegian->height() / 2)).toPoint();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, norwegianCenter, 1000);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, norwegianCenter, 300);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, norwegianCenter, 1000);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, norwegianCenter, 300);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, englishCenter, 1000);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, englishCenter, 300);
gifRecorder.waitForFinish();
}
void tst_Gifs::scrollBar()
{
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(6);
gifRecorder.setQmlFileName("qtquickcontrols2-scrollbar.qml");
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QQuickItem *scrollBar = window->property("scrollBar").value<QQuickItem*>();
QVERIFY(scrollBar);
// Flick in the center of the screen to show that there's a scroll bar.
const QPoint lhsWindowBottom = QPoint(0, window->height() - 1);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, lhsWindowBottom, 100);
QTest::mouseMove(window, lhsWindowBottom - QPoint(0, 10), 30);
QTest::mouseMove(window, lhsWindowBottom - QPoint(0, 30), 30);
QTest::mouseMove(window, lhsWindowBottom - QPoint(0, 60), 30);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, lhsWindowBottom - QPoint(0, 100), 30);
// Scroll with the scroll bar.
const QPoint rhsWindowBottom = QPoint(window->width() - 1, window->height() - 1);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, rhsWindowBottom, 2000);
const QPoint rhsWindowTop = QPoint(window->width() - 1, 1);
moveSmoothly(window, rhsWindowBottom, rhsWindowTop,
qAbs(rhsWindowTop.y() - rhsWindowBottom.y()), QEasingCurve::InCubic, 10);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, rhsWindowTop, 20);
gifRecorder.waitForFinish();
}
void tst_Gifs::scrollBarSnap_data()
{
QTest::addColumn<QString>("gifBaseName");
QTest::addColumn<int>("snapMode");
QTest::newRow("NoSnap") << "qtquickcontrols2-scrollbar-nosnap" << 0;
QTest::newRow("SnapAlways") << "qtquickcontrols2-scrollbar-snapalways" << 1;
QTest::newRow("SnapOnRelease") << "qtquickcontrols2-scrollbar-snaponrelease" << 2;
}
void tst_Gifs::scrollBarSnap()
{
QFETCH(QString, gifBaseName);
QFETCH(int, snapMode);
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(8);
gifRecorder.setHighQuality(true);
gifRecorder.setQmlFileName("qtquickcontrols2-scrollbar-snap.qml");
gifRecorder.setOutputFileBaseName(gifBaseName);
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QQuickItem *scrollbar = window->property("scrollbar").value<QQuickItem*>();
QVERIFY(scrollbar);
QVERIFY(scrollbar->setProperty("snapMode", QVariant(snapMode)));
QCOMPARE(scrollbar->property("snapMode").toInt(), snapMode);
const QPoint startPos(scrollbar->property("leftPadding").toReal(), scrollbar->y() + scrollbar->height() / 2);
const int availableWidth = scrollbar->property("availableWidth").toReal();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, startPos, 200);
const QPoint pos1 = startPos + QPoint(availableWidth * 0.3, 0);
moveSmoothly(window, startPos, pos1, pos1.x() - startPos.x(), QEasingCurve::OutQuint, 30);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos1, 0);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, pos1, 400);
const QPoint pos2 = startPos + QPoint(availableWidth * 0.6, 0);
moveSmoothly(window, pos1, pos2, pos2.x() - pos1.x(), QEasingCurve::OutQuint, 30);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, pos2, 0);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, pos2, 400);
moveSmoothly(window, pos2, startPos, pos2.x() - startPos.x(), QEasingCurve::OutQuint, 30);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, startPos, 0);
gifRecorder.waitForFinish();
}
void tst_Gifs::scrollIndicator()
{
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(6);
gifRecorder.setQmlFileName("qtquickcontrols2-scrollindicator.qml");
gifRecorder.start();
// Flick in the center of the screen to show that there's a scroll indicator.
QQuickWindow *window = gifRecorder.window();
const QPoint windowBottom = QPoint(0, window->height() - 1);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, windowBottom, 100);
QTest::mouseMove(window, windowBottom - QPoint(0, 10), 30);
QTest::mouseMove(window, windowBottom - QPoint(0, 30), 30);
QTest::mouseMove(window, windowBottom - QPoint(0, 60), 30);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, windowBottom - QPoint(0, 100), 30);
// Scroll back down.
const QPoint windowTop = QPoint(0, 0);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, windowTop, 2000);
QTest::mouseMove(window, windowTop + QPoint(0, 10), 30);
QTest::mouseMove(window, windowTop + QPoint(0, 30), 30);
QTest::mouseMove(window, windowTop + QPoint(0, 60), 30);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, windowTop + QPoint(0, 100), 30);
gifRecorder.waitForFinish();
}
void tst_Gifs::progressBar_data()
{
QTest::addColumn<bool>("indeterminate");
QTest::newRow("indeterminate:false") << false;
QTest::newRow("indeterminate:true") << true;
}
void tst_Gifs::progressBar()
{
QFETCH(bool, indeterminate);
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(4);
gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-progressbar%1").arg(
indeterminate ? QLatin1String("-indeterminate.qml") : QLatin1String(".qml")));
gifRecorder.start();
gifRecorder.waitForFinish();
}
void tst_Gifs::stackView_data()
{
QTest::addColumn<QString>("name");
QTest::addColumn<int>("duration");
QTest::newRow("push") << "push" << 8;
QTest::newRow("pop") << "pop" << 6;
QTest::newRow("unwind") << "unwind" << 6;
QTest::newRow("replace") << "replace" << 6;
}
void tst_Gifs::stackView()
{
QFETCH(QString, name);
QFETCH(int, duration);
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(duration);
gifRecorder.setHighQuality(true);
gifRecorder.setQmlFileName(QString::fromLatin1("qtquickcontrols2-stackview-%1.qml").arg(name));
gifRecorder.start();
gifRecorder.waitForFinish();
}
void tst_Gifs::drawer()
{
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(4);
gifRecorder.setHighQuality(true);
gifRecorder.setQmlFileName("qtquickcontrols2-drawer.qml");
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QObject *drawer = window->property("drawer").value<QObject*>();
qreal width = drawer->property("width").toReal();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(1, 1), 100);
moveSmoothly(window, QPoint(1, 1), QPoint(width, 1), width, QEasingCurve::InOutBack, 1);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(width, 1), 30);
QTest::qWait(1000);
QMetaObject::invokeMethod(drawer, "close");
gifRecorder.waitForFinish();
}
void tst_Gifs::delayButton()
{
GifRecorder gifRecorder;
gifRecorder.setDataDirPath(dataDirPath);
gifRecorder.setOutputDir(outputDir);
gifRecorder.setRecordingDuration(9);
gifRecorder.setQmlFileName("qtquickcontrols2-delaybutton.qml");
gifRecorder.start();
QQuickWindow *window = gifRecorder.window();
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 0);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 1500);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 1000);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 200);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 1500);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 1730);
QTest::mousePress(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 1000);
QTest::mouseRelease(window, Qt::LeftButton, Qt::NoModifier, QPoint(window->width() / 2, window->height() / 2), 2070); // 0.69 * 3000
gifRecorder.waitForFinish();
}
QTEST_MAIN(tst_Gifs)
#include "tst_gifs.moc"