summaryrefslogtreecommitdiffstats
path: root/tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests')
-rw-r--r--tests/auto/auto.pro8
-rw-r--r--tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp69
-rw-r--r--tests/auto/quick/dialogs/BLACKLIST8
-rw-r--r--tests/auto/quick/inspectorserver/tst_inspectorserver.cpp2
-rw-r--r--tests/auto/quick/publicapi/tst_publicapi.cpp31
-rw-r--r--tests/auto/quick/qmltests/data/tst_action.qml16
-rw-r--r--tests/auto/quick/qmltests/data/tst_download.qml93
-rw-r--r--tests/auto/quick/qmltests/data/tst_findText.qml84
-rw-r--r--tests/auto/quick/qquickwebengineview/BLACKLIST7
-rw-r--r--tests/auto/shared/https.pri4
-rw-r--r--tests/auto/shared/httpserver.cpp31
-rw-r--r--tests/auto/shared/httpserver.h13
-rw-r--r--tests/auto/shared/httpsserver.h81
-rw-r--r--tests/auto/shared/httpsserver.qrc6
-rw-r--r--tests/auto/shared/resources/cert.pem64
-rw-r--r--tests/auto/shared/resources/key.pem27
-rw-r--r--tests/auto/widgets/accessibility/tst_accessibility.cpp1
-rw-r--r--tests/auto/widgets/certificateerror/certificateerror.pro3
-rw-r--r--tests/auto/widgets/certificateerror/tst_certificateerror.cpp124
-rw-r--r--tests/auto/widgets/devtools/tst_devtools.cpp4
-rw-r--r--tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp34
-rw-r--r--tests/auto/widgets/loadsignals/tst_loadsignals.cpp5
-rw-r--r--tests/auto/widgets/origins/resources/redirect.css8
-rw-r--r--tests/auto/widgets/origins/resources/redirect.html10
-rw-r--r--tests/auto/widgets/origins/tst_origins.cpp88
-rw-r--r--tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp171
-rw-r--r--tests/auto/widgets/qwebenginepage/BLACKLIST5
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/lifecycle.html17
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp837
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc1
-rw-r--r--tests/auto/widgets/qwebengineprofile/BLACKLIST2
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp46
-rw-r--r--tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp134
-rw-r--r--tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp2
-rw-r--r--tests/auto/widgets/qwebengineview/BLACKLIST3
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp68
-rw-r--r--tests/auto/widgets/spellchecking/tst_spellchecking.cpp83
-rw-r--r--tests/auto/widgets/util.h2
-rw-r--r--tests/auto/widgets/widgets.pro4
-rw-r--r--tests/manual/widgets/webgl/main.cpp6
-rw-r--r--tests/quicktestbrowser/main.cpp2
-rw-r--r--tests/tests.pro6
42 files changed, 2017 insertions, 193 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro
index 06430cf8e..59bcd5aef 100644
--- a/tests/auto/auto.pro
+++ b/tests/auto/auto.pro
@@ -1,9 +1,9 @@
TEMPLATE = subdirs
-SUBDIRS = quick
+qtHaveModule(webengine) {
+ SUBDIRS += quick
+}
qtHaveModule(webenginewidgets) {
- SUBDIRS += widgets
-# core tests depend on widgets for now
- SUBDIRS += core
+ SUBDIRS += core widgets
}
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
index 7d3ad1440..c0762aa14 100644
--- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
+++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp
@@ -65,6 +65,7 @@ private Q_SLOTS:
void requestInterceptorByResourceType();
void firstPartyUrlHttp();
void passRefererHeader();
+ void initiator();
};
tst_QWebEngineUrlRequestInterceptor::tst_QWebEngineUrlRequestInterceptor()
@@ -95,11 +96,13 @@ struct RequestInfo {
RequestInfo(QWebEngineUrlRequestInfo &info)
: requestUrl(info.requestUrl())
, firstPartyUrl(info.firstPartyUrl())
+ , initiator(info.initiator())
, resourceType(info.resourceType())
{}
QUrl requestUrl;
QUrl firstPartyUrl;
+ QUrl initiator;
int resourceType;
};
@@ -111,6 +114,7 @@ class TestRequestInterceptor : public QWebEngineUrlRequestInterceptor
public:
QList<RequestInfo> requestInfos;
bool shouldIntercept;
+ QMap<QUrl, QUrl> requestInitiatorUrls;
void interceptRequest(QWebEngineUrlRequestInfo &info) override
{
@@ -125,6 +129,7 @@ public:
// Set referrer header
info.setHttpHeader(kHttpHeaderRefererName, kHttpHeaderReferrerValue);
+ requestInitiatorUrls.insert(info.requestUrl(), info.initiator());
requestInfos.append(info);
}
@@ -553,5 +558,69 @@ void tst_QWebEngineUrlRequestInterceptor::passRefererHeader()
QVERIFY(succeeded);
}
+void tst_QWebEngineUrlRequestInterceptor::initiator()
+{
+ QWebEngineProfile profile;
+ TestRequestInterceptor interceptor(/* intercept */ false);
+ profile.setUrlRequestInterceptor(&interceptor);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ QUrl url = QUrl("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_video");
+ page.setUrl(QUrl(url));
+ if (!loadSpy.wait(15000) || !loadSpy.at(0).at(0).toBool())
+ QSKIP("Couldn't load page from network, skipping test.");
+
+ QList<RequestInfo> infos;
+
+ // SubFrame
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeSubFrame));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeSubFrame);
+ foreach (auto info, infos)
+ QCOMPARE(info.initiator, interceptor.requestInitiatorUrls[info.requestUrl]);
+
+ // Stylesheet
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeStylesheet));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeStylesheet);
+ foreach (auto info, infos)
+ QCOMPARE(info.initiator, interceptor.requestInitiatorUrls[info.requestUrl]);
+
+ // Script
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeScript));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeScript);
+ foreach (auto info, infos)
+ QCOMPARE(info.initiator, interceptor.requestInitiatorUrls[info.requestUrl]);
+
+ // Image
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeImage));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeImage);
+ foreach (auto info, infos)
+ QCOMPARE(info.initiator, interceptor.requestInitiatorUrls[info.requestUrl]);
+
+ // FontResource
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFontResource));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFontResource);
+ foreach (auto info, infos)
+ QCOMPARE(info.initiator, interceptor.requestInitiatorUrls[info.requestUrl]);
+
+ // Media
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeMedia));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeMedia);
+ foreach (auto info, infos)
+ QCOMPARE(info.initiator, interceptor.requestInitiatorUrls[info.requestUrl]);
+
+ // Favicon
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFavicon));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeFavicon);
+ foreach (auto info, infos)
+ QCOMPARE(info.initiator, interceptor.requestInitiatorUrls[info.requestUrl]);
+
+ // XMLHttpRequest
+ QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeXhr));
+ infos = interceptor.getUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeXhr);
+ foreach (auto info, infos)
+ QCOMPARE(info.initiator, interceptor.requestInitiatorUrls[info.requestUrl]);
+}
+
QTEST_MAIN(tst_QWebEngineUrlRequestInterceptor)
#include "tst_qwebengineurlrequestinterceptor.moc"
diff --git a/tests/auto/quick/dialogs/BLACKLIST b/tests/auto/quick/dialogs/BLACKLIST
new file mode 100644
index 000000000..10b7391a0
--- /dev/null
+++ b/tests/auto/quick/dialogs/BLACKLIST
@@ -0,0 +1,8 @@
+[contextMenuRequested]
+osx-10.13
+[javaScriptDialogRequested]
+osx-10.13
+[colorDialogRequested]
+osx-10.13
+[fileDialogRequested]
+osx-10.13
diff --git a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
index 922c7769e..224814f7e 100644
--- a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
+++ b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp
@@ -167,7 +167,7 @@ void tst_InspectorServer::openRemoteDebuggingSession()
// - The page list didn't return a valid inspector URL
// - Or the front-end couldn't be loaded through the inspector HTTP server
// - Or the web socket connection couldn't be established between the front-end and the page through the inspector server
- QTRY_VERIFY_WITH_TIMEOUT(inspectorWebView->title().startsWith("DevTools -"), 20000);
+ QTRY_VERIFY_WITH_TIMEOUT(inspectorWebView->title().startsWith("DevTools -"), 30000);
}
QTEST_MAIN(tst_InspectorServer)
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp
index 90b768ac7..321972057 100644
--- a/tests/auto/quick/publicapi/tst_publicapi.cpp
+++ b/tests/auto/quick/publicapi/tst_publicapi.cpp
@@ -35,6 +35,7 @@
#include <QtTest/QtTest>
#include <QtWebEngine/QQuickWebEngineProfile>
#include <QtWebEngine/QQuickWebEngineScript>
+#include <QtWebEngineCore/QWebEngineFindTextResult>
#include <QtWebEngineCore/QWebEngineNotification>
#include <QtWebEngineCore/QWebEngineQuotaRequest>
#include <QtWebEngineCore/QWebEngineRegisterProtocolHandlerRequest>
@@ -80,10 +81,12 @@ static const QList<const QMetaObject *> typesToCheck = QList<const QMetaObject *
<< &QQuickWebEngineColorDialogRequest::staticMetaObject
<< &QQuickWebEngineFileDialogRequest::staticMetaObject
<< &QQuickWebEngineFormValidationMessageRequest::staticMetaObject
+ << &QQuickWebEngineTooltipRequest::staticMetaObject
<< &QQuickWebEngineContextMenuRequest::staticMetaObject
<< &QWebEngineQuotaRequest::staticMetaObject
<< &QWebEngineRegisterProtocolHandlerRequest::staticMetaObject
<< &QWebEngineNotification::staticMetaObject
+ << &QWebEngineFindTextResult::staticMetaObject
;
static QList<const char *> knownEnumNames = QList<const char *>();
@@ -259,6 +262,12 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineDownloadItem.type --> DownloadType"
<< "QQuickWebEngineDownloadItem.typeChanged() --> void"
<< "QQuickWebEngineDownloadItem.view --> QQuickWebEngineView*"
+ << "QQuickWebEngineDownloadItem.url --> QUrl"
+ << "QQuickWebEngineDownloadItem.suggestedFileName --> QString"
+ << "QQuickWebEngineDownloadItem.downloadDirectory --> QString"
+ << "QQuickWebEngineDownloadItem.downloadDirectoryChanged() --> void"
+ << "QQuickWebEngineDownloadItem.downloadFileName --> QString"
+ << "QQuickWebEngineDownloadItem.downloadFileNameChanged() --> void"
<< "QQuickWebEngineFileDialogRequest.FileModeOpen --> FileMode"
<< "QQuickWebEngineFileDialogRequest.FileModeOpenMultiple --> FileMode"
<< "QQuickWebEngineFileDialogRequest.FileModeSave --> FileMode"
@@ -269,6 +278,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineFileDialogRequest.dialogAccept(QStringList) --> void"
<< "QQuickWebEngineFileDialogRequest.dialogReject() --> void"
<< "QQuickWebEngineFileDialogRequest.mode --> FileMode"
+ << "QWebEngineFindTextResult.numberOfMatches --> int"
+ << "QWebEngineFindTextResult.activeMatch --> int"
<< "QQuickWebEngineFormValidationMessageRequest.Hide --> RequestType"
<< "QQuickWebEngineFormValidationMessageRequest.Move --> RequestType"
<< "QQuickWebEngineFormValidationMessageRequest.Show --> RequestType"
@@ -277,6 +288,13 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineFormValidationMessageRequest.subText --> QString"
<< "QQuickWebEngineFormValidationMessageRequest.text --> QString"
<< "QQuickWebEngineFormValidationMessageRequest.type --> RequestType"
+ << "QQuickWebEngineTooltipRequest.Hide --> RequestType"
+ << "QQuickWebEngineTooltipRequest.Show --> RequestType"
+ << "QQuickWebEngineTooltipRequest.x --> int"
+ << "QQuickWebEngineTooltipRequest.y --> int"
+ << "QQuickWebEngineTooltipRequest.text --> QString"
+ << "QQuickWebEngineTooltipRequest.type --> RequestType"
+ << "QQuickWebEngineTooltipRequest.accepted --> bool"
<< "QQuickWebEngineFullScreenRequest.accept() --> void"
<< "QQuickWebEngineFullScreenRequest.origin --> QUrl"
<< "QQuickWebEngineFullScreenRequest.reject() --> void"
@@ -596,6 +614,9 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.LetterExtra --> PrintedPageSizeId"
<< "QQuickWebEngineView.LetterPlus --> PrintedPageSizeId"
<< "QQuickWebEngineView.LetterSmall --> PrintedPageSizeId"
+ << "QQuickWebEngineView.LifecycleState.Active --> LifecycleState"
+ << "QQuickWebEngineView.LifecycleState.Discarded --> LifecycleState"
+ << "QQuickWebEngineView.LifecycleState.Frozen --> LifecycleState"
<< "QQuickWebEngineView.LinkClickedNavigation --> NavigationType"
<< "QQuickWebEngineView.LoadFailedStatus --> LoadStatus"
<< "QQuickWebEngineView.LoadStartedStatus --> LoadStatus"
@@ -628,6 +649,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.Prc32K --> PrintedPageSizeId"
<< "QQuickWebEngineView.Prc32KBig --> PrintedPageSizeId"
<< "QQuickWebEngineView.Quarto --> PrintedPageSizeId"
+ << "QQuickWebEngineView.RedirectNavigation --> NavigationType"
<< "QQuickWebEngineView.Redo --> WebAction"
<< "QQuickWebEngineView.Reload --> WebAction"
<< "QQuickWebEngineView.ReloadAndBypassCache --> WebAction"
@@ -676,6 +698,7 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.findText(QString) --> void"
<< "QQuickWebEngineView.findText(QString,FindFlags) --> void"
<< "QQuickWebEngineView.findText(QString,FindFlags,QJSValue) --> void"
+ << "QQuickWebEngineView.findTextFinished(QWebEngineFindTextResult) --> void"
<< "QQuickWebEngineView.formValidationMessageRequested(QQuickWebEngineFormValidationMessageRequest*) --> void"
<< "QQuickWebEngineView.fullScreenCancelled() --> void"
<< "QQuickWebEngineView.fullScreenRequested(QQuickWebEngineFullScreenRequest) --> void"
@@ -692,6 +715,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.isFullScreenChanged() --> void"
<< "QQuickWebEngineView.javaScriptConsoleMessage(JavaScriptConsoleMessageLevel,QString,int,QString) --> void"
<< "QQuickWebEngineView.javaScriptDialogRequested(QQuickWebEngineJavaScriptDialogRequest*) --> void"
+ << "QQuickWebEngineView.lifecycleState --> LifecycleState"
+ << "QQuickWebEngineView.lifecycleStateChanged(LifecycleState) --> void"
<< "QQuickWebEngineView.linkHovered(QUrl) --> void"
<< "QQuickWebEngineView.loadHtml(QString) --> void"
<< "QQuickWebEngineView.loadHtml(QString,QUrl) --> void"
@@ -715,6 +740,8 @@ static const QStringList expectedAPI = QStringList()
<< "QQuickWebEngineView.quotaRequested(QWebEngineQuotaRequest) --> void"
<< "QQuickWebEngineView.recentlyAudible --> bool"
<< "QQuickWebEngineView.recentlyAudibleChanged(bool) --> void"
+ << "QQuickWebEngineView.recommendedState --> LifecycleState"
+ << "QQuickWebEngineView.recommendedStateChanged(LifecycleState) --> void"
<< "QQuickWebEngineView.registerProtocolHandlerRequested(QWebEngineRegisterProtocolHandlerRequest) --> void"
<< "QQuickWebEngineView.reload() --> void"
<< "QQuickWebEngineView.reloadAndBypassCache() --> void"
@@ -736,6 +763,7 @@ static const QStringList expectedAPI = QStringList()
#endif
<< "QQuickWebEngineView.title --> QString"
<< "QQuickWebEngineView.titleChanged() --> void"
+ << "QQuickWebEngineView.tooltipRequested(QQuickWebEngineTooltipRequest*) --> void"
<< "QQuickWebEngineView.triggerWebAction(WebAction) --> void"
<< "QQuickWebEngineView.url --> QUrl"
<< "QQuickWebEngineView.urlChanged() --> void"
@@ -811,8 +839,9 @@ static void checkKnownType(const QByteArray &typeName)
static void gatherAPI(const QString &prefix, const QMetaEnum &metaEnum, QStringList *output)
{
+ const auto format = metaEnum.isScoped() ? "%1%3.%2 --> %3" : "%1%2 --> %3";
for (int i = 0; i < metaEnum.keyCount(); ++i)
- *output << QString::fromLatin1("%1%2 --> %3").arg(prefix).arg(metaEnum.key(i)).arg(metaEnum.name());
+ *output << QString::fromLatin1(format).arg(prefix).arg(metaEnum.key(i)).arg(metaEnum.name());
}
static void gatherAPI(const QString &prefix, const QMetaProperty &property, QStringList *output)
diff --git a/tests/auto/quick/qmltests/data/tst_action.qml b/tests/auto/quick/qmltests/data/tst_action.qml
index 56a91d8d0..852d4145a 100644
--- a/tests/auto/quick/qmltests/data/tst_action.qml
+++ b/tests/auto/quick/qmltests/data/tst_action.qml
@@ -51,8 +51,8 @@ TestWebEngineView {
{ webAction: WebEngineView.Forward, text: "Forward", iconName: "go-next", enabled: false },
{ webAction: WebEngineView.Stop, text: "Stop", iconName: "", enabled: false },
{ webAction: WebEngineView.Reload, text: "Reload", iconName: "view-refresh", enabled: true },
- { webAction: WebEngineView.Cut, text: "Cut", iconName: "Cut", enabled: true },
- { webAction: WebEngineView.Copy, text: "Copy", iconName: "", enabled: true },
+ { webAction: WebEngineView.Cut, text: "Cut", iconName: "Cut", enabled: false },
+ { webAction: WebEngineView.Copy, text: "Copy", iconName: "", enabled: false },
{ webAction: WebEngineView.Paste, text: "Paste", iconName: "", enabled: true },
{ webAction: WebEngineView.Undo, text: "Undo", iconName: "", enabled: true },
{ webAction: WebEngineView.Redo, text: "Redo", iconName: "", enabled: true },
@@ -76,7 +76,7 @@ TestWebEngineView {
{ webAction: WebEngineView.InspectElement, text: "Inspect", iconName: "", enabled: true },
{ webAction: WebEngineView.ExitFullScreen, text: "Exit full screen", iconName: "", enabled: true },
{ webAction: WebEngineView.RequestClose, text: "Close Page", iconName: "", enabled: true },
- { webAction: WebEngineView.Unselect, text: "Unselect", iconName: "", enabled: true },
+ { webAction: WebEngineView.Unselect, text: "Unselect", iconName: "", enabled: false },
{ webAction: WebEngineView.SavePage, text: "Save page", iconName: "", enabled: true },
{ webAction: WebEngineView.ViewSource, text: "View page source", iconName: "view-source", enabled: true },
{ webAction: WebEngineView.ToggleBold, text: "&Bold", iconName: "", enabled: true },
@@ -110,17 +110,17 @@ TestWebEngineView {
webEngineView.url = Qt.resolvedUrl("test1.html");
verify(webEngineView.waitForLoadSucceeded());
- var copyAction = webEngineView.action(WebEngineView.Copy);
- verify(copyAction);
+ var selectAction = webEngineView.action(WebEngineView.SelectAll);
+ verify(selectAction);
var stopAction = webEngineView.action(WebEngineView.Stop);
verify(stopAction);
- var triggerSpy = createTemporaryObject(signalSpy, actionTests, {target: copyAction, signalName: "triggered"});
+ var triggerSpy = createTemporaryObject(signalSpy, actionTests, {target: selectAction, signalName: "triggered"});
var stopTriggerSpy = createTemporaryObject(signalSpy, actionTests, {target: stopAction, signalName: "triggered"});
- verify(copyAction.enabled);
- copyAction.trigger();
+ verify(selectAction.enabled);
+ selectAction.trigger();
compare(triggerSpy.count, 1);
verify(!stopAction.enabled);
diff --git a/tests/auto/quick/qmltests/data/tst_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml
index 5eb704cce..e049f3621 100644
--- a/tests/auto/quick/qmltests/data/tst_download.qml
+++ b/tests/auto/quick/qmltests/data/tst_download.qml
@@ -28,7 +28,7 @@
import QtQuick 2.0
import QtTest 1.0
-import QtWebEngine 1.9
+import QtWebEngine 1.10
import Qt.labs.platform 1.0
TestWebEngineView {
@@ -42,10 +42,22 @@ TestWebEngineView {
property bool cancelDownload: false
property var downloadState: []
property var downloadInterruptReason: null
+ property url downloadUrl: ""
+ property string suggestedFileName: ""
+ property string downloadDirectory: ""
+ property string downloadFileName: ""
+ property string downloadedPath: ""
+ property string downloadedSetPath: ""
+ property int downloadDirectoryChanged: 0
+ property int downloadFileNameChanged: 0
+ property int downloadPathChanged: 0
function urlToPath(url) {
var path = url.toString()
- path = path.replace(/^(file:\/{2})/,"")
+ if (Qt.platform.os !== "windows")
+ path = path.replace(/^(file:\/{2})/, "")
+ else
+ path = path.replace(/^(file:\/{3})/, "")
return path
}
@@ -66,21 +78,36 @@ TestWebEngineView {
ignoreUnknownSignals: true
onStateChanged: downloadState.push(target.state)
onInterruptReasonChanged: downloadInterruptReason = target.interruptReason
+ onDownloadDirectoryChanged: downloadDirectoryChanged++
+ onDownloadFileNameChanged: downloadFileNameChanged++
+ onPathChanged: downloadPathChanged++
}
WebEngineProfile {
id: testDownloadProfile
onDownloadRequested: {
+ testDownloadProfile.downloadPath = urlToPath(StandardPaths.writableLocation(StandardPaths.TempLocation))
downloadState.push(download.state)
downloadItemConnections.target = download
if (cancelDownload) {
download.cancel()
} else {
totalBytes = download.totalBytes
- download.path = "testfile.zip"
+
+ if (downloadedSetPath.length != 0) {
+ download.path = testDownloadProfile.downloadPath + downloadedSetPath
+ downloadedPath = download.path
+ } else {
+ download.downloadDirectory = downloadDirectory.length != 0 ? testDownloadProfile.downloadPath + downloadDirectory : testDownloadProfile.downloadPath
+ download.downloadFileName = downloadFileName.length != 0 ? downloadFileName : "testfile.zip"
+ downloadedPath = download.downloadDirectory + download.downloadFileName
+ }
+
download.accept()
}
+ downloadUrl = download.url
+ suggestedFileName = download.suggestedFileName
}
onDownloadFinished: {
receivedBytes = download.receivedBytes;
@@ -99,6 +126,13 @@ TestWebEngineView {
downloadItemConnections.target = null
downloadState = []
downloadInterruptReason = null
+ downloadDirectoryChanged = 0
+ downloadFileNameChanged = 0
+ downloadPathChanged = 0
+ downloadDirectory = ""
+ downloadFileName = ""
+ downloadedPath = ""
+ downloadedSetPath = ""
}
function test_downloadRequest() {
@@ -106,6 +140,8 @@ TestWebEngineView {
webEngineView.url = Qt.resolvedUrl("download.zip")
downLoadRequestedSpy.wait()
compare(downLoadRequestedSpy.count, 1)
+ compare(downloadUrl, webEngineView.url)
+ compare(suggestedFileName, "download.zip")
compare(downloadState[0], WebEngineDownloadItem.DownloadRequested)
verify(!downloadInterruptReason)
}
@@ -115,6 +151,8 @@ TestWebEngineView {
webEngineView.url = Qt.resolvedUrl("download.zip")
downLoadRequestedSpy.wait()
compare(downLoadRequestedSpy.count, 1)
+ compare(downloadUrl, webEngineView.url)
+ compare(suggestedFileName, "download.zip")
compare(totalBytes, 325)
verify(!downloadInterruptReason)
}
@@ -124,6 +162,8 @@ TestWebEngineView {
webEngineView.url = Qt.resolvedUrl("download.zip")
downLoadRequestedSpy.wait()
compare(downLoadRequestedSpy.count, 1)
+ compare(downloadUrl, webEngineView.url)
+ compare(suggestedFileName, "download.zip")
compare(downloadState[0], WebEngineDownloadItem.DownloadRequested)
tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadInProgress)
downloadFinishedSpy.wait()
@@ -138,6 +178,8 @@ TestWebEngineView {
webEngineView.url = Qt.resolvedUrl("download.zip")
downLoadRequestedSpy.wait()
compare(downLoadRequestedSpy.count, 1)
+ compare(downloadUrl, webEngineView.url)
+ compare(suggestedFileName, "download.zip")
compare(downloadFinishedSpy.count, 1)
tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadCancelled)
tryCompare(webEngineView, "downloadInterruptReason", WebEngineDownloadItem.UserCanceled)
@@ -153,5 +195,50 @@ TestWebEngineView {
testDownloadProfile.downloadPath = downloadPath;
compare(testDownloadProfile.downloadPath, downloadPath);
}
+
+ function test_downloadToDirectoryWithFileName() {
+ compare(downLoadRequestedSpy.count, 0);
+ compare(downloadDirectoryChanged, 0);
+ compare(downloadFileNameChanged, 0);
+ downloadDirectory = "/test/";
+ downloadFileName = "test.zip";
+ webEngineView.url = Qt.resolvedUrl("download.zip");
+ downLoadRequestedSpy.wait();
+ compare(downLoadRequestedSpy.count, 1);
+ compare(downloadUrl, webEngineView.url);
+ compare(suggestedFileName, "download.zip");
+ compare(downloadState[0], WebEngineDownloadItem.DownloadRequested);
+ tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadInProgress);
+ compare(downloadedPath, testDownloadProfile.downloadPath + downloadDirectory + downloadFileName);
+ compare(downloadDirectoryChanged, 1);
+ compare(downloadFileNameChanged, 1);
+ compare(downloadPathChanged, 2);
+ downloadFinishedSpy.wait();
+ compare(totalBytes, receivedBytes);
+ tryCompare(downloadState, "2", WebEngineDownloadItem.DownloadCompleted);
+ verify(!downloadInterruptReason);
+ }
+
+ function test_downloadWithSetPath() {
+ compare(downLoadRequestedSpy.count, 0);
+ compare(downloadDirectoryChanged, 0);
+ compare(downloadFileNameChanged, 0);
+ downloadedSetPath = "/test/test.zip";
+ webEngineView.url = Qt.resolvedUrl("download.zip");
+ downLoadRequestedSpy.wait();
+ compare(downLoadRequestedSpy.count, 1);
+ compare(downloadUrl, webEngineView.url);
+ compare(suggestedFileName, "download.zip");
+ compare(downloadState[0], WebEngineDownloadItem.DownloadRequested);
+ tryCompare(downloadState, "1", WebEngineDownloadItem.DownloadInProgress);
+ compare(downloadedPath, testDownloadProfile.downloadPath + downloadedSetPath);
+ compare(downloadDirectoryChanged, 1);
+ compare(downloadFileNameChanged, 1);
+ compare(downloadPathChanged, 2);
+ downloadFinishedSpy.wait();
+ compare(totalBytes, receivedBytes);
+ tryCompare(downloadState, "2", WebEngineDownloadItem.DownloadCompleted);
+ verify(!downloadInterruptReason);
+ }
}
}
diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml
index 14053a675..c02a1348e 100644
--- a/tests/auto/quick/qmltests/data/tst_findText.qml
+++ b/tests/auto/quick/qmltests/data/tst_findText.qml
@@ -38,9 +38,16 @@ TestWebEngineView {
property int matchCount: 0
property bool findFailed: false
+ SignalSpy {
+ id: findTextSpy
+ target: webEngineView
+ signalName: "findTextFinished"
+ }
+
function clear() {
findFailed = false
matchCount = -1
+ findTextSpy.clear()
}
function findCallbackCalled() { return matchCount != -1 }
@@ -104,6 +111,9 @@ TestWebEngineView {
webEngineView.findText("Hello", findFlags, webEngineView.findTextCallback)
tryCompare(webEngineView, "matchCount", 1)
verify(!findFailed)
+ tryCompare(findTextSpy, "count", 1)
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 1)
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 1)
}
function test_findTextCaseInsensitive() {
@@ -115,6 +125,9 @@ TestWebEngineView {
webEngineView.findText("heLLo", findFlags, webEngineView.findTextCallback)
tryCompare(webEngineView, "matchCount", 1)
verify(!findFailed)
+ tryCompare(findTextSpy, "count", 1)
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 1)
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 1)
}
function test_findTextManyMatches() {
@@ -126,6 +139,9 @@ TestWebEngineView {
webEngineView.findText("bla", findFlags, webEngineView.findTextCallback)
tryCompare(webEngineView, "matchCount", 100, 20000)
verify(!findFailed)
+ tryCompare(findTextSpy, "count", 1)
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 100)
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 1)
}
@@ -138,6 +154,9 @@ TestWebEngineView {
webEngineView.findText("heLLo", findFlags, webEngineView.findTextCallback)
tryCompare(webEngineView, "matchCount", 0)
verify(findFailed)
+ tryCompare(findTextSpy, "count", 1)
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 0)
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 0)
}
function test_findTextNotFound() {
@@ -149,6 +168,9 @@ TestWebEngineView {
webEngineView.findText("string-that-is-not-threre", findFlags, webEngineView.findTextCallback)
tryCompare(webEngineView, "matchCount", 0)
verify(findFailed)
+ tryCompare(findTextSpy, "count", 1)
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 0)
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 0)
}
function test_findTextAfterNotFound() {
@@ -160,6 +182,9 @@ TestWebEngineView {
webEngineView.findText("hello", findFlags, webEngineView.findTextCallback)
tryCompare(webEngineView, "matchCount", 0)
verify(findFailed)
+ tryCompare(findTextSpy, "count", 1)
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 0)
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 0)
webEngineView.url = Qt.resolvedUrl("test1.html")
verify(webEngineView.waitForLoadSucceeded())
@@ -168,6 +193,9 @@ TestWebEngineView {
webEngineView.findText("hello", findFlags, webEngineView.findTextCallback)
tryCompare(webEngineView, "matchCount", 1)
verify(!findFailed)
+ tryCompare(findTextSpy, "count", 1)
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 1)
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 1)
}
function test_findTextInModifiedDOMAfterNotFound() {
@@ -182,6 +210,9 @@ TestWebEngineView {
webEngineView.findText("hello", findFlags, webEngineView.findTextCallback)
tryCompare(webEngineView, "matchCount", 0, 20000)
verify(findFailed)
+ tryCompare(findTextSpy, "count", 1)
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 0)
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 0)
runJavaScript("document.body.innerHTML = 'blahellobla'");
tryVerify(function() { return getBodyInnerHTML() == "blahellobla"; }, 20000);
@@ -190,6 +221,9 @@ TestWebEngineView {
webEngineView.findText("hello", findFlags, webEngineView.findTextCallback)
tryCompare(webEngineView, "matchCount", 1)
verify(!findFailed)
+ tryCompare(findTextSpy, "count", 1)
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 1)
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 1)
}
function test_findTextInterruptedByLoad() {
@@ -227,5 +261,55 @@ TestWebEngineView {
webEngineView.findText('New page', findFlags, webEngineView.findTextCallback)
tryCompare(webEngineView, 'matchCount', 1)
}
+
+ function test_findTextActiveMatchOrdinal() {
+ webEngineView.loadHtml(
+ "<html><body>" +
+ "foo bar foo bar foo" +
+ "</body></html>");
+ verify(webEngineView.waitForLoadSucceeded());
+
+ // Iterate over all "foo" matches.
+ webEngineView.clear();
+ for (var i = 1; i <= 3; ++i) {
+ webEngineView.findText("foo");
+ findTextSpy.wait();
+ compare(findTextSpy.count, i);
+ compare(findTextSpy.signalArguments[i-1][0].numberOfMatches, 3);
+ compare(findTextSpy.signalArguments[i-1][0].activeMatch, i);
+ }
+
+ // The last match is followed by the fist one.
+ webEngineView.clear();
+ webEngineView.findText("foo");
+ findTextSpy.wait();
+ compare(findTextSpy.count, 1);
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 3);
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 1);
+
+ // The first match is preceded by the last one.
+ webEngineView.clear();
+ webEngineView.findText("foo", WebEngineView.FindBackward);
+ findTextSpy.wait();
+ compare(findTextSpy.count, 1);
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 3);
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 3);
+
+ // Finding another word resets the activeMatch.
+ webEngineView.clear();
+ webEngineView.findText("bar");
+ findTextSpy.wait();
+ compare(findTextSpy.count, 1);
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 2);
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 1);
+
+ // If no match activeMatch is 0.
+ webEngineView.clear();
+ webEngineView.findText("bla");
+ findTextSpy.wait();
+ compare(findTextSpy.count, 1);
+ compare(findTextSpy.signalArguments[0][0].numberOfMatches, 0);
+ compare(findTextSpy.signalArguments[0][0].activeMatch, 0);
+ }
}
}
diff --git a/tests/auto/quick/qquickwebengineview/BLACKLIST b/tests/auto/quick/qquickwebengineview/BLACKLIST
index 49c5332ff..d4d5c9844 100644
--- a/tests/auto/quick/qquickwebengineview/BLACKLIST
+++ b/tests/auto/quick/qquickwebengineview/BLACKLIST
@@ -1,5 +1,2 @@
-[javascriptClipboard:default]
-opensuse-leap
-
-[javascriptClipboard:canPaste]
-opensuse-leap
+[transparentWebEngineViews]
+windows
diff --git a/tests/auto/shared/https.pri b/tests/auto/shared/https.pri
new file mode 100644
index 000000000..ce4c147f7
--- /dev/null
+++ b/tests/auto/shared/https.pri
@@ -0,0 +1,4 @@
+include($$PWD/http.pri)
+
+HEADERS += $$PWD/httpsserver.h
+RESOURCES += $$PWD/httpsserver.qrc
diff --git a/tests/auto/shared/httpserver.cpp b/tests/auto/shared/httpserver.cpp
index b85af9901..e282fc8b8 100644
--- a/tests/auto/shared/httpserver.cpp
+++ b/tests/auto/shared/httpserver.cpp
@@ -31,9 +31,21 @@
Q_LOGGING_CATEGORY(gHttpServerLog, "HttpServer")
-HttpServer::HttpServer(QObject *parent) : QObject(parent)
+HttpServer::HttpServer(QObject *parent) : HttpServer(new QTcpServer, "http", parent)
{
- connect(&m_tcpServer, &QTcpServer::newConnection, this, &HttpServer::handleNewConnection);
+}
+
+HttpServer::HttpServer(QTcpServer *tcpServer, const QString &protocol, QObject *parent)
+ : QObject(parent), m_tcpServer(tcpServer)
+{
+ m_url.setHost(QStringLiteral("127.0.0.1"));
+ m_url.setScheme(protocol);
+ connect(tcpServer, &QTcpServer::newConnection, this, &HttpServer::handleNewConnection);
+}
+
+HttpServer::~HttpServer()
+{
+ delete m_tcpServer;
}
bool HttpServer::start()
@@ -41,21 +53,18 @@ bool HttpServer::start()
m_error = false;
m_expectingError = false;
- if (!m_tcpServer.listen()) {
- qCWarning(gHttpServerLog).noquote() << m_tcpServer.errorString();
+ if (!m_tcpServer->listen()) {
+ qCWarning(gHttpServerLog).noquote() << m_tcpServer->errorString();
return false;
}
- m_url.setScheme(QStringLiteral("http"));
- m_url.setHost(QStringLiteral("127.0.0.1"));
- m_url.setPort(m_tcpServer.serverPort());
-
+ m_url.setPort(m_tcpServer->serverPort());
return true;
}
bool HttpServer::stop()
{
- m_tcpServer.close();
+ m_tcpServer->close();
return m_error == m_expectingError;
}
@@ -73,12 +82,12 @@ QUrl HttpServer::url(const QString &path) const
void HttpServer::handleNewConnection()
{
- auto rr = new HttpReqRep(m_tcpServer.nextPendingConnection(), this);
+ auto rr = new HttpReqRep(m_tcpServer->nextPendingConnection(), this);
connect(rr, &HttpReqRep::requestReceived, [this, rr]() {
Q_EMIT newRequest(rr);
rr->close();
});
- connect(rr, &HttpReqRep::responseSent, [this, rr]() {
+ connect(rr, &HttpReqRep::responseSent, [rr]() {
qCInfo(gHttpServerLog).noquote() << rr->requestMethod() << rr->requestPath()
<< rr->responseStatus() << rr->responseBody().size();
});
diff --git a/tests/auto/shared/httpserver.h b/tests/auto/shared/httpserver.h
index b4649244e..57f824bb5 100644
--- a/tests/auto/shared/httpserver.h
+++ b/tests/auto/shared/httpserver.h
@@ -59,19 +59,22 @@ class HttpServer : public QObject
Q_OBJECT
public:
explicit HttpServer(QObject *parent = nullptr);
+ explicit HttpServer(QTcpServer *server, const QString &protocol, QObject *parent = nullptr);
+
+ ~HttpServer() override;
// Must be called to start listening.
//
// Returns true if a TCP port has been successfully bound.
- Q_REQUIRED_RESULT bool start();
+ Q_INVOKABLE Q_REQUIRED_RESULT bool start();
// Stops listening and performs final error checks.
- Q_REQUIRED_RESULT bool stop();
+ Q_INVOKABLE Q_REQUIRED_RESULT bool stop();
- void setExpectError(bool b);
+ Q_INVOKABLE void setExpectError(bool b);
// Full URL for given relative path
- QUrl url(const QString &path = QStringLiteral("/")) const;
+ Q_INVOKABLE QUrl url(const QString &path = QStringLiteral("/")) const;
Q_SIGNALS:
// Emitted after a HTTP request has been successfully parsed.
@@ -81,7 +84,7 @@ private Q_SLOTS:
void handleNewConnection();
private:
- QTcpServer m_tcpServer;
+ QTcpServer *m_tcpServer;
QUrl m_url;
bool m_error = false;
bool m_expectingError = false;
diff --git a/tests/auto/shared/httpsserver.h b/tests/auto/shared/httpsserver.h
new file mode 100644
index 000000000..32c8e8345
--- /dev/null
+++ b/tests/auto/shared/httpsserver.h
@@ -0,0 +1,81 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+#ifndef HTTPSSERVER_H
+#define HTTPSSERVER_H
+
+#include "httpreqrep.h"
+#include "httpserver.h"
+
+#include <QDebug>
+#include <QFile>
+#include <QSslKey>
+#include <QSslSocket>
+#include <QSslConfiguration>
+#include <QTcpServer>
+
+struct SslTcpServer : QTcpServer
+{
+ SslTcpServer() {
+ sslconf.setLocalCertificateChain(QSslCertificate::fromPath(":/resources/cert.pem"));
+ sslconf.setPrivateKey(readKey(":/resources/key.pem"));
+ }
+
+ void incomingConnection(qintptr d) override {
+ auto socket = new QSslSocket(this);
+ socket->setSslConfiguration(sslconf);
+
+ if (!socket->setSocketDescriptor(d)) {
+ qWarning() << "Failed to setup ssl socket!";
+ delete socket;
+ return;
+ }
+
+ connect(socket, QOverload<QSslSocket::SocketError>::of(&QSslSocket::error),
+ [] (QSslSocket::SocketError e) { qWarning() << "! Socket Error:" << e; });
+ connect(socket, QOverload<const QList<QSslError> &>::of(&QSslSocket::sslErrors),
+ [] (const QList<QSslError> &le) { qWarning() << "! SSL Errors:\n" << le; });
+
+ addPendingConnection(socket);
+ socket->startServerEncryption();
+ }
+
+ QSslKey readKey(const QString &path) const {
+ QFile file(path);
+ file.open(QIODevice::ReadOnly);
+ return QSslKey(file.readAll(), QSsl::Rsa, QSsl::Pem);
+ }
+
+ QSslConfiguration sslconf;
+};
+
+struct HttpsServer : HttpServer
+{
+ HttpsServer(QObject *parent = nullptr) : HttpServer(new SslTcpServer, "https", parent) { }
+};
+
+#endif
diff --git a/tests/auto/shared/httpsserver.qrc b/tests/auto/shared/httpsserver.qrc
new file mode 100644
index 000000000..ec57a1983
--- /dev/null
+++ b/tests/auto/shared/httpsserver.qrc
@@ -0,0 +1,6 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>resources/cert.pem</file>
+ <file>resources/key.pem</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/shared/resources/cert.pem b/tests/auto/shared/resources/cert.pem
new file mode 100644
index 000000000..3aaaf289c
--- /dev/null
+++ b/tests/auto/shared/resources/cert.pem
@@ -0,0 +1,64 @@
+-----BEGIN CERTIFICATE-----
+MIIEpDCCAoygAwIBAgIUO90aty9AMjvBvzfUhr1WwdBrKkMwDQYJKoZIhvcNAQEL
+BQAwfzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
+DVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDEyMDAGA1UEAwwpQmFkU1NM
+IEludGVybWVkaWF0ZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwHhcNMTkwODI2MTQ0
+NDIxWhcNMTkwODI3MTQ0NDIxWjBjMQswCQYDVQQGEwJVUzETMBEGA1UECAwKQ2Fs
+aWZvcm5pYTEWMBQGA1UEBwwNU2FuIEZyYW5jaXNjbzEPMA0GA1UECgwGQmFkU1NM
+MRYwFAYDVQQDDA0qLmJhZHNzbC50ZXN0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8A
+MIIBCgKCAQEAkybT/L4zJCqefpd+eYT6aQ0PtobQfFgP+n+z5wWoUxIAJnjb5ZW4
+7IJxka/2/ggzJOfrUBur54LkTfFQ+yX85eKYCuH0GLz+Rve50LDn0ya6qSgmEhDG
+0bend2tMZY+Nl3B+5Ane1vua8hdJjv3ZO3e5UgpQwysL54eYyhEWWlbFWF11LhEd
+MYp953UGLqoV4Mlw+Li8TmFwdKQx6icgBTuloXLzk9aUU+b6NbXdadNXkmzg09IC
+sb8pnMXiF2P9Xm5rK0IoiRkSHxVnU12nQXh65Ns/2Dj5DcbHmVdvallfr4wnLeFP
+UotysZnvFmE7FLMSr/eQfkTG+Jlb7ZhoGwIDAQABozQwMjAJBgNVHRMEAjAAMCUG
+A1UdEQQeMByCDSouYmFkc3NsLnRlc3SCC2JhZHNzbC50ZXN0MA0GCSqGSIb3DQEB
+CwUAA4ICAQA7Yc+QQzqSK15ibmaYrkqq+cumggsWLCprW8jvzhpWBt9IjToP5nsy
+sKinYPoZR8jvZ1YVotcts7uQT7DkqeWkB+l+88c7gQdgujvBo6v9/g+jrXFKgsJD
+IBmkho8hpd63Slqv2Yp4bYT20O5EvR9CQvwSkwTs+ylBNEs1Q+AbekxmBjuYUxHn
+9xL4/GZ6ufoNv676iCoXo4mnDrCD8e8MRiZoU9Lq4G41HGiLWV0tM/M6BdVJYGzl
+FcBg0ZKnQT9OCWEPRe3zyRS6a+MivPAzxS8z/kYaRN+C7H68Mib3xPDsEETz1MnO
+uzGAPHAAgtYWYJi+CaaNWkgAv4n+UIQa0oyqPn4z5hLcsO+nMBws2Sg0mkQLilBX
+N1ciCdVMi7sHKuLa7GVksq/RQrXnZcQhoYQRrZAaAHKbxyo/M2pNqmDiFJppdH7a
+6Rj2vYf6ig/FXAzDGsDvf/tsGCxgJTFzGly+GsWVe40vyjfWHxWWDU/eGjfGO05k
+Xzjm+kYGJnH2hfiIlX1Jeu/jjIodiSy31F0hvuKlJu8PfaQ7oo5neRzwRO6Wq9rR
+7DMsQN6OtXGnnA+ogC0korA+aXev6wzbwYUhzMf1YTzEjrFNIXeIHsQSzq6lPcIE
+JOly5wjyO/eNF7mpHyDX8brY6Hn+bgyDeKAmsUvhOCEXgaPpKlP4gQ==
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIGeTCCBGGgAwIBAgIUbVL7tFc7sgPIYnt+REVc0wiHdBcwDQYJKoZIhvcNAQEL
+BQAwdzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcM
+DVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDEqMCgGA1UEAwwhQmFkU1NM
+IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5MB4XDTE5MDgyNjE0NDQyMFoXDTI5
+MDgyMzE0NDQyMFowfzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWEx
+FjAUBgNVBAcMDVNhbiBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDEyMDAGA1UE
+AwwpQmFkU1NMIEludGVybWVkaWF0ZSBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkwggIi
+MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCgoU4q43DJEUyoAOeK31uyEgLn
+s5CCd6XFmGp6wln0yupwmYRaDiCoSJ1qpmjYt+gIHpDAFS2ZzR4TbZORFirjY0cQ
+6+IWwpBEQR0hOluWN99CqjdCxfuZwiTvTV3FQv1IJZ13g23Uh2xRbnrzC2muDHzT
+4ZNM3aayvziMGY6n33aksEc6WMZb3p/Qn2OepeC7EzZiy4tXKPf9OaOPbae5aJWZ
+bOzzydFLkV4UqZb5FfySt8toIivPeIlRCiPodWLb2y5DYUXyWBk1dpbIcVa/LusV
+vsBELeJ+BFDRH1NHtwOrhOkZHKMr3SQ1YRlNDEeHUVmQkori397j9JjpPzScQJ6r
+d/W4mGyzgRmguIy9IpKMbxX5/1A6c6l5q0HqMgPv84GWxlhav4xwsOf90iT2vLPZ
+yllVCgCsCfvLEyVFhER18HAo8mTkQqKL7ZO96xXHgugA7dFN/C3BdC9kYP/GbAwd
+J0R6qKrfSiyyk1VbjWfFdFH/G/bT9H0nrjMj5tCT4q/zDCb5HkBp3BOoyUKb9yyt
+a1Cht/Iu3f1SlQzsrDBt9iMMCjXoNNAJcV7ZZ6HCxcWwfAwxgylQgq8UG60shxhn
+CBPhcA8JM+mk2nghTU2pxwY/KpAd0H4/a79b0DE97dCOnNHzyP3tqP8RenG549B0
+gsNO60aG01k6P9jFuQIDAQABo4H0MIHxMB0GA1UdDgQWBBQgvWmDuYqQ6xX7y8xc
+cgky1FO7jzCBtAYDVR0jBIGsMIGpgBTUGo+svIaoSMF/shILSbeiQ1zAQKF7pHkw
+dzELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFjAUBgNVBAcMDVNh
+biBGcmFuY2lzY28xDzANBgNVBAoMBkJhZFNTTDEqMCgGA1UEAwwhQmFkU1NMIFJv
+b3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5ghR1qCPxzkfCSCwMFHm98245f0pk0zAM
+BgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjANBgkqhkiG9w0BAQsFAAOCAgEAnGr6
+t1+KNGZV9hmAE3SyMzHRpgwtqIG4kl94A7Pz3CbA8+q7u7DW8l1GdaNx2J2wo+R5
+rJi02V5e7TNa7ZS5S9WGYHZ2y6QOjXuT28VMAPX+3HAgxk3RMxocpLpkPp8hhD/9
+S5KxA6AQDUN6av8E3xeuuWYWmTvAXNHK5ABXDFxxTp902ozNnZaSk2DxAUqcsOD4
+ago0IhRdkFGe1Q7F8gOxtlUL5owNL4uhRP8BbwOja2Gopn2+kA9CNqdwPI4Ipjlr
+yo61oCqzy3RAXOUct8WAvybacADmJODAxDq9O5fAZuYZScjjj1ASowmbyDH/Wb9z
++WfiKKH4BfgOIukzK3I1M9wiSDefIodCFfEVXbdNudZj8f9Gw4RrZwkUuxDLeRWG
+ReDtzAWq7G0Diw3uX40S4jaj3MeS6oHp2Nrj/VyjSRiYTeN/pnA9N0M5VuCYYvXD
+f50rrigjQfOgb4TmnyJAjXWVkXW7Fa+ooLsbvlfr8wP8f31y1cgWPHTVIv6Kmug7
+Bg88k3x5gLTXmutDjseORonhGMRdAxHgJVf5aKfzdRpwXZTDZJXhsAz9OdlOhNZd
+UrYo680QugA0V3H5D8Egbr2AUUSMDkn133COjeOIDknFxX3qDqeTzqLZCAEBIoKn
+Adpix0jvG1Ys4Ayq6K2wQFdGFjtl6LsiGC7pWWU=
+-----END CERTIFICATE-----
diff --git a/tests/auto/shared/resources/key.pem b/tests/auto/shared/resources/key.pem
new file mode 100644
index 000000000..89922679a
--- /dev/null
+++ b/tests/auto/shared/resources/key.pem
@@ -0,0 +1,27 @@
+-----BEGIN RSA PRIVATE KEY-----
+MIIEowIBAAKCAQEAkybT/L4zJCqefpd+eYT6aQ0PtobQfFgP+n+z5wWoUxIAJnjb
+5ZW47IJxka/2/ggzJOfrUBur54LkTfFQ+yX85eKYCuH0GLz+Rve50LDn0ya6qSgm
+EhDG0bend2tMZY+Nl3B+5Ane1vua8hdJjv3ZO3e5UgpQwysL54eYyhEWWlbFWF11
+LhEdMYp953UGLqoV4Mlw+Li8TmFwdKQx6icgBTuloXLzk9aUU+b6NbXdadNXkmzg
+09ICsb8pnMXiF2P9Xm5rK0IoiRkSHxVnU12nQXh65Ns/2Dj5DcbHmVdvallfr4wn
+LeFPUotysZnvFmE7FLMSr/eQfkTG+Jlb7ZhoGwIDAQABAoIBADRXy3BL98UVo+tD
+2ClBtBFKJBy5N9ADQyvH4SZ8TLO/423L7+xqpaz7eYppHWKfaBHorTuBnFRtquhO
+vo+Xo63iPFMirMFf+NMlq2MgilYBoMQrE9+5N//BZECGWlaGCcekrH5RRIMUXLlg
+rzm98lfE7pbQNIo39bQV97NpAJqBWPuoIvCrbRCysGoA5j7ptZ/EhSlC00eA7ybD
+CeYHmh8NrsapKOTGb5u1v3paV8X/mH6vKmsVs7n6LC0opBxzM8eAHEAQ6h8rmz9H
+y99FWDYha3lOS4SLkTnuRnNHOMLJajPq3Isu+BgzLWuRGnKZ3rmuUFwPNkCZTvsV
+dTdBE4ECgYEAw6jBEil0e8Pc9sGqnz93e8qrYE9wSPso4q3BNJgTbN48kon6mqh7
+gQVgEP/75Th5YrJUrY9Pd/8H9uoMOxbDXgOXG/xNnhC0L+7aM8nhKlxCLndY1e56
+/YymYYH4+D9ZD2u526mK/nmCg2QGOkCVYYp7NXe/mA0g34drKjefmj8CgYEAwIhq
+rZhlfAvQThSOqQA9zA7NXPDh4KzIjr8htVu5YvVcv5W2uhsni9DXFaloPnhuLdJ7
+MnPF2WqzQ9YqFrGn/9/OTqeE23f60ed04qLGM4BApb45y5Kw6sCPnWu7dMYfny9i
+XeZA2A+ODmqVkrU+ZNVzqzS1krYyUP3exd1voyUCgYEAqPRARH6np3gqhqoVvA4C
+D1OjSTdPrrWzSIriG5h2rbv6ck/Tp1l1zKPnoMZrrjRmHWQA2x61cNk4926DwUKW
+0cgn5HKqU6P49Ks8oRvi48FnJNjKTXHxoqChy/GAHF4Xecl8ZMKy06v5l5v4BLVg
+SSpb2n/dYl9z05IMaBhAKeECgYBKB2n1S6ah1q0GiLL92mDoiDyAYwKG8AjBkk40
+vIsAuNUruTYkQvKmuOsqohO6CXZb2hWSpZ9KZNN+3ucaCL9PDE/4QEM+W9iuQu/X
+gLzy6npxAD6avtGVweq2ncjbMp7QB1ksP69pJDn74xGV8miGPuiVyNOUEMgyChtR
+Oz6EnQKBgEth0w80CBg6b3NKuASoc/vC08njZQvWpe5xrzY2DL8epVKb1qf6+8SE
+eX34cIcSaonEZ2g67MAeIG6jtmPwxWk4EYAsO1u4XiyziABkoNyLKVH4hZg61BsV
+jL7R5UrUvBbhKLFOwkcB4Kwdwu7COB/UKa5XJBTMbuw1UTyxlUeI
+-----END RSA PRIVATE KEY-----
diff --git a/tests/auto/widgets/accessibility/tst_accessibility.cpp b/tests/auto/widgets/accessibility/tst_accessibility.cpp
index b0165cfbc..d69a4c0a7 100644
--- a/tests/auto/widgets/accessibility/tst_accessibility.cpp
+++ b/tests/auto/widgets/accessibility/tst_accessibility.cpp
@@ -389,6 +389,7 @@ void tst_Accessibility::roles()
QWebEngineView webView;
webView.setHtml("<html><body>" + html + "</body></html>");
+ webView.show();
QSignalSpy spyFinished(&webView, &QWebEngineView::loadFinished);
QVERIFY(spyFinished.wait());
diff --git a/tests/auto/widgets/certificateerror/certificateerror.pro b/tests/auto/widgets/certificateerror/certificateerror.pro
new file mode 100644
index 000000000..73ba7515b
--- /dev/null
+++ b/tests/auto/widgets/certificateerror/certificateerror.pro
@@ -0,0 +1,3 @@
+include(../tests.pri)
+include(../../shared/https.pri)
+QT *= core-private
diff --git a/tests/auto/widgets/certificateerror/tst_certificateerror.cpp b/tests/auto/widgets/certificateerror/tst_certificateerror.cpp
new file mode 100644
index 000000000..f11d9236c
--- /dev/null
+++ b/tests/auto/widgets/certificateerror/tst_certificateerror.cpp
@@ -0,0 +1,124 @@
+/****************************************************************************
+**
+** Copyright (C) 2019 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$
+**
+****************************************************************************/
+#include <httpsserver.h>
+#include <util.h>
+
+#include <QWebEngineCertificateError>
+#include <QWebEnginePage>
+#include <QWebEngineSettings>
+
+#include <QtTest/QtTest>
+
+class tst_CertificateError : public QObject
+{
+ Q_OBJECT
+public:
+ tst_CertificateError() { }
+
+private Q_SLOTS:
+ void handleError_data();
+ void handleError();
+};
+
+struct PageWithCertificateErrorHandler : QWebEnginePage
+{
+ PageWithCertificateErrorHandler(bool defer, bool accept, QObject *p = nullptr)
+ : QWebEnginePage(p), deferError(defer), acceptCertificate(accept)
+ , loadSpy(this, &QWebEnginePage::loadFinished) {
+ }
+
+ bool deferError, acceptCertificate;
+
+ QSignalSpy loadSpy;
+ QScopedPointer<QWebEngineCertificateError> error;
+
+ bool certificateError(const QWebEngineCertificateError &e) override {
+ error.reset(new QWebEngineCertificateError(e));
+ if (deferError)
+ error->defer();
+ return acceptCertificate;
+ }
+};
+
+void tst_CertificateError::handleError_data()
+{
+ QTest::addColumn<bool>("deferError");
+ QTest::addColumn<bool>("acceptCertificate");
+ QTest::addColumn<QString>("expectedContent");
+ QTest::addRow("Reject") << false << false << QString();
+ QTest::addRow("DeferReject") << true << false << QString();
+ QTest::addRow("DeferAccept") << true << true << "TEST";
+}
+
+void tst_CertificateError::handleError()
+{
+ HttpsServer server;
+ server.setExpectError(true);
+ QVERIFY(server.start());
+
+ connect(&server, &HttpsServer::newRequest, [&] (HttpReqRep *rr) {
+ rr->setResponseBody(QByteArrayLiteral("<html><body>TEST</body></html>"));
+ rr->sendResponse();
+ });
+
+ QFETCH(bool, deferError);
+ QFETCH(bool, acceptCertificate);
+ QFETCH(QString, expectedContent);
+
+ PageWithCertificateErrorHandler page(deferError, acceptCertificate);
+ page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+
+ page.setUrl(server.url());
+ QTRY_VERIFY(page.error);
+ QVERIFY(page.error->isOverridable());
+ auto chain = page.error->certificateChain();
+ QCOMPARE(chain.size(), 2);
+ QCOMPARE(chain[0].serialNumber(), "3b:dd:1a:b7:2f:40:32:3b:c1:bf:37:d4:86:bd:56:c1:d0:6b:2a:43");
+ QCOMPARE(chain[1].serialNumber(), "6d:52:fb:b4:57:3b:b2:03:c8:62:7b:7e:44:45:5c:d3:08:87:74:17");
+
+ if (deferError) {
+ QVERIFY(page.error->deferred());
+ QVERIFY(!page.error->answered());
+ QCOMPARE(page.loadSpy.count(), 0);
+ QCOMPARE(toPlainTextSync(&page), QString());
+
+ if (acceptCertificate)
+ page.error->ignoreCertificateError();
+ else
+ page.error->rejectCertificate();
+
+ QVERIFY(page.error->answered());
+ page.error.reset();
+ }
+ QTRY_COMPARE_WITH_TIMEOUT(page.loadSpy.count(), 1, 30000);
+ QCOMPARE(page.loadSpy.takeFirst().value(0).toBool(), acceptCertificate);
+ QCOMPARE(toPlainTextSync(&page), expectedContent);
+}
+
+QTEST_MAIN(tst_CertificateError)
+#include <tst_certificateerror.moc>
diff --git a/tests/auto/widgets/devtools/tst_devtools.cpp b/tests/auto/widgets/devtools/tst_devtools.cpp
index 8f3b90a14..3026b3931 100644
--- a/tests/auto/widgets/devtools/tst_devtools.cpp
+++ b/tests/auto/widgets/devtools/tst_devtools.cpp
@@ -46,7 +46,7 @@ void tst_DevTools::attachAndDestroyPageFirst()
QSignalSpy spy(page, &QWebEnginePage::loadFinished);
page->load(QUrl("data:text/plain,foobarbaz"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 12000);
inspector->setInspectedPage(page);
page->triggerAction(QWebEnginePage::InspectElement);
@@ -67,7 +67,7 @@ void tst_DevTools::attachAndDestroyInspectorFirst()
QSignalSpy spy(page, &QWebEnginePage::loadFinished);
page->setHtml(QStringLiteral("<body><h1>FOO BAR!</h1></body>"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 12000);
page->triggerAction(QWebEnginePage::InspectElement);
diff --git a/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp b/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp
index 540c8d505..1469ddb15 100644
--- a/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp
+++ b/tests/auto/widgets/faviconmanager/tst_faviconmanager.cpp
@@ -107,7 +107,7 @@ void tst_FaviconManager::faviconLoad()
QUrl url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("faviconmanager/resources/favicon-single.html"));
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QTRY_COMPARE(iconChangedSpy.count(), 1);
@@ -132,7 +132,7 @@ void tst_FaviconManager::faviconLoadFromResources()
QUrl url("qrc:/resources/favicon-single.html");
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QTRY_COMPARE(iconChangedSpy.count(), 1);
@@ -161,7 +161,7 @@ void tst_FaviconManager::faviconLoadEncodedUrl()
QUrl url(urlString + QLatin1String("?favicon=load should work with#whitespace!"));
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QTRY_COMPARE(iconChangedSpy.count(), 1);
@@ -189,7 +189,7 @@ void tst_FaviconManager::noFavicon()
QUrl url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("faviconmanager/resources/test1.html"));
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QCOMPARE(iconUrlChangedSpy.count(), 0);
QCOMPARE(iconChangedSpy.count(), 0);
@@ -206,7 +206,7 @@ void tst_FaviconManager::aboutBlank()
QUrl url("about:blank");
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QCOMPARE(iconUrlChangedSpy.count(), 0);
QCOMPARE(iconChangedSpy.count(), 0);
@@ -226,7 +226,7 @@ void tst_FaviconManager::unavailableFavicon()
QUrl url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("faviconmanager/resources/favicon-unavailable.html"));
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QCOMPARE(iconUrlChangedSpy.count(), 0);
QCOMPARE(iconChangedSpy.count(), 0);
@@ -245,7 +245,7 @@ void tst_FaviconManager::errorPageEnabled()
QUrl url("http://url.invalid");
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QCOMPARE(iconUrlChangedSpy.count(), 0);
QCOMPARE(iconChangedSpy.count(), 0);
@@ -264,7 +264,7 @@ void tst_FaviconManager::errorPageDisabled()
QUrl url("http://url.invalid");
m_page->load(url);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 12000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QCOMPARE(iconUrlChangedSpy.count(), 0);
QCOMPARE(iconChangedSpy.count(), 0);
@@ -288,7 +288,7 @@ void tst_FaviconManager::bestFavicon()
url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("faviconmanager/resources/favicon-misc.html"));
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QTRY_COMPARE(iconChangedSpy.count(), 1);
@@ -311,7 +311,7 @@ void tst_FaviconManager::bestFavicon()
url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("faviconmanager/resources/favicon-shortcut.html"));
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QTRY_VERIFY(iconUrlChangedSpy.count() >= 1);
QTRY_VERIFY(iconChangedSpy.count() >= 1);
@@ -347,7 +347,7 @@ void tst_FaviconManager::touchIcon()
QUrl url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("faviconmanager/resources/favicon-touch.html"));
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QCOMPARE(iconUrlChangedSpy.count(), 0);
QCOMPARE(iconChangedSpy.count(), 0);
@@ -367,7 +367,7 @@ void tst_FaviconManager::multiIcon()
QUrl url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("faviconmanager/resources/favicon-multi.html"));
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QTRY_COMPARE(iconChangedSpy.count(), 1);
@@ -395,7 +395,7 @@ void tst_FaviconManager::candidateIcon()
QUrl url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("faviconmanager/resources/favicon-shortcut.html"));
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QTRY_COMPARE(iconChangedSpy.count(), 1);
@@ -432,7 +432,7 @@ void tst_FaviconManager::downloadIconsDisabled()
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QCOMPARE(iconUrlChangedSpy.count(), 0);
QCOMPARE(iconChangedSpy.count(), 0);
@@ -465,7 +465,7 @@ void tst_FaviconManager::downloadTouchIconsEnabled()
m_page->load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QTRY_COMPARE(iconChangedSpy.count(), 1);
@@ -494,7 +494,7 @@ void tst_FaviconManager::dynamicFavicon()
m_page->setHtml("<html>"
"<link rel='icon' type='image/png' href='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII='/>"
"</html>");
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
QTRY_COMPARE(iconChangedSpy.count(), 1);
@@ -525,7 +525,7 @@ void tst_FaviconManager::touchIconWithSameURL()
QTRY_COMPARE(loadFinishedSpy.count(), 1);
// 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(iconUrlChangedSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 30000);
QCOMPARE(m_page->iconUrl().toString(), icon);
QTRY_COMPARE(iconChangedSpy.count(), 1);
diff --git a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
index e614f3751..20e5fbf0d 100644
--- a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
+++ b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp
@@ -234,11 +234,12 @@ void tst_LoadSignals::fileDownloadDoesNotTriggerLoadSignals_qtbug66661()
QTemporaryDir tempDir;
QWebEngineDownloadItem::DownloadState downloadState = QWebEngineDownloadItem::DownloadRequested;
connect(view->page()->profile(), &QWebEngineProfile::downloadRequested,
- [this, &downloadState, &tempDir](QWebEngineDownloadItem* item){
+ [&downloadState, &tempDir](QWebEngineDownloadItem* item){
connect(item, &QWebEngineDownloadItem::stateChanged, [&downloadState](QWebEngineDownloadItem::DownloadState newState){
downloadState = newState;
});
- item->setPath(tempDir.filePath(QFileInfo(item->path()).fileName()));
+ item->setDownloadDirectory(tempDir.filePath(QFileInfo(item->path()).path()));
+ item->setDownloadFileName(QFileInfo(item->path()).fileName());
item->accept();
});
diff --git a/tests/auto/widgets/origins/resources/redirect.css b/tests/auto/widgets/origins/resources/redirect.css
new file mode 100644
index 000000000..41d7560cc
--- /dev/null
+++ b/tests/auto/widgets/origins/resources/redirect.css
@@ -0,0 +1,8 @@
+@font-face {
+ font-family: 'MyWebFont';
+ src: url('redirect1:/resources/Akronim-Regular.woff2') format('woff2');
+}
+
+body {
+ font-family: 'MyWebFont', Fallback, sans-serif;
+}
diff --git a/tests/auto/widgets/origins/resources/redirect.html b/tests/auto/widgets/origins/resources/redirect.html
new file mode 100644
index 000000000..04948e14b
--- /dev/null
+++ b/tests/auto/widgets/origins/resources/redirect.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>redirect</title>
+ <link rel="stylesheet" href="redirect1:/resources/redirect.css">
+ </head>
+ <body>
+ Text
+ </body>
+</html>
diff --git a/tests/auto/widgets/origins/tst_origins.cpp b/tests/auto/widgets/origins/tst_origins.cpp
index c1307c5e6..990ca70a7 100644
--- a/tests/auto/widgets/origins/tst_origins.cpp
+++ b/tests/auto/widgets/origins/tst_origins.cpp
@@ -122,6 +122,25 @@ void registerSchemes()
scheme.setDefaultPort(42);
QWebEngineUrlScheme::registerScheme(scheme);
}
+
+ {
+ QWebEngineUrlScheme scheme(QBAL("redirect1"));
+ scheme.setFlags(QWebEngineUrlScheme::CorsEnabled);
+ QWebEngineUrlScheme::registerScheme(scheme);
+ }
+
+ {
+ QWebEngineUrlScheme scheme(QBAL("redirect2"));
+ scheme.setFlags(QWebEngineUrlScheme::CorsEnabled);
+ QWebEngineUrlScheme::registerScheme(scheme);
+ }
+
+ {
+ QWebEngineUrlScheme scheme(QBAL("cors"));
+ scheme.setFlags(QWebEngineUrlScheme::CorsEnabled);
+ QWebEngineUrlScheme::registerScheme(scheme);
+ }
+
}
Q_CONSTRUCTOR_FUNCTION(registerSchemes)
@@ -145,13 +164,27 @@ public:
profile->installUrlSchemeHandler(QBAL("HostSyntax-ContentSecurityPolicyIgnored"), this);
profile->installUrlSchemeHandler(QBAL("HostAndPortSyntax"), this);
profile->installUrlSchemeHandler(QBAL("HostPortAndUserInformationSyntax"), this);
+ profile->installUrlSchemeHandler(QBAL("redirect1"), this);
+ profile->installUrlSchemeHandler(QBAL("redirect2"), this);
+ profile->installUrlSchemeHandler(QBAL("cors"), this);
}
+ QVector<QUrl> &requests() { return m_requests; }
+
private:
void requestStarted(QWebEngineUrlRequestJob *job) override
{
+ QUrl url = job->requestUrl();
+ m_requests << url;
+
+ if (url.scheme() == QBAL("redirect1")) {
+ url.setScheme(QBAL("redirect2"));
+ job->redirect(url);
+ return;
+ }
+
QString pathPrefix = QSL(THIS_DIR);
- QString pathSuffix = job->requestUrl().path();
+ QString pathSuffix = url.path();
QFile *file = new QFile(pathPrefix + pathSuffix, job);
if (!file->open(QIODevice::ReadOnly)) {
job->fail(QWebEngineUrlRequestJob::RequestFailed);
@@ -160,8 +193,12 @@ private:
QByteArray mimeType = QBAL("text/html");
if (pathSuffix.endsWith(QSL(".js")))
mimeType = QBAL("application/javascript");
+ else if (pathSuffix.endsWith(QSL(".css")))
+ mimeType = QBAL("text/css");
job->reply(mimeType, file);
}
+
+ QVector<QUrl> m_requests;
};
class tst_Origins final : public QObject {
@@ -169,6 +206,7 @@ class tst_Origins final : public QObject {
private Q_SLOTS:
void initTestCase();
+ void cleanup();
void cleanupTestCase();
void jsUrlCanon();
@@ -187,6 +225,7 @@ private Q_SLOTS:
void serviceWorker();
void viewSource();
void createObjectURL();
+ void redirect();
private:
bool load(const QUrl &url)
@@ -209,10 +248,19 @@ private:
void tst_Origins::initTestCase()
{
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ QRegularExpression("Please register the custom scheme 'tst'.*"));
+
m_page = new QWebEnginePage(&m_profile, nullptr);
m_handler = new TstUrlSchemeHandler(&m_profile);
}
+void tst_Origins::cleanup()
+{
+ m_handler->requests().clear();
+}
+
void tst_Origins::cleanupTestCase()
{
delete m_handler;
@@ -346,11 +394,7 @@ void tst_Origins::jsUrlOrigin()
QCOMPARE(eval(QSL("new URL(\"file:/etc/passwd\").origin")), QVariant(QSL("file://")));
QCOMPARE(eval(QSL("new URL(\"file://foo.com/etc/passwd\").origin")), QVariant(QSL("file://")));
- // The qrc scheme should behave like file.
- QCOMPARE(eval(QSL("new URL(\"qrc:/crysis.css\").origin")), QVariant(QSL("qrc://")));
- QCOMPARE(eval(QSL("new URL(\"qrc://foo.com/crysis.css\").origin")), QVariant(QSL("qrc://")));
-
- // Unregistered schemes behaves like opaque origins.
+ // Unregistered schemes behave like file.
QCOMPARE(eval(QSL("new URL(\"tst:/banana\").origin")), QVariant(QSL("tst://")));
QCOMPARE(eval(QSL("new URL(\"tst://foo.com/banana\").origin")), QVariant(QSL("tst://")));
@@ -367,8 +411,9 @@ void tst_Origins::jsUrlOrigin()
QVariant(QSL("hostportanduserinformationsyntax://foo")));
// A PathSyntax scheme should have a 'universal' origin.
- QCOMPARE(eval(QSL("new URL(\"PathSyntax:foo\").origin")),
- QVariant(QSL("pathsyntax://")));
+ QCOMPARE(eval(QSL("new URL(\"PathSyntax:foo\").origin")), QVariant(QSL("pathsyntax:")));
+ QCOMPARE(eval(QSL("new URL(\"qrc:/crysis.css\").origin")), QVariant(QSL("qrc:")));
+ QCOMPARE(eval(QSL("new URL(\"qrc://foo.com/crysis.css\").origin")), QVariant(QSL("qrc:")));
// The NoAccessAllowed flag forces opaque origins.
QCOMPARE(eval(QSL("new URL(\"PathSyntax-NoAccessAllowed:foo\").origin")),
@@ -532,7 +577,9 @@ void tst_Origins::mixedSchemesWithCsp()
// Load the main page over one scheme, then make an XMLHttpRequest to a
// different scheme.
//
-// XMLHttpRequests can only be made to http, https, data, and chrome.
+// Cross-origin XMLHttpRequests can only be made to CORS-enabled schemes. These
+// include the builtin schemes http, https, data, and chrome, as well as custom
+// schemes with the CorsEnabled flag.
void tst_Origins::mixedXHR()
{
QVERIFY(load(QSL("file:" THIS_DIR "resources/mixedXHR.html")));
@@ -544,6 +591,8 @@ void tst_Origins::mixedXHR()
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("error")));
eval(QSL("sendXHR('data:,ok')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok")));
+ eval(QSL("sendXHR('cors:/resources/mixedXHR.txt')"));
+ QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok")));
QVERIFY(load(QSL("qrc:/resources/mixedXHR.html")));
eval(QSL("sendXHR('file:" THIS_DIR "resources/mixedXHR.txt')"));
@@ -554,6 +603,8 @@ void tst_Origins::mixedXHR()
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("error")));
eval(QSL("sendXHR('data:,ok')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok")));
+ eval(QSL("sendXHR('cors:/resources/mixedXHR.txt')"));
+ QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok")));
QVERIFY(load(QSL("tst:/resources/mixedXHR.html")));
eval(QSL("sendXHR('file:" THIS_DIR "resources/mixedXHR.txt')"));
@@ -564,6 +615,8 @@ void tst_Origins::mixedXHR()
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok")));
eval(QSL("sendXHR('data:,ok')"));
QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok")));
+ eval(QSL("sendXHR('cors:/resources/mixedXHR.txt')"));
+ QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok")));
}
#if defined(WEBSOCKETS)
@@ -709,7 +762,7 @@ void tst_Origins::serviceWorker()
QVERIFY(load(QSL("qrc:/resources/serviceWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
QVERIFY(eval(QSL("error")).toString()
- .contains(QSL("The URL protocol of the current origin ('qrc://') is not supported.")));
+ .contains(QSL("The URL protocol of the current origin ('qrc:') is not supported.")));
QVERIFY(load(QSL("tst:/resources/serviceWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
@@ -724,7 +777,7 @@ void tst_Origins::serviceWorker()
QVERIFY(load(QSL("PathSyntax-Secure:/resources/serviceWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
QVERIFY(eval(QSL("error")).toString()
- .contains(QSL("The URL protocol of the current origin ('pathsyntax-secure://') is not supported.")));
+ .contains(QSL("The URL protocol of the current origin ('pathsyntax-secure:') is not supported.")));
QVERIFY(load(QSL("PathSyntax-ServiceWorkersAllowed:/resources/serviceWorker.html")));
QTRY_VERIFY(eval(QSL("done")).toBool());
@@ -775,5 +828,18 @@ void tst_Origins::createObjectURL()
QVERIFY(eval(QSL("result")).toString().startsWith(QSL("blob:tst:")));
}
+void tst_Origins::redirect()
+{
+ QVERIFY(load(QSL("redirect1:/resources/redirect.html")));
+ QTRY_COMPARE(m_handler->requests().size(), 7);
+ QCOMPARE(m_handler->requests()[0], QUrl(QStringLiteral("redirect1:/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[1], QUrl(QStringLiteral("redirect2:/resources/redirect.html")));
+ QCOMPARE(m_handler->requests()[2], QUrl(QStringLiteral("redirect1:/resources/redirect.css")));
+ QCOMPARE(m_handler->requests()[3], QUrl(QStringLiteral("redirect2:/resources/redirect.css")));
+ QCOMPARE(m_handler->requests()[4], QUrl(QStringLiteral("redirect1:/resources/Akronim-Regular.woff2")));
+ QCOMPARE(m_handler->requests()[5], QUrl(QStringLiteral("redirect1:/resources/Akronim-Regular.woff2")));
+ QCOMPARE(m_handler->requests()[6], QUrl(QStringLiteral("redirect2:/resources/Akronim-Regular.woff2")));
+}
+
QTEST_MAIN(tst_Origins)
#include "tst_origins.moc"
diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
index 3566c2216..4a5b4e3eb 100644
--- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
+++ b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp
@@ -78,6 +78,7 @@ private Q_SLOTS:
void downloadToNonExistentDir();
void downloadToReadOnlyDir();
void downloadPathValidation();
+ void downloadToDirectoryWithFileName();
private:
void saveLink(QPoint linkPos);
@@ -447,6 +448,8 @@ void tst_QWebEngineDownloadItem::downloadLink()
QByteArray slashFileName = QByteArrayLiteral("/") + fileName;
QString suggestedPath =
QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + slashFileName;
+ QString downloadDirectory = tmpDir.path();
+ QString downloadFileName = fileName;
QString downloadPath = tmpDir.path() + slashFileName;
QUrl downloadUrl = m_server->url(slashFileName);
int acceptedCount = 0;
@@ -460,7 +463,7 @@ void tst_QWebEngineDownloadItem::downloadLink()
QCOMPARE(item->type(), expectedDownloadType(userAction, fileDisposition));
QCOMPARE(item->isSavePageDownload(), false);
QCOMPARE(item->mimeType(), QString(fileMimeTypeDetected));
- QCOMPARE(item->path(), suggestedPath);
+ QCOMPARE(QDir(item->downloadDirectory()).filePath(item->downloadFileName()), suggestedPath);
QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat);
QCOMPARE(item->url(), downloadUrl);
QCOMPARE(item->page(), m_page);
@@ -474,14 +477,15 @@ void tst_QWebEngineDownloadItem::downloadLink()
QCOMPARE(item->type(), expectedDownloadType(userAction, fileDisposition));
QCOMPARE(item->isSavePageDownload(), false);
QCOMPARE(item->mimeType(), QString(fileMimeTypeDetected));
- QCOMPARE(item->path(), downloadPath);
+ QCOMPARE(QDir(item->downloadDirectory()).filePath(item->downloadFileName()), downloadPath);
QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat);
QCOMPARE(item->url(), downloadUrl);
QCOMPARE(item->page(), m_page);
finishedCount++;
});
- item->setPath(downloadPath);
+ item->setDownloadDirectory(downloadDirectory);
+ item->setDownloadFileName(downloadFileName);
item->accept();
acceptedCount++;
@@ -575,7 +579,8 @@ void tst_QWebEngineDownloadItem::downloadTwoLinks()
QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat);
QCOMPARE(item->mimeType(), QStringLiteral("text/plain"));
QString filePart = QChar('/') + item->url().fileName();
- QCOMPARE(item->path(), standardDir + filePart);
+ QString fileName = item->url().fileName();
+ QCOMPARE(QDir(item->downloadDirectory()).filePath(item->downloadFileName()), standardDir + filePart);
// type() is broken due to race condition in DownloadManagerDelegateQt
if (action1 == ClickLink && action2 == ClickLink) {
@@ -590,7 +595,8 @@ void tst_QWebEngineDownloadItem::downloadTwoLinks()
connect(item, &QWebEngineDownloadItem::finished, [&]() {
finishedCount++;
});
- item->setPath(tmpDir.path() + filePart);
+ item->setDownloadDirectory(tmpDir.path());
+ item->setDownloadFileName(fileName);
item->accept();
acceptedCount++;
@@ -655,7 +661,7 @@ void tst_QWebEngineDownloadItem::downloadPage()
QCOMPARE(item->isSavePageDownload(), true);
// FIXME(juvaldma): why is mimeType always the same?
QCOMPARE(item->mimeType(), QStringLiteral("application/x-mimearchive"));
- QCOMPARE(item->path(), downloadPath);
+ QCOMPARE(QDir(item->downloadDirectory()).filePath(item->downloadFileName()), downloadPath);
QCOMPARE(item->savePageFormat(), savePageFormat);
QCOMPARE(item->url(), downloadUrl);
QCOMPARE(item->page(), m_page);
@@ -670,7 +676,7 @@ void tst_QWebEngineDownloadItem::downloadPage()
QCOMPARE(item->type(), QWebEngineDownloadItem::SavePage);
QCOMPARE(item->isSavePageDownload(), true);
QCOMPARE(item->mimeType(), QStringLiteral("application/x-mimearchive"));
- QCOMPARE(item->path(), downloadPath);
+ QCOMPARE(QDir(item->downloadDirectory()).filePath(item->downloadFileName()), downloadPath);
QCOMPARE(item->savePageFormat(), savePageFormat);
QCOMPARE(item->url(), downloadUrl);
QCOMPARE(item->page(), m_page);
@@ -869,6 +875,7 @@ void tst_QWebEngineDownloadItem::downloadUniqueFilename()
QFETCH(QString, extension);
QString fileName = QString("%1.%2").arg(baseName).arg(extension);
QString downloadedFilePath;
+ QString suggestedFileName;
bool downloadFinished = false;
QTemporaryDir tmpDir;
@@ -890,6 +897,7 @@ void tst_QWebEngineDownloadItem::downloadUniqueFilename()
// Set up profile and download handler
ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ suggestedFileName = item->suggestedFileName();
item->accept();
connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
@@ -899,7 +907,7 @@ void tst_QWebEngineDownloadItem::downloadUniqueFilename()
QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
QCOMPARE(item->type(), QWebEngineDownloadItem::Attachment);
QCOMPARE(item->isSavePageDownload(), false);
- downloadedFilePath = item->path();
+ downloadedFilePath = QDir(item->downloadDirectory()).filePath(item->downloadFileName());
downloadFinished = true;
});
});
@@ -915,6 +923,7 @@ void tst_QWebEngineDownloadItem::downloadUniqueFilename()
QTRY_VERIFY(downloadFinished);
QVERIFY(QFile(downloadedFilePath).exists());
QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + " (" + QString::number(i) + ")." + extension);
+ QCOMPARE(suggestedFileName, fileName);
}
}
@@ -925,6 +934,7 @@ void tst_QWebEngineDownloadItem::downloadUniqueFilenameWithTimestamp()
QString extension("txt");
QString fileName = QString("%1.%2").arg(baseName).arg(extension);
QString downloadedFilePath;
+ QString suggestedFileName;
bool downloadFinished = false;
QTemporaryDir tmpDir;
@@ -945,6 +955,7 @@ void tst_QWebEngineDownloadItem::downloadUniqueFilenameWithTimestamp()
// Set up profile and download handler
ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ suggestedFileName = item->suggestedFileName();
item->accept();
connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
@@ -954,7 +965,7 @@ void tst_QWebEngineDownloadItem::downloadUniqueFilenameWithTimestamp()
QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
QCOMPARE(item->page(), m_page);
downloadFinished = true;
- downloadedFilePath = item->path();
+ downloadedFilePath = QDir(item->downloadDirectory()).filePath(item->downloadFileName());
});
});
@@ -975,6 +986,7 @@ void tst_QWebEngineDownloadItem::downloadUniqueFilenameWithTimestamp()
QTRY_VERIFY(downloadFinished);
QVERIFY(QFile(downloadedFilePath).exists());
QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + " (100)." + extension);
+ QCOMPARE(suggestedFileName, fileName);
// Check if the downloaded files are suffixed with timestamp after the 100th download.
for (int i = 101; i < 103; i++) {
@@ -988,6 +1000,7 @@ void tst_QWebEngineDownloadItem::downloadUniqueFilenameWithTimestamp()
// 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)));
+ QCOMPARE(suggestedFileName, fileName);
}
}
@@ -1014,6 +1027,7 @@ void tst_QWebEngineDownloadItem::downloadToNonExistentDir()
QString extension("txt");
QString fileName = QString("%1.%2").arg(baseName).arg(extension);
QString downloadedFilePath;
+ QString suggestedFileName;
bool downloadFinished = false;
QTemporaryDir tmpDir;
@@ -1035,6 +1049,7 @@ void tst_QWebEngineDownloadItem::downloadToNonExistentDir()
// Set up profile and download handler
ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ suggestedFileName = item->suggestedFileName();
item->accept();
connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
@@ -1044,7 +1059,7 @@ void tst_QWebEngineDownloadItem::downloadToNonExistentDir()
QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
QCOMPARE(item->page(), m_page);
downloadFinished = true;
- downloadedFilePath = item->path();
+ downloadedFilePath = QDir(item->downloadDirectory()).filePath(item->downloadFileName());
});
});
@@ -1056,6 +1071,7 @@ void tst_QWebEngineDownloadItem::downloadToNonExistentDir()
QTRY_VERIFY(downloadFinished);
QVERIFY(QFile(downloadedFilePath).exists());
QCOMPARE(downloadedFilePath, nonExistentDownloadPath + "/" + fileName);
+ QCOMPARE(suggestedFileName, fileName);
}
void tst_QWebEngineDownloadItem::downloadToReadOnlyDir()
@@ -1067,6 +1083,7 @@ void tst_QWebEngineDownloadItem::downloadToReadOnlyDir()
QString extension("txt");
QString fileName = QString("%1.%2").arg(baseName).arg(extension);
QString downloadedFilePath;
+ QString suggestedFileName;
bool downloadAccepted = false;
bool downloadFinished = false;
@@ -1089,9 +1106,10 @@ void tst_QWebEngineDownloadItem::downloadToReadOnlyDir()
QPointer<QWebEngineDownloadItem> downloadItem;
ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ suggestedFileName = item->suggestedFileName();
downloadItem = item;
item->accept();
- connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
+ connect(item, &QWebEngineDownloadItem::finished, [&]() {
downloadFinished = true;
});
downloadAccepted = true;
@@ -1109,6 +1127,7 @@ void tst_QWebEngineDownloadItem::downloadToReadOnlyDir()
QCOMPARE(downloadItem->isFinished(), false);
QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::FileAccessDenied);
QVERIFY(!QFile(downloadedFilePath).exists());
+ QCOMPARE(suggestedFileName, fileName);
// Clear m_requestedDownloads explicitly because download is accepted but never finished.
m_requestedDownloads.clear();
@@ -1233,5 +1252,135 @@ void tst_QWebEngineDownloadItem::downloadPathValidation()
QDir::setCurrent(oldPath);
}
+void tst_QWebEngineDownloadItem::downloadToDirectoryWithFileName()
+{
+ QString downloadDirectory;
+ QString downloadFileName;
+ QString downloadedFilePath;
+ QString downloadedSuggestedFileName;
+ QString fileName = "test.txt";
+ QString uniqueFileName = "test (1).txt";
+
+ bool downloadFinished = false;
+
+ QTemporaryDir tmpDir;
+ QVERIFY(tmpDir.isValid());
+ m_profile->setDownloadPath(tmpDir.path());
+
+ // Set up HTTP server
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream"));
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ rr->setResponseBody(QByteArrayLiteral("a"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
+
+ // Set up profile and download handler
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+
+ if (!downloadDirectory.isEmpty()) {
+ item->setDownloadDirectory(downloadDirectory);
+ QCOMPARE(item->downloadDirectory(), downloadDirectory);
+ }
+
+ if (!downloadFileName.isEmpty()) {
+ item->setDownloadFileName(downloadFileName);
+ QCOMPARE(item->downloadFileName(), downloadFileName);
+ }
+
+ QCOMPARE(item->path(), QDir(item->downloadDirectory()).filePath(item->downloadFileName()));
+ item->accept();
+
+ connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
+ QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
+ QCOMPARE(item->isFinished(), true);
+ QCOMPARE(item->totalBytes(), item->receivedBytes());
+ QVERIFY(item->receivedBytes() > 0);
+ QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
+ QCOMPARE(item->page(), m_page);
+ downloadFinished = true;
+ downloadedFilePath = QDir(item->downloadDirectory()).filePath(item->downloadFileName());
+ downloadedSuggestedFileName = item->suggestedFileName();
+ });
+ });
+
+ // Download file to the default download directory.
+ downloadDirectory = "";
+ downloadFileName = "";
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, QDir(m_profile->downloadPath()).filePath(fileName));
+ QCOMPARE(downloadedSuggestedFileName, fileName);
+
+ // Download the same file to another directory
+ downloadFinished = false;
+ downloadDirectory = m_profile->downloadPath() + QDir::separator() + "test1" + QDir::separator();
+ downloadFileName = "";
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, QDir(downloadDirectory).filePath(fileName));
+ QCOMPARE(downloadedSuggestedFileName, fileName);
+
+ // Download the same file to the same directory and the file name must be unique.
+ downloadFinished = false;
+ downloadDirectory = m_profile->downloadPath() + QDir::separator() + "test1" + QDir::separator();
+ downloadFileName = "";
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, QDir(downloadDirectory).filePath(uniqueFileName));
+ QCOMPARE(downloadedSuggestedFileName, fileName);
+
+ // Download another file to the same directory and set file name by
+ // QWebEngineDownloadItem::setDownloadDirectory() and setDownloadFileName() to avoid uniquification.
+ downloadFinished = false;
+ downloadDirectory = m_profile->downloadPath() + QDir::separator() + "test1" + QDir::separator();
+ downloadFileName = "test1.txt";
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, QDir(downloadDirectory).filePath(downloadFileName));
+ QCOMPARE(downloadedSuggestedFileName, fileName);
+
+ // Download the same file to another directory without uniquifying the file name
+ downloadFinished = false;
+ downloadDirectory = m_profile->downloadPath() + QDir::separator() + "test2" + QDir::separator();
+ downloadFileName = "test1.txt";
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, QDir(downloadDirectory).filePath(downloadFileName));
+ QCOMPARE(downloadedSuggestedFileName, fileName);
+
+ // Download the same file to same directory and set file name by
+ // QWebEngineDownloadItem::setDownloadDirectory() and setDownloadFileName() to avoid uniquification.
+ downloadFinished = false;
+ downloadDirectory = m_profile->downloadPath() + QDir::separator() + "test2" + QDir::separator();
+ downloadFileName = "test1.txt";
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, QDir(downloadDirectory).filePath(downloadFileName));
+ QCOMPARE(downloadedSuggestedFileName, fileName);
+
+ // Download the same file in the same directory.
+ // Use the suggested file name (test.txt) and the file name will not be unique because this file name don't yet exists.
+ downloadFinished = false;
+ downloadDirectory = m_profile->downloadPath() + QDir::separator() + "test2" + QDir::separator();
+ downloadFileName = "";
+ m_page->setUrl(m_server->url("/" + fileName));
+ QTRY_VERIFY(downloadFinished);
+ QVERIFY(QFile(downloadedFilePath).exists());
+ QCOMPARE(downloadedFilePath, QDir(downloadDirectory).filePath(fileName));
+ QCOMPARE(downloadedSuggestedFileName, fileName);
+}
+
QTEST_MAIN(tst_QWebEngineDownloadItem)
#include "tst_qwebenginedownloaditem.moc"
diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
index af47c70f7..7857ee818 100644
--- a/tests/auto/widgets/qwebenginepage/BLACKLIST
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -4,8 +4,5 @@ osx
[mouseMovementProperties]
windows
-[getUserMediaRequestDesktopVideoManyPages]
-windows
-
-[getUserMediaRequestDesktopVideoManyRequests]
+[fullScreenRequested]
windows
diff --git a/tests/auto/widgets/qwebenginepage/resources/lifecycle.html b/tests/auto/widgets/qwebenginepage/resources/lifecycle.html
new file mode 100644
index 000000000..aa477a359
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/lifecycle.html
@@ -0,0 +1,17 @@
+<!DOCTYPE html>
+<html>
+ <head>
+ <title>Lifecycle</title>
+ <script>
+ let frozenness = 0;
+ document.addEventListener("freeze", function() {
+ frozenness += 1;
+ });
+ document.addEventListener("resume", function() {
+ frozenness -= 1;
+ });
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index 8d5b486b2..931dbf7f0 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -47,6 +47,7 @@
#include <qnetworkreply.h>
#include <qnetworkrequest.h>
#include <qwebenginedownloaditem.h>
+#include <qwebenginefindtextresult.h>
#include <qwebenginefullscreenrequest.h>
#include <qwebenginehistory.h>
#include <qwebenginenotification.h>
@@ -127,6 +128,8 @@ private Q_SLOTS:
void findText();
void findTextResult();
void findTextSuccessiveShouldCallAllCallbacks();
+ void findTextCalledOnMatch();
+ void findTextActiveMatchOrdinal();
void deleteQWebEngineViewTwice();
void loadSignalsOrder_data();
void loadSignalsOrder();
@@ -202,9 +205,23 @@ private Q_SLOTS:
void sendNotification();
void contentsSize();
+ void setLifecycleState();
+ void setVisible();
+ void discardPreservesProperties();
+ void discardBeforeInitialization();
+ void automaticUndiscard();
+ void setLifecycleStateWithDevTools();
+ void discardPreservesCommittedLoad();
+ void discardAbortsPendingLoad();
+ void discardAbortsPendingLoadAndPreservesCommittedLoad();
+ void recommendedState();
+ void recommendedStateAuto();
+ void setLifecycleStateAndReload();
+
void editActionsWithExplicitFocus();
void editActionsWithInitialFocus();
void editActionsWithFocusOnIframe();
+ void editActionsWithoutSelection();
void customUserAgentInNewTab();
@@ -290,9 +307,9 @@ protected:
{
Q_UNUSED(url);
Q_UNUSED(isMainFrame);
- if (type == QWebEnginePage::NavigationTypeFormSubmitted)
- return m_acceptNavigationRequest;
- return true;
+ if (type == QWebEnginePage::NavigationTypeTyped)
+ return true;
+ return m_acceptNavigationRequest;
}
};
@@ -579,7 +596,7 @@ void tst_QWebEnginePage::acceptNavigationRequestNavigationType()
<< QWebEnginePage::NavigationTypeBackForward
<< QWebEnginePage::NavigationTypeReload
<< QWebEnginePage::NavigationTypeTyped
- << QWebEnginePage::NavigationTypeOther;
+ << QWebEnginePage::NavigationTypeRedirect;
QVERIFY(expectedList.count() == page.navigations.count());
for (int i = 0; i < expectedList.count(); ++i) {
QCOMPARE(page.navigations[i].type, expectedList[i]);
@@ -927,18 +944,24 @@ void tst_QWebEnginePage::findText()
// Invoking a stopFinding operation will not change or clear the currently selected text,
// if nothing was found beforehand.
{
- CallbackSpy<bool> spy;
- m_view->findText("", 0, spy.ref());
- QVERIFY(spy.wasCalled());
+ CallbackSpy<bool> callbackSpy;
+ QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ m_view->findText("", 0, callbackSpy.ref());
+ QVERIFY(callbackSpy.wasCalled());
+ QCOMPARE(signalSpy.count(), 1);
QTRY_COMPARE(m_view->selectedText(), QString("foo bar"));
}
// Invoking a startFinding operation with text that won't be found, will clear the current
// selection.
{
- CallbackSpy<bool> spy;
- m_view->findText("Will not be found", 0, spy.ref());
- QCOMPARE(spy.waitForResult(), false);
+ CallbackSpy<bool> callbackSpy;
+ QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ m_view->findText("Will not be found", 0, callbackSpy.ref());
+ QCOMPARE(callbackSpy.waitForResult(), false);
+ QTRY_COMPARE(signalSpy.count(), 1);
+ auto result = signalSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ QCOMPARE(result.numberOfMatches(), 0);
QTRY_VERIFY(m_view->selectedText().isEmpty());
}
@@ -949,24 +972,36 @@ void tst_QWebEnginePage::findText()
// Invoking a startFinding operation with text that will be found, will clear the current
// selection as well.
{
- CallbackSpy<bool> spy;
- m_view->findText("foo", 0, spy.ref());
- QVERIFY(spy.waitForResult());
+ CallbackSpy<bool> callbackSpy;
+ QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ m_view->findText("foo", 0, callbackSpy.ref());
+ QVERIFY(callbackSpy.waitForResult());
+ QTRY_COMPARE(signalSpy.count(), 1);
QTRY_VERIFY(m_view->selectedText().isEmpty());
}
// Invoking a stopFinding operation after text was found, will set the selected text to the
// found text.
{
- CallbackSpy<bool> spy;
- m_view->findText("", 0, spy.ref());
- QTRY_VERIFY(spy.wasCalled());
+ CallbackSpy<bool> callbackSpy;
+ QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ m_view->findText("", 0, callbackSpy.ref());
+ QTRY_VERIFY(callbackSpy.wasCalled());
+ QTRY_COMPARE(signalSpy.count(), 1);
QTRY_COMPARE(m_view->selectedText(), QString("foo"));
}
}
void tst_QWebEnginePage::findTextResult()
{
+ QSignalSpy findTextSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ auto signalResult = [&findTextSpy]() -> QVector<int> {
+ if (findTextSpy.count() != 1)
+ return QVector<int>({-1, -1});
+ auto r = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ return QVector<int>({ r.numberOfMatches(), r.activeMatch() });
+ };
+
// findText will abort in blink if the view has an empty size.
m_view->resize(800, 600);
m_view->show();
@@ -976,15 +1011,21 @@ void tst_QWebEnginePage::findTextResult()
QTRY_COMPARE(loadSpy.count(), 1);
QCOMPARE(findTextSync(m_page, ""), false);
+ QCOMPARE(signalResult(), QVector<int>({0, 0}));
const QStringList words = { "foo", "bar" };
for (const QString &subString : words) {
QCOMPARE(findTextSync(m_page, subString), true);
+ QCOMPARE(signalResult(), QVector<int>({1, 1}));
+
QCOMPARE(findTextSync(m_page, ""), false);
+ QCOMPARE(signalResult(), QVector<int>({0, 0}));
}
QCOMPARE(findTextSync(m_page, "blahhh"), false);
+ QCOMPARE(signalResult(), QVector<int>({0, 0}));
QCOMPARE(findTextSync(m_page, ""), false);
+ QCOMPARE(signalResult(), QVector<int>({0, 0}));
}
void tst_QWebEnginePage::findTextSuccessiveShouldCallAllCallbacks()
@@ -1010,6 +1051,91 @@ void tst_QWebEnginePage::findTextSuccessiveShouldCallAllCallbacks()
QVERIFY(spy5.wasCalled());
}
+void tst_QWebEnginePage::findTextCalledOnMatch()
+{
+ QSignalSpy loadSpy(m_view->page(), &QWebEnginePage::loadFinished);
+
+ // findText will abort in blink if the view has an empty size.
+ m_view->resize(800, 600);
+ m_view->show();
+ m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ // CALLBACK
+ bool callbackCalled = false;
+ m_view->page()->findText("foo", 0, [this, &callbackCalled](bool found) {
+ QVERIFY(found);
+
+ m_view->page()->findText("bar", 0, [&callbackCalled](bool found) {
+ QVERIFY(found);
+ callbackCalled = true;
+ });
+ });
+ QTRY_VERIFY(callbackCalled);
+
+ // SIGNAL
+ int findTextFinishedCount = 0;
+ connect(m_view->page(), &QWebEnginePage::findTextFinished, [this, &findTextFinishedCount](QWebEngineFindTextResult result) {
+ QCOMPARE(result.numberOfMatches(), 1);
+ if (findTextFinishedCount == 0)
+ m_view->page()->findText("bar");
+ findTextFinishedCount++;
+ });
+
+ m_view->page()->findText("foo");
+ QTRY_COMPARE(findTextFinishedCount, 2);
+}
+
+void tst_QWebEnginePage::findTextActiveMatchOrdinal()
+{
+ QSignalSpy loadSpy(m_view->page(), &QWebEnginePage::loadFinished);
+ QSignalSpy findTextSpy(m_view->page(), &QWebEnginePage::findTextFinished);
+ QWebEngineFindTextResult result;
+
+ // findText will abort in blink if the view has an empty size.
+ m_view->resize(800, 600);
+ m_view->show();
+ m_view->setHtml(QString("<html><head></head><body><div>foo bar foo bar foo</div></body></html>"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+
+ // Iterate over all "foo" matches.
+ for (int i = 1; i <= 3; ++i) {
+ m_view->page()->findText("foo", 0);
+ QTRY_COMPARE(findTextSpy.count(), 1);
+ result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ QCOMPARE(result.numberOfMatches(), 3);
+ QCOMPARE(result.activeMatch(), i);
+ }
+
+ // The last match is followed by the fist one.
+ m_view->page()->findText("foo", 0);
+ QTRY_COMPARE(findTextSpy.count(), 1);
+ result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ QCOMPARE(result.numberOfMatches(), 3);
+ QCOMPARE(result.activeMatch(), 1);
+
+ // The first match is preceded by the last one.
+ m_view->page()->findText("foo", QWebEnginePage::FindBackward);
+ QTRY_COMPARE(findTextSpy.count(), 1);
+ result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ QCOMPARE(result.numberOfMatches(), 3);
+ QCOMPARE(result.activeMatch(), 3);
+
+ // Finding another word resets the activeMatch.
+ m_view->page()->findText("bar", 0);
+ 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);
+ QTRY_COMPARE(findTextSpy.count(), 1);
+ result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
+ QCOMPARE(result.numberOfMatches(), 0);
+ QCOMPARE(result.activeMatch(), 0);
+}
+
static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows)
{
const auto tlws = QGuiApplication::topLevelWindows();
@@ -1070,6 +1196,8 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove()
QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
QTRY_VERIFY(!popup->position().isNull());
QCOMPARE(popupPos + offset, popup->position());
+ QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(1, 1));
+ QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
}
void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
@@ -3419,6 +3547,645 @@ void tst_QWebEnginePage::contentsSize()
QCOMPARE(m_page->contentsSize().height(), 1216);
}
+void tst_QWebEnginePage::setLifecycleState()
+{
+ qRegisterMetaType<QWebEnginePage::LifecycleState>("LifecycleState");
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy lifecycleSpy(&page, &QWebEnginePage::lifecycleStateChanged);
+ QSignalSpy visibleSpy(&page, &QWebEnginePage::visibleChanged);
+
+ page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
+ QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
+
+ // Active -> Frozen
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
+ QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(1));
+
+ // Frozen -> Active
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
+ QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
+
+ // Active -> Discarded
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+ QTest::ignoreMessage(QtWarningMsg, "runJavaScript: disabled in Discarded state");
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant());
+ QTest::ignoreMessage(QtWarningMsg, "runJavaScript: disabled in Discarded state");
+ QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant());
+ QCOMPARE(loadSpy.count(), 0);
+
+ // Discarded -> Frozen (illegal!)
+ QTest::ignoreMessage(QtWarningMsg,
+ "setLifecycleState: failed to transition from Discarded to Frozen state: "
+ "illegal transition");
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
+
+ // Discarded -> Active
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(true));
+ QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
+
+ // Active -> Frozen -> Discarded -> Active
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(lifecycleSpy.count(), 3);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(true));
+ QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
+
+ // Reload clears document.wasDiscarded
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
+}
+
+void tst_QWebEnginePage::setVisible()
+{
+ qRegisterMetaType<QWebEnginePage::LifecycleState>("LifecycleState");
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy lifecycleSpy(&page, &QWebEnginePage::lifecycleStateChanged);
+ QSignalSpy visibleSpy(&page, &QWebEnginePage::visibleChanged);
+
+ page.load(QStringLiteral("about:blank"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(page.isVisible(), false);
+
+ // hidden -> visible
+ page.setVisible(true);
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(page.isVisible(), true);
+
+ // Active -> Frozen (illegal)
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "setLifecycleState: failed to transition from Active to Frozen state: page is visible");
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(lifecycleSpy.count(), 0);
+
+ // visible -> hidden
+ page.setVisible(false);
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(false));
+ QCOMPARE(page.isVisible(), false);
+
+ // Active -> Frozen
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Frozen);
+
+ // hidden -> visible (triggers Frozen -> Active)
+ page.setVisible(true);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(page.isVisible(), true);
+
+ // Active -> Discarded (illegal)
+ QTest::ignoreMessage(QtWarningMsg,
+ "setLifecycleState: failed to transition from Active to Discarded state: "
+ "page is visible");
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(lifecycleSpy.count(), 0);
+
+ // visible -> hidden
+ page.setVisible(false);
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(false));
+ QCOMPARE(page.isVisible(), false);
+
+ // Active -> Discarded
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
+
+ // hidden -> visible (triggers Discarded -> Active)
+ page.setVisible(true);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(page.isVisible(), true);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+}
+
+void tst_QWebEnginePage::discardPreservesProperties()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+
+ page.load(QStringLiteral("about:blank"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+
+ // Change as many properties as possible to non-default values
+ bool audioMuted = true;
+ QVERIFY(page.isAudioMuted() != audioMuted);
+ page.setAudioMuted(audioMuted);
+ QColor backgroundColor = Qt::black;
+ QVERIFY(page.backgroundColor() != backgroundColor);
+ page.setBackgroundColor(backgroundColor);
+ qreal zoomFactor = 2;
+ QVERIFY(page.zoomFactor() != zoomFactor);
+ page.setZoomFactor(zoomFactor);
+#if QT_CONFIG(webengine_webchannel)
+ QWebChannel *webChannel = new QWebChannel(&page);
+ page.setWebChannel(webChannel);
+#endif
+
+ // Take snapshot of the rest
+ QSizeF contentsSize = page.contentsSize();
+ QIcon icon = page.icon();
+ QUrl iconUrl = page.iconUrl();
+ QUrl requestedUrl = page.requestedUrl();
+ QString title = page.title();
+ QUrl url = page.url();
+
+ // History should be preserved too
+ int historyCount = page.history()->count();
+ QCOMPARE(historyCount, 1);
+ int historyIndex = page.history()->currentItemIndex();
+ QCOMPARE(historyIndex, 0);
+ QWebEngineHistoryItem historyItem = page.history()->currentItem();
+ QVERIFY(historyItem.isValid());
+
+ // Discard + undiscard
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+
+ // Property changes should be preserved
+ QCOMPARE(page.isAudioMuted(), audioMuted);
+ QCOMPARE(page.backgroundColor(), backgroundColor);
+ QCOMPARE(page.contentsSize(), contentsSize);
+ QCOMPARE(page.icon(), icon);
+ QCOMPARE(page.iconUrl(), iconUrl);
+ QCOMPARE(page.requestedUrl(), requestedUrl);
+ QCOMPARE(page.title(), title);
+ QCOMPARE(page.url(), url);
+ QCOMPARE(page.zoomFactor(), zoomFactor);
+#if QT_CONFIG(webengine_webchannel)
+ QCOMPARE(page.webChannel(), webChannel);
+#endif
+ QCOMPARE(page.history()->count(), historyCount);
+ QCOMPARE(page.history()->currentItemIndex(), historyIndex);
+ QCOMPARE(page.history()->currentItem().url(), historyItem.url());
+ QCOMPARE(page.history()->currentItem().originalUrl(), historyItem.originalUrl());
+ QCOMPARE(page.history()->currentItem().title(), historyItem.title());
+}
+
+void tst_QWebEnginePage::discardBeforeInitialization()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ // The call is ignored
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+}
+
+void tst_QWebEnginePage::automaticUndiscard()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+
+ page.load(QStringLiteral("about:blank"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+
+ // setUrl
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ page.setUrl(QStringLiteral("qrc:/resources/lifecycle.html"));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+
+ // setContent
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ page.setContent(QByteArrayLiteral("foo"));
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+}
+
+void tst_QWebEnginePage::setLifecycleStateWithDevTools()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage inspectedPage(&profile);
+ QWebEnginePage devToolsPage(&profile);
+ QSignalSpy devToolsSpy(&devToolsPage, &QWebEnginePage::loadFinished);
+ QSignalSpy inspectedSpy(&inspectedPage, &QWebEnginePage::loadFinished);
+
+ // Ensure pages are initialized
+ inspectedPage.load(QStringLiteral("about:blank"));
+ devToolsPage.load(QStringLiteral("about:blank"));
+ QTRY_COMPARE(inspectedSpy.count(), 1);
+ QCOMPARE(inspectedSpy.takeFirst().value(0), QVariant(true));
+ QTRY_COMPARE(devToolsSpy.count(), 1);
+ QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
+
+ // Open DevTools with Frozen inspectedPage
+ inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ inspectedPage.setDevToolsPage(&devToolsPage);
+ QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(devToolsSpy.count(), 1);
+ QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
+ inspectedPage.setDevToolsPage(nullptr);
+
+ // Open DevTools with Discarded inspectedPage
+ inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ inspectedPage.setDevToolsPage(&devToolsPage);
+ QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(devToolsSpy.count(), 1);
+ QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
+ QTRY_COMPARE(inspectedSpy.count(), 1);
+ QCOMPARE(inspectedSpy.takeFirst().value(0), QVariant(true));
+ inspectedPage.setDevToolsPage(nullptr);
+
+ // Open DevTools with Frozen devToolsPage
+ devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ devToolsPage.setInspectedPage(&inspectedPage);
+ QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(devToolsSpy.count(), 1);
+ QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
+ devToolsPage.setInspectedPage(nullptr);
+
+ // Open DevTools with Discarded devToolsPage
+ devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ devToolsPage.setInspectedPage(&inspectedPage);
+ QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(devToolsSpy.count(), 2);
+ QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(false));
+ QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
+ // keep DevTools open
+
+ // Try to change state while DevTools are open
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "setLifecycleState: failed to transition from Active to Frozen state: DevTools open");
+ inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTest::ignoreMessage(QtWarningMsg,
+ "setLifecycleState: failed to transition from Active to Discarded state: "
+ "DevTools open");
+ inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTest::ignoreMessage(
+ QtWarningMsg,
+ "setLifecycleState: failed to transition from Active to Frozen state: DevTools open");
+ devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QTest::ignoreMessage(QtWarningMsg,
+ "setLifecycleState: failed to transition from Active to Discarded state: "
+ "DevTools open");
+ devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+}
+
+void tst_QWebEnginePage::discardPreservesCommittedLoad()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadStartedSpy(&page, &QWebEnginePage::loadStarted);
+ QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy urlChangedSpy(&page, &QWebEnginePage::urlChanged);
+ QSignalSpy titleChangedSpy(&page, &QWebEnginePage::titleChanged);
+
+ QString url = QStringLiteral("qrc:/resources/lifecycle.html");
+ page.setUrl(url);
+ QTRY_COMPARE(loadStartedSpy.count(), 1);
+ loadStartedSpy.clear();
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(urlChangedSpy.count(), 1);
+ QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url)));
+ QCOMPARE(page.url(), url);
+ QCOMPARE(titleChangedSpy.count(), 2);
+ QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(url));
+ QString title = QStringLiteral("Lifecycle");
+ QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(title));
+ QCOMPARE(page.title(), title);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(loadStartedSpy.count(), 0);
+ QCOMPARE(loadFinishedSpy.count(), 0);
+ QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(page.url(), QUrl(url));
+ QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(page.title(), title);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE(loadStartedSpy.count(), 1);
+ loadStartedSpy.clear();
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(page.url(), url);
+ QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(page.title(), title);
+}
+
+void tst_QWebEnginePage::discardAbortsPendingLoad()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadStartedSpy(&page, &QWebEnginePage::loadStarted);
+ QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy urlChangedSpy(&page, &QWebEnginePage::urlChanged);
+ QSignalSpy titleChangedSpy(&page, &QWebEnginePage::titleChanged);
+
+ connect(&page, &QWebEnginePage::loadStarted,
+ [&]() { page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded); });
+ QUrl url = QStringLiteral("qrc:/resources/lifecycle.html");
+ page.setUrl(url);
+ QTRY_COMPARE(loadStartedSpy.count(), 1);
+ loadStartedSpy.clear();
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(false));
+ QCOMPARE(urlChangedSpy.count(), 2);
+ QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(url));
+ QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl()));
+ QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(page.url(), QUrl());
+ QCOMPARE(page.title(), QString());
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(loadStartedSpy.count(), 0);
+ QCOMPARE(loadFinishedSpy.count(), 0);
+ QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(page.url(), QUrl());
+ QCOMPARE(page.title(), QString());
+}
+
+void tst_QWebEnginePage::discardAbortsPendingLoadAndPreservesCommittedLoad()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadStartedSpy(&page, &QWebEnginePage::loadStarted);
+ QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy urlChangedSpy(&page, &QWebEnginePage::urlChanged);
+ QSignalSpy titleChangedSpy(&page, &QWebEnginePage::titleChanged);
+
+ QString url1 = QStringLiteral("qrc:/resources/lifecycle.html");
+ page.setUrl(url1);
+ QTRY_COMPARE(loadStartedSpy.count(), 1);
+ loadStartedSpy.clear();
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(urlChangedSpy.count(), 1);
+ QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url1)));
+ QCOMPARE(page.url(), url1);
+ QCOMPARE(titleChangedSpy.count(), 2);
+ QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(url1));
+ QString title = QStringLiteral("Lifecycle");
+ QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(title));
+ QCOMPARE(page.title(), title);
+
+ connect(&page, &QWebEnginePage::loadStarted,
+ [&]() { page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded); });
+ QString url2 = QStringLiteral("about:blank");
+ page.setUrl(url2);
+ QTRY_COMPARE(loadStartedSpy.count(), 1);
+ loadStartedSpy.clear();
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(false));
+ QCOMPARE(urlChangedSpy.count(), 2);
+ QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url2)));
+ QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url1)));
+ QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(page.url(), url1);
+ QCOMPARE(page.title(), title);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(loadStartedSpy.count(), 0);
+ QCOMPARE(loadFinishedSpy.count(), 0);
+ QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(page.url(), url1);
+ QCOMPARE(page.title(), title);
+}
+
+void tst_QWebEnginePage::recommendedState()
+{
+ qRegisterMetaType<QWebEnginePage::LifecycleState>("LifecycleState");
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+
+ struct Event {
+ enum { StateChange, RecommendationChange } key;
+ QWebEnginePage::LifecycleState value;
+ };
+ std::vector<Event> events;
+ connect(&page, &QWebEnginePage::lifecycleStateChanged, [&](QWebEnginePage::LifecycleState state) {
+ events.push_back(Event { Event::StateChange, state });
+ });
+ connect(&page, &QWebEnginePage::recommendedStateChanged, [&](QWebEnginePage::LifecycleState state) {
+ events.push_back(Event { Event::RecommendationChange, state });
+ });
+
+ page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
+ QTRY_COMPARE(events.size(), 1u);
+ QCOMPARE(events[0].key, Event::RecommendationChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Frozen);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Frozen);
+
+ page.setVisible(true);
+ QTRY_COMPARE(events.size(), 1u);
+ QCOMPARE(events[0].key, Event::RecommendationChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Active);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Active);
+
+ page.setVisible(false);
+ QTRY_COMPARE(events.size(), 1u);
+ QCOMPARE(events[0].key, Event::RecommendationChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Frozen);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Frozen);
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(events.size(), 2u);
+ QCOMPARE(events[0].key, Event::RecommendationChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(events[1].key, Event::RecommendationChange);
+ QCOMPARE(events[1].value, QWebEnginePage::LifecycleState::Frozen);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Frozen);
+
+ QWebEnginePage devTools;
+ page.setDevToolsPage(&devTools);
+ QTRY_COMPARE(events.size(), 1u);
+ QCOMPARE(events[0].key, Event::RecommendationChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Active);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Active);
+
+ page.setDevToolsPage(nullptr);
+ QTRY_COMPARE(events.size(), 1u);
+ QCOMPARE(events[0].key, Event::RecommendationChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Frozen);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Frozen);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QTRY_COMPARE(events.size(), 2u);
+ QCOMPARE(events[0].key, Event::StateChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(events[1].key, Event::RecommendationChange);
+ QCOMPARE(events[1].value, QWebEnginePage::LifecycleState::Discarded);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Discarded);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QTRY_COMPARE(events.size(), 1u);
+ QCOMPARE(events[0].key, Event::StateChange);
+ QCOMPARE(events[0].value, QWebEnginePage::LifecycleState::Discarded);
+ events.clear();
+ QCOMPARE(page.recommendedState(), QWebEnginePage::LifecycleState::Discarded);
+}
+
+void tst_QWebEnginePage::recommendedStateAuto()
+{
+ qRegisterMetaType<QWebEnginePage::LifecycleState>("LifecycleState");
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy lifecycleSpy(&page, &QWebEnginePage::lifecycleStateChanged);
+ connect(&page, &QWebEnginePage::recommendedStateChanged, &page, &QWebEnginePage::setLifecycleState);
+
+ page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
+ QTRY_COMPARE(lifecycleSpy.count(), 2);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+
+ page.setVisible(true);
+ QTRY_COMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+
+ page.setVisible(false);
+ QTRY_COMPARE(lifecycleSpy.count(), 2);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(lifecycleSpy.count(), 3);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+
+ QWebEnginePage devTools;
+ page.setDevToolsPage(&devTools);
+ QTRY_COMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+
+ page.setDevToolsPage(nullptr);
+ QTRY_COMPARE(lifecycleSpy.count(), 2);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+}
+
+void tst_QWebEnginePage::setLifecycleStateAndReload()
+{
+ qRegisterMetaType<QWebEnginePage::LifecycleState>("LifecycleState");
+
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ QSignalSpy lifecycleSpy(&page, &QWebEnginePage::lifecycleStateChanged);
+
+ page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+ QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Frozen);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
+}
+
void tst_QWebEnginePage::editActionsWithExplicitFocus()
{
QWebEngineView view;
@@ -3506,6 +4273,44 @@ void tst_QWebEnginePage::editActionsWithFocusOnIframe()
QCOMPARE(page->selectedText(), QStringLiteral("inner"));
}
+void tst_QWebEnginePage::editActionsWithoutSelection()
+{
+ QWebEngineView view;
+ QWebEnginePage *page = view.page();
+ view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
+
+ QSignalSpy loadFinishedSpy(page, &QWebEnginePage::loadFinished);
+ QSignalSpy selectionChangedSpy(page, &QWebEnginePage::selectionChanged);
+ QSignalSpy actionChangedSpy(page->action(QWebEnginePage::SelectAll), &QAction::changed);
+
+ page->setHtml(QString("<html><body><div>foo bar</div></body></html>"));
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(actionChangedSpy.count(), 1);
+
+ QVERIFY(!page->action(QWebEnginePage::Cut)->isEnabled());
+ QVERIFY(!page->action(QWebEnginePage::Copy)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Paste)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Undo)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Redo)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::PasteAndMatchStyle)->isEnabled());
+ QVERIFY(!page->action(QWebEnginePage::Unselect)->isEnabled());
+
+ page->triggerAction(QWebEnginePage::SelectAll);
+ QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QCOMPARE(page->hasSelection(), true);
+ QCOMPARE(page->selectedText(), QStringLiteral("foo bar"));
+
+ QVERIFY(page->action(QWebEnginePage::Cut)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Copy)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Paste)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Undo)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Redo)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::PasteAndMatchStyle)->isEnabled());
+ QVERIFY(page->action(QWebEnginePage::Unselect)->isEnabled());
+}
+
void tst_QWebEnginePage::customUserAgentInNewTab()
{
HttpServer server;
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
index cf32486e7..013a307de 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
@@ -23,6 +23,7 @@
<file>resources/foo.txt</file>
<file>resources/bar.txt</file>
<file>resources/path with spaces.txt</file>
+ <file>resources/lifecycle.html</file>
</qresource>
<qresource prefix='/shared'>
<file alias='notification.html'>../../shared/data/notification.html</file>
diff --git a/tests/auto/widgets/qwebengineprofile/BLACKLIST b/tests/auto/widgets/qwebengineprofile/BLACKLIST
index fc1c957dd..55806eec4 100644
--- a/tests/auto/widgets/qwebengineprofile/BLACKLIST
+++ b/tests/auto/widgets/qwebengineprofile/BLACKLIST
@@ -1,5 +1,3 @@
-[clearDataFromCache]
-*
[disableCache]
*
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 921831700..a7a5ba62a 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -45,6 +45,7 @@
#endif
#include <map>
+#include <mutex>
class tst_QWebEngineProfile : public QObject
{
@@ -65,6 +66,7 @@ private Q_SLOTS:
void urlSchemeHandlerRequestHeaders();
void urlSchemeHandlerInstallation();
void urlSchemeHandlerXhrStatus();
+ void urlSchemeHandlerScriptModule();
void customUserAgent();
void httpAcceptLanguage();
void downloadItem();
@@ -85,6 +87,7 @@ void tst_QWebEngineProfile::initTestCase()
stream.setDefaultPort(8080);
letterto.setSyntax(QWebEngineUrlScheme::Syntax::Path);
aviancarrier.setSyntax(QWebEngineUrlScheme::Syntax::Path);
+ aviancarrier.setFlags(QWebEngineUrlScheme::CorsEnabled);
QWebEngineUrlScheme::registerScheme(foo);
QWebEngineUrlScheme::registerScheme(stream);
QWebEngineUrlScheme::registerScheme(letterto);
@@ -262,18 +265,18 @@ public:
bool isSequential() const override { return true; }
qint64 bytesAvailable() const override
{
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
return m_bytesAvailable;
}
bool atEnd() const override
{
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
return (m_data.size() >= 1000 && m_bytesRead >= 1000);
}
protected:
void timerEvent(QTimerEvent *) override
{
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
m_bytesAvailable += 200;
m_data.append(200, 'c');
emit readyRead();
@@ -285,7 +288,7 @@ protected:
qint64 readData(char *data, qint64 maxlen) override
{
- QMutexLocker lock(&m_mutex);
+ const std::lock_guard<QRecursiveMutex> lock(m_mutex);
qint64 len = qMin(qint64(m_bytesAvailable), maxlen);
if (len) {
memcpy(data, m_data.constData() + m_bytesRead, len);
@@ -302,7 +305,12 @@ protected:
}
private:
+#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
mutable QMutex m_mutex{QMutex::Recursive};
+ using QRecursiveMutex = QMutex;
+#else
+ mutable QRecursiveMutex m_mutex;
+#endif
QByteArray m_data;
QBasicTimer m_timer;
int m_bytesRead;
@@ -526,7 +534,7 @@ void tst_QWebEngineProfile::urlSchemeHandlerRequestHeaders()
QWebEngineProfile profile;
profile.installUrlSchemeHandler("myscheme", &handler);
- profile.setRequestInterceptor(&interceptor);
+ profile.setUrlRequestInterceptor(&interceptor);
QWebEnginePage page(&profile);
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
@@ -678,6 +686,34 @@ void tst_QWebEngineProfile::urlSchemeHandlerXhrStatus()
#endif
}
+class ScriptsUrlSchemeHandler : public QWebEngineUrlSchemeHandler
+{
+public:
+ void requestStarted(QWebEngineUrlRequestJob *job)
+ {
+ auto *script = new QBuffer(job);
+ script->setData(QByteArrayLiteral("window.test = 'SUCCESS';"));
+ job->reply("text/javascript", script);
+ }
+};
+
+void tst_QWebEngineProfile::urlSchemeHandlerScriptModule()
+{
+ ScriptsUrlSchemeHandler handler;
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("aviancarrier", &handler);
+ QWebEnginePage page(&profile);
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.setHtml(QStringLiteral("<html><head><script src=\"aviancarrier:///\"></script></head><body>Test1</body></html>"));
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("test")).toString(), QStringLiteral("SUCCESS"));
+
+ loadFinishedSpy.clear();
+ page.setHtml(QStringLiteral("<html><head><script type=\"module\" src=\"aviancarrier:///\"></script></head><body>Test2</body></html>"));
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("test")).toString(), QStringLiteral("SUCCESS"));
+}
+
void tst_QWebEngineProfile::customUserAgent()
{
QString defaultUserAgent = QWebEngineProfile::defaultProfile()->httpUserAgent();
diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
index 9a2ee9311..2044f0df4 100644
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -30,6 +30,26 @@
#include <QWebChannel>
#endif
+static bool verifyOrder(QStringList orderList)
+{
+ QStringList expected = {
+ "DocumentCreation",
+ "DOMContentLoaded",
+ "DocumentReady",
+ "load",
+ "Deferred"
+ };
+
+ if (orderList.at(4) == "load (timeout)") {
+ if (orderList.at(3) != "Deferred")
+ return false;
+ expected[3] = "Deferred";
+ expected[4] = "load (timeout)";
+ }
+
+ return orderList == expected;
+}
+
class tst_QWebEngineScript: public QObject {
Q_OBJECT
@@ -51,6 +71,7 @@ private Q_SLOTS:
#endif
void noTransportWithoutWebChannel();
void scriptsInNestedIframes();
+ void matchQrcUrl();
};
void tst_QWebEngineScript::domEditing()
@@ -101,15 +122,28 @@ void tst_QWebEngineScript::loadEvents()
script.setRunsOnSubFrames(true);
if (injectionPoint == QWebEngineScript::DocumentCreation) {
script.setSourceCode(QStringLiteral(R"(
- var log = ["DocumentCreation"];
- for (let type of ["DOMContentLoaded", "load"]) {
- window.addEventListener(type, () => log.push(type));
+ var log = ['DocumentCreation'];
+ var timestamps = {'DocumentCreation': Date.now()};
+ for (let type of ['DOMContentLoaded', 'load']) {
+ window.addEventListener(type, () => {
+ timestamps[type] = Date.now();
+ if (type === 'load' && log.includes('Deferred') && timestamps['Deferred'] - timestamps['DOMContentLoaded'] > 500)
+ log.push(type + ' (timeout)');
+ else
+ log.push(type);
+ });
}
)"));
} else if (injectionPoint == QWebEngineScript::DocumentReady) {
- script.setSourceCode(QStringLiteral(R"(log.push("DocumentReady"))"));
+ script.setSourceCode(QStringLiteral(R"(
+ timestamps['DocumentReady'] = Date.now();
+ log.push('DocumentReady');
+ )"));
} else {
- script.setSourceCode(QStringLiteral(R"(log.push("Deferred"))"));
+ script.setSourceCode(QStringLiteral(R"(
+ timestamps['Deferred'] = Date.now();
+ log.push('Deferred');
+ )"));
}
return script;
}
@@ -144,49 +178,49 @@ void tst_QWebEngineScript::loadEvents()
profile.pages.emplace_back(profile);
Page &page = profile.pages.back();
- const QStringList expected = {
- "DocumentCreation",
- "DOMContentLoaded",
- "DocumentReady",
- "load",
- "Deferred"
- };
-
// Single frame / setHtml
page.setHtml(QStringLiteral("<!DOCTYPE html><html><head><title>mr</title></head><body></body></html>"));
- QTRY_COMPARE(page.spy.count(), 1);
- QCOMPARE(page.spy.takeFirst().value(0).toBool(), true);
- QCOMPARE(page.eval("window.log", QWebEngineScript::MainWorld).toStringList(), expected);
- QCOMPARE(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList(), expected);
+ QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000);
+ QVERIFY(page.spy.takeFirst().value(0).toBool());
+ QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList()));
+ QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
+
+ // After discard
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
+ QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000);
+ QVERIFY(page.spy.takeFirst().value(0).toBool());
+ QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList()));
+ QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
// Multiple frames
page.load(QUrl("qrc:/resources/test_iframe_main.html"));
- QTRY_COMPARE(page.spy.count(), 1);
- QCOMPARE(page.spy.takeFirst().value(0).toBool(), true);
- QCOMPARE(page.eval("window.log", QWebEngineScript::MainWorld).toStringList(), expected);
- QCOMPARE(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList(), expected);
- QCOMPARE(page.eval("window[0].log", QWebEngineScript::MainWorld).toStringList(), expected);
- QCOMPARE(page.eval("window[0].log", QWebEngineScript::ApplicationWorld).toStringList(), expected);
- QCOMPARE(page.eval("window[0][0].log", QWebEngineScript::MainWorld).toStringList(), expected);
- QCOMPARE(page.eval("window[0][0].log", QWebEngineScript::ApplicationWorld).toStringList(), expected);
+ QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000);
+ QVERIFY(page.spy.takeFirst().value(0).toBool());
+ QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList()));
+ QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
+ QVERIFY(verifyOrder(page.eval("window[0].log", QWebEngineScript::MainWorld).toStringList()));
+ QVERIFY(verifyOrder(page.eval("window[0].log", QWebEngineScript::ApplicationWorld).toStringList()));
+ QVERIFY(verifyOrder(page.eval("window[0][0].log", QWebEngineScript::MainWorld).toStringList()));
+ QVERIFY(verifyOrder(page.eval("window[0][0].log", QWebEngineScript::ApplicationWorld).toStringList()));
// Cross-process navigation
page.load(QUrl("chrome://gpu"));
- QTRY_COMPARE(page.spy.count(), 1);
- QCOMPARE(page.spy.takeFirst().value(0).toBool(), true);
- QCOMPARE(page.eval("window.log", QWebEngineScript::MainWorld).toStringList(), expected);
- QCOMPARE(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList(), expected);
+ QTRY_COMPARE_WITH_TIMEOUT(page.spy.count(), 1, 20000);
+ QVERIFY(page.spy.takeFirst().value(0).toBool());
+ QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::MainWorld).toStringList()));
+ QVERIFY(verifyOrder(page.eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
// Using window.open from JS
QVERIFY(profile.pages.size() == 1);
page.load(QUrl("qrc:/resources/test_window_open.html"));
- QTRY_VERIFY(profile.pages.size() == 2);
+ QTRY_COMPARE(profile.pages.size(), 2);
QTRY_COMPARE(profile.pages.front().spy.count(), 1);
QTRY_COMPARE(profile.pages.back().spy.count(), 1);
- QCOMPARE(profile.pages.front().eval("window.log", QWebEngineScript::MainWorld).toStringList(), expected);
- QCOMPARE(profile.pages.front().eval("window.log", QWebEngineScript::ApplicationWorld).toStringList(), expected);
- QCOMPARE(profile.pages.back().eval("window.log", QWebEngineScript::MainWorld).toStringList(), expected);
- QCOMPARE(profile.pages.back().eval("window.log", QWebEngineScript::ApplicationWorld).toStringList(), expected);
+ QVERIFY(verifyOrder(profile.pages.front().eval("window.log", QWebEngineScript::MainWorld).toStringList()));
+ QVERIFY(verifyOrder(profile.pages.front().eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
+ QVERIFY(verifyOrder(profile.pages.back().eval("window.log", QWebEngineScript::MainWorld).toStringList()));
+ QVERIFY(verifyOrder(profile.pages.back().eval("window.log", QWebEngineScript::ApplicationWorld).toStringList()));
}
void tst_QWebEngineScript::scriptWorld_data()
@@ -531,6 +565,11 @@ void tst_QWebEngineScript::navigation()
page.setUrl(url3);
QTRY_COMPARE(spyTextChanged.count(), 3);
QCOMPARE(testObject.text(), url3);
+
+ page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ page.setUrl(url1);
+ QTRY_COMPARE(spyTextChanged.count(), 4);
+ QCOMPARE(testObject.text(), url1);
}
// Try to set TestObject::text to an invalid UTF-16 string.
@@ -551,6 +590,33 @@ void tst_QWebEngineScript::webChannelWithBadString()
QCOMPARE(host.text(), data);
}
#endif
+
+void tst_QWebEngineScript::matchQrcUrl()
+{
+ QWebEnginePage page;
+ QWebEngineView view;
+ view.setPage(&page);
+ QWebEngineScript s;
+ s.setInjectionPoint(QWebEngineScript::DocumentReady);
+ s.setWorldId(QWebEngineScript::MainWorld);
+
+
+ s.setSourceCode(QStringLiteral(R"(
+// ==UserScript==
+// @match qrc:/*main.html
+// ==/UserScript==
+
+document.title = 'New title';
+ )"));
+
+ page.scripts().insert(s);
+ page.load(QUrl("qrc:/resources/test_iframe_main.html"));
+ view.show();
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+ QVERIFY(spyFinished.wait());
+ QCOMPARE(page.title(), "New title");
+}
+
QTEST_MAIN(tst_QWebEngineScript)
#include "tst_qwebenginescript.moc"
diff --git a/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp b/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp
index 0704cf383..b4061b984 100644
--- a/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp
+++ b/tests/auto/widgets/qwebenginesettings/tst_qwebenginesettings.cpp
@@ -177,7 +177,7 @@ void tst_QWebEngineSettings::setInAcceptNavigationRequest()
{
NavigationRequestOverride page;
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
- QWebEngineSettings::globalSettings()->setAttribute(QWebEngineSettings::JavascriptEnabled, false);
+ QWebEngineSettings::defaultSettings()->setAttribute(QWebEngineSettings::JavascriptEnabled, false);
QVERIFY(!page.settings()->testAttribute(QWebEngineSettings::JavascriptEnabled));
page.load(QUrl("about:blank"));
diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST
index 9087067f5..266f08886 100644
--- a/tests/auto/widgets/qwebengineview/BLACKLIST
+++ b/tests/auto/widgets/qwebengineview/BLACKLIST
@@ -3,3 +3,6 @@ osx
[textSelectionOutOfInputField]
*
+
+[visibilityState3]
+windows
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
index 1bb65d7df..31438996f 100644
--- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
+++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
@@ -203,6 +203,7 @@ private Q_SLOTS:
void setViewDeletesImplicitPage();
void setPagePreservesExplicitPage();
void setViewPreservesExplicitPage();
+ void closeDiscardsPage();
};
// This will be called before the first test function is executed.
@@ -238,31 +239,46 @@ void tst_QWebEngineView::renderHints()
QVERIFY(!(webView.renderHints() & QPainter::Antialiasing));
QVERIFY(webView.renderHints() & QPainter::TextAntialiasing);
QVERIFY(webView.renderHints() & QPainter::SmoothPixmapTransform);
+#if QT_DEPRECATED_SINCE(5, 14)
QVERIFY(!(webView.renderHints() & QPainter::HighQualityAntialiasing));
+#endif
+ QVERIFY(!(webView.renderHints() & QPainter::Antialiasing));
webView.setRenderHint(QPainter::Antialiasing, true);
QVERIFY(webView.renderHints() & QPainter::Antialiasing);
QVERIFY(webView.renderHints() & QPainter::TextAntialiasing);
QVERIFY(webView.renderHints() & QPainter::SmoothPixmapTransform);
+#if QT_DEPRECATED_SINCE(5, 14)
QVERIFY(!(webView.renderHints() & QPainter::HighQualityAntialiasing));
+#endif
+ QVERIFY(!(webView.renderHints() & QPainter::Antialiasing));
webView.setRenderHint(QPainter::Antialiasing, false);
QVERIFY(!(webView.renderHints() & QPainter::Antialiasing));
QVERIFY(webView.renderHints() & QPainter::TextAntialiasing);
QVERIFY(webView.renderHints() & QPainter::SmoothPixmapTransform);
+#if QT_DEPRECATED_SINCE(5, 14)
QVERIFY(!(webView.renderHints() & QPainter::HighQualityAntialiasing));
+#endif
+ QVERIFY(!(webView.renderHints() & QPainter::Antialiasing));
webView.setRenderHint(QPainter::SmoothPixmapTransform, true);
QVERIFY(!(webView.renderHints() & QPainter::Antialiasing));
QVERIFY(webView.renderHints() & QPainter::TextAntialiasing);
QVERIFY(webView.renderHints() & QPainter::SmoothPixmapTransform);
+#if QT_DEPRECATED_SINCE(5, 14)
QVERIFY(!(webView.renderHints() & QPainter::HighQualityAntialiasing));
+#endif
+ QVERIFY(!(webView.renderHints() & QPainter::Antialiasing));
webView.setRenderHint(QPainter::SmoothPixmapTransform, false);
QVERIFY(webView.renderHints() & QPainter::TextAntialiasing);
QVERIFY(!(webView.renderHints() & QPainter::SmoothPixmapTransform));
+#if QT_DEPRECATED_SINCE(5, 14)
QVERIFY(!(webView.renderHints() & QPainter::HighQualityAntialiasing));
#endif
+ QVERIFY(!(webView.renderHints() & QPainter::Antialiasing));
+#endif
}
void tst_QWebEngineView::getWebKitVersion()
@@ -481,14 +497,14 @@ void tst_QWebEngineView::microFocusCoordinates()
evaluateJavaScriptSync(webView.page(), "document.getElementById('input1').focus()");
QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("input1"));
- QTRY_VERIFY(webView.focusProxy()->inputMethodQuery(Qt::ImMicroFocus).isValid());
- QVariant initialMicroFocus = webView.focusProxy()->inputMethodQuery(Qt::ImMicroFocus);
+ QTRY_VERIFY(webView.focusProxy()->inputMethodQuery(Qt::ImCursorRectangle).isValid());
+ QVariant initialMicroFocus = webView.focusProxy()->inputMethodQuery(Qt::ImCursorRectangle);
evaluateJavaScriptSync(webView.page(), "window.scrollBy(0, 50)");
QTRY_VERIFY(scrollSpy.count() > 0);
- QTRY_VERIFY(webView.focusProxy()->inputMethodQuery(Qt::ImMicroFocus).isValid());
- QVariant currentMicroFocus = webView.focusProxy()->inputMethodQuery(Qt::ImMicroFocus);
+ QTRY_VERIFY(webView.focusProxy()->inputMethodQuery(Qt::ImCursorRectangle).isValid());
+ QVariant currentMicroFocus = webView.focusProxy()->inputMethodQuery(Qt::ImCursorRectangle);
QCOMPARE(initialMicroFocus.toRect().translated(QPoint(0,-50)), currentMicroFocus.toRect());
}
@@ -1515,7 +1531,7 @@ void tst_QWebEngineView::postData()
eventloop.quit();
});
- connect(socket, &QIODevice::readyRead, this, [this, socket, &server, &postData](){
+ connect(socket, &QIODevice::readyRead, this, [socket, &server, &postData](){
QByteArray rawData = socket->readAll();
QStringList lines = QString::fromLocal8Bit(rawData).split("\r\n");
@@ -1830,11 +1846,14 @@ void tst_QWebEngineView::softwareInputPanel()
void tst_QWebEngineView::inputContextQueryInput()
{
- TestInputContext testContext;
QWebEngineView view;
view.resize(640, 480);
view.show();
+ // testContext will be destroyed before the view, so no events are sent accidentally
+ // when the view is destroyed.
+ TestInputContext testContext;
+
QSignalSpy selectionChangedSpy(&view, SIGNAL(selectionChanged()));
QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
view.setHtml("<html><body>"
@@ -2196,6 +2215,22 @@ void tst_QWebEngineView::textSelectionOutOfInputField()
QVERIFY(!view.hasSelection());
QVERIFY(view.page()->selectedText().isEmpty());
+ // Select text by ctrl+a
+ QTest::keyClick(view.windowHandle(), Qt::Key_A, Qt::ControlModifier);
+ QVERIFY(selectionChangedSpy.wait());
+ QCOMPARE(selectionChangedSpy.count(), 3);
+ QVERIFY(view.hasSelection());
+ QCOMPARE(view.page()->selectedText(), QString("This is a text"));
+
+ // Deselect text via discard+undiscard
+ view.hide();
+ view.page()->setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
+ view.show();
+ QVERIFY(loadFinishedSpy.wait());
+ QCOMPARE(selectionChangedSpy.count(), 4);
+ QVERIFY(!view.hasSelection());
+ QVERIFY(view.page()->selectedText().isEmpty());
+
selectionChangedSpy.clear();
view.setHtml("<html><body>"
" This is a text"
@@ -2971,7 +3006,7 @@ void tst_QWebEngineView::mouseLeave()
QVBoxLayout *layout = new QVBoxLayout;
layout->setAlignment(Qt::AlignTop);
layout->setSpacing(0);
- layout->setMargin(0);
+ layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(label);
layout->addWidget(view);
containerWidget->setLayout(layout);
@@ -3070,7 +3105,6 @@ void tst_QWebEngineView::webUIURLs_data()
QTest::newRow("supervised-user-internals") << QUrl("chrome://supervised-user-internals") << false;
QTest::newRow("sync-internals") << QUrl("chrome://sync-internals") << false;
QTest::newRow("system") << QUrl("chrome://system") << false;
- QTest::newRow("taskscheduler-internals") << QUrl("chrome://taskscheduler-internals") << true;
QTest::newRow("terms") << QUrl("chrome://terms") << false;
QTest::newRow("thumbnails") << QUrl("chrome://thumbnails") << false;
QTest::newRow("tracing") << QUrl("chrome://tracing") << false;
@@ -3091,7 +3125,7 @@ void tst_QWebEngineView::webUIURLs()
view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool)));
view.load(url);
- QVERIFY(loadFinishedSpy.wait());
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 12000);
QCOMPARE(loadFinishedSpy.takeFirst().at(0).toBool(), supported);
}
@@ -3292,5 +3326,21 @@ void tst_QWebEngineView::setViewPreservesExplicitPage()
QVERIFY(explicitPage1); // should not be deleted
}
+void tst_QWebEngineView::closeDiscardsPage()
+{
+ QWebEngineProfile profile;
+ QWebEnginePage page(&profile);
+ QWebEngineView view;
+ view.setPage(&page);
+ view.resize(300, 300);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QCOMPARE(page.isVisible(), true);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
+ view.close();
+ QCOMPARE(page.isVisible(), false);
+ QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
+}
+
QTEST_MAIN(tst_QWebEngineView)
#include "tst_qwebengineview.moc"
diff --git a/tests/auto/widgets/spellchecking/tst_spellchecking.cpp b/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
index d02fc78b9..64df05d89 100644
--- a/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
+++ b/tests/auto/widgets/spellchecking/tst_spellchecking.cpp
@@ -72,10 +72,7 @@ class tst_Spellchecking : public QObject
private Q_SLOTS:
void init();
void cleanup();
- void initTestCase();
- void spellCheckLanguage();
- void spellCheckLanguages();
- void spellCheckEnabled();
+ void settings();
void spellcheck();
void spellcheck_data();
@@ -84,19 +81,8 @@ private:
WebView *m_view;
};
-void tst_Spellchecking::initTestCase()
-{
- QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
- QVERIFY(profile);
- QVERIFY(!profile->isSpellCheckEnabled());
- QVERIFY(profile->spellCheckLanguages().isEmpty());
-}
-
void tst_Spellchecking::init()
{
- QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
- profile->setSpellCheckEnabled(false);
- profile->setSpellCheckLanguages(QStringList());
m_view = new WebView();
}
@@ -106,7 +92,6 @@ void tst_Spellchecking::load()
m_view->show();
QSignalSpy spyFinished(m_view->page(), &QWebEnginePage::loadFinished);
QVERIFY(spyFinished.wait());
-
}
void tst_Spellchecking::cleanup()
@@ -114,29 +99,57 @@ void tst_Spellchecking::cleanup()
delete m_view;
}
-void tst_Spellchecking::spellCheckLanguage()
+void tst_Spellchecking::settings()
{
- QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
- QVERIFY(profile);
- profile->setSpellCheckLanguages({"en-US"});
- QVERIFY(profile->spellCheckLanguages() == QStringList({"en-US"}));
-}
+ // Default profile has spellchecking disabled
-void tst_Spellchecking::spellCheckLanguages()
-{
- QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
- QVERIFY(profile);
- profile->setSpellCheckLanguages({"en-US","de-DE"});
- QVERIFY(profile->spellCheckLanguages() == QStringList({"en-US","de-DE"}));
-}
+ QVERIFY(!QWebEngineProfile::defaultProfile()->isSpellCheckEnabled());
+ QVERIFY(QWebEngineProfile::defaultProfile()->spellCheckLanguages().isEmpty());
+ // New named profiles have spellchecking disabled
-void tst_Spellchecking::spellCheckEnabled()
-{
- QWebEngineProfile *profile = QWebEngineProfile::defaultProfile();
- QVERIFY(profile);
- profile->setSpellCheckEnabled(true);
- QVERIFY(profile->isSpellCheckEnabled());
+ auto profile1 = std::make_unique<QWebEngineProfile>(QStringLiteral("Profile1"));
+ QVERIFY(!profile1->isSpellCheckEnabled());
+ QVERIFY(profile1->spellCheckLanguages().isEmpty());
+
+ auto profile2 = std::make_unique<QWebEngineProfile>(QStringLiteral("Profile2"));
+ QVERIFY(!profile2->isSpellCheckEnabled());
+ QVERIFY(profile2->spellCheckLanguages().isEmpty());
+
+ // New otr profiles have spellchecking disabled
+
+ auto profile3 = std::make_unique<QWebEngineProfile>();
+ QVERIFY(!profile2->isSpellCheckEnabled());
+ QVERIFY(profile2->spellCheckLanguages().isEmpty());
+
+ // Settings can be changed
+
+ profile1->setSpellCheckEnabled(true);
+ QVERIFY(profile1->isSpellCheckEnabled());
+
+ profile1->setSpellCheckLanguages({"en-US"});
+ QVERIFY(profile1->spellCheckLanguages() == QStringList({"en-US"}));
+
+ profile1->setSpellCheckLanguages({"en-US","de-DE"});
+ QVERIFY(profile1->spellCheckLanguages() == QStringList({"en-US","de-DE"}));
+
+ // Settings are per profile
+
+ QVERIFY(!profile2->isSpellCheckEnabled());
+ QVERIFY(profile2->spellCheckLanguages().isEmpty());
+
+ QVERIFY(!profile3->isSpellCheckEnabled());
+ QVERIFY(profile3->spellCheckLanguages().isEmpty());
+
+ // Settings are not persisted
+
+ // TODO(juvaldma): Write from dtor currently usually happens *after* the
+ // read from the ctor, so this test would pass even if settings were
+ // persisted. It would start to fail on the second run though.
+ profile1.reset();
+ profile1 = std::make_unique<QWebEngineProfile>(QStringLiteral("Profile1"));
+ QVERIFY(!profile1->isSpellCheckEnabled());
+ QVERIFY(profile1->spellCheckLanguages().isEmpty());
}
void tst_Spellchecking::spellcheck()
diff --git a/tests/auto/widgets/util.h b/tests/auto/widgets/util.h
index f27466225..eba974f33 100644
--- a/tests/auto/widgets/util.h
+++ b/tests/auto/widgets/util.h
@@ -85,7 +85,7 @@ public:
T waitForResult() {
if (!called) {
- timeoutTimer.start(10000);
+ timeoutTimer.start(20000);
eventLoop.exec();
}
return result;
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index 92159bf83..6d65eecb5 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -30,6 +30,10 @@ qtConfig(webengine-printing-and-pdf) {
SUBDIRS += printing
}
+qtConfig(ssl) {
+ SUBDIRS += certificateerror
+}
+
qtConfig(webengine-spellchecker):!cross_compile {
!qtConfig(webengine-native-spellchecker) {
SUBDIRS += spellchecking
diff --git a/tests/manual/widgets/webgl/main.cpp b/tests/manual/widgets/webgl/main.cpp
index 364eda8b9..c18a15bac 100644
--- a/tests/manual/widgets/webgl/main.cpp
+++ b/tests/manual/widgets/webgl/main.cpp
@@ -30,9 +30,9 @@
#include <QtCore/QLoggingCategory>
#include <QtCore/QOperatingSystemVersion>
#include <QtGui/QOpenGLContext>
+#include <QtGui/QScreen>
#include <QtGui/QSurfaceFormat>
#include <QtWidgets/QApplication>
-#include <QtWidgets/QDesktopWidget>
#include <QtWidgets/QGroupBox>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QMainWindow>
@@ -104,7 +104,7 @@ MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
QSize MainWindow::sizeHint() const
{
- const QRect desktopRect = QApplication::desktop()->screenGeometry();
+ const QRect desktopRect = QGuiApplication::primaryScreen()->geometry();
const QSize size = desktopRect.size() * qreal(0.9);
return size;
}
@@ -172,7 +172,7 @@ int main(int argc, char *argv[])
MainWindow w;
// Move middle-ish.
- const QRect desktopRect = QApplication::desktop()->screenGeometry();
+ const QRect desktopRect = QGuiApplication::primaryScreen()->geometry();
const QSize pos = desktopRect.size() * qreal(0.1);
w.move(pos.width(), pos.height());
diff --git a/tests/quicktestbrowser/main.cpp b/tests/quicktestbrowser/main.cpp
index 00c1ee4ad..b886564f3 100644
--- a/tests/quicktestbrowser/main.cpp
+++ b/tests/quicktestbrowser/main.cpp
@@ -88,7 +88,7 @@ int main(int argc, char **argv)
index = rootMeta->indexOfProperty("testProfile");
Q_ASSERT(index != -1);
QMetaProperty profileProperty = rootMeta->property(index);
- profileProperty.write(rootObject, qVariantFromValue(profile));
+ profileProperty.write(rootObject, QVariant::fromValue(profile));
QMetaObject::invokeMethod(rootObject, "load", Q_ARG(QVariant, startupUrl()));
diff --git a/tests/tests.pro b/tests/tests.pro
index 2922e5076..acb223640 100644
--- a/tests/tests.pro
+++ b/tests/tests.pro
@@ -1,3 +1,7 @@
TEMPLATE = subdirs
-SUBDIRS += auto quicktestbrowser
+SUBDIRS += auto
+
+qtHaveModule(webengine) {
+ SUBDIRS += quicktestbrowser
+}