summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets')
-rw-r--r--tests/auto/widgets/accessibility/tst_accessibility.cpp84
-rw-r--r--tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp4
-rw-r--r--tests/auto/widgets/origins/BLACKLIST3
-rw-r--r--tests/auto/widgets/origins/tst_origins.cpp22
-rw-r--r--tests/auto/widgets/proxypac/proxypac.pro4
-rw-r--r--tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp48
-rw-r--r--tests/auto/widgets/qwebenginepage/BLACKLIST12
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp335
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp56
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp287
-rw-r--r--tests/auto/widgets/schemes/tst_schemes.cpp76
-rw-r--r--tests/auto/widgets/spellchecking/tst_spellchecking.cpp8
-rw-r--r--tests/auto/widgets/util.h2
13 files changed, 652 insertions, 289 deletions
diff --git a/tests/auto/widgets/accessibility/tst_accessibility.cpp b/tests/auto/widgets/accessibility/tst_accessibility.cpp
index d69a4c0a7..5f472332f 100644
--- a/tests/auto/widgets/accessibility/tst_accessibility.cpp
+++ b/tests/auto/widgets/accessibility/tst_accessibility.cpp
@@ -20,9 +20,13 @@
#include <qtest.h>
#include "../util.h"
+#include <QHBoxLayout>
+#include <QMainWindow>
+
#include <qaccessible.h>
#include <qwebengineview.h>
#include <qwebenginepage.h>
+#include <qwebenginesettings.h>
#include <qwidget.h>
class tst_Accessibility : public QObject
@@ -38,6 +42,8 @@ public Q_SLOTS:
private Q_SLOTS:
void noPage();
void hierarchy();
+ void focusChild();
+ void focusChild_data();
void text();
void value();
void roles_data();
@@ -142,6 +148,80 @@ void tst_Accessibility::hierarchy()
QCOMPARE(input, child);
}
+void tst_Accessibility::focusChild_data()
+{
+ QTest::addColumn<QString>("interfaceName");
+ QTest::addColumn<QVector<QAccessible::Role>>("ancestorRoles");
+
+ QTest::newRow("QWebEngineView") << QString("QWebEngineView") << QVector<QAccessible::Role>({QAccessible::Client});
+ QTest::newRow("RenderWidgetHostViewQtDelegate") << QString("RenderWidgetHostViewQtDelegate") << QVector<QAccessible::Role>({QAccessible::Client});
+ QTest::newRow("QMainWindow") << QString("QMainWindow") << QVector<QAccessible::Role>({QAccessible::Window, QAccessible::Client /* central widget */, QAccessible::Client /* view */});
+}
+
+void tst_Accessibility::focusChild()
+{
+ auto traverseToWebDocumentAccessibleInterface = [](QAccessibleInterface *iface) -> QAccessibleInterface * {
+ QFETCH(QVector<QAccessible::Role>, ancestorRoles);
+ for (int i = 0; i < ancestorRoles.size(); ++i) {
+ if (iface->childCount() == 0 || iface->role() != ancestorRoles[i])
+ return nullptr;
+ iface = iface->child(0);
+ }
+
+ if (iface->role() != QAccessible::WebDocument)
+ return nullptr;
+
+ return iface;
+ };
+
+ QMainWindow mainWindow;
+ QWebEngineView *webView = new QWebEngineView;
+ QWidget *centralWidget = new QWidget;
+ QHBoxLayout *centralLayout = new QHBoxLayout;
+ centralWidget->setLayout(centralLayout);
+ mainWindow.setCentralWidget(centralWidget);
+ centralLayout->addWidget(webView);
+
+ mainWindow.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mainWindow));
+
+ webView->settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
+ webView->setHtml("<html><body>" \
+ "<input id='input1' type='text' value='some text'/>" \
+ "</body></html>");
+ webView->show();
+ QSignalSpy spyFinished(webView, &QWebEngineView::loadFinished);
+ QVERIFY(spyFinished.wait());
+
+ QVERIFY(webView->focusWidget());
+ QAccessibleInterface *iface = nullptr;
+ QFETCH(QString, interfaceName);
+ if (interfaceName == "QWebEngineView")
+ iface = QAccessible::queryAccessibleInterface(webView);
+ else if (interfaceName == "RenderWidgetHostViewQtDelegate")
+ iface = QAccessible::queryAccessibleInterface(webView->focusWidget());
+ else if (interfaceName == "QMainWindow")
+ iface = QAccessible::queryAccessibleInterface(&mainWindow);
+ QVERIFY(iface);
+
+ // Make sure the input field does not have the focus.
+ evaluateJavaScriptSync(webView->page(), "document.getElementById('input1').blur()");
+ QTRY_VERIFY(evaluateJavaScriptSync(webView->page(), "document.activeElement.id").toString().isEmpty());
+
+ QVERIFY(iface->focusChild());
+ QTRY_COMPARE(iface->focusChild()->role(), QAccessible::WebDocument);
+ QCOMPARE(traverseToWebDocumentAccessibleInterface(iface), iface->focusChild());
+
+ // Set active focus on the input field.
+ evaluateJavaScriptSync(webView->page(), "document.getElementById('input1').focus()");
+ QTRY_COMPARE(evaluateJavaScriptSync(webView->page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
+
+ QVERIFY(iface->focusChild());
+ QTRY_COMPARE(iface->focusChild()->role(), QAccessible::EditableText);
+ // <html> -> <body> -> <input>
+ QCOMPARE(traverseToWebDocumentAccessibleInterface(iface)->child(0)->child(0), iface->focusChild());
+}
+
void tst_Accessibility::text()
{
QWebEngineView webView;
@@ -259,7 +339,7 @@ void tst_Accessibility::roles_data()
QTest::newRow("AX_ROLE_ABBR") << QString("<abbr>a</abbr>") << false << QAccessible::StaticText;
QTest::newRow("AX_ROLE_ALERT") << QString("<div role='alert'>alert</div>") << true << QAccessible::AlertMessage;
QTest::newRow("AX_ROLE_ALERT_DIALOG") << QString("<div role='alertdialog'>alert</div>") << true << QAccessible::AlertMessage;
- //QTest::newRow("AX_ROLE_ANCHOR") << QString("<a>target</a>") << false << QAccessible::Link; // FIXME: The test case might be wrong (see https://codereview.chromium.org/2713193003)
+ QTest::newRow("AX_ROLE_ANCHOR") << QString("<a id='a'>Chapter a</a>") << false << QAccessible::Link;
QTest::newRow("AX_ROLE_ANNOTATION") << QString("<rt>a</rt>") << false << QAccessible::StaticText;
QTest::newRow("AX_ROLE_APPLICATION") << QString("<div role='application'>landmark</div>") << true << QAccessible::Document;
QTest::newRow("AX_ROLE_ARTICLE") << QString("<article>a</article>") << true << QAccessible::Section;
@@ -365,7 +445,7 @@ void tst_Accessibility::roles_data()
//QTest::newRow("AX_ROLE_TABLE_HEADER_CONTAINER"); // No mapping to ARIA role
QTest::newRow("AX_ROLE_TAB") << QString("<div role='tab'>a</div>") << true << QAccessible::PageTab;
QTest::newRow("AX_ROLE_TAB_LIST") << QString("<div role='tablist'>a</div>") << true << QAccessible::PageTabList;
- QTest::newRow("AX_ROLE_TAB_PANEL") << QString("<div role='tab'>a</div>") << true << QAccessible::PageTab;
+ QTest::newRow("AX_ROLE_TAB_PANEL") << QString("<div role='tabpanel'>a</div>") << true << QAccessible::Pane;
QTest::newRow("AX_ROLE_TERM") << QString("<div role='term'>a</div>") << true << QAccessible::StaticText;
QTest::newRow("AX_ROLE_TEXT_FIELD") << QString("<input type='text'></input>") << false << QAccessible::EditableText;
QTest::newRow("AX_ROLE_TIME") << QString("<time>a</time>") << false << QAccessible::Clock;
diff --git a/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp b/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp
index 1469ddb15..46038cdc6 100644
--- a/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp
+++ b/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp
@@ -522,10 +522,10 @@ void tst_FaviconManager::touchIconWithSameURL()
"<link rel='icon' type='image/png' href='" + icon + "'/>"
"<link rel='apple-touch-icon' type='image/png' href='" + icon + "'/>"
"</html>");
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
// The default favicon has to be loaded even if its URL is also set as a touch icon while touch icons are disabled.
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QCOMPARE(m_page->iconUrl().toString(), icon);
QTRY_COMPARE(iconChangedSpy.count(), 1);
diff --git a/tests/auto/widgets/origins/BLACKLIST b/tests/auto/widgets/origins/BLACKLIST
new file mode 100644
index 000000000..db858f11e
--- /dev/null
+++ b/tests/auto/widgets/origins/BLACKLIST
@@ -0,0 +1,3 @@
+# QTBUG-81556
+[mixedXHR]
+*
diff --git a/tests/auto/widgets/origins/tst_origins.cpp b/tests/auto/widgets/origins/tst_origins.cpp
index c63f4d690..e3927f763 100644
--- a/tests/auto/widgets/origins/tst_origins.cpp
+++ b/tests/auto/widgets/origins/tst_origins.cpp
@@ -481,6 +481,8 @@ void tst_Origins::subdirWithoutAccess()
{
ScopedAttribute sa(m_page->settings(), QWebEngineSettings::LocalContentCanAccessFileUrls, false);
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
QVERIFY(verifyLoad(QSL("file:" THIS_DIR "resources/subdir/index.html")));
QCOMPARE(eval(QSL("msg[0]")), QVariant());
QCOMPARE(eval(QSL("msg[1]")), QVariant());
@@ -507,22 +509,28 @@ void tst_Origins::mixedSchemes()
QVERIFY(verifyLoad(QSL("file:" THIS_DIR "resources/mixedSchemes.html")));
eval(QSL("setIFrameUrl('file:" THIS_DIR "resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('qrc:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('tst:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
QVERIFY(verifyLoad(QSL("qrc:/resources/mixedSchemes.html")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('file:" THIS_DIR "resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
eval(QSL("setIFrameUrl('qrc:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('tst:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
QVERIFY(verifyLoad(QSL("tst:/resources/mixedSchemes.html")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Not allowed to load local resource")));
eval(QSL("setIFrameUrl('file:" THIS_DIR "resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("cannotLoad")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('qrc:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
eval(QSL("setIFrameUrl('tst:/resources/mixedSchemes_frame.html')"));
@@ -531,36 +539,47 @@ void tst_Origins::mixedSchemes()
QVERIFY(verifyLoad(QSL("PathSyntax:/resources/mixedSchemes.html")));
eval(QSL("setIFrameUrl('PathSyntax:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Not allowed to load local resource")));
eval(QSL("setIFrameUrl('PathSyntax-Local:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("cannotLoad")));
eval(QSL("setIFrameUrl('PathSyntax-LocalAccessAllowed:/resources/mixedSchemes_frame.html')"));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('PathSyntax-NoAccessAllowed:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
QVERIFY(verifyLoad(QSL("PathSyntax-LocalAccessAllowed:/resources/mixedSchemes.html")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('PathSyntax:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('PathSyntax-Local:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
eval(QSL("setIFrameUrl('PathSyntax-LocalAccessAllowed:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('PathSyntax-NoAccessAllowed:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
QVERIFY(verifyLoad(QSL("PathSyntax-NoAccessAllowed:/resources/mixedSchemes.html")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('PathSyntax:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Not allowed to load local resource")));
eval(QSL("setIFrameUrl('PathSyntax-Local:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("cannotLoad")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('PathSyntax-LocalAccessAllowed:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('PathSyntax-NoAccessAllowed:/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
QVERIFY(verifyLoad(QSL("HostSyntax://a/resources/mixedSchemes.html")));
eval(QSL("setIFrameUrl('HostSyntax://a/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('HostSyntax://b/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
}
@@ -569,14 +588,17 @@ void tst_Origins::mixedSchemes()
void tst_Origins::mixedSchemesWithCsp()
{
QVERIFY(verifyLoad(QSL("HostSyntax://a/resources/mixedSchemesWithCsp.html")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("violates the following Content Security Policy")));
eval(QSL("setIFrameUrl('HostSyntax://a/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("violates the following Content Security Policy")));
eval(QSL("setIFrameUrl('HostSyntax://b/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
QVERIFY(verifyLoad(QSL("HostSyntax-ContentSecurityPolicyIgnored://a/resources/mixedSchemesWithCsp.html")));
eval(QSL("setIFrameUrl('HostSyntax-ContentSecurityPolicyIgnored://a/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadAndAccess")));
+ QTest::ignoreMessage(QtSystemMsg, QRegularExpression(QSL("Uncaught SecurityError")));
eval(QSL("setIFrameUrl('HostSyntax-ContentSecurityPolicyIgnored://b/resources/mixedSchemes_frame.html')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("canLoadButNotAccess")));
}
diff --git a/tests/auto/widgets/proxypac/proxypac.pro b/tests/auto/widgets/proxypac/proxypac.pro
index 4dbcd9365..2aacb4366 100644
--- a/tests/auto/widgets/proxypac/proxypac.pro
+++ b/tests/auto/widgets/proxypac/proxypac.pro
@@ -4,8 +4,10 @@ HEADERS += proxyserver.h
SOURCES += proxyserver.cpp
proxy_pac.name = QTWEBENGINE_CHROMIUM_FLAGS
+
+win32:proxy_pac.value = --proxy-pac-url="file:///$$PWD/proxy.pac"
+else:proxy_pac.value = --proxy-pac-url="file://$$PWD/proxy.pac"
boot2qt:proxy_pac.value = "--single-process --no-sandbox --proxy-pac-url=file://$$PWD/proxy.pac"
-else: proxy_pac.value = --proxy-pac-url="file://$$PWD/proxy.pac"
QT_TOOL_ENV += proxy_pac
diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
index d34e3cefe..55d8ac6e8 100644
--- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
+++ b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
@@ -80,6 +80,7 @@ private Q_SLOTS:
#if QT_DEPRECATED_SINCE(5, 14)
void downloadPathValidation();
#endif
+ void downloadToDirectoryWithFileName_data();
void downloadToDirectoryWithFileName();
private:
@@ -622,14 +623,17 @@ void tst_QWebEngineDownloadItem::downloadTwoLinks()
void tst_QWebEngineDownloadItem::downloadPage_data()
{
+ QTest::addColumn<bool>("saveWithPageAction");
QTest::addColumn<QWebEngineDownloadItem::SavePageFormat>("savePageFormat");
- QTest::newRow("SingleHtmlSaveFormat") << QWebEngineDownloadItem::SingleHtmlSaveFormat;
- QTest::newRow("CompleteHtmlSaveFormat") << QWebEngineDownloadItem::CompleteHtmlSaveFormat;
- QTest::newRow("MimeHtmlSaveFormat") << QWebEngineDownloadItem::MimeHtmlSaveFormat;
+ QTest::newRow("SingleHtmlSaveFormat") << false << QWebEngineDownloadItem::SingleHtmlSaveFormat;
+ QTest::newRow("CompleteHtmlSaveFormat") << false << QWebEngineDownloadItem::CompleteHtmlSaveFormat;
+ QTest::newRow("MimeHtmlSaveFormat") << false << QWebEngineDownloadItem::MimeHtmlSaveFormat;
+ QTest::newRow("SavePageAction") << true << QWebEngineDownloadItem::MimeHtmlSaveFormat;
}
void tst_QWebEngineDownloadItem::downloadPage()
{
+ QFETCH(bool, saveWithPageAction);
QFETCH(QWebEngineDownloadItem::SavePageFormat, savePageFormat);
// Set up HTTP server
@@ -649,12 +653,12 @@ void tst_QWebEngineDownloadItem::downloadPage()
// Set up profile and download handler
QTemporaryDir tmpDir;
QVERIFY(tmpDir.isValid());
- QString downloadPath = tmpDir.path() + QStringLiteral("/test.html");
+ QString downloadFileName("test.html"), downloadPath = tmpDir.filePath(downloadFileName);
QUrl downloadUrl = m_server->url("/");
int acceptedCount = 0;
int finishedCount = 0;
ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
- QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadInProgress);
+ QCOMPARE(item->state(), saveWithPageAction ? QWebEngineDownloadItem::DownloadRequested : QWebEngineDownloadItem::DownloadInProgress);
QCOMPARE(item->isFinished(), false);
QCOMPARE(item->totalBytes(), -1);
QCOMPARE(item->receivedBytes(), 0);
@@ -663,11 +667,19 @@ void tst_QWebEngineDownloadItem::downloadPage()
QCOMPARE(item->isSavePageDownload(), true);
// FIXME(juvaldma): why is mimeType always the same?
QCOMPARE(item->mimeType(), QStringLiteral("application/x-mimearchive"));
- QCOMPARE(QDir(item->downloadDirectory()).filePath(item->downloadFileName()), downloadPath);
QCOMPARE(item->savePageFormat(), savePageFormat);
QCOMPARE(item->url(), downloadUrl);
QCOMPARE(item->page(), m_page);
- // no need to call item->accept()
+
+ if (saveWithPageAction) {
+ QVERIFY(!item->downloadDirectory().isEmpty());
+ QVERIFY(!item->downloadFileName().isEmpty());
+ item->setDownloadDirectory(tmpDir.path());
+ item->setDownloadFileName(downloadFileName);
+ item->accept();
+ } // save with explicit path accepts download automatically
+
+ QCOMPARE(QDir(item->downloadDirectory()).filePath(item->downloadFileName()), downloadPath);
connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
@@ -697,7 +709,11 @@ void tst_QWebEngineDownloadItem::downloadPage()
QCOMPARE(indexRequestCount, 1);
// Save some HTML
- m_page->save(downloadPath, savePageFormat);
+ if (saveWithPageAction)
+ m_page->triggerAction(QWebEnginePage::SavePage);
+ else
+ m_page->save(downloadPath, savePageFormat);
+
QTRY_COMPARE(acceptedCount, 1);
QTRY_COMPARE(finishedCount, 1);
QFile file(downloadPath);
@@ -1256,8 +1272,17 @@ void tst_QWebEngineDownloadItem::downloadPathValidation()
}
#endif
+void tst_QWebEngineDownloadItem::downloadToDirectoryWithFileName_data()
+{
+ QTest::addColumn<bool>("setDirectoryFirst");
+
+ QTest::newRow("setDirectoryFirst") << true;
+ QTest::newRow("setFileNameFirst") << false;
+}
+
void tst_QWebEngineDownloadItem::downloadToDirectoryWithFileName()
{
+ QFETCH(bool, setDirectoryFirst);
QString downloadDirectory;
QString downloadFileName;
QString downloadedFilePath;
@@ -1287,7 +1312,7 @@ void tst_QWebEngineDownloadItem::downloadToDirectoryWithFileName()
// Set up profile and download handler
ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
- if (!downloadDirectory.isEmpty()) {
+ if (!downloadDirectory.isEmpty() && setDirectoryFirst) {
item->setDownloadDirectory(downloadDirectory);
QCOMPARE(item->downloadDirectory(), downloadDirectory);
}
@@ -1297,6 +1322,11 @@ void tst_QWebEngineDownloadItem::downloadToDirectoryWithFileName()
QCOMPARE(item->downloadFileName(), downloadFileName);
}
+ if (!downloadDirectory.isEmpty() && !setDirectoryFirst) {
+ item->setDownloadDirectory(downloadDirectory);
+ QCOMPARE(item->downloadDirectory(), downloadDirectory);
+ }
+
QCOMPARE(item->path(), QDir(item->downloadDirectory()).filePath(item->downloadFileName()));
item->accept();
diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
index 7857ee818..3053876d4 100644
--- a/tests/auto/widgets/qwebenginepage/BLACKLIST
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -3,6 +3,14 @@ osx
[mouseMovementProperties]
windows
+macos # Can't move cursor (QTBUG-76312)
-[fullScreenRequested]
-windows
+# QTBUG-81614
+[setHtmlWithBaseURL]
+*
+
+[devTools]
+msvc-2019
+
+[setLifecycleStateWithDevTools]
+msvc-2019
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 27aa7a1f7..7fdf897ca 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -225,9 +225,14 @@ private Q_SLOTS:
void editActionsWithoutSelection();
void customUserAgentInNewTab();
+ void renderProcessCrashed();
+ void renderProcessPid();
private:
static QPoint elementCenter(QWebEnginePage *page, const QString &id);
+ static bool isFalseJavaScriptResult(QWebEnginePage *page, const QString &javaScript);
+ static bool isTrueJavaScriptResult(QWebEnginePage *page, const QString &javaScript);
+ static bool isEmptyListJavaScriptResult(QWebEnginePage *page, const QString &javaScript);
QWebEngineView* m_view;
QWebEnginePage* m_page;
@@ -754,20 +759,39 @@ void tst_QWebEnginePage::textSelection()
void tst_QWebEnginePage::backActionUpdate()
{
QWebEngineView view;
+ view.resize(640, 480);
+ view.show();
+
QWebEnginePage *page = view.page();
+ QSignalSpy loadSpy(page, &QWebEnginePage::loadFinished);
QAction *action = page->action(QWebEnginePage::Back);
QVERIFY(!action->isEnabled());
- QSignalSpy loadSpy(page, SIGNAL(loadFinished(bool)));
- QUrl url = QUrl("qrc:///resources/framedindex.html");
- page->load(url);
+
+ page->load(QUrl("qrc:///resources/framedindex.html"));
QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
QVERIFY(!action->isEnabled());
- QTest::mouseClick(&view, Qt::LeftButton, 0, QPoint(10, 10));
- QEXPECT_FAIL("", "Behavior change: Load signals are emitted only for the main frame in QtWebEngine.", Continue);
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 2, 100);
- QEXPECT_FAIL("", "FIXME: Mouse events aren't passed from the QWebEngineView down to the RWHVQtDelegateWidget", Continue);
- QVERIFY(action->isEnabled());
+ auto firstAnchorCenterInFrame = [](QWebEnginePage *page, const QString &frameName) {
+ QVariantList rectList = evaluateJavaScriptSync(page,
+ "(function(){"
+ "var frame = document.getElementsByName('" + frameName + "')[0];"
+ "var anchor = frame.contentDocument.getElementsByTagName('a')[0];"
+ "var rect = anchor.getBoundingClientRect();"
+ "return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
+ "})()").toList();
+
+ if (rectList.count() != 2) {
+ qWarning("firstAnchorCenterInFrame failed.");
+ return QPoint();
+ }
+
+ return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
+ };
+
+ QVERIFY(evaluateJavaScriptSync(page, "document.getElementsByName('frame_b')[0].contentDocument == undefined").toBool());
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, firstAnchorCenterInFrame(page, "frame_c"));
+ QTRY_VERIFY(evaluateJavaScriptSync(page, "document.getElementsByName('frame_b')[0].contentDocument != undefined").toBool());
+ QTRY_VERIFY(action->isEnabled());
}
void tst_QWebEnginePage::localStorageVisibility()
@@ -947,7 +971,7 @@ void tst_QWebEnginePage::findText()
{
CallbackSpy<bool> callbackSpy;
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
- m_view->findText("", 0, callbackSpy.ref());
+ m_view->findText("", {}, callbackSpy.ref());
QVERIFY(callbackSpy.wasCalled());
QCOMPARE(signalSpy.count(), 1);
QTRY_COMPARE(m_view->selectedText(), QString("foo bar"));
@@ -958,7 +982,7 @@ void tst_QWebEnginePage::findText()
{
CallbackSpy<bool> callbackSpy;
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
- m_view->findText("Will not be found", 0, callbackSpy.ref());
+ m_view->findText("Will not be found", {}, callbackSpy.ref());
QCOMPARE(callbackSpy.waitForResult(), false);
QTRY_COMPARE(signalSpy.count(), 1);
auto result = signalSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
@@ -975,7 +999,7 @@ void tst_QWebEnginePage::findText()
{
CallbackSpy<bool> callbackSpy;
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
- m_view->findText("foo", 0, callbackSpy.ref());
+ m_view->findText("foo", {}, callbackSpy.ref());
QVERIFY(callbackSpy.waitForResult());
QTRY_COMPARE(signalSpy.count(), 1);
QTRY_VERIFY(m_view->selectedText().isEmpty());
@@ -986,11 +1010,24 @@ void tst_QWebEnginePage::findText()
{
CallbackSpy<bool> callbackSpy;
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
- m_view->findText("", 0, callbackSpy.ref());
+ m_view->findText("", {}, callbackSpy.ref());
QTRY_VERIFY(callbackSpy.wasCalled());
QTRY_COMPARE(signalSpy.count(), 1);
QTRY_COMPARE(m_view->selectedText(), QString("foo"));
}
+
+ // Invoking startFinding operation for the same text twice. Without any wait, the second one
+ // should interrupt the first one.
+ {
+ QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ m_view->findText("foo", {});
+ m_view->findText("foo", {});
+ QTRY_COMPARE(signalSpy.count(), 2);
+ QTRY_VERIFY(m_view->selectedText().isEmpty());
+
+ QCOMPARE(signalSpy.at(0).value(0).value<QWebEngineFindTextResult>().numberOfMatches(), 0);
+ QCOMPARE(signalSpy.at(1).value(0).value<QWebEngineFindTextResult>().numberOfMatches(), 1);
+ }
}
void tst_QWebEnginePage::findTextResult()
@@ -1039,11 +1076,11 @@ void tst_QWebEnginePage::findTextSuccessiveShouldCallAllCallbacks()
QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
m_view->setHtml(QString("<html><head></head><body><div>abcdefg abcdefg abcdefg abcdefg abcdefg</div></body></html>"));
QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
- m_page->findText("abcde", 0, spy1.ref());
- m_page->findText("abcd", 0, spy2.ref());
- m_page->findText("abc", 0, spy3.ref());
- m_page->findText("ab", 0, spy4.ref());
- m_page->findText("a", 0, spy5.ref());
+ m_page->findText("abcde", {}, spy1.ref());
+ m_page->findText("abcd", {}, spy2.ref());
+ m_page->findText("abc", {}, spy3.ref());
+ m_page->findText("ab", {}, spy4.ref());
+ m_page->findText("a", {}, spy5.ref());
spy5.waitForResult();
QVERIFY(spy1.wasCalled());
QVERIFY(spy2.wasCalled());
@@ -1064,10 +1101,10 @@ void tst_QWebEnginePage::findTextCalledOnMatch()
// CALLBACK
bool callbackCalled = false;
- m_view->page()->findText("foo", 0, [this, &callbackCalled](bool found) {
+ m_view->page()->findText("foo", {}, [this, &callbackCalled](bool found) {
QVERIFY(found);
- m_view->page()->findText("bar", 0, [&callbackCalled](bool found) {
+ m_view->page()->findText("bar", {}, [&callbackCalled](bool found) {
QVERIFY(found);
callbackCalled = true;
});
@@ -1101,7 +1138,7 @@ void tst_QWebEnginePage::findTextActiveMatchOrdinal()
// Iterate over all "foo" matches.
for (int i = 1; i <= 3; ++i) {
- m_view->page()->findText("foo", 0);
+ m_view->page()->findText("foo", {});
QTRY_COMPARE(findTextSpy.count(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 3);
@@ -1109,7 +1146,7 @@ void tst_QWebEnginePage::findTextActiveMatchOrdinal()
}
// The last match is followed by the fist one.
- m_view->page()->findText("foo", 0);
+ m_view->page()->findText("foo", {});
QTRY_COMPARE(findTextSpy.count(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 3);
@@ -1123,14 +1160,14 @@ void tst_QWebEnginePage::findTextActiveMatchOrdinal()
QCOMPARE(result.activeMatch(), 3);
// Finding another word resets the activeMatch.
- m_view->page()->findText("bar", 0);
+ m_view->page()->findText("bar", {});
QTRY_COMPARE(findTextSpy.count(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 2);
QCOMPARE(result.activeMatch(), 1);
// If no match activeMatch is 0.
- m_view->page()->findText("bla", 0);
+ m_view->page()->findText("bla", {});
QTRY_COMPARE(findTextSpy.count(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 0);
@@ -1668,156 +1705,51 @@ void tst_QWebEnginePage::openWindowDefaultSize()
QCOMPARE(requestedGeometry.height(), 100);
}
-class JavaScriptCallbackBase
+bool tst_QWebEnginePage::isFalseJavaScriptResult(QWebEnginePage *page, const QString &javaScript)
{
-public:
- JavaScriptCallbackBase()
- {
- if (watcher)
- QMetaObject::invokeMethod(watcher, "add");
- }
-
- void operator() (const QVariant &result)
- {
- check(result);
- if (watcher)
- QMetaObject::invokeMethod(watcher, "notify");
- }
-
-protected:
- virtual void check(const QVariant &result) = 0;
-
-private:
- friend class JavaScriptCallbackWatcher;
- static QPointer<QObject> watcher;
-};
-
-QPointer<QObject> JavaScriptCallbackBase::watcher = 0;
-
-class JavaScriptCallback : public JavaScriptCallbackBase
-{
-public:
- JavaScriptCallback() { }
- JavaScriptCallback(const QVariant& _expected) : expected(_expected) { }
-
- void check(const QVariant& result) override
- {
- QVERIFY(result.isValid());
- QCOMPARE(result, expected);
- }
-
-private:
- QVariant expected;
-};
-
-class JavaScriptCallbackNull : public JavaScriptCallbackBase
-{
-public:
- void check(const QVariant& result) override
- {
- QVERIFY(result.isNull());
-// FIXME: Returned null values are currently invalid QVariants.
-// QVERIFY(result.isValid());
- }
-};
+ QVariant result = evaluateJavaScriptSync(page, javaScript);
+ return !result.isNull() && result.isValid() && result == QVariant(false);
+}
-class JavaScriptCallbackUndefined : public JavaScriptCallbackBase
+bool tst_QWebEnginePage::isTrueJavaScriptResult(QWebEnginePage *page, const QString &javaScript)
{
-public:
- void check(const QVariant& result) override
- {
- QVERIFY(result.isNull());
- QVERIFY(!result.isValid());
- }
-};
+ QVariant result = evaluateJavaScriptSync(page, javaScript);
+ return !result.isNull() && result.isValid() && result == QVariant(true);
+}
-class JavaScriptCallbackWatcher : public QObject
+bool tst_QWebEnginePage::isEmptyListJavaScriptResult(QWebEnginePage *page, const QString &javaScript)
{
- Q_OBJECT
-public:
- JavaScriptCallbackWatcher()
- {
- Q_ASSERT(!JavaScriptCallbackBase::watcher);
- JavaScriptCallbackBase::watcher = this;
- }
-
- Q_INVOKABLE void add()
- {
- available++;
- }
-
- Q_INVOKABLE void notify()
- {
- called++;
- if (called == available)
- emit allCalled();
- }
-
- bool wait(int maxSeconds = 30)
- {
- if (called == available)
- return true;
-
- QTestEventLoop loop;
- connect(this, SIGNAL(allCalled()), &loop, SLOT(exitLoop()));
- loop.enterLoop(maxSeconds);
- return !loop.timeout();
- }
-
-signals:
- void allCalled();
-
-private:
- int available = 0;
- int called = 0;
-};
-
+ QVariant result = evaluateJavaScriptSync(page, javaScript);
+ return !result.isNull() && result.isValid() && result == QList<QVariant>();
+}
void tst_QWebEnginePage::runJavaScript()
{
TestPage page;
- JavaScriptCallbackWatcher watcher;
-
- JavaScriptCallback callbackBool(QVariant(false));
- page.runJavaScript("false", QWebEngineCallback<const QVariant&>(callbackBool));
-
- JavaScriptCallback callbackInt(QVariant(2));
- page.runJavaScript("2", QWebEngineCallback<const QVariant&>(callbackInt));
-
- JavaScriptCallback callbackDouble(QVariant(2.5));
- page.runJavaScript("2.5", QWebEngineCallback<const QVariant&>(callbackDouble));
-
- JavaScriptCallback callbackString(QVariant(QStringLiteral("Test")));
- page.runJavaScript("\"Test\"", QWebEngineCallback<const QVariant&>(callbackString));
-
- QVariantList list;
- JavaScriptCallback callbackList(list);
- page.runJavaScript("[]", QWebEngineCallback<const QVariant&>(callbackList));
-
+ QVariant result;
QVariantMap map;
- map.insert(QStringLiteral("test"), QVariant(2));
- JavaScriptCallback callbackMap(map);
- page.runJavaScript("var el = {\"test\": 2}; el", QWebEngineCallback<const QVariant&>(callbackMap));
- JavaScriptCallbackNull callbackNull;
- page.runJavaScript("null", QWebEngineCallback<const QVariant&>(callbackNull));
+ QVERIFY(isFalseJavaScriptResult(&page, "false"));
+ QCOMPARE(evaluateJavaScriptSync(&page, "2").toInt(), 2);
+ QCOMPARE(evaluateJavaScriptSync(&page, "2.5").toDouble(), 2.5);
+ QCOMPARE(evaluateJavaScriptSync(&page, "\"Test\"").toString(), "Test");
+ QVERIFY(isEmptyListJavaScriptResult(&page, "[]"));
- JavaScriptCallbackUndefined callbackUndefined;
- page.runJavaScript("undefined", QWebEngineCallback<const QVariant&>(callbackUndefined));
+ map.insert(QStringLiteral("test"), QVariant(2));
+ QCOMPARE(evaluateJavaScriptSync(&page, "var el = {\"test\": 2}; el").toMap(), map);
- JavaScriptCallback callbackDate(QVariant(42.0));
- page.runJavaScript("new Date(42000)", QWebEngineCallback<const QVariant&>(callbackDate));
+ QVERIFY(evaluateJavaScriptSync(&page, "null").isNull());
- JavaScriptCallback callbackBlob(QVariant(QByteArray(8, 0)));
- page.runJavaScript("new ArrayBuffer(8)", QWebEngineCallback<const QVariant&>(callbackBlob));
+ result = evaluateJavaScriptSync(&page, "undefined");
+ QVERIFY(result.isNull() && !result.isValid());
- JavaScriptCallbackUndefined callbackFunction;
- page.runJavaScript("(function(){})", QWebEngineCallback<const QVariant&>(callbackFunction));
+ QCOMPARE(evaluateJavaScriptSync(&page, "new Date(42000)").toDate(), QVariant(42.0).toDate());
+ QCOMPARE(evaluateJavaScriptSync(&page, "new ArrayBuffer(8)").toByteArray(), QByteArray(8, 0));
- JavaScriptCallback callbackPromise(QVariant(QVariantMap{}));
- page.runJavaScript("new Promise(function(){})", QWebEngineCallback<const QVariant&>(callbackPromise));
+ result = evaluateJavaScriptSync(&page, "(function(){})");
+ QVERIFY(result.isNull() && !result.isValid());
- QVERIFY(watcher.wait());
+ QCOMPARE(evaluateJavaScriptSync(&page, "new Promise(function(){})"), QVariant(QVariantMap{}));
}
void tst_QWebEnginePage::runJavaScriptDisabled()
@@ -1860,7 +1792,6 @@ void tst_QWebEnginePage::runJavaScriptFromSlot()
void tst_QWebEnginePage::fullScreenRequested()
{
- JavaScriptCallbackWatcher watcher;
QWebEngineView view;
QWebEnginePage* page = view.page();
view.show();
@@ -1871,9 +1802,8 @@ void tst_QWebEnginePage::fullScreenRequested()
page->load(QUrl("qrc:///resources/fullscreen.html"));
QTRY_COMPARE(loadSpy.count(), 1);
- page->runJavaScript("document.webkitFullscreenEnabled", JavaScriptCallback(true));
- page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(false));
- QVERIFY(watcher.wait());
+ QTRY_VERIFY(isTrueJavaScriptResult(page, "document.webkitFullscreenEnabled"));
+ QVERIFY(isFalseJavaScriptResult(page, "document.webkitIsFullScreen"));
// FullscreenRequest must be a user gesture
bool acceptRequest = true;
@@ -1883,17 +1813,15 @@ void tst_QWebEnginePage::fullScreenRequested()
});
QTest::keyPress(view.focusProxy(), Qt::Key_Space);
- QTRY_VERIFY(evaluateJavaScriptSync(page, "document.webkitIsFullScreen").toBool());
- page->runJavaScript("document.webkitExitFullscreen()", JavaScriptCallbackUndefined());
- QVERIFY(watcher.wait());
+ QTRY_VERIFY(isTrueJavaScriptResult(page, "document.webkitIsFullScreen"));
+ page->runJavaScript("document.webkitExitFullscreen()");
+ QTRY_VERIFY(isFalseJavaScriptResult(page, "document.webkitIsFullScreen"));
acceptRequest = false;
- page->runJavaScript("document.webkitFullscreenEnabled", JavaScriptCallback(true));
+ QVERIFY(isTrueJavaScriptResult(page, "document.webkitFullscreenEnabled"));
QTest::keyPress(view.focusProxy(), Qt::Key_Space);
- QVERIFY(watcher.wait());
- page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(false));
- QVERIFY(watcher.wait());
+ QTRY_VERIFY(isFalseJavaScriptResult(page, "document.webkitIsFullScreen"));
}
void tst_QWebEnginePage::quotaRequested()
@@ -2026,7 +1954,8 @@ void tst_QWebEnginePage::urlChange()
QUrl testUrl("http://test.qt.io/");
m_view->setHtml(QStringLiteral("<h1>Test</h1"), testUrl);
- QTRY_COMPARE(urlSpy.size(), 1);
+ QTRY_COMPARE(urlSpy.size(), 2);
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), QUrl("data:text/html;charset=UTF-8,%3Ch1%3ETest%3C%2Fh1"));
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), testUrl);
}
@@ -2086,7 +2015,7 @@ private Q_SLOTS:
void continueError()
{
- emit error(this->error());
+ emit error(this->networkError());
emit finished();
}
};
@@ -2767,14 +2696,14 @@ void tst_QWebEnginePage::setUrlUsingStateObject()
evaluateJavaScriptSync(m_page, "window.history.pushState(null, 'push', 'navigate/to/here')");
expectedUrlChangeCount++;
- QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
QCOMPARE(m_page->url(), QUrl("qrc:/resources/navigate/to/here"));
QCOMPARE(m_page->history()->count(), 2);
QVERIFY(m_page->history()->canGoBack());
evaluateJavaScriptSync(m_page, "window.history.replaceState(null, 'replace', 'another/location')");
expectedUrlChangeCount++;
- QCOMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
QCOMPARE(m_page->url(), QUrl("qrc:/resources/navigate/to/another/location"));
QCOMPARE(m_page->history()->count(), 2);
QVERIFY(!m_page->history()->canGoForward());
@@ -2823,8 +2752,8 @@ void tst_QWebEnginePage::setUrlThenLoads()
const QUrl urlToLoad2("qrc:/resources/test1.html");
m_page->load(urlToLoad1);
- QCOMPARE(m_page->url(), urlToLoad1);
- QCOMPARE(m_page->requestedUrl(), urlToLoad1);
+ QTRY_COMPARE(m_page->url(), urlToLoad1);
+ QTRY_COMPARE(m_page->requestedUrl(), urlToLoad1);
// baseUrlSync spins an event loop and this sometimes return the next result.
// QCOMPARE(baseUrlSync(m_page), baseUrl);
QTRY_COMPARE(startedSpy.count(), 2);
@@ -2838,8 +2767,8 @@ void tst_QWebEnginePage::setUrlThenLoads()
QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
m_page->load(urlToLoad2);
- QCOMPARE(m_page->url(), urlToLoad2);
- QCOMPARE(m_page->requestedUrl(), urlToLoad2);
+ QTRY_COMPARE(m_page->url(), urlToLoad2);
+ QTRY_COMPARE(m_page->requestedUrl(), urlToLoad2);
QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
QTRY_COMPARE(startedSpy.count(), 3);
@@ -3352,7 +3281,7 @@ void tst_QWebEnginePage::dataURLFragment()
QTRY_COMPARE(loadFinishedSpy.count(), 1);
QSignalSpy urlChangedSpy(m_page, SIGNAL(urlChanged(QUrl)));
- QTest::mouseClick(m_view->focusProxy(), Qt::LeftButton, 0, elementCenter(m_page, "link"));
+ QTest::mouseClick(m_view->focusProxy(), Qt::LeftButton, {}, elementCenter(m_page, "link"));
QVERIFY(urlChangedSpy.wait());
QCOMPARE(m_page->url().fragment(), QStringLiteral("anchor"));
@@ -3362,7 +3291,7 @@ void tst_QWebEnginePage::dataURLFragment()
"</body></html>", QUrl("http://test.qt.io/mytest.html"));
QTRY_COMPARE(loadFinishedSpy.count(), 2);
- QTest::mouseClick(m_view->focusProxy(), Qt::LeftButton, 0, elementCenter(m_page, "link"));
+ QTest::mouseClick(m_view->focusProxy(), Qt::LeftButton, {}, elementCenter(m_page, "link"));
QVERIFY(urlChangedSpy.wait());
QCOMPARE(m_page->url(), QUrl("http://test.qt.io/mytest.html#anchor"));
}
@@ -3384,7 +3313,7 @@ void tst_QWebEnginePage::devTools()
QCOMPARE(devToolsPage.devToolsPage(), nullptr);
QCOMPARE(devToolsPage.inspectedPage(), &inspectedPage1);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 30000);
QVERIFY(spy.takeFirst().value(0).toBool());
devToolsPage.setInspectedPage(&inspectedPage2);
@@ -3396,7 +3325,7 @@ void tst_QWebEnginePage::devTools()
QCOMPARE(devToolsPage.devToolsPage(), nullptr);
QCOMPARE(devToolsPage.inspectedPage(), &inspectedPage2);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 30000);
QVERIFY(spy.takeFirst().value(0).toBool());
devToolsPage.setInspectedPage(nullptr);
@@ -3432,7 +3361,7 @@ void tst_QWebEnginePage::openLinkInDifferentProfile()
QTRY_COMPARE(spy1.count(), 1);
QVERIFY(spy1.takeFirst().value(0).toBool());
page1.targetPage = &page2;
- QTest::mouseClick(view.focusProxy(), Qt::MiddleButton, 0, elementCenter(&page1, "link"));
+ QTest::mouseClick(view.focusProxy(), Qt::MiddleButton, {}, elementCenter(&page1, "link"));
QTRY_COMPARE(spy2.count(), 1);
QVERIFY(spy2.takeFirst().value(0).toBool());
}
@@ -3876,9 +3805,9 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
// Ensure pages are initialized
inspectedPage.load(QStringLiteral("about:blank"));
devToolsPage.load(QStringLiteral("about:blank"));
- QTRY_COMPARE(inspectedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(inspectedSpy.count(), 1, 30000);
QCOMPARE(inspectedSpy.takeFirst().value(0), QVariant(true));
- QTRY_COMPARE(devToolsSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 30000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
// Open DevTools with Frozen inspectedPage
@@ -4389,7 +4318,7 @@ void tst_QWebEnginePage::customUserAgentInNewTab()
QTRY_COMPARE(spy.count(), 1);
QVERIFY(spy.takeFirst().value(0).toBool());
QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("navigator.userAgent")).toString(), profile1.httpUserAgent());
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, elementCenter(&page, "link"));
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
QTRY_VERIFY(page.newPage);
QTRY_VERIFY(!lastUserAgent.isEmpty());
QCOMPARE(lastUserAgent, profile1.httpUserAgent().toUtf8());
@@ -4404,12 +4333,50 @@ void tst_QWebEnginePage::customUserAgentInNewTab()
QString("'>link</a></body></html>"));
QTRY_COMPARE(spy.count(), 1);
QVERIFY(spy.takeFirst().value(0).toBool());
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, elementCenter(&page, "link"));
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
QTRY_VERIFY(page.newPage);
QTRY_VERIFY(!lastUserAgent.isEmpty());
QCOMPARE(lastUserAgent, profile2.httpUserAgent().toUtf8());
}
+void tst_QWebEnginePage::renderProcessCrashed()
+{
+ using Status = QWebEnginePage::RenderProcessTerminationStatus;
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ bool done = false;
+ Status status;
+ connect(&page, &QWebEnginePage::renderProcessTerminated, [&](Status newStatus) {
+ status = newStatus;
+ done = true;
+ });
+ page.load(QUrl("chrome://crash"));
+ QTRY_VERIFY_WITH_TIMEOUT(done, 20000);
+ // The status depends on whether stack traces are enabled. With
+ // --disable-in-process-stack-traces we get an AbnormalTerminationStatus,
+ // otherwise a CrashedTerminationStatus.
+ QVERIFY(status == QWebEnginePage::CrashedTerminationStatus ||
+ status == QWebEnginePage::AbnormalTerminationStatus);
+}
+
+void tst_QWebEnginePage::renderProcessPid()
+{
+ QCOMPARE(m_page->renderProcessPid(), 0);
+
+ m_page->load(QUrl("about:blank"));
+ QSignalSpy spyFinished(m_page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
+
+ QVERIFY(m_page->renderProcessPid() > 1);
+
+ bool crashed = false;
+ connect(m_page, &QWebEnginePage::renderProcessTerminated, [&]() { crashed = true; });
+ m_page->load(QUrl("chrome://crash"));
+ QTRY_VERIFY_WITH_TIMEOUT(crashed, 20000);
+
+ QCOMPARE(m_page->renderProcessPid(), 0);
+}
+
static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")};
W_QTEST_MAIN(tst_QWebEnginePage, params)
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index a7a5ba62a..1dd8a38c8 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -67,6 +67,7 @@ private Q_SLOTS:
void urlSchemeHandlerInstallation();
void urlSchemeHandlerXhrStatus();
void urlSchemeHandlerScriptModule();
+ void urlSchemeHandlerLongReply();
void customUserAgent();
void httpAcceptLanguage();
void downloadItem();
@@ -153,17 +154,17 @@ void tst_QWebEngineProfile::testProfile()
void tst_QWebEngineProfile::clearDataFromCache()
{
- QWebEnginePage page;
-
QDir cacheDir("./tst_QWebEngineProfile_cacheDir");
cacheDir.makeAbsolute();
if (cacheDir.exists())
cacheDir.removeRecursively();
cacheDir.mkpath(cacheDir.path());
- QWebEngineProfile *profile = page.profile();
- profile->setCachePath(cacheDir.path());
- profile->setHttpCacheType(QWebEngineProfile::DiskHttpCache);
+ QWebEngineProfile profile(QStringLiteral("Test"));
+ profile.setCachePath(cacheDir.path());
+ profile.setHttpCacheType(QWebEngineProfile::DiskHttpCache);
+
+ QWebEnginePage page(&profile, nullptr);
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
page.load(QUrl("http://qt-project.org"));
@@ -180,7 +181,7 @@ void tst_QWebEngineProfile::clearDataFromCache()
QSignalSpy directoryChangedSpy(&fileSystemWatcher, SIGNAL(directoryChanged(const QString &)));
// It deletes most of the files, but not all of them.
- profile->clearHttpCache();
+ profile.clearHttpCache();
QTest::qWait(1000);
QTRY_VERIFY(directoryChangedSpy.count() > 0);
@@ -294,7 +295,7 @@ protected:
memcpy(data, m_data.constData() + m_bytesRead, len);
m_bytesAvailable -= len;
m_bytesRead += len;
- } else if (m_data.size() > 0)
+ } else if (atEnd())
return -1;
return len;
@@ -714,6 +715,31 @@ void tst_QWebEngineProfile::urlSchemeHandlerScriptModule()
QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("test")).toString(), QStringLiteral("SUCCESS"));
}
+class LongReplyUrlSchemeHandler : public QWebEngineUrlSchemeHandler
+{
+public:
+ LongReplyUrlSchemeHandler(QObject *parent = nullptr) : QWebEngineUrlSchemeHandler(parent) {}
+ ~LongReplyUrlSchemeHandler() {}
+
+ void requestStarted(QWebEngineUrlRequestJob *job)
+ {
+ QBuffer *buffer = new QBuffer(job);
+ buffer->setData(QByteArray(128 * 1024, ' ') +
+ "<html><head><title>Minify this!</title></head></html>");
+ job->reply("text/html", buffer);
+ }
+};
+
+void tst_QWebEngineProfile::urlSchemeHandlerLongReply()
+{
+ LongReplyUrlSchemeHandler handler;
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("aviancarrier", &handler);
+ QWebEnginePage page(&profile);
+ page.load(QUrl("aviancarrier:/"));
+ QTRY_COMPARE(page.title(), QString("Minify this!"));
+}
+
void tst_QWebEngineProfile::customUserAgent()
{
QString defaultUserAgent = QWebEngineProfile::defaultProfile()->httpUserAgent();
@@ -815,26 +841,32 @@ void tst_QWebEngineProfile::initiator()
InitiatorSpy handler;
QWebEngineProfile profile;
profile.installUrlSchemeHandler("foo", &handler);
- QWebEnginePage page(&profile);
+ QWebEnginePage page(&profile, nullptr);
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.load(QUrl("about:blank"));
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ loadFinishedSpy.clear();
// about:blank has a unique origin, so initiator should be QUrl("null")
evaluateJavaScriptSync(&page, "window.location = 'foo:bar'");
- QVERIFY(loadFinishedSpy.wait());
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ loadFinishedSpy.clear();
QCOMPARE(handler.initiator, QUrl("null"));
page.setHtml("", QUrl("http://test:123/foo%20bar"));
- QVERIFY(loadFinishedSpy.wait());
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ loadFinishedSpy.clear();
// baseUrl determines the origin, so QUrl("http://test:123")
evaluateJavaScriptSync(&page, "window.location = 'foo:bar'");
- QVERIFY(loadFinishedSpy.wait());
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ loadFinishedSpy.clear();
QCOMPARE(handler.initiator, QUrl("http://test:123"));
// Directly calling load/setUrl should have initiator QUrl(), meaning
// browser-initiated, trusted.
page.load(QUrl("foo:bar"));
- QVERIFY(loadFinishedSpy.wait());
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
QCOMPARE(handler.initiator, QUrl());
}
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 044fac9d7..f15a65469 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -60,6 +60,8 @@ do { \
QCOMPARE((__expr), __expected); \
} while (0)
+static QTouchDevice* s_touchDevice = nullptr;
+
static QPoint elementCenter(QWebEnginePage *page, const QString &id)
{
const QString jsCode(
@@ -165,6 +167,9 @@ private Q_SLOTS:
void keyboardEvents();
void keyboardFocusAfterPopup();
void mouseClick();
+ void touchTap();
+ void touchTapAndHold();
+ void touchTapAndHoldCancelled();
void postData();
void inputFieldOverridesShortcuts();
@@ -210,6 +215,7 @@ private Q_SLOTS:
// It is only called once.
void tst_QWebEngineView::initTestCase()
{
+ s_touchDevice = QTest::createTouchDevice();
}
// This will be called after the last test function is executed.
@@ -531,7 +537,7 @@ void tst_QWebEngineView::focusInputTypes()
// 'text' field
QPoint textInputCenter = elementCenter(webView.page(), "textInput");
- QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("textInput"));
VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), Qt::ImhPreferLowercase);
QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
@@ -539,7 +545,7 @@ void tst_QWebEngineView::focusInputTypes()
// 'password' field
QPoint passwordInputCenter = elementCenter(webView.page(), "passwordInput");
- QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, passwordInputCenter);
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, {}, passwordInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("passwordInput"));
VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), (Qt::ImhSensitiveData | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase | Qt::ImhHiddenText));
QVERIFY(!webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
@@ -547,7 +553,7 @@ void tst_QWebEngineView::focusInputTypes()
// 'tel' field
QPoint telInputCenter = elementCenter(webView.page(), "telInput");
- QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, telInputCenter);
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, {}, telInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("telInput"));
VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), Qt::ImhDialableCharactersOnly);
QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
@@ -555,7 +561,7 @@ void tst_QWebEngineView::focusInputTypes()
// 'number' field
QPoint numberInputCenter = elementCenter(webView.page(), "numberInput");
- QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, numberInputCenter);
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, {}, numberInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("numberInput"));
VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), Qt::ImhFormattedNumbersOnly);
QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
@@ -563,7 +569,7 @@ void tst_QWebEngineView::focusInputTypes()
// 'email' field
QPoint emailInputCenter = elementCenter(webView.page(), "emailInput");
- QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, emailInputCenter);
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, {}, emailInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("emailInput"));
VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), Qt::ImhEmailCharactersOnly);
QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
@@ -571,28 +577,28 @@ void tst_QWebEngineView::focusInputTypes()
// 'url' field
QPoint urlInputCenter = elementCenter(webView.page(), "urlInput");
- QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, urlInputCenter);
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, {}, urlInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("urlInput"));
VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), (Qt::ImhUrlCharactersOnly | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase));
QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
QTRY_VERIFY(inputMethodQuery(Qt::ImEnabled).toBool());
// 'password' field
- QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, passwordInputCenter);
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, {}, passwordInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("passwordInput"));
VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), (Qt::ImhSensitiveData | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase | Qt::ImhHiddenText));
QVERIFY(!webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
QTRY_COMPARE(inputMethodQuery(Qt::ImEnabled).toBool(), imeHasHiddenTextCapability);
// 'text' type
- QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("textInput"));
VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), Qt::ImhPreferLowercase);
QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
QTRY_VERIFY(inputMethodQuery(Qt::ImEnabled).toBool());
// 'password' field
- QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, passwordInputCenter);
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, {}, passwordInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("passwordInput"));
VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), (Qt::ImhSensitiveData | Qt::ImhNoPredictiveText | Qt::ImhNoAutoUppercase | Qt::ImhHiddenText));
QVERIFY(!webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
@@ -600,7 +606,7 @@ void tst_QWebEngineView::focusInputTypes()
// 'text area' field
QPoint textAreaCenter = elementCenter(webView.page(), "textArea");
- QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, 0, textAreaCenter);
+ QTest::mouseClick(webView.focusProxy(), Qt::LeftButton, {}, textAreaCenter);
QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("textArea"));
VERIFY_INPUTMETHOD_HINTS(webView.focusProxy()->inputMethodHints(), (Qt::ImhMultiLine | Qt::ImhPreferLowercase));
QVERIFY(webView.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
@@ -689,12 +695,12 @@ void tst_QWebEngineView::horizontalScrollbarTest()
QSignalSpy scrollSpy(view.page(), SIGNAL(scrollPositionChanged(QPointF)));
// Note: The test below assumes that the layout direction is Qt::LeftToRight.
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, QPoint(550, 595));
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, QPoint(550, 595));
scrollSpy.wait();
QVERIFY(view.page()->scrollPosition().x() > 0);
// Note: The test below assumes that the layout direction is Qt::LeftToRight.
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, QPoint(20, 595));
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, QPoint(20, 595));
scrollSpy.wait();
QVERIFY(view.page()->scrollPosition() == QPoint(0, 0));
}
@@ -1465,7 +1471,7 @@ void tst_QWebEngineView::mouseClick()
QVERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
textInputCenter = elementCenter(view.page(), "input");
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
QCOMPARE(selectionChangedSpy.count(), 0);
QVERIFY(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString().isEmpty());
@@ -1486,7 +1492,7 @@ void tst_QWebEngineView::mouseClick()
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QStringLiteral("Company"));
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QVERIFY(selectionChangedSpy.wait());
QCOMPARE(selectionChangedSpy.count(), 2);
QVERIFY(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString().isEmpty());
@@ -1507,12 +1513,178 @@ void tst_QWebEngineView::mouseClick()
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
QCOMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString(), QStringLiteral("The Qt Company"));
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QVERIFY(selectionChangedSpy.wait());
QCOMPARE(selectionChangedSpy.count(), 3);
QVERIFY(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString().isEmpty());
}
+void tst_QWebEngineView::touchTap()
+{
+#if defined(Q_OS_MACOS)
+ QSKIP("Synthetic touch events are not supported on macOS");
+#endif
+
+ QWebEngineView view;
+ view.show();
+ view.resize(200, 200);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QSignalSpy loadFinishedSpy(&view, &QWebEngineView::loadFinished);
+
+ view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);
+ view.setHtml("<html><body>"
+ "<p id='text' style='width: 150px;'>The Qt Company</p>"
+ "<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>"
+ "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
+
+ auto singleTap = [](QWidget* target, const QPoint& tapCoords) -> void {
+ QTest::touchEvent(target, s_touchDevice).press(1, tapCoords, target);
+ QTest::touchEvent(target, s_touchDevice).stationary(1);
+ QTest::touchEvent(target, s_touchDevice).release(1, tapCoords, target);
+ };
+
+ // Single tap on text doesn't trigger a selection
+ singleTap(view.focusProxy(), elementCenter(view.page(), "text"));
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
+ QTRY_VERIFY(!view.hasSelection());
+
+ // Single tap inside the input field focuses it without selecting the text
+ singleTap(view.focusProxy(), elementCenter(view.page(), "input"));
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
+ QTRY_VERIFY(!view.hasSelection());
+
+ // Single tap on the div clears the input field focus
+ singleTap(view.focusProxy(), elementCenter(view.page(), "notext"));
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
+
+ // Double tap on text still doesn't trigger a selection
+ singleTap(view.focusProxy(), elementCenter(view.page(), "text"));
+ singleTap(view.focusProxy(), elementCenter(view.page(), "text"));
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
+ QTRY_VERIFY(!view.hasSelection());
+
+ // Double tap inside the input field focuses it and selects the word under it
+ singleTap(view.focusProxy(), elementCenter(view.page(), "input"));
+ singleTap(view.focusProxy(), elementCenter(view.page(), "input"));
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
+ QTRY_COMPARE(view.selectedText(), QStringLiteral("Company2"));
+
+ // Double tap outside the input field behaves like a single tap: clears its focus and selection
+ singleTap(view.focusProxy(), elementCenter(view.page(), "notext"));
+ singleTap(view.focusProxy(), elementCenter(view.page(), "notext"));
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
+ QTRY_VERIFY(!view.hasSelection());
+}
+
+void tst_QWebEngineView::touchTapAndHold()
+{
+#if defined(Q_OS_MACOS)
+ QSKIP("Synthetic touch events are not supported on macOS");
+#endif
+
+ QWebEngineView view;
+ view.show();
+ view.resize(200, 200);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QSignalSpy loadFinishedSpy(&view, &QWebEngineView::loadFinished);
+
+ view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);
+ view.setHtml("<html><body>"
+ "<p id='text' style='width: 150px;'>The Qt Company</p>"
+ "<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>"
+ "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
+
+ auto tapAndHold = [](QWidget* target, const QPoint& tapCoords) -> void {
+ QTest::touchEvent(target, s_touchDevice).press(1, tapCoords, target);
+ QTest::touchEvent(target, s_touchDevice).stationary(1);
+ QTest::qWait(1000);
+ QTest::touchEvent(target, s_touchDevice).release(1, tapCoords, target);
+ };
+
+ // Tap-and-hold on text selects the word under it
+ tapAndHold(view.focusProxy(), elementCenter(view.page(), "text"));
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
+ QTRY_COMPARE(view.selectedText(), QStringLiteral("Company"));
+
+ // Tap-and-hold inside the input field focuses it and selects the word under it
+ tapAndHold(view.focusProxy(), elementCenter(view.page(), "input"));
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input"));
+ QTRY_COMPARE(view.selectedText(), QStringLiteral("Company2"));
+
+ // Only test the page context menu on Windows, as Linux doesn't handle context menus consistently
+ // and other non-desktop platforms like Android may not even support context menus at all
+#if defined(Q_OS_WIN)
+ // Tap-and-hold clears the text selection and shows the page's context menu
+ QVERIFY(QApplication::activePopupWidget() == nullptr);
+ tapAndHold(view.focusProxy(), elementCenter(view.page(), "notext"));
+ QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
+ QTRY_VERIFY(!view.hasSelection());
+ QTRY_VERIFY(QApplication::activePopupWidget() != nullptr);
+
+ QApplication::activePopupWidget()->close();
+ QVERIFY(QApplication::activePopupWidget() == nullptr);
+#endif
+}
+
+void tst_QWebEngineView::touchTapAndHoldCancelled()
+{
+#if defined(Q_OS_MACOS)
+ QSKIP("Synthetic touch events are not supported on macOS");
+#endif
+
+ QWebEngineView view;
+ view.show();
+ view.resize(200, 200);
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ QSignalSpy loadFinishedSpy(&view, &QWebEngineView::loadFinished);
+
+ view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false);
+ view.setHtml("<html><body>"
+ "<p id='text' style='width: 150px;'>The Qt Company</p>"
+ "<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>"
+ "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>"
+ "</body></html>");
+ QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty());
+
+ auto cancelledTapAndHold = [](QWidget* target, const QPoint& tapCoords) -> void {
+ QTest::touchEvent(target, s_touchDevice).press(1, tapCoords, target);
+ QTest::touchEvent(target, s_touchDevice).stationary(1);
+ QTest::qWait(1000);
+ QWindowSystemInterface::handleTouchCancelEvent(target->windowHandle(), s_touchDevice);
+ };
+
+ // A cancelled tap-and-hold should cancel text selection, but currently doesn't
+ cancelledTapAndHold(view.focusProxy(), elementCenter(view.page(), "text"));
+ QEXPECT_FAIL("", "Incorrect Chromium selection behavior when cancelling tap-and-hold on text", Continue);
+ QTRY_VERIFY_WITH_TIMEOUT(!view.hasSelection(), 100);
+
+ // A cancelled tap-and-hold should cancel input field focusing and selection, but currently doesn't
+ cancelledTapAndHold(view.focusProxy(), elementCenter(view.page(), "input"));
+ QEXPECT_FAIL("", "Incorrect Chromium selection behavior when cancelling tap-and-hold on input field", Continue);
+ QTRY_VERIFY_WITH_TIMEOUT(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty(), 100);
+ QEXPECT_FAIL("", "Incorrect Chromium focus behavior when cancelling tap-and-hold on input field", Continue);
+ QTRY_VERIFY_WITH_TIMEOUT(!view.hasSelection(), 100);
+
+ // Only test the page context menu on Windows, as Linux doesn't handle context menus consistently
+ // and other non-desktop platforms like Android may not even support context menus at all
+#if defined(Q_OS_WIN)
+ // A cancelled tap-and-hold cancels the context menu
+ QVERIFY(QApplication::activePopupWidget() == nullptr);
+ cancelledTapAndHold(view.focusProxy(), elementCenter(view.page(), "notext"));
+ QVERIFY(QApplication::activePopupWidget() == nullptr);
+#endif
+}
+
void tst_QWebEngineView::postData()
{
QMap<QString, QString> postData;
@@ -1657,6 +1829,7 @@ void tst_QWebEngineView::inputFieldOverridesShortcuts()
view.setHtml(QString("<html><body>"
"<button id=\"btn1\" type=\"button\">push it real good</button>"
"<input id=\"input1\" type=\"text\" value=\"x\">"
+ "<input id=\"pass1\" type=\"password\" value=\"x\">"
"</body></html>"));
QVERIFY(loadFinishedSpy.wait());
@@ -1668,6 +1841,11 @@ void tst_QWebEngineView::inputFieldOverridesShortcuts()
"document.getElementById('input1').value").toString();
};
+ auto passwordFieldValue = [&view] () -> QString {
+ return evaluateJavaScriptSync(view.page(),
+ "document.getElementById('pass1').value").toString();
+ };
+
// The input form is not focused. The action is triggered on pressing Shift+Delete.
action->setShortcut(Qt::SHIFT + Qt::Key_Delete);
QTest::keyClick(view.windowHandle(), Qt::Key_Delete, Qt::ShiftModifier);
@@ -1691,8 +1869,20 @@ void tst_QWebEngineView::inputFieldOverridesShortcuts()
QTRY_COMPARE(inputFieldValue(), QString("yxx"));
QVERIFY(!actionTriggered);
+ // The password input form is focused. The action is not triggered, and the form's text changed.
+ evaluateJavaScriptSync(view.page(), "document.getElementById('pass1').focus();");
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("pass1"));
+ actionTriggered = false;
+ QTest::keyClick(view.windowHandle(), Qt::Key_Y);
+ QTRY_COMPARE(passwordFieldValue(), QString("yx"));
+ QTest::keyClick(view.windowHandle(), Qt::Key_X);
+ QTRY_COMPARE(passwordFieldValue(), QString("yxx"));
+ QVERIFY(!actionTriggered);
+
// The input form is focused. Make sure we don't override all short cuts.
// A Ctrl-1 action is no default Qt key binding and should be triggerable.
+ evaluateJavaScriptSync(view.page(), "document.getElementById('input1').focus();");
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
action->setShortcut(Qt::CTRL + Qt::Key_1);
QTest::keyClick(view.windowHandle(), Qt::Key_1, Qt::ControlModifier);
QTRY_VERIFY(actionTriggered);
@@ -1800,7 +1990,7 @@ void tst_QWebEngineView::softwareInputPanel()
QVERIFY(loadFinishedSpy.wait());
QPoint textInputCenter = elementCenter(view.page(), "input1");
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
// This part of the test checks if the SIP (Software Input Panel) is triggered,
@@ -1819,7 +2009,7 @@ void tst_QWebEngineView::softwareInputPanel()
QTRY_VERIFY(!testContext.isInputPanelVisible());
testContext.hideInputPanel();
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QTRY_VERIFY(testContext.isInputPanelVisible());
view.setHtml("<html><body><p id='para'>nothing to input here</p></body></html>");
@@ -1827,7 +2017,7 @@ void tst_QWebEngineView::softwareInputPanel()
testContext.hideInputPanel();
QPoint paraCenter = elementCenter(view.page(), "para");
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, paraCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, paraCenter);
QVERIFY(!testContext.isInputPanelVisible());
@@ -1839,7 +2029,7 @@ void tst_QWebEngineView::softwareInputPanel()
QVERIFY(loadFinishedSpy.wait());
QPoint btnDivCenter = elementCenter(view.page(), "btnDiv");
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, btnDivCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, btnDivCenter);
QVERIFY(!testContext.isInputPanelVisible());
}
@@ -1864,7 +2054,7 @@ void tst_QWebEngineView::inputContextQueryInput()
// Set focus on an input field.
QPoint textInputCenter = elementCenter(view.page(), "input1");
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QTRY_COMPARE(testContext.infos.count(), 2);
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
foreach (const InputMethodInfo &info, testContext.infos) {
@@ -2013,7 +2203,7 @@ void tst_QWebEngineView::inputMethods()
QTRY_COMPARE(loadFinishedSpy.size(), 1);
QPoint textInputCenter = elementCenter(view.page(), "input1");
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
// ImCursorRectangle
@@ -2114,7 +2304,7 @@ void tst_QWebEngineView::textSelectionInInputField()
// LEFT to RIGHT selection
// Mouse click event moves the current cursor to the end of the text
QPoint textInputCenter = elementCenter(view.page(), "input1");
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImCursorPosition).toInt(), 11);
QTRY_COMPARE(view.focusProxy()->inputMethodQuery(Qt::ImAnchorPosition).toInt(), 11);
@@ -2156,7 +2346,7 @@ void tst_QWebEngineView::textSelectionInInputField()
// RIGHT to LEFT selection
// Deselect the selection (this moves the current cursor to the end of the text)
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QVERIFY(selectionChangedSpy.wait());
QCOMPARE(selectionChangedSpy.count(), 2);
@@ -2196,7 +2386,7 @@ void tst_QWebEngineView::textSelectionOutOfInputField()
QVERIFY(view.page()->selectedText().isEmpty());
// Simple click should not update text selection, however it updates selection bounds in Chromium
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, view.geometry().center());
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, view.geometry().center());
QCOMPARE(selectionChangedSpy.count(), 0);
QVERIFY(!view.hasSelection());
QVERIFY(view.page()->selectedText().isEmpty());
@@ -2209,7 +2399,7 @@ void tst_QWebEngineView::textSelectionOutOfInputField()
QCOMPARE(view.page()->selectedText(), QString("This is a text"));
// Deselect text by mouse click
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, view.geometry().center());
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, view.geometry().center());
QVERIFY(selectionChangedSpy.wait());
QCOMPARE(selectionChangedSpy.count(), 2);
QVERIFY(!view.hasSelection());
@@ -2256,7 +2446,7 @@ void tst_QWebEngineView::textSelectionOutOfInputField()
// Remove selection by clicking into an input field
QPoint textInputCenter = elementCenter(view.page(), "input1");
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QVERIFY(selectionChangedSpy.wait());
QCOMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
QCOMPARE(selectionChangedSpy.count(), 2);
@@ -2271,7 +2461,7 @@ void tst_QWebEngineView::textSelectionOutOfInputField()
QCOMPARE(view.page()->selectedText(), QString("QtWebEngine"));
// Deselect input field's text by mouse click
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, view.geometry().center());
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, view.geometry().center());
QVERIFY(selectionChangedSpy.wait());
QCOMPARE(selectionChangedSpy.count(), 4);
QVERIFY(!view.hasSelection());
@@ -2292,14 +2482,14 @@ void tst_QWebEngineView::hiddenText()
QVERIFY(loadFinishedSpy.wait());
QPoint passwordInputCenter = elementCenter(view.page(), "password1");
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, passwordInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, passwordInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("password1"));
QVERIFY(!view.focusProxy()->testAttribute(Qt::WA_InputMethodEnabled));
QVERIFY(view.focusProxy()->inputMethodHints() & Qt::ImhHiddenText);
QPoint textInputCenter = elementCenter(view.page(), "input1");
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
QVERIFY(!(view.focusProxy()->inputMethodHints() & Qt::ImhHiddenText));
}
@@ -2917,7 +3107,7 @@ void tst_QWebEngineView::globalMouseSelection()
// Deselect the selection (this moves the current cursor to the end of the text)
QPoint textInputCenter = elementCenter(view.page(), "input1");
- QTest::mouseClick(view.focusProxy(), Qt::LeftButton, 0, textInputCenter);
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter);
QVERIFY(selectionChangedSpy.wait());
QCOMPARE(selectionChangedSpy.count(), 2);
QVERIFY(QApplication::clipboard()->text(QClipboard::Selection).isEmpty());
@@ -2958,36 +3148,55 @@ void tst_QWebEngineView::noContextMenu()
void tst_QWebEngineView::contextMenu_data()
{
QTest::addColumn<int>("childrenCount");
+ QTest::addColumn<bool>("isCustomMenu");
QTest::addColumn<Qt::ContextMenuPolicy>("contextMenuPolicy");
- QTest::newRow("defaultContextMenu") << 1 << Qt::DefaultContextMenu;
- QTest::newRow("customContextMenu") << 1 << Qt::CustomContextMenu;
- QTest::newRow("preventContextMenu") << 0 << Qt::PreventContextMenu;
+ QTest::newRow("defaultContextMenu") << 1 << false << Qt::DefaultContextMenu;
+ QTest::newRow("customContextMenu") << 1 << true << Qt::CustomContextMenu;
+ QTest::newRow("preventContextMenu") << 0 << false << Qt::PreventContextMenu;
}
void tst_QWebEngineView::contextMenu()
{
QFETCH(int, childrenCount);
+ QFETCH(bool, isCustomMenu);
QFETCH(Qt::ContextMenuPolicy, contextMenuPolicy);
QWebEngineView view;
+ QMenu *customMenu = nullptr;
if (contextMenuPolicy == Qt::CustomContextMenu) {
- connect(&view, &QWebEngineView::customContextMenuRequested, [&view](const QPoint &pt) {
- QMenu* menu = new QMenu(&view);
- menu->addAction("Action1");
- menu->addAction("Action2");
- menu->popup(pt);
+ connect(&view, &QWebEngineView::customContextMenuRequested, [&view, &customMenu] (const QPoint &pt) {
+ Q_ASSERT(!customMenu);
+ customMenu = new QMenu(&view);
+ customMenu->addAction("Action1");
+ customMenu->addAction("Action2");
+ customMenu->popup(pt);
});
}
view.setContextMenuPolicy(contextMenuPolicy);
+
+ // input is supposed to be skipped before first real navigation in >= 79
+ QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished);
+ view.load(QUrl("about:blank"));
view.resize(640, 480);
view.show();
+ QTRY_COMPARE(loadSpy.count(), 1);
QVERIFY(view.findChildren<QMenu *>().isEmpty());
QTest::mouseMove(view.windowHandle(), QPoint(10,10));
QTest::mouseClick(view.windowHandle(), Qt::RightButton);
- QTRY_COMPARE(view.findChildren<QMenu *>().count(), childrenCount);
+
+ // verify for zero children will always succeed, so should be tested with at least minor timeout
+ if (childrenCount <= 0) {
+ QVERIFY(!QTest::qWaitFor([&view] () { return view.findChildren<QMenu *>().count() > 0; }, 500));
+ } else {
+ QTRY_COMPARE(view.findChildren<QMenu *>().count(), childrenCount);
+ if (isCustomMenu) {
+ QCOMPARE(view.findChildren<QMenu *>().first(), customMenu);
+ }
+ }
+ QCOMPARE(!!customMenu, isCustomMenu);
}
void tst_QWebEngineView::mouseLeave()
diff --git a/tests/auto/widgets/schemes/tst_schemes.cpp b/tests/auto/widgets/schemes/tst_schemes.cpp
index 1b6093571..a4a0e34ff 100644
--- a/tests/auto/widgets/schemes/tst_schemes.cpp
+++ b/tests/auto/widgets/schemes/tst_schemes.cpp
@@ -38,6 +38,7 @@ class tst_Schemes : public QObject
Q_OBJECT
private Q_SLOTS:
+ void unknownUrlSchemePolicy_data();
void unknownUrlSchemePolicy();
};
@@ -58,8 +59,27 @@ public:
}
};
+Q_DECLARE_METATYPE(QWebEngineSettings::UnknownUrlSchemePolicy)
+
+void tst_Schemes::unknownUrlSchemePolicy_data()
+{
+ QTest::addColumn<QWebEngineSettings::UnknownUrlSchemePolicy>("policy");
+ QTest::addColumn<bool>("userAction");
+ QTest::newRow("DisallowUnknownUrlSchemes, script") << QWebEngineSettings::DisallowUnknownUrlSchemes << false;
+ QTest::newRow("DisallowUnknownUrlSchemes, user") << QWebEngineSettings::DisallowUnknownUrlSchemes << true;
+ QTest::newRow("AllowUnknownUrlSchemesFromUserInteraction, script") << QWebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction << false;
+ QTest::newRow("AllowUnknownUrlSchemesFromUserInteraction, user") << QWebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction << true;
+ QTest::newRow("AllowAllUnknownUrlSchemes, script") << QWebEngineSettings::AllowAllUnknownUrlSchemes << false;
+ QTest::newRow("AllowAllUnknownUrlSchemes, user") << QWebEngineSettings::AllowAllUnknownUrlSchemes << true;
+ QTest::newRow("default UnknownUrlSchemePolicy, script") << QWebEngineSettings::UnknownUrlSchemePolicy(0) << false;
+ QTest::newRow("default UnknownUrlSchemePolicy, user") << QWebEngineSettings::UnknownUrlSchemePolicy(0) << true;
+}
+
void tst_Schemes::unknownUrlSchemePolicy()
{
+ QFETCH(QWebEngineSettings::UnknownUrlSchemePolicy, policy);
+ QFETCH(bool, userAction);
+
QWebEngineView view;
AcceptNavigationRequestHandler page;
QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
@@ -71,41 +91,31 @@ void tst_Schemes::unknownUrlSchemePolicy()
settings->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
settings->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
- QWebEngineSettings::UnknownUrlSchemePolicy policies[6] = {QWebEngineSettings::DisallowUnknownUrlSchemes,
- QWebEngineSettings::DisallowUnknownUrlSchemes,
- QWebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction,
- QWebEngineSettings::AllowUnknownUrlSchemesFromUserInteraction,
- QWebEngineSettings::AllowAllUnknownUrlSchemes,
- QWebEngineSettings::AllowAllUnknownUrlSchemes};
- // even iterations are for navigation-requests from javascript,
- // odd iterations are for navigations-requests from user-interaction
- for (int i = 0; i < 8; i++) {
- if (i <= 5)
- settings->setUnknownUrlSchemePolicy(policies[i]);
- else
- settings->resetUnknownUrlSchemePolicy();
- loadFinishedSpy.clear();
- page.acceptNavigationRequestCalls = 0;
- bool shouldAccept;
-
- if (i % 2 == 0) { // navigation request coming from javascript
- shouldAccept = (4 <= i && i <= 5); // only case AllowAllUnknownUrlSchemes
- view.setHtml("<html><script>setTimeout(function(){ window.location.href='nonexistentscheme://somewhere'; }, 10);</script><body>testing...</body></html>");
- } else { // navigation request coming from user interaction
- shouldAccept = (2 <= i); // all cases except DisallowUnknownUrlSchemes
- view.setHtml("<html><body><a id='nonexlink' href='nonexistentscheme://somewhere'>nonexistentscheme://somewhere</a></body></html>");
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 15000);
- // focus and trigger the link
- view.page()->runJavaScript("document.getElementById('nonexlink').focus();", [&view](const QVariant &result) {
- Q_UNUSED(result);
- QTest::sendKeyEvent(QTest::Press, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier);
- QTest::sendKeyEvent(QTest::Release, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier);
- });
- }
+ if (policy > 0)
+ settings->setUnknownUrlSchemePolicy(policy);
+ else
+ settings->resetUnknownUrlSchemePolicy();
+ loadFinishedSpy.clear();
+ page.acceptNavigationRequestCalls = 0;
+ bool shouldAccept;
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 2, 60000);
- QCOMPARE(page.acceptNavigationRequestCalls, shouldAccept ? 1 : 0);
+ if (!userAction) { // navigation request coming from javascript
+ shouldAccept = (policy == QWebEngineSettings::AllowAllUnknownUrlSchemes);
+ view.setHtml("<html><script>setTimeout(function(){ window.location.href='nonexistentscheme://somewhere'; }, 10);</script><body>testing...</body></html>");
+ } else { // navigation request coming from user interaction
+ shouldAccept = (policy != QWebEngineSettings::DisallowUnknownUrlSchemes);
+ view.setHtml("<html><body><a id='nonexlink' href='nonexistentscheme://somewhere'>nonexistentscheme://somewhere</a></body></html>");
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 15000);
+ // focus and trigger the link
+ view.page()->runJavaScript("document.getElementById('nonexlink').focus();", [&view](const QVariant &result) {
+ Q_UNUSED(result);
+ QTest::sendKeyEvent(QTest::Press, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier);
+ QTest::sendKeyEvent(QTest::Release, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier);
+ });
}
+
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 2, 60000);
+ QCOMPARE(page.acceptNavigationRequestCalls, shouldAccept ? 1 : 0);
}
QTEST_MAIN(tst_Schemes)
diff --git a/tests/auto/widgets/spellchecking/tst_spellchecking.cpp b/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
index 64df05d89..801e2a76c 100644
--- a/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
+++ b/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
@@ -41,10 +41,10 @@ public:
void activateMenu(QWidget *widget, const QPoint &position)
{
QTest::mouseMove(widget, position);
- QTest::mousePress(widget, Qt::RightButton, 0, position);
+ QTest::mousePress(widget, Qt::RightButton, {}, position);
QContextMenuEvent evcont(QContextMenuEvent::Mouse, position, mapToGlobal(position));
event(&evcont);
- QTest::mouseRelease(widget, Qt::RightButton, 0, position);
+ QTest::mouseRelease(widget, Qt::RightButton, {}, position);
}
const QWebEngineContextMenuData& data()
@@ -175,8 +175,8 @@ void tst_Spellchecking::spellcheck()
//type text, spellchecker needs time
QTest::mouseMove(m_view->focusWidget(), QPoint(20,20));
- QTest::mousePress(m_view->focusWidget(), Qt::LeftButton, 0, QPoint(20,20));
- QTest::mouseRelease(m_view->focusWidget(), Qt::LeftButton, 0, QPoint(20,20));
+ QTest::mousePress(m_view->focusWidget(), Qt::LeftButton, {}, QPoint(20,20));
+ QTest::mouseRelease(m_view->focusWidget(), Qt::LeftButton, {}, QPoint(20,20));
QString text("I lowe Qt ....");
for (int i = 0; i < text.length(); i++) {
QTest::keyClicks(m_view->focusWidget(), text.at(i));
diff --git a/tests/auto/widgets/util.h b/tests/auto/widgets/util.h
index eba974f33..20241be8b 100644
--- a/tests/auto/widgets/util.h
+++ b/tests/auto/widgets/util.h
@@ -132,7 +132,7 @@ static inline QString toHtmlSync(QWebEnginePage *page)
static inline bool findTextSync(QWebEnginePage *page, const QString &subString)
{
CallbackSpy<bool> spy;
- page->findText(subString, 0, spy.ref());
+ page->findText(subString, {}, spy.ref());
return spy.waitForResult();
}