summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/quick/qmltests/BLACKLIST3
-rw-r--r--tests/auto/quick/qmltests/data/tst_mouseMove.qml96
-rw-r--r--tests/auto/quick/qmltests/data/tst_viewSource.qml9
-rw-r--r--tests/auto/quick/qmltests/qmltests.pro3
-rw-r--r--tests/auto/quick/qquickwebengineview/qquickwebengineview.pro2
-rw-r--r--tests/auto/quick/quick.pro2
-rw-r--r--tests/auto/quick/tests.pri2
-rw-r--r--tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp97
-rw-r--r--tests/auto/widgets/qwebenginepage/qwebenginepage.pro2
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/bar.txt1
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/foo.txt1
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/path with spaces.txt1
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp160
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc3
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp54
-rw-r--r--tests/auto/widgets/widgets.pro4
16 files changed, 397 insertions, 43 deletions
diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST
index 19d75dfb7..f449f4949 100644
--- a/tests/auto/quick/qmltests/BLACKLIST
+++ b/tests/auto/quick/qmltests/BLACKLIST
@@ -19,3 +19,6 @@ linux
[WebEngineViewSingleFileUpload::test_acceptSingleFileSelection]
*
+
+[WebViewFindText::test_findTextInterruptedByLoad]
+*
diff --git a/tests/auto/quick/qmltests/data/tst_mouseMove.qml b/tests/auto/quick/qmltests/data/tst_mouseMove.qml
new file mode 100644
index 000000000..adb937139
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_mouseMove.qml
@@ -0,0 +1,96 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 2.0
+import QtTest 1.0
+import QtWebEngine 1.4
+
+Rectangle {
+ id: root
+ width: 200
+ height: 200
+
+ Column {
+ anchors.fill: parent
+ Rectangle {
+ id: placeHolder
+ width: parent.width
+ height: 100
+ color: "red"
+ }
+
+ TestWebEngineView {
+ id: webEngineView
+ width: parent.width
+ height: 100
+
+ function getInnerText(element) {
+ var innerText;
+ runJavaScript("document.getElementById('" + element + "').innerText", function(result) {
+ innerText = result;
+ });
+ testCase.tryVerify(function() { return innerText != undefined; });
+ return innerText;
+ }
+ }
+ }
+
+ TestCase {
+ id: testCase
+ name: "WebEngineViewMouseMove"
+ when: windowShown
+
+ function test_mouseLeave() {
+ mouseMove(root, 0, 0);
+ webEngineView.loadHtml(
+ "<html>" +
+ "<head><script>" +
+ "function init() {" +
+ " var div = document.getElementById('testDiv');" +
+ " div.onmouseenter = function(e) { div.innerText = 'Mouse IN' };" +
+ " div.onmouseleave = function(e) { div.innerText = 'Mouse OUT' };" +
+ "}" +
+ "</script></head>" +
+ "<body onload='init()' style='margin: 0px; padding: 0px'>" +
+ " <div id='testDiv' style='width: 100%; height: 100%; background-color: green' />" +
+ "</body>" +
+ "</html>");
+ verify(webEngineView.waitForLoadSucceeded());
+ verify(!webEngineView.getInnerText("testDiv"));
+
+ for (var i = 90; i < 110; ++i)
+ mouseMove(root, 50, i);
+ tryVerify(function() { return webEngineView.getInnerText("testDiv") == "Mouse IN" });
+
+ for (var i = 110; i > 90; --i)
+ mouseMove(root, 50, i);
+ tryVerify(function() { return webEngineView.getInnerText("testDiv") == "Mouse OUT" });
+ }
+ }
+}
+
diff --git a/tests/auto/quick/qmltests/data/tst_viewSource.qml b/tests/auto/quick/qmltests/data/tst_viewSource.qml
index 22c3947d3..576035ef2 100644
--- a/tests/auto/quick/qmltests/data/tst_viewSource.qml
+++ b/tests/auto/quick/qmltests/data/tst_viewSource.qml
@@ -63,7 +63,7 @@ TestWebEngineView {
name: "WebEngineViewSource"
function init() {
- webEngineView.url = Qt.resolvedUrl("about:blank");
+ webEngineView.url = Qt.resolvedUrl("test1.html");
verify(webEngineView.waitForLoadSucceeded());
newViewRequestedSpy.clear();
@@ -103,8 +103,8 @@ TestWebEngineView {
{ tag: "view-source:about:blank", userInputUrl: "view-source:about:blank", loadSucceed: true, url: "view-source:about:blank", title: "view-source:about:blank" },
{ tag: testLocalUrl, userInputUrl: testLocalUrl, loadSucceed: true, url: testLocalUrl, title: "test1.html" },
{ tag: testLocalUrlWithoutScheme, userInputUrl: testLocalUrlWithoutScheme, loadSucceed: true, url: testLocalUrl, title: "test1.html" },
- { tag: "view-source:http://non.existent", userInputUrl: "view-source:http://non.existent", loadSucceed: false, url: "view-source:http://non.existent/", title: "non.existent" },
- { tag: "view-source:non.existent", userInputUrl: "view-source:non.existent", loadSucceed: false, url: "view-source:http://non.existent/", title: "non.existent" },
+ { tag: "view-source:http://non.existent", userInputUrl: "view-source:http://non.existent", loadSucceed: false, url: "http://non.existent/", title: "non.existent" },
+ { tag: "view-source:non.existent", userInputUrl: "view-source:non.existent", loadSucceed: false, url: "http://non.existent/", title: "non.existent" },
];
}
@@ -114,11 +114,10 @@ TestWebEngineView {
if (row.loadSucceed) {
verify(webEngineView.waitForLoadSucceeded());
- tryVerify(function() { return titleChangedSpy.count >= 1; });
} else {
verify(webEngineView.waitForLoadFailed());
- tryVerify(function() { return titleChangedSpy.count >= 2; });
}
+ tryVerify(function() { return titleChangedSpy.count == 1; });
compare(webEngineView.url, row.url);
tryCompare(webEngineView, "title", row.title);
diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro
index 9530e115c..bb209a70c 100644
--- a/tests/auto/quick/qmltests/qmltests.pro
+++ b/tests/auto/quick/qmltests/qmltests.pro
@@ -62,6 +62,7 @@ OTHER_FILES += \
$$PWD/data/tst_loadRecursionCrash.qml \
$$PWD/data/tst_loadUrl.qml \
$$PWD/data/tst_mouseClick.qml \
+ $$PWD/data/tst_mouseMove.qml \
$$PWD/data/tst_navigationHistory.qml \
$$PWD/data/tst_navigationRequested.qml \
$$PWD/data/tst_newViewRequest.qml \
@@ -100,7 +101,7 @@ OTHER_FILES += \
load(qt_build_paths)
DEFINES += QUICK_TEST_SOURCE_DIR=\\\"$$re_escape($$PWD$${QMAKE_DIR_SEP}data)\\\"
-!qtConfig(testsupport) {
+!qtConfig(webengine-testsupport) {
PLUGIN_EXTENSION = .so
PLUGIN_PREFIX = lib
osx: PLUGIN_PREFIX = .dylib
diff --git a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
index 0f62ec21d..25bf44597 100644
--- a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
+++ b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro
@@ -5,7 +5,7 @@ QT_PRIVATE += webengine-private gui-private
HEADERS += ../shared/util.h
-qtConfig(printing-and-pdf) {
+qtConfig(webengine-printing-and-pdf) {
DEFINES += ENABLE_PDF
}
diff --git a/tests/auto/quick/quick.pro b/tests/auto/quick/quick.pro
index 2e6343469..e67cf0ed0 100644
--- a/tests/auto/quick/quick.pro
+++ b/tests/auto/quick/quick.pro
@@ -8,7 +8,7 @@ SUBDIRS += \
qquickwebenginedefaultsurfaceformat \
qquickwebengineview
-qtConfig(testsupport) {
+qtConfig(webengine-testsupport) {
SUBDIRS += \
qmltests \
qquickwebengineviewgraphics
diff --git a/tests/auto/quick/tests.pri b/tests/auto/quick/tests.pri
index 15f6517a4..7983a248f 100644
--- a/tests/auto/quick/tests.pri
+++ b/tests/auto/quick/tests.pri
@@ -19,7 +19,7 @@ QT += testlib network quick webengine
# This define is used by some tests to look up resources in the source tree
DEFINES += TESTS_SOURCE_DIR=\\\"$$PWD/\\\"
-qtConfig(testsupport) {
+qtConfig(webengine-testsupport) {
DEFINES += ENABLE_QML_TESTSUPPORT_API
}
diff --git a/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp b/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp
index 9531d0cf4..7094c8e4b 100644
--- a/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp
+++ b/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp
@@ -27,6 +27,7 @@
****************************************************************************/
#include <QCoreApplication>
+#include <QSignalSpy>
#include <QStandardPaths>
#include <QTemporaryDir>
#include <QTest>
@@ -37,6 +38,18 @@
#include <httpserver.h>
#include <waitforsignal.h>
+static std::unique_ptr<HttpReqRep> waitForFaviconRequest(HttpServer *server)
+{
+ auto rr = waitForRequest(server);
+ if (!rr ||
+ rr->requestMethod() != QByteArrayLiteral("GET") ||
+ rr->requestPath() != QByteArrayLiteral("/favicon.ico"))
+ return nullptr;
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ return std::move(rr);
+}
+
class tst_QWebEngineDownloads : public QObject
{
Q_OBJECT
@@ -46,6 +59,7 @@ private Q_SLOTS:
void downloadTwoLinks();
void downloadPage_data();
void downloadPage();
+ void downloadViaSetUrl();
};
enum DownloadTestUserAction {
@@ -317,12 +331,8 @@ void tst_QWebEngineDownloads::downloadLink()
QVERIFY(loadOk);
// 1.1. Ignore favicon request
- auto favIconRR = waitForRequest(&server);
+ auto favIconRR = waitForFaviconRequest(&server);
QVERIFY(favIconRR);
- QCOMPARE(favIconRR->requestMethod(), QByteArrayLiteral("GET"));
- QCOMPARE(favIconRR->requestPath(), QByteArrayLiteral("/favicon.ico"));
- favIconRR->setResponseStatus(404);
- favIconRR->sendResponse();
// 2. Simulate user action
//
@@ -439,12 +449,8 @@ void tst_QWebEngineDownloads::downloadTwoLinks()
QVERIFY(waitForSignal(&page, &QWebEnginePage::loadFinished, [&](bool ok){ loadOk = ok; }));
QVERIFY(loadOk);
- auto favIconRR = waitForRequest(&server);
+ auto favIconRR = waitForFaviconRequest(&server);
QVERIFY(favIconRR);
- QCOMPARE(favIconRR->requestMethod(), QByteArrayLiteral("GET"));
- QCOMPARE(favIconRR->requestPath(), QByteArrayLiteral("/favicon.ico"));
- favIconRR->setResponseStatus(404);
- favIconRR->sendResponse();
QTRY_VERIFY(view.focusWidget());
QWidget *renderWidget = view.focusWidget();
@@ -541,12 +547,8 @@ void tst_QWebEngineDownloads::downloadPage()
QVERIFY(waitForSignal(&page, &QWebEnginePage::loadFinished, [&](bool ok){ loadOk = ok; }));
QVERIFY(loadOk);
- auto favIconRR = waitForRequest(&server);
+ auto favIconRR = waitForFaviconRequest(&server);
QVERIFY(favIconRR);
- QCOMPARE(favIconRR->requestMethod(), QByteArrayLiteral("GET"));
- QCOMPARE(favIconRR->requestPath(), QByteArrayLiteral("/favicon.ico"));
- favIconRR->setResponseStatus(404);
- favIconRR->sendResponse();
QTemporaryDir tmpDir;
QVERIFY(tmpDir.isValid());
@@ -593,5 +595,70 @@ void tst_QWebEngineDownloads::downloadPage()
QVERIFY(file.exists());
}
+void tst_QWebEngineDownloads::downloadViaSetUrl()
+{
+ // Reproduce the scenario described in QTBUG-63388 by triggering downloads
+ // of the same file multiple times via QWebEnginePage::setUrl
+
+ HttpServer server;
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy urlSpy(&page, &QWebEnginePage::urlChanged);
+ const QUrl indexUrl = server.url();
+ const QUrl fileUrl = server.url(QByteArrayLiteral("/file"));
+
+ // Set up the test scenario by trying to load some unrelated HTML.
+
+ page.setUrl(indexUrl);
+
+ auto indexRR = waitForRequest(&server);
+ QVERIFY(indexRR);
+ QCOMPARE(indexRR->requestMethod(), QByteArrayLiteral("GET"));
+ QCOMPARE(indexRR->requestPath(), QByteArrayLiteral("/"));
+ indexRR->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html"));
+ indexRR->setResponseBody(QByteArrayLiteral("<html><body>Hello</body></html>"));
+ indexRR->sendResponse();
+
+ auto indexFavRR = waitForFaviconRequest(&server);
+ QVERIFY(indexFavRR);
+
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(urlSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), indexUrl);
+
+ // Download files via setUrl. With QTBUG-63388 after the first iteration the
+ // downloads would be triggered for indexUrl and not fileUrl.
+
+ QVector<QUrl> downloadUrls;
+ QObject::connect(&profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ downloadUrls.append(item->url());
+ });
+
+ for (int i = 0; i != 3; ++i) {
+ page.setUrl(fileUrl);
+ QCOMPARE(page.url(), fileUrl);
+
+ auto fileRR = waitForRequest(&server);
+ QVERIFY(fileRR);
+ fileRR->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ fileRR->setResponseBody(QByteArrayLiteral("redacted"));
+ fileRR->sendResponse();
+
+ auto fileFavRR = waitForFaviconRequest(&server);
+ QVERIFY(fileFavRR);
+
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(urlSpy.count(), 2);
+ QTRY_COMPARE(downloadUrls.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), false);
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), fileUrl);
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), indexUrl);
+ QCOMPARE(downloadUrls.takeFirst(), fileUrl);
+ QCOMPARE(page.url(), indexUrl);
+ }
+}
+
QTEST_MAIN(tst_QWebEngineDownloads)
#include "tst_qwebenginedownloads.moc"
diff --git a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
index a2dbd4d70..47c09e1ce 100644
--- a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
+++ b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
@@ -1,4 +1,4 @@
include(../tests.pri)
QT *= core-private
-qtConfig(printing-and-pdf): DEFINES+=QWEBENGINEPAGE_PDFPRINTINGENABLED
+qtConfig(webengine-printing-and-pdf): DEFINES+=QWEBENGINEPAGE_PDFPRINTINGENABLED
diff --git a/tests/auto/widgets/qwebenginepage/resources/bar.txt b/tests/auto/widgets/qwebenginepage/resources/bar.txt
new file mode 100644
index 000000000..5716ca598
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/bar.txt
@@ -0,0 +1 @@
+bar
diff --git a/tests/auto/widgets/qwebenginepage/resources/foo.txt b/tests/auto/widgets/qwebenginepage/resources/foo.txt
new file mode 100644
index 000000000..257cc5642
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/foo.txt
@@ -0,0 +1 @@
+foo
diff --git a/tests/auto/widgets/qwebenginepage/resources/path with spaces.txt b/tests/auto/widgets/qwebenginepage/resources/path with spaces.txt
new file mode 100644
index 000000000..4f79cb0dd
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/path with spaces.txt
@@ -0,0 +1 @@
+contents with spaces
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index b4b1abc8c..1c9b668ae 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -193,6 +193,8 @@ private Q_SLOTS:
void setUrlWithPendingLoads();
void setUrlToEmpty();
void setUrlToInvalid();
+ void setUrlToBadDomain();
+ void setUrlToBadPort();
void setUrlHistory();
void setUrlUsingStateObject();
void setUrlThenLoads_data();
@@ -200,6 +202,7 @@ private Q_SLOTS:
void loadFinishedAfterNotFoundError();
void loadInSignalHandlers_data();
void loadInSignalHandlers();
+ void loadFromQrc();
void restoreHistory();
void toPlainTextLoadFinishedRace_data();
@@ -2655,18 +2658,19 @@ Q_OBJECT
public:
GetUserMediaTestPage()
: m_gotRequest(false)
+ , m_loadSucceeded(false)
{
connect(this, &QWebEnginePage::featurePermissionRequested, this, &GetUserMediaTestPage::onFeaturePermissionRequested);
-
+ connect(this, &QWebEnginePage::loadFinished, [this](bool success){
+ m_loadSucceeded = success;
+ });
// We need to load content from a resource in order for the securityOrigin to be valid.
- QSignalSpy loadSpy(this, SIGNAL(loadFinished(bool)));
load(QUrl("qrc:///resources/content.html"));
- QTRY_COMPARE(loadSpy.count(), 1);
}
void jsGetUserMedia(const QString & constraints)
{
- runJavaScript(
+ evaluateJavaScriptSync(this,
QStringLiteral(
"var promiseFulfilled = false;"
"var promiseRejected = false;"
@@ -2707,6 +2711,11 @@ public:
return m_gotRequest;
}
+ bool loadSucceeded() const
+ {
+ return m_loadSucceeded;
+ }
+
private Q_SLOTS:
void onFeaturePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature)
{
@@ -2717,6 +2726,7 @@ private Q_SLOTS:
private:
bool m_gotRequest;
+ bool m_loadSucceeded;
QWebEnginePage::Feature m_requestedFeature;
QUrl m_requestSecurityOrigin;
@@ -2747,6 +2757,7 @@ void tst_QWebEnginePage::getUserMediaRequest()
QFETCH(QWebEnginePage::Feature, feature);
GetUserMediaTestPage page;
+ QTRY_VERIFY_WITH_TIMEOUT(page.loadSucceeded(), 20000);
page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
// 1. Rejecting request on C++ side should reject promise on JS side.
@@ -2775,6 +2786,7 @@ void tst_QWebEnginePage::getUserMediaRequest()
void tst_QWebEnginePage::getUserMediaRequestDesktopAudio()
{
GetUserMediaTestPage page;
+ QTRY_VERIFY_WITH_TIMEOUT(page.loadSucceeded(), 20000);
page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
// Audio-only desktop capture is not supported. JS Promise should be
@@ -2792,6 +2804,7 @@ void tst_QWebEnginePage::getUserMediaRequestDesktopAudio()
void tst_QWebEnginePage::getUserMediaRequestSettingDisabled()
{
GetUserMediaTestPage page;
+ QTRY_VERIFY_WITH_TIMEOUT(page.loadSucceeded(), 20000);
page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, false);
// With the setting disabled, the JS Promise should be rejected without
@@ -3180,21 +3193,19 @@ void tst_QWebEnginePage::progressSignal()
void tst_QWebEnginePage::urlChange()
{
- QSignalSpy urlSpy(m_page, SIGNAL(urlChanged(QUrl)));
+ QSignalSpy urlSpy(m_page, &QWebEnginePage::urlChanged);
QUrl dataUrl("data:text/html,<h1>Test");
m_view->setUrl(dataUrl);
- QVERIFY(urlSpy.wait());
-
- QCOMPARE(urlSpy.size(), 1);
+ QTRY_COMPARE(urlSpy.size(), 1);
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), dataUrl);
QUrl dataUrl2("data:text/html,<html><head><title>title</title></head><body><h1>Test</body></html>");
m_view->setUrl(dataUrl2);
- QVERIFY(urlSpy.wait());
-
- QCOMPARE(urlSpy.size(), 2);
+ QTRY_COMPARE(urlSpy.size(), 1);
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), dataUrl2);
}
class FakeReply : public QNetworkReply {
@@ -3305,7 +3316,7 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures()
page.load(second);
QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 12000);
- QCOMPARE(page.url(), first);
+ QCOMPARE(page.url(), second);
QCOMPARE(page.requestedUrl(), second);
QVERIFY(!spy.at(1).first().toBool());
}
@@ -3819,6 +3830,90 @@ void tst_QWebEnginePage::setUrlToInvalid()
QCOMPARE(baseUrlSync(&page), aboutBlank);
}
+void tst_QWebEnginePage::setUrlToBadDomain()
+{
+ // Failing to load a URL should still emit a urlChanged signal.
+ //
+ // This test is based on the scenario in QTBUG-48995 where the second setUrl
+ // call first triggers an unexpected additional urlChanged signal with the
+ // original url before the expected signal with the new url.
+
+ // RFC 2606 says the .invalid TLD should be invalid.
+ const QUrl url1 = QStringLiteral("http://this.is.definitely.invalid/");
+ const QUrl url2 = QStringLiteral("http://this.is.also.invalid/");
+ QWebEnginePage page;
+ QSignalSpy urlSpy(&page, &QWebEnginePage::urlChanged);
+ QSignalSpy titleSpy(&page, &QWebEnginePage::titleChanged);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+
+ page.setUrl(url1);
+
+ QTRY_COMPARE(urlSpy.count(), 1);
+ QTRY_COMPARE(titleSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url1);
+ QCOMPARE(titleSpy.takeFirst().value(0).toString(), url1.host());
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), false);
+
+ QCOMPARE(page.url(), url1);
+ QCOMPARE(page.title(), url1.host());
+
+ page.setUrl(url2);
+
+ QTRY_COMPARE(urlSpy.count(), 1);
+ QTRY_COMPARE(titleSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url2);
+ QCOMPARE(titleSpy.takeFirst().value(0).toString(), url2.host());
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), false);
+
+ QCOMPARE(page.url(), url2);
+ QCOMPARE(page.title(), url2.host());
+}
+
+void tst_QWebEnginePage::setUrlToBadPort()
+{
+ // Failing to load a URL should still emit a urlChanged signal.
+
+ // Ports 244-245 are hopefully unbound (marked unassigned in RFC1700).
+ const QUrl url1 = QStringLiteral("http://127.0.0.1:244/");
+ const QUrl url2 = QStringLiteral("http://127.0.0.1:245/");
+ QWebEnginePage page;
+ QSignalSpy urlSpy(&page, &QWebEnginePage::urlChanged);
+ QSignalSpy titleSpy(&page, &QWebEnginePage::titleChanged);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+
+ page.setUrl(url1);
+
+ QTRY_COMPARE(urlSpy.count(), 1);
+ QTRY_COMPARE(titleSpy.count(), 2);
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url1);
+ QCOMPARE(titleSpy.takeFirst().value(0).toString(), url1.authority());
+ QCOMPARE(titleSpy.takeFirst().value(0).toString(), url1.host());
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), false);
+
+ QCOMPARE(page.url(), url1);
+ QCOMPARE(page.title(), url1.host());
+
+ page.setUrl(url2);
+
+ QTRY_COMPARE(urlSpy.count(), 1);
+ QTRY_COMPARE(titleSpy.count(), 2);
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url2);
+ QCOMPARE(titleSpy.takeFirst().value(0).toString(), url2.authority());
+ QCOMPARE(titleSpy.takeFirst().value(0).toString(), url2.host());
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), false);
+
+ QCOMPARE(page.url(), url2);
+ QCOMPARE(page.title(), url2.host());
+}
+
static QStringList collectHistoryUrls(QWebEngineHistory *history)
{
QStringList urls;
@@ -3979,9 +4074,8 @@ void tst_QWebEnginePage::setUrlThenLoads()
const QUrl urlToLoad1("qrc:/resources/test2.html");
const QUrl urlToLoad2("qrc:/resources/test1.html");
- // Just after first load. URL didn't changed yet.
m_page->load(urlToLoad1);
- QCOMPARE(m_page->url(), url);
+ QCOMPARE(m_page->url(), urlToLoad1);
QCOMPARE(m_page->requestedUrl(), urlToLoad1);
// baseUrlSync spins an event loop and this sometimes return the next result.
// QCOMPARE(baseUrlSync(m_page), baseUrl);
@@ -3995,9 +4089,8 @@ void tst_QWebEnginePage::setUrlThenLoads()
QCOMPARE(m_page->requestedUrl(), urlToLoad1);
QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
- // Just after second load. URL didn't changed yet.
m_page->load(urlToLoad2);
- QCOMPARE(m_page->url(), urlToLoad1);
+ QCOMPARE(m_page->url(), urlToLoad2);
QCOMPARE(m_page->requestedUrl(), urlToLoad2);
QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
QTRY_COMPARE(startedSpy.count(), 3);
@@ -4120,6 +4213,41 @@ void tst_QWebEnginePage::loadInSignalHandlers()
QCOMPARE(m_page->url(), urlForSetter);
}
+void tst_QWebEnginePage::loadFromQrc()
+{
+ QWebEnginePage page;
+ QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
+
+ // Standard case.
+ page.load(QStringLiteral("qrc:///resources/foo.txt"));
+ QTRY_COMPARE(spy.count(), 1);
+ QCOMPARE(spy.takeFirst().value(0).toBool(), true);
+ QCOMPARE(toPlainTextSync(&page), QStringLiteral("foo\n"));
+
+ // Query and fragment parts are ignored.
+ page.load(QStringLiteral("qrc:///resources/bar.txt?foo=1#bar"));
+ QTRY_COMPARE(spy.count(), 1);
+ QCOMPARE(spy.takeFirst().value(0).toBool(), true);
+ QCOMPARE(toPlainTextSync(&page), QStringLiteral("bar\n"));
+
+ // Literal spaces are OK.
+ page.load(QStringLiteral("qrc:///resources/path with spaces.txt"));
+ QTRY_COMPARE(spy.count(), 1);
+ QCOMPARE(spy.takeFirst().value(0).toBool(), true);
+ QCOMPARE(toPlainTextSync(&page), QStringLiteral("contents with spaces\n"));
+
+ // Escaped spaces are OK too.
+ page.load(QStringLiteral("qrc:///resources/path%20with%20spaces.txt"));
+ QTRY_COMPARE(spy.count(), 1);
+ QCOMPARE(spy.takeFirst().value(0).toBool(), true);
+ QCOMPARE(toPlainTextSync(&page), QStringLiteral("contents with spaces\n"));
+
+ // Resource not found, loading fails.
+ page.load(QStringLiteral("qrc:///nope"));
+ QTRY_COMPARE(spy.count(), 1);
+ QCOMPARE(spy.takeFirst().value(0).toBool(), false);
+}
+
void tst_QWebEnginePage::restoreHistory()
{
QWebChannel channel;
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
index 4fddd7a3f..fc83aefa5 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
@@ -19,5 +19,8 @@
<file>resources/test2.html</file>
<file>resources/testiframe.html</file>
<file>resources/testiframe2.html</file>
+ <file>resources/foo.txt</file>
+ <file>resources/bar.txt</file>
+ <file>resources/path with spaces.txt</file>
</qresource>
</RCC>
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index c3c8f9b28..8d2f92d96 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -35,6 +35,7 @@
#include <qtemporarydir.h>
#include <QClipboard>
#include <QCompleter>
+#include <QLabel>
#include <QLineEdit>
#include <QHBoxLayout>
#include <QMenu>
@@ -172,6 +173,9 @@ private Q_SLOTS:
void imeCompositionQueryEvent_data();
void imeCompositionQueryEvent();
void newlineInTextarea();
+
+ void mouseLeave();
+
#ifndef QT_NO_CLIPBOARD
void globalMouseSelection();
#endif
@@ -2423,5 +2427,55 @@ void tst_QWebEngineView::contextMenu()
QTRY_COMPARE(view.findChildren<QMenu *>().count(), childrenCount);
}
+void tst_QWebEngineView::mouseLeave()
+{
+ QScopedPointer<QWidget> containerWidget(new QWidget);
+
+ QLabel *label = new QLabel(containerWidget.data());
+ label->setStyleSheet("background-color: red;");
+ label->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+ label->setMinimumHeight(100);
+
+ QWebEngineView *view = new QWebEngineView(containerWidget.data());
+ view->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed));
+ view->setMinimumHeight(100);
+
+ QVBoxLayout *layout = new QVBoxLayout;
+ layout->setAlignment(Qt::AlignTop);
+ layout->setSpacing(0);
+ layout->setMargin(0);
+ layout->addWidget(label);
+ layout->addWidget(view);
+ containerWidget->setLayout(layout);
+ containerWidget->show();
+ QVERIFY(QTest::qWaitForWindowExposed(containerWidget.data()));
+ QTest::mouseMove(containerWidget->windowHandle(), QPoint(0, 0));
+
+ auto innerText = [view]() -> QString {
+ return evaluateJavaScriptSync(view->page(), "document.getElementById('testDiv').innerText").toString();
+ };
+
+ QSignalSpy loadFinishedSpy(view, SIGNAL(loadFinished(bool)));
+ view->setHtml("<html>"
+ "<head><script>"
+ "function init() {"
+ " var div = document.getElementById('testDiv');"
+ " div.onmouseenter = function(e) { div.innerText = 'Mouse IN' };"
+ " div.onmouseleave = function(e) { div.innerText = 'Mouse OUT' };"
+ "}"
+ "</script></head>"
+ "<body onload='init()' style='margin: 0px; padding: 0px'>"
+ " <div id='testDiv' style='width: 100%; height: 100%; background-color: green' />"
+ "</body>"
+ "</html>");
+ QVERIFY(loadFinishedSpy.wait());
+ QVERIFY(innerText().isEmpty());
+
+ QTest::mouseMove(containerWidget->windowHandle(), QPoint(50, 150));
+ QTRY_COMPARE(innerText(), QStringLiteral("Mouse IN"));
+ QTest::mouseMove(containerWidget->windowHandle(), QPoint(50, 50));
+ QTRY_COMPARE(innerText(), QStringLiteral("Mouse OUT"));
+}
+
QTEST_MAIN(tst_QWebEngineView)
#include "tst_qwebengineview.moc"
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index 027eeb235..32a7806fe 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -19,8 +19,8 @@ qtConfig(accessibility) {
SUBDIRS += qwebengineaccessibility
}
-qtConfig(spellchecker):!cross_compile {
- !qtConfig(native-spellchecker) {
+qtConfig(webengine-spellchecker):!cross_compile {
+ !qtConfig(webengine-native-spellchecker) {
SUBDIRS += qwebenginespellcheck
} else {
message("Spellcheck test will not be built because it depends on usage of Hunspell dictionaries.")