summaryrefslogtreecommitdiffstats
path: root/tests/auto
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-05-28 09:55:20 +0200
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-05-28 09:55:20 +0200
commit5087a4eaa32e08fe59f1f5b71dc21dda0876a759 (patch)
tree234e059dbe9226f242ca15b063952ad37e4f54da /tests/auto
parent6eadb2f2588b240b5fcda38e1f68a49a4690eb6b (diff)
parentf2db8f1988a3767d4f35aa4724d4e168e80dad59 (diff)
Merge remote-tracking branch 'origin/5.15' into dev
Diffstat (limited to 'tests/auto')
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.html16
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.js3
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp88
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc2
-rw-r--r--tests/auto/quick/qmltests/data/TestWebEngineView.qml7
-rw-r--r--tests/auto/quick/qmltests/data/tst_certificateError.qml114
-rw-r--r--tests/auto/quick/qmltests/qmltests.pro1
-rw-r--r--tests/auto/quick/qmltests/tst_qmltests.cpp4
-rw-r--r--tests/auto/quick/qmltests2/data/tst_filePicker.qml40
-rw-r--r--tests/auto/shared/httpreqrep.h4
-rw-r--r--tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp6
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp88
12 files changed, 333 insertions, 40 deletions
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.html
new file mode 100644
index 000000000..af44b45a2
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.html
@@ -0,0 +1,16 @@
+<!DOCTYPE html>
+<html>
+ <body>
+ <script>
+ if ('serviceWorker' in navigator) {
+ window.addEventListener('load', function() {
+ navigator.serviceWorker.register('/sw.js').then(function(registration) {
+ console.log('ServiceWorker registration successful with scope: ', registration.scope);
+ }, function(err) {
+ console.error('ServiceWorker registration failed: ', err);
+ });
+ });
+ }
+ </script>
+ </body>
+</html>
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.js b/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.js
new file mode 100644
index 000000000..2216e2a07
--- /dev/null
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/sw.js
@@ -0,0 +1,3 @@
+self.addEventListener('install', function(event) {
+ console.log('ServiceWorker installed');
+});
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index b8ecce635..350c15174 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -74,6 +74,8 @@ private Q_SLOTS:
void passRefererHeader();
void initiator_data();
void initiator();
+ void jsServiceWorker_data();
+ void jsServiceWorker();
};
tst_QWebEngineUrlRequestInterceptor::tst_QWebEngineUrlRequestInterceptor()
@@ -186,6 +188,58 @@ public:
}
};
+class TestServer : public HttpServer
+{
+public:
+ TestServer()
+ {
+ connect(this, &HttpServer::newRequest, this, &TestServer::onNewRequest);
+ }
+
+private:
+ void onNewRequest(HttpReqRep *rr)
+ {
+ const QDir resourceDir(TESTS_SOURCE_DIR "qwebengineurlrequestinterceptor/resources");
+ QString path = rr->requestPath();
+ path.remove(0, 1);
+
+ if (rr->requestMethod() != "GET" || !resourceDir.exists(path))
+ {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ return;
+ }
+
+ QFile file(resourceDir.filePath(path));
+ file.open(QIODevice::ReadOnly);
+ QByteArray data = file.readAll();
+ rr->setResponseBody(data);
+ QMimeDatabase db;
+ QMimeType mime = db.mimeTypeForFileNameAndData(file.fileName(), data);
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), mime.name().toUtf8());
+ rr->sendResponse();
+ }
+};
+
+class ConsolePage : public QWebEnginePage {
+ Q_OBJECT
+public:
+ ConsolePage(QWebEngineProfile* profile) : QWebEnginePage(profile) {}
+
+ virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID)
+ {
+ levels.append(level);
+ messages.append(message);
+ lineNumbers.append(lineNumber);
+ sourceIDs.append(sourceID);
+ }
+
+ QList<int> levels;
+ QStringList messages;
+ QList<int> lineNumbers;
+ QStringList sourceIDs;
+};
+
void tst_QWebEngineUrlRequestInterceptor::interceptRequest_data()
{
QTest::addColumn<InterceptorSetter>("setter");
@@ -699,5 +753,39 @@ void tst_QWebEngineUrlRequestInterceptor::initiator()
QVERIFY(interceptor.requestInitiatorUrls[info.requestUrl].contains(info.initiator));
}
+void tst_QWebEngineUrlRequestInterceptor::jsServiceWorker_data()
+{
+ interceptRequest_data();
+}
+
+void tst_QWebEngineUrlRequestInterceptor::jsServiceWorker()
+{
+ QFETCH(InterceptorSetter, setter);
+
+ TestServer server;
+ QVERIFY(server.start());
+
+ QWebEngineProfile profile(QStringLiteral("Test"));
+ std::unique_ptr<ConsolePage> page;
+ page.reset(new ConsolePage(&profile));
+ TestRequestInterceptor interceptor(/* intercept */ false);
+ (profile.*setter)(&interceptor);
+ QVERIFY(loadSync(page.get(), server.url("/sw.html")));
+
+ // We expect only one message here, because logging of services workers is not exposed in our API.
+ QTRY_COMPARE(page->messages.count(), 1);
+ QCOMPARE(page->levels.at(0), QWebEnginePage::InfoMessageLevel);
+
+ QUrl firstPartyUrl = QUrl(server.url().toString() + "sw.js");
+ QList<RequestInfo> infos;
+ // Service Worker
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker);
+ foreach (auto info, infos)
+ QCOMPARE(info.firstPartyUrl, firstPartyUrl);
+
+ QVERIFY(server.stop());
+}
+
QTEST_MAIN(tst_QWebEngineUrlRequestInterceptor)
#include "tst_qwebengineurlrequestinterceptor.moc"
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc
index 13dbb134e..6a34635f7 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc
@@ -17,6 +17,8 @@
<file>resources/resource_in_iframe.html</file>
<file>resources/script.js</file>
<file>resources/style.css</file>
+ <file>resources/sw.html</file>
+ <file>resources/sw.js</file>
<file>resources/icons/favicon.png</file>
</qresource>
</RCC>
diff --git a/tests/auto/quick/qmltests/data/TestWebEngineView.qml b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
index f5e83c5d2..6db076ae8 100644
--- a/tests/auto/quick/qmltests/data/TestWebEngineView.qml
+++ b/tests/auto/quick/qmltests/data/TestWebEngineView.qml
@@ -111,5 +111,12 @@ WebEngineView {
onWindowCloseRequested: {
windowCloseRequestedSignalEmitted = true;
}
+
+ function getBodyText() {
+ let text
+ runJavaScript('document.body.innerText', function(t) { text = t })
+ testCase.tryVerify(function() { return text !== undefined })
+ return text
+ }
}
diff --git a/tests/auto/quick/qmltests/data/tst_certificateError.qml b/tests/auto/quick/qmltests/data/tst_certificateError.qml
new file mode 100644
index 000000000..0629be175
--- /dev/null
+++ b/tests/auto/quick/qmltests/data/tst_certificateError.qml
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2020 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.2
+import QtTest 1.0
+import QtWebEngine 1.9
+
+import Test.Shared 1.0 as Shared
+
+TestWebEngineView {
+ id: view; width: 320; height: 320
+
+ property bool deferError: false
+ property bool acceptCertificate: false
+
+ onCertificateError: function(error) {
+ if (deferError)
+ error.defer()
+ else if (acceptCertificate)
+ error.ignoreCertificateError()
+ else
+ error.rejectCertificate()
+ }
+
+ SignalSpy {
+ id: spyError
+ target: view
+ signalName: 'certificateError'
+ }
+
+ TestCase {
+ name: 'CertificateError'
+ when: windowShown
+
+ function initTestCase() {
+ Shared.HttpsServer.setExpectError(true)
+ Shared.HttpsServer.newRequest.connect(function (request) {
+ request.setResponseBody('<html><body>Test</body></html>')
+ request.sendResponse()
+ })
+ view.settings.errorPageEnabled = false
+ }
+
+ function init() {
+ verify(Shared.HttpsServer.start())
+ }
+
+ function cleanup() {
+ Shared.HttpsServer.stop()
+ view.deferError = false
+ view.acceptCertificate = false
+ spyError.clear()
+ }
+
+ function test_error_data() {
+ return [
+ { tag: 'reject', deferError: false, acceptCertificate: false, expectedContent: '' },
+ { tag: 'defer_reject', deferError: true, acceptCertificate: false, expectedContent: '' },
+ { tag: 'defer_accept', deferError: true, acceptCertificate: true, expectedContent: 'Test' },
+ ]
+ }
+
+ function test_error(data) {
+ view.deferError = data.deferError
+ view.acceptCertificate = data.acceptCertificate
+ view.url = Shared.HttpsServer.url()
+
+ if (data.deferError) {
+ spyError.wait()
+ compare(spyError.count, 1)
+ compare('', view.getBodyText())
+
+ let error = spyError.signalArguments[0][0]
+ if (data.acceptCertificate)
+ error.ignoreCertificateError()
+ else
+ error.rejectCertificate()
+ }
+
+ if (data.acceptCertificate)
+ verify(view.waitForLoadSucceeded())
+ else
+ verify(view.waitForLoadFailed())
+
+ compare(spyError.count, 1)
+ compare(data.expectedContent, view.getBodyText())
+ }
+ }
+}
diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro
index 5c57f7ad9..6bec6dc0d 100644
--- a/tests/auto/quick/qmltests/qmltests.pro
+++ b/tests/auto/quick/qmltests/qmltests.pro
@@ -1,4 +1,5 @@
include(../tests.pri)
+include(../../shared/https.pri)
QT += qmltest
diff --git a/tests/auto/quick/qmltests/tst_qmltests.cpp b/tests/auto/quick/qmltests/tst_qmltests.cpp
index 9e8d25222..0d830931d 100644
--- a/tests/auto/quick/qmltests/tst_qmltests.cpp
+++ b/tests/auto/quick/qmltests/tst_qmltests.cpp
@@ -26,6 +26,8 @@
**
****************************************************************************/
+#include <httpsserver.h>
+
#include <QtCore/QScopedPointer>
#include <QTemporaryDir>
#include <QtQuickTest/quicktest.h>
@@ -144,6 +146,8 @@ int main(int argc, char **argv)
QTEST_SET_MAIN_SOURCE_PATH
+ qmlRegisterSingletonType<HttpsServer>("Test.Shared", 1, 0, "HttpsServer", [&] (QQmlEngine *, QJSEngine *) { return new HttpsServer; });
+
int i = quick_test_main(argc, argv, "qmltests", QUICK_TEST_SOURCE_DIR);
return i;
}
diff --git a/tests/auto/quick/qmltests2/data/tst_filePicker.qml b/tests/auto/quick/qmltests2/data/tst_filePicker.qml
index ffd7ef87b..ab30d9e82 100644
--- a/tests/auto/quick/qmltests2/data/tst_filePicker.qml
+++ b/tests/auto/quick/qmltests2/data/tst_filePicker.qml
@@ -36,6 +36,7 @@ TestWebEngineView {
id: webEngineView
width: 400
height: 300
+ property var titleChanges: []
function driveLetter() {
if (Qt.platform.os !== "windows")
@@ -54,6 +55,8 @@ TestWebEngineView {
signalName: "renderProcessTerminated"
}
+ onTitleChanged: { titleChanges.push(webEngineView.title) }
+
TestCase {
name: "WebEngineViewSingleFileUpload"
when: windowShown
@@ -65,6 +68,7 @@ TestWebEngineView {
FilePickerParams.nameFilters = []
titleSpy.clear()
terminationSpy.clear()
+ titleChanges = []
}
function cleanup() {
@@ -80,14 +84,14 @@ TestWebEngineView {
function test_acceptSingleFileSelection_data() {
return [
+ { tag: "test.txt", input: "test.txt", expected: "Failed to Upload" },
{ tag: driveLetter() + "/test.txt", input: driveLetter() + "/test.txt", expected: "test.txt" },
- { tag: driveLetter() + "test.txt", input: driveLetter() + "test.txt", expected: "Failed to Upload" },
{ tag: driveLetter() + "/tést.txt", input: driveLetter() + "/tést.txt", expected: "tést.txt" },
{ tag: driveLetter() + "/t%65st.txt", input: driveLetter() + "/t%65st.txt", expected: "t%65st.txt" },
{ tag: "file:///" + driveLetter() + "test.txt", input: "file:///" + driveLetter() + "test.txt", expected: "test.txt" },
{ tag: "file:///" + driveLetter() + "tést.txt", input: "file:///" + driveLetter() + "tést.txt", expected: "tést.txt" },
- { tag: "file:///" + driveLetter() + "t%65st.txt", input: "file:///" + driveLetter() + "t%65st.txt", expected: "test.txt" },
- { tag: "file://" + driveLetter() + "test.txt", input: "file://" + driveLetter() + "test.txt", expected: "test.txt" },
+ { tag: "file:///" + driveLetter() + "t%65st.txt", input: "file:///" + driveLetter() + "t%65st.txt", expected: "t%65st.txt" },
+ { tag: "file://" + driveLetter() + "test.txt", input: "file://" + driveLetter() + "test.txt", expected: "Failed to Upload" },
{ tag: "file:/" + driveLetter() + "test.txt", input: "file:/" + driveLetter() + "test.txt", expected: "test.txt"},
{ tag: "file:test//test.txt", input: "file:test//test.txt", expected: "Failed to Upload" },
{ tag: "http://test.txt", input: "http://test.txt", expected: "Failed to Upload" },
@@ -107,7 +111,10 @@ TestWebEngineView {
keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog.
tryCompare(FilePickerParams, "filePickerOpened", true);
- tryCompare(webEngineView, "title", row.expected);
+ webEngineView.url = Qt.resolvedUrl("about:blank");
+ verify(webEngineView.waitForLoadSucceeded());
+ tryCompare(webEngineView, "title", "about:blank");
+ compare(titleChanges[titleChanges.length-2], row.expected);
// Custom dialog
@@ -125,7 +132,10 @@ TestWebEngineView {
keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog.
tryVerify(function() { return finished; });
- tryCompare(webEngineView, "title", row.expected);
+ webEngineView.url = Qt.resolvedUrl("about:blank");
+ verify(webEngineView.waitForLoadSucceeded());
+ tryCompare(webEngineView, "title", "about:blank");
+ compare(titleChanges[titleChanges.length-2], row.expected);
webEngineView.fileDialogRequested.disconnect(acceptedFileHandler);
}
@@ -212,19 +222,19 @@ TestWebEngineView {
{ tag: "C:/test.txt", input: "C:/test.txt", expected: "test.txt"},
{ tag: "C:\\test.txt", input: "C:\\test.txt", expected: "test.txt"},
{ tag: "C:\\Documents and Settings\\test\\test.txt", input: "C:\\Documents and Settings\\test\\test.txt", expected: "test.txt"},
- { tag: "\\\\applib\\products\\a%2Db\\ abc%5F9\\t.est\\test.txt", input: "file://applib/products/a%2Db/ abc%5F9/4148.920a/media/test.txt", expected: "test.txt"},
- { tag: "file://applib/products/a%2Db/ abc%5F9/t.est/test.txt", input: "file://applib/products/a%2Db/ abc%5F9/4148.920a/media/test.txt", expected: "test.txt"},
+ { tag: "\\\\applib\\products\\a%2Db\\ abc%5F9\\t.est\\test.txt", input: "\\\\applib\\products\\a%2Db\\ abc%5F9\\t.est\\test.txt", expected: "test.txt"},
+ { tag: "file://applib/products/a%2Db/ abc%5F9/4148.920a/media/test.txt", input: "file://applib/products/a%2Db/ abc%5F9/4148.920a/media/test.txt", expected: "test.txt"},
{ tag: "file://applib/products/a-b/abc_1/t.est/test.txt", input: "file://applib/products/a-b/abc_1/t.est/test.txt", expected: "test.txt"},
{ tag: "file:\\\\applib\\products\\a-b\\abc_1\\t:est\\test.txt", input: "file:\\\\applib\\products\\a-b\\abc_1\\t:est\\test.txt", expected: "test.txt"},
- { tag: "file:C:/test.txt", input: "file:C:/test.txt", expected: "Failed to Upload"},
- { tag: "file:/C:/test.txt", input: "file:/C:/test.txt", expected: "Failed to Upload"},
+ { tag: "file:C:/test.txt", input: "file:C:/test.txt", expected: "test.tx"},
+ { tag: "file:/C:/test.txt", input: "file:/C:/test.txt", expected: "test.tx"},
{ tag: "file://C:/test.txt", input: "file://C:/test.txt", expected: "Failed to Upload"},
{ tag: "file:///C:test.txt", input: "file:///C:test.txt", expected: "Failed to Upload"},
{ tag: "file:///C:/test.txt", input: "file:///C:/test.txt", expected: "test.txt"},
{ tag: "file:///C:\\test.txt", input: "file:///C:\\test.txt", expected: "test.txt"},
{ tag: "file:\\//C:/test.txt", input: "file:\\//C:/test.txt", expected: "test.txt"},
{ tag: "file:\\\\/C:\\test.txt", input: "file:\\\\/C:\\test.txt", expected: "test.txt"},
- { tag: "\\\\?\\C:/test.txt", input: "\\\\?\\C:/test.txt", expected: "Failed to Upload"},
+ { tag: "\\\\?\\C:/test.txt", input: "\\\\?\\C:/test.txt", expected: "test.tx"},
];
}
@@ -241,7 +251,10 @@ TestWebEngineView {
keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog.
tryCompare(FilePickerParams, "filePickerOpened", true);
- tryCompare(webEngineView, "title", row.expected);
+ webEngineView.url = Qt.resolvedUrl("about:blank");
+ verify(webEngineView.waitForLoadSucceeded());
+ tryCompare(webEngineView, "title", "about:blank");
+ compare(titleChanges[titleChanges.length-2], row.expected);
// Custom dialog
@@ -259,7 +272,10 @@ TestWebEngineView {
keyClick(Qt.Key_Enter); // Focus is on the button. Open FileDialog.
tryVerify(function() { return finished; });
- tryCompare(webEngineView, "title", row.expected);
+ webEngineView.url = Qt.resolvedUrl("about:blank");
+ verify(webEngineView.waitForLoadSucceeded());
+ tryCompare(webEngineView, "title", "about:blank");
+ compare(titleChanges[titleChanges.length-2], row.expected);
webEngineView.fileDialogRequested.disconnect(acceptedFileHandler);
}
diff --git a/tests/auto/shared/httpreqrep.h b/tests/auto/shared/httpreqrep.h
index bee8119eb..1666b17d0 100644
--- a/tests/auto/shared/httpreqrep.h
+++ b/tests/auto/shared/httpreqrep.h
@@ -40,7 +40,7 @@ class HttpReqRep : public QObject
public:
explicit HttpReqRep(QTcpSocket *socket, QObject *parent = nullptr);
- void sendResponse();
+ Q_INVOKABLE void sendResponse();
void close();
// Request parameters (only valid after requestReceived())
@@ -61,7 +61,7 @@ public:
m_responseHeaders[key.toLower()] = std::move(value);
}
QByteArray responseBody() const { return m_responseBody; }
- void setResponseBody(QByteArray content)
+ Q_INVOKABLE void setResponseBody(QByteArray content)
{
m_responseHeaders["content-length"] = QByteArray::number(content.size());
m_responseBody = std::move(content);
diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
index 55d8ac6e8..39948c211 100644
--- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
+++ b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
@@ -1016,8 +1016,10 @@ void tst_QWebEngineDownloadItem::downloadUniqueFilenameWithTimestamp()
QRegularExpressionMatch match = fileNameCheck.match(downloadedFilePath);
QVERIFY(match.hasMatch());
// ISO 8601 Date and time in UTC
- QRegExp timestamp("^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9])([0-5][0-9])([0-5][0-9])([.][0-9]+)?(Z|[+-](?:2[0-3]|[01][0-9])[0-5][0-9])?$");
- QVERIFY(timestamp.exactMatch(match.captured(1)));
+ QRegularExpression timestamp("^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|["
+ "12][0-9])T(2[0-3]|[01][0-9])([0-5][0-9])([0-5][0-9])([.][0-9]"
+ "+)?(Z|[+-](?:2[0-3]|[01][0-9])[0-5][0-9])?$");
+ QVERIFY(timestamp.match(match.captured(1)).hasMatch());
QCOMPARE(suggestedFileName, fileName);
}
}
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 190758ed2..7bd540cc6 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -200,11 +200,10 @@ private Q_SLOTS:
void triggerActionWithoutMenu();
void dynamicFrame();
- void notificationRequest_data();
- void notificationRequest();
+ void notificationPermission_data();
+ void notificationPermission();
void sendNotification();
void contentsSize();
- void notificationPermission();
void setLifecycleState();
void setVisible();
@@ -229,6 +228,7 @@ private Q_SLOTS:
void renderProcessPid();
void backgroundColor();
void audioMuted();
+ void closeContents();
private:
static QPoint elementCenter(QWebEnginePage *page, const QString &id);
@@ -3575,42 +3575,61 @@ public:
}
};
-void tst_QWebEnginePage::notificationRequest_data()
+void tst_QWebEnginePage::notificationPermission_data()
{
+ QTest::addColumn<bool>("setOnInit");
QTest::addColumn<QWebEnginePage::PermissionPolicy>("policy");
QTest::addColumn<QString>("permission");
- QTest::newRow("deny") << QWebEnginePage::PermissionDeniedByUser << "denied";
- QTest::newRow("grant") << QWebEnginePage::PermissionGrantedByUser << "granted";
+ QTest::newRow("denyOnInit") << true << QWebEnginePage::PermissionDeniedByUser << "denied";
+ QTest::newRow("deny") << false << QWebEnginePage::PermissionDeniedByUser << "denied";
+ QTest::newRow("grant") << false << QWebEnginePage::PermissionGrantedByUser << "granted";
+ QTest::newRow("grantOnInit") << true << QWebEnginePage::PermissionGrantedByUser << "granted";
}
-void tst_QWebEnginePage::notificationRequest()
+void tst_QWebEnginePage::notificationPermission()
{
+ QFETCH(bool, setOnInit);
QFETCH(QWebEnginePage::PermissionPolicy, policy);
QFETCH(QString, permission);
- NotificationPage page(policy);
- QVERIFY(page.spyLoad.waitForResult());
+ QWebEngineProfile otr;
+ QWebEnginePage page(&otr, nullptr);
- page.resetPermission();
- QCOMPARE(page.getPermission(), "default");
+ QUrl baseUrl("https://www.example.com/somepage.html");
- page.requestPermission();
- page.spyRequest.waitForResult();
- QVERIFY(page.spyRequest.wasCalled());
+ bool permissionRequested = false, errorState = false;
+ connect(&page, &QWebEnginePage::featurePermissionRequested, &page, [&] (const QUrl &o, QWebEnginePage::Feature f) {
+ if (f != QWebEnginePage::Notifications)
+ return;
+ if (permissionRequested || o != baseUrl.url(QUrl::RemoveFilename)) {
+ qWarning() << "Unexpected case. Can't proceed." << setOnInit << permissionRequested << o;
+ errorState = true;
+ return;
+ }
+ permissionRequested = true;
+ page.setFeaturePermission(o, f, policy);
+ });
- QCOMPARE(page.getPermission(), permission);
-}
+ if (setOnInit)
+ page.setFeaturePermission(baseUrl, QWebEnginePage::Notifications, policy);
-void tst_QWebEnginePage::notificationPermission()
-{
- QWebEngineProfile otr;
- QWebEnginePage page(&otr, nullptr);
QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
- page.setHtml(QString("<html><body>Test</body></html>"), QUrl("https://www.example.com"));
+ page.setHtml(QString("<html><body>Test</body></html>"), baseUrl);
QTRY_COMPARE(spy.count(), 1);
- QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), QLatin1String("default"));
- page.setFeaturePermission(QUrl("https://www.example.com"), QWebEnginePage::Notifications, QWebEnginePage::PermissionGrantedByUser);
- QTRY_COMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), QLatin1String("granted"));
+
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), setOnInit ? permission : QLatin1String("default"));
+
+ if (!setOnInit) {
+ page.setFeaturePermission(baseUrl, QWebEnginePage::Notifications, policy);
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), permission);
+ }
+
+ auto js = QStringLiteral("var permission; Notification.requestPermission().then(p => { permission = p })");
+ evaluateJavaScriptSync(&page, js);
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, "permission").toString(), permission);
+ // permission is not 'remembered' from api standpoint, hence is not suppressed on explicit call from JS
+ QVERIFY(permissionRequested);
+ QVERIFY(!errorState);
}
void tst_QWebEnginePage::sendNotification()
@@ -4608,6 +4627,27 @@ void tst_QWebEnginePage::audioMuted()
QCOMPARE(spy[1][0], QVariant(false));
}
+void tst_QWebEnginePage::closeContents()
+{
+ TestPage page;
+ QSignalSpy windowCreatedSpy(&page, &TestPage::windowCreated);
+ page.runJavaScript("var dialog = window.open('', '', 'width=100, height=100');");
+ QTRY_COMPARE(windowCreatedSpy.count(), 1);
+
+ QWebEngineView *dialogView = new QWebEngineView;
+ QWebEnginePage *dialogPage = page.createdWindows[0];
+ dialogPage->setView(dialogView);
+ QCOMPARE(dialogPage->lifecycleState(), QWebEnginePage::LifecycleState::Active);
+
+ // This should not crash.
+ connect(dialogPage, &QWebEnginePage::windowCloseRequested, dialogView, &QWebEngineView::close);
+ page.runJavaScript("dialog.close();");
+
+ // QWebEngineView::closeEvent() sets the life cycle state to discarded.
+ QTRY_COMPARE(dialogPage->lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
+ delete dialogView;
+}
+
static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")};
W_QTEST_MAIN(tst_QWebEnginePage, params)