aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickcontrolstestutils/dialogstestutils_p.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/quickcontrolstestutils/dialogstestutils_p.h')
-rw-r--r--src/quickcontrolstestutils/dialogstestutils_p.h158
1 files changed, 158 insertions, 0 deletions
diff --git a/src/quickcontrolstestutils/dialogstestutils_p.h b/src/quickcontrolstestutils/dialogstestutils_p.h
new file mode 100644
index 0000000000..dfa46fdd94
--- /dev/null
+++ b/src/quickcontrolstestutils/dialogstestutils_p.h
@@ -0,0 +1,158 @@
+// Copyright (C) 2021 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
+
+#ifndef DIALOGSTESTUTILS_H
+#define DIALOGSTESTUTILS_H
+
+//
+// W A R N I N G
+// -------------
+//
+// This file is not part of the Qt API. It exists purely as an
+// implementation detail. This header file may change from version to
+// version without notice, or even be removed.
+//
+// We mean it.
+//
+
+#include <QtQuickTemplates2/private/qquickapplicationwindow_p.h>
+
+#include <QtQuickTestUtils/private/qmlutils_p.h>
+#include <QtQuickTestUtils/private/visualtestutils_p.h>
+
+// We need these for Windows, because FolderListModel returns a lowercase drive letter; e.g.:
+// "file:///c:/blah.txt", whereas other API returns "file:///C:/blah.txt".
+#define COMPARE_URL(url1, url2) \
+ QCOMPARE(QFileInfo(url1.toLocalFile()).absoluteFilePath(), QFileInfo(url2.toLocalFile()).absoluteFilePath());
+
+// Store a copy of the arguments in case { ... } list initializer syntax is used as an argument,
+// which could result in two different lists being created and passed to std::transform()
+// (and would also require it to be enclosed in parentheses everywhere it's used).
+#define COMPARE_URLS(actualUrls, expectedUrls) \
+{ \
+ const QList<QUrl> actualUrlsCopy = actualUrls; \
+ QList<QString> actualPaths; \
+ std::transform(actualUrlsCopy.begin(), actualUrlsCopy.end(), std::back_insert_iterator(actualPaths), \
+ [](const QUrl &url) { return QFileInfo(url.toLocalFile()).absoluteFilePath(); }); \
+ const QList<QUrl> expectedUrlsCopy = expectedUrls; \
+ QList<QString> expectedPaths; \
+ std::transform(expectedUrlsCopy.begin(), expectedUrlsCopy.end(), std::back_insert_iterator(expectedPaths), \
+ [](const QUrl &url) { return QFileInfo(url.toLocalFile()).absoluteFilePath(); }); \
+ QCOMPARE(actualPaths, expectedPaths); \
+}
+
+#define OPEN_QUICK_DIALOG() \
+QVERIFY2(dialogHelper.isWindowInitialized(), dialogHelper.failureMessage()); \
+QVERIFY(dialogHelper.waitForWindowActive()); \
+QVERIFY(dialogHelper.openDialog()); \
+QTRY_VERIFY(dialogHelper.isQuickDialogOpen());
+
+#define CLOSE_QUICK_DIALOG() \
+ do { \
+ dialogHelper.dialog->close(); \
+ QVERIFY(!dialogHelper.dialog->isVisible()); \
+ QTRY_VERIFY(!dialogHelper.quickDialog->isVisible()); \
+ } while (false)
+
+QT_BEGIN_NAMESPACE
+class QWindow;
+
+class QQuickListView;
+
+class QQuickAbstractButton;
+
+class QQuickDialogButtonBox;
+class QQuickFolderBreadcrumbBar;
+
+namespace QQuickDialogTestUtils
+{
+
+// Saves duplicating a bunch of code in every test.
+template<typename DialogType, typename QuickDialogType>
+class DialogTestHelper
+{
+public:
+ DialogTestHelper(QQmlDataTest *testCase, const QString &testFilePath,
+ const QStringList &qmlImportPaths = {}, const QVariantMap &initialProperties = {}) :
+ appHelper(testCase, testFilePath, initialProperties, qmlImportPaths)
+ {
+ if (!appHelper.ready)
+ return;
+
+ dialog = appHelper.window->property("dialog").value<DialogType*>();
+ if (!dialog) {
+ appHelper.errorMessage = "\"dialog\" property is not valid";
+ return;
+ }
+
+ appHelper.window->show();
+ appHelper.window->requestActivate();
+ }
+
+ Q_REQUIRED_RESULT bool isWindowInitialized() const
+ {
+ return appHelper.ready;
+ }
+
+ Q_REQUIRED_RESULT bool waitForWindowActive()
+ {
+ return QTest::qWaitForWindowActive(appHelper.window);
+ }
+
+ /*
+ Opens the dialog. For non-native dialogs, it is necessary to ensure that
+ isQuickDialogOpen() returns true before trying to access its internals.
+ */
+ virtual bool openDialog()
+ {
+ dialog->open();
+ if (!dialog->isVisible()) {
+ appHelper.errorMessage = "Dialog is not visible";
+ return false;
+ }
+
+ // We might want to call this function more than once,
+ // and we only need to get these members the first time.
+ if (!quickDialog) {
+ quickDialog = appHelper.window->findChild<QuickDialogType*>();
+ if (!quickDialog) {
+ appHelper.errorMessage = "Can't find Qt Quick-based dialog";
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ bool isQuickDialogOpen() const
+ {
+ return quickDialog->isOpened();
+ }
+
+ QQuickWindow *window() const
+ {
+ return appHelper.window;
+ }
+
+ const char *failureMessage() const
+ {
+ return appHelper.errorMessage.constData();
+ }
+
+ QQuickVisualTestUtils::QQuickApplicationHelper appHelper;
+ DialogType *dialog = nullptr;
+ QuickDialogType *quickDialog = nullptr;
+};
+
+bool verifyFileDialogDelegates(QQuickListView *fileDialogListView, const QStringList &expectedFiles, QString &failureMessage);
+
+bool verifyBreadcrumbDelegates(QQuickFolderBreadcrumbBar *breadcrumbBar, const QUrl &expectedFolder, QString &failureMessage);
+
+QQuickAbstractButton *findDialogButton(QQuickDialogButtonBox *box, const QString &buttonText);
+
+void enterText(QWindow *window, const QString &textToEnter);
+}
+
+QT_END_NAMESPACE
+
+#endif // DIALOGSTESTUTILS_H