diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-05-10 14:39:15 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2021-05-12 12:46:13 +0200 |
commit | 4629185e555e6c891d6308ae7cafa584ce6d731f (patch) | |
tree | 1ed9f01ec7fdb6f52a607cab0a31b60bb60179d2 /tests/auto | |
parent | f8527fa9427984082cd425d304d29fd030ff5b1a (diff) | |
parent | 5d41d39b82acb3e2da597df0588fb906e212d608 (diff) |
Merge remote-tracking branch 'origin/5.15' into dev
Conflicts:
examples/webenginewidgets/printme/printhandler.cpp
src/3rdparty
src/core/api/qwebenginepage_p.h
src/core/content_browser_client_qt.h
src/core/web_contents_adapter_client.h
src/core/web_contents_delegate_qt.cpp
src/core/web_contents_delegate_qt.h
src/webenginequick/api/qquickwebengineview_p_p.h
tests/auto/quick/qmltests/data/tst_download.qml
tests/auto/quick/qmltests/data/tst_viewSoure.qml
tests/auto/widgets/loadsignals/tst_loadsignals.cpp
tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
Change-Id: I9c1819ec15e13d4f8e244defe860e26274b5d4be
Diffstat (limited to 'tests/auto')
42 files changed, 476 insertions, 212 deletions
diff --git a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp index 8416abfdb..dbd645a83 100644 --- a/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp +++ b/tests/auto/core/qwebenginecookiestore/tst_qwebenginecookiestore.cpp @@ -249,22 +249,27 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP() QWebEngineCookieStore *client = m_profile->cookieStore(); QAtomicInt accessTested = 0; - client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &) { ++accessTested; return true; }); + QList<QPair<QUrl, QUrl>> resourceFirstParty; + client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &request) { + resourceFirstParty.append(qMakePair(request.origin, request.firstPartyUrl)); + ++accessTested; + return true; + }); HttpServer httpServer; - - if (!httpServer.start()) - QSKIP("Failed to start http server"); + httpServer.setHostDomain(QString("sub.test.localhost")); + QVERIFY(httpServer.start()); QByteArray cookieRequestHeader; connect(&httpServer, &HttpServer::newRequest, [&cookieRequestHeader](HttpReqRep *rr) { - if (rr->requestPath().size() <= 1) { + if (rr->requestMethod() == "GET" && rr->requestPath() == "/test.html") { cookieRequestHeader = rr->requestHeader(QByteArrayLiteral("Cookie")); if (cookieRequestHeader.isEmpty()) rr->setResponseHeader(QByteArrayLiteral("Set-Cookie"), QByteArrayLiteral("Test=test")); + rr->setResponseBody("<head><link rel='icon' type='image/png' href='resources/Fav.png'/>" + "<title>Page with a favicon and an icon</title></head>" + "<body><img src='resources/Img.ico'></body>"); rr->sendResponse(); - } else { - rr->sendResponse(404); } }); @@ -273,12 +278,13 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP() QSignalSpy cookieRemovedSpy(client, SIGNAL(cookieRemoved(const QNetworkCookie &))); QSignalSpy serverSpy(&httpServer, SIGNAL(newRequest(HttpReqRep *))); - page.load(httpServer.url()); + QUrl firstPartyUrl = httpServer.url("/test.html"); + page.load(firstPartyUrl); QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 30000); QVERIFY(loadSpy.takeFirst().takeFirst().toBool()); QTRY_COMPARE(cookieAddedSpy.count(), 1); - QTRY_COMPARE(accessTested.loadAcquire(), 3); + QTRY_COMPARE(accessTested.loadAcquire(), 4); QVERIFY(cookieRequestHeader.isEmpty()); page.triggerAction(QWebEnginePage::Reload); @@ -286,12 +292,16 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP() QVERIFY(loadSpy.takeFirst().takeFirst().toBool()); QVERIFY(!cookieRequestHeader.isEmpty()); QTRY_COMPARE(cookieAddedSpy.count(), 1); - QTRY_COMPARE(accessTested.loadAcquire(), 5); + QTRY_COMPARE(accessTested.loadAcquire(), 7); client->deleteAllCookies(); QTRY_COMPARE(cookieRemovedSpy.count(), 1); - client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &) { ++accessTested; return false; }); + client->setCookieFilter([&](const QWebEngineCookieStore::FilterRequest &request) { + resourceFirstParty.append(qMakePair(request.origin, request.firstPartyUrl)); + ++accessTested; + return false; + }); page.triggerAction(QWebEnginePage::ReloadAndBypassCache); QTRY_COMPARE(loadSpy.count(), 1); QVERIFY(loadSpy.takeFirst().takeFirst().toBool()); @@ -299,8 +309,7 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP() // Test cookies are NOT added: QTest::qWait(100); QCOMPARE(cookieAddedSpy.count(), 1); - QTRY_COMPARE(accessTested.loadAcquire(), 8); - + QTRY_COMPARE(accessTested.loadAcquire(), 11); page.triggerAction(QWebEnginePage::Reload); QTRY_COMPARE(loadSpy.count(), 1); QVERIFY(loadSpy.takeFirst().takeFirst().toBool()); @@ -308,8 +317,13 @@ void tst_QWebEngineCookieStore::basicFilterOverHTTP() QCOMPARE(cookieAddedSpy.count(), 1); // Wait for last GET /favicon.ico - QTRY_COMPARE(serverSpy.count(), 8); + QTRY_COMPARE(serverSpy.count(), 12); (void) httpServer.stop(); + + QCOMPARE(resourceFirstParty.size(), accessTested.loadAcquire()); + for (auto &&p : qAsConst(resourceFirstParty)) + QVERIFY2(p.second == firstPartyUrl, + qPrintable(QString("Resource [%1] has wrong firstPartyUrl: %2").arg(p.first.toString(), p.second.toString()))); } void tst_QWebEngineCookieStore::html5featureFilter() diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp index 090da3d6a..0d4e172ee 100644 --- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp +++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp @@ -726,7 +726,7 @@ void tst_QWebEngineUrlRequestInterceptor::jsServiceWorker() QTRY_COMPARE(page->messages.count(), 1); QCOMPARE(page->levels.at(0), QWebEnginePage::InfoMessageLevel); - QUrl firstPartyUrl = QUrl(server.url().toString(QUrl::RemovePort)); + QUrl firstPartyUrl = QUrl(server.url().toString() + "sw.js"); QList<RequestInfo> infos; // Service Worker QTRY_VERIFY(interceptor.hasUrlRequestForType(QWebEngineUrlRequestInfo::ResourceTypeServiceWorker)); diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST new file mode 100644 index 000000000..e5a575f06 --- /dev/null +++ b/tests/auto/quick/qmltests/BLACKLIST @@ -0,0 +1,5 @@ +[CertificateError::test_error] +macos + +[NewViewRequest::test_loadNewViewRequest] +macos diff --git a/tests/auto/quick/qmltests/data/TestWebEngineView.qml b/tests/auto/quick/qmltests/data/TestWebEngineView.qml index 4840f474d..f82589f7d 100644 --- a/tests/auto/quick/qmltests/data/TestWebEngineView.qml +++ b/tests/auto/quick/qmltests/data/TestWebEngineView.qml @@ -104,7 +104,6 @@ WebEngineView { } TestResult { id: testResult } - TestCase { id: testCase } onLoadingChanged: function(load) { loadStatus = load.status diff --git a/tests/auto/quick/qmltests/data/test4.html b/tests/auto/quick/qmltests/data/test4.html index c9b395ee5..cf5708994 100644 --- a/tests/auto/quick/qmltests/data/test4.html +++ b/tests/auto/quick/qmltests/data/test4.html @@ -24,6 +24,7 @@ } </script> <div id="content"> + <p><a id='anchor' href='#anchor'>anchor</a> <p>bla00 <p>bla01 <p>bla02 diff --git a/tests/auto/quick/qmltests/data/tst_action.qml b/tests/auto/quick/qmltests/data/tst_action.qml index 852d4145a..91f260e0e 100644 --- a/tests/auto/quick/qmltests/data/tst_action.qml +++ b/tests/auto/quick/qmltests/data/tst_action.qml @@ -41,7 +41,7 @@ TestWebEngineView { } TestCase { - id: actionTests + id: testCase name: "WebEngineAction" when: windowShown @@ -116,8 +116,8 @@ TestWebEngineView { var stopAction = webEngineView.action(WebEngineView.Stop); verify(stopAction); - var triggerSpy = createTemporaryObject(signalSpy, actionTests, {target: selectAction, signalName: "triggered"}); - var stopTriggerSpy = createTemporaryObject(signalSpy, actionTests, {target: stopAction, signalName: "triggered"}); + var triggerSpy = createTemporaryObject(signalSpy, testCase, {target: selectAction, signalName: "triggered"}); + var stopTriggerSpy = createTemporaryObject(signalSpy, testCase, {target: stopAction, signalName: "triggered"}); verify(selectAction.enabled); selectAction.trigger(); @@ -148,7 +148,7 @@ TestWebEngineView { compare(enabledSpy.count, 0); selectAllAction.trigger(); compare(triggerSpy.count, 0); - compare(getTextSelection(), ""); + compare(webEngineView.getTextSelection(), ""); // Focus content by focusing window from JavaScript. Edit actions should be enabled and functional. webView.runJavaScript("window.focus();"); @@ -157,6 +157,7 @@ TestWebEngineView { selectAllAction.trigger(); compare(triggerSpy.count, 1); tryVerify(function() { return webView.getTextSelection() === "foo bar" }); + webView.destroy(); } function test_editActionsWithInitialFocus() { @@ -180,6 +181,7 @@ TestWebEngineView { selectAllAction.trigger(); compare(triggerSpy.count, 1); tryVerify(function() { return webView.getTextSelection() === "foo bar" }); + webView.destroy(); } } } diff --git a/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml index c360a1da2..83a2dc8c9 100644 --- a/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml +++ b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml @@ -55,6 +55,7 @@ Item { } TestCase { + id: testCase name: "ActiveFocusOnPress" when:windowShown diff --git a/tests/auto/quick/qmltests/data/tst_audioMuted.qml b/tests/auto/quick/qmltests/data/tst_audioMuted.qml index c626d07a0..d0d9e35c3 100644 --- a/tests/auto/quick/qmltests/data/tst_audioMuted.qml +++ b/tests/auto/quick/qmltests/data/tst_audioMuted.qml @@ -42,7 +42,7 @@ TestWebEngineView { } TestCase { - id: test + id: testCase name: "WebEngineViewAudioMuted" function test_audioMuted() { diff --git a/tests/auto/quick/qmltests/data/tst_certificateError.qml b/tests/auto/quick/qmltests/data/tst_certificateError.qml index 976de88a9..d6c7edfd8 100644 --- a/tests/auto/quick/qmltests/data/tst_certificateError.qml +++ b/tests/auto/quick/qmltests/data/tst_certificateError.qml @@ -45,6 +45,7 @@ TestWebEngineView { } TestCase { + id: testCase name: 'CertificateError' when: windowShown @@ -55,6 +56,7 @@ TestWebEngineView { request.sendResponse() }) view.settings.errorPageEnabled = false + view.profile.useForGlobalCertificateVerification = true } function init() { diff --git a/tests/auto/quick/qmltests/data/tst_contextMenu.qml b/tests/auto/quick/qmltests/data/tst_contextMenu.qml index 99450a159..8493ba1c7 100644 --- a/tests/auto/quick/qmltests/data/tst_contextMenu.qml +++ b/tests/auto/quick/qmltests/data/tst_contextMenu.qml @@ -65,12 +65,12 @@ TestWebEngineView { } function destroyContextMenu() { - contextMenuTest.keyPress(Qt.Key_Escape); + testCase.keyPress(Qt.Key_Escape); return getContextMenus().length == 0; } TestCase { - id: contextMenuTest + id: testCase name: "WebEngineViewContextMenu" when: windowShown diff --git a/tests/auto/quick/qmltests/data/tst_favicon.qml b/tests/auto/quick/qmltests/data/tst_favicon.qml index 92c50876c..fc8b90542 100644 --- a/tests/auto/quick/qmltests/data/tst_favicon.qml +++ b/tests/auto/quick/qmltests/data/tst_favicon.qml @@ -59,16 +59,16 @@ TestWebEngineView { function getFaviconPixel(faviconImage) { var grabImage = Qt.createQmlObject(" import QtQuick 2.5\n - Image { }", test) + Image { }", testCase) var faviconCanvas = Qt.createQmlObject(" import QtQuick 2.5\n - Canvas { }", test) + Canvas { }", testCase) - test.tryVerify(function() { return faviconImage.status == Image.Ready }); + testCase.tryVerify(function() { return faviconImage.status == Image.Ready }); faviconImage.grabToImage(function(result) { grabImage.source = result.url }); - test.tryVerify(function() { return grabImage.status == Image.Ready }); + testCase.tryVerify(function() { return grabImage.status == Image.Ready }); faviconCanvas.width = faviconImage.width; faviconCanvas.height = faviconImage.height; @@ -97,7 +97,7 @@ TestWebEngineView { } TestCase { - id: test + id: testCase name: "WebEngineFavicon" when: windowShown @@ -315,7 +315,7 @@ TestWebEngineView { function test_faviconProvider(row) { var faviconImage = Qt.createQmlObject(" import QtQuick 2.5\n - Image { sourceSize: Qt.size(width, height) }", test) + Image { sourceSize: Qt.size(width, height) }", testCase) compare(iconChangedSpy.count, 0) @@ -338,7 +338,7 @@ TestWebEngineView { function test_dynamicFavicon() { var faviconImage = Qt.createQmlObject(" import QtQuick 2.5\n - Image { width: 16; height: 16; sourceSize: Qt.size(width, height); }", test) + Image { width: 16; height: 16; sourceSize: Qt.size(width, height); }", testCase) faviconImage.source = Qt.binding(function() { return webEngineView.icon; }); var colors = [ diff --git a/tests/auto/quick/qmltests/data/tst_faviconDownload.qml b/tests/auto/quick/qmltests/data/tst_faviconDownload.qml index 9aa32279c..7d9c39814 100644 --- a/tests/auto/quick/qmltests/data/tst_faviconDownload.qml +++ b/tests/auto/quick/qmltests/data/tst_faviconDownload.qml @@ -47,7 +47,7 @@ TestWebEngineView { } TestCase { - id: test + id: testCase name: "WebEngineFaviconDownload" function init() { diff --git a/tests/auto/quick/qmltests/data/tst_filePicker.qml b/tests/auto/quick/qmltests/data/tst_filePicker.qml index ab30d9e82..4313c8d9e 100644 --- a/tests/auto/quick/qmltests/data/tst_filePicker.qml +++ b/tests/auto/quick/qmltests/data/tst_filePicker.qml @@ -58,6 +58,7 @@ TestWebEngineView { onTitleChanged: { titleChanges.push(webEngineView.title) } TestCase { + id: testCase name: "WebEngineViewSingleFileUpload" when: windowShown diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml index c02a1348e..0b4a8d459 100644 --- a/tests/auto/quick/qmltests/data/tst_findText.qml +++ b/tests/auto/quick/qmltests/data/tst_findText.qml @@ -56,7 +56,7 @@ TestWebEngineView { // If this starts to fail then either clear was not called before findText // or unexpected callback was triggered from some search. // On c++ side callback id can be checked to verify - testcase.verify(!findCallbackCalled(), 'Unexpected callback call or uncleared state before findText call!') + testCase.verify(!findCallbackCalled(), 'Unexpected callback call or uncleared state before findText call!') webEngineView.matchCount = matchCount findFailed = matchCount == 0 @@ -64,7 +64,7 @@ TestWebEngineView { TestCase { - id: testcase + id: testCase name: "WebViewFindText" function getBodyInnerHTML() { diff --git a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml index 93410a727..b2b7374f6 100644 --- a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml +++ b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml @@ -65,6 +65,7 @@ Item { } TestCase { + id: testCase name: "WebEngineViewFocusOnNavigation" when: windowShown diff --git a/tests/auto/quick/qmltests/data/tst_inputMethod.qml b/tests/auto/quick/qmltests/data/tst_inputMethod.qml index 0bf9f7eb0..00f85cb71 100644 --- a/tests/auto/quick/qmltests/data/tst_inputMethod.qml +++ b/tests/auto/quick/qmltests/data/tst_inputMethod.qml @@ -40,6 +40,7 @@ TestWebEngineView { testSupport: WebEngineTestSupport { } TestCase { + id: testCase name: "WebEngineViewInputMethod" when: windowShown diff --git a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml index 2536f319b..136863c4c 100644 --- a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml +++ b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml @@ -36,6 +36,7 @@ TestWebEngineView { height: 480 TestCase { + id: testCase name: "WebEngineViewKeyboardEvents" when: windowShown diff --git a/tests/auto/quick/qmltests/data/tst_loadFail.qml b/tests/auto/quick/qmltests/data/tst_loadFail.qml index 8a46afbad..c27ae8b0f 100644 --- a/tests/auto/quick/qmltests/data/tst_loadFail.qml +++ b/tests/auto/quick/qmltests/data/tst_loadFail.qml @@ -119,21 +119,22 @@ TestWebEngineView { verify(!loadRequest.isErrorPage) // Loading of the unavailableUrl must fail - loadRequest = loadRequestArray[1] + loadRequest = loadRequestArray[3] compare(loadRequest.status, WebEngineView.LoadFailedStatus) compare(loadRequest.errorDomain, WebEngineView.InternalErrorDomain) compare(loadRequest.url, unavailableUrl) verify(!loadRequest.isErrorPage) + // error page load is done inside main load through test support // Start to load error page - loadRequest = loadRequestArray[2] + loadRequest = loadRequestArray[1] compare(loadRequest.status, WebEngineView.LoadStartedStatus) compare(loadRequest.errorDomain, WebEngineView.NoErrorDomain) compare(loadRequest.url, "chrome-error://chromewebdata/") verify(loadRequest.isErrorPage) // Loading of the error page must be successful - loadRequest = loadRequestArray[3] + loadRequest = loadRequestArray[2] compare(loadRequest.status, WebEngineView.LoadSucceededStatus) compare(loadRequest.errorDomain, WebEngineView.NoErrorDomain) compare(loadRequest.url, "chrome-error://chromewebdata/") diff --git a/tests/auto/quick/qmltests/data/tst_loadHtml.qml b/tests/auto/quick/qmltests/data/tst_loadHtml.qml index ed1de41fd..6ed9a4317 100644 --- a/tests/auto/quick/qmltests/data/tst_loadHtml.qml +++ b/tests/auto/quick/qmltests/data/tst_loadHtml.qml @@ -42,6 +42,7 @@ TestWebEngineView { } TestCase { + id: testCase name: "WebEngineViewLoadHtml" when: windowShown diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml index 817a28637..b60a00faf 100644 --- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml +++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml @@ -52,6 +52,7 @@ TestWebEngineView { } TestCase { + id: testCase name: "WebEngineViewLoadUrl" when: windowShown @@ -298,20 +299,19 @@ TestWebEngineView { compare(loadRequestArray[0].status, WebEngineView.LoadStartedStatus); compare(loadRequestArray[1].status, WebEngineView.LoadSucceededStatus); - // In-page navigation. - webEngineView.url = Qt.resolvedUrl("test4.html#content"); - // In-page navigation doesn't trigger load succeeded, wait for load progress instead. - tryCompare(loadRequestArray, "length", 3); - tryCompare(webEngineView, "loadProgress", 100); - compare(loadRequestArray[2].status, WebEngineView.LoadStartedStatus); + // In-page navigation shouldn't trigger load + let anchorUrl = Qt.resolvedUrl("test4.html#anchor"); + let c = webEngineView.getElementCenter('anchor') + mouseClick(webEngineView, c.x, c.y) + tryCompare(webEngineView, 'url', anchorUrl) // Load after in-page navigation. webEngineView.url = Qt.resolvedUrl("test4.html"); verify(webEngineView.waitForLoadSucceeded()); compare(webEngineView.loadProgress, 100); - compare(loadRequestArray.length, 5); - compare(loadRequestArray[3].status, WebEngineView.LoadStartedStatus); - compare(loadRequestArray[4].status, WebEngineView.LoadSucceededStatus); + compare(loadRequestArray.length, 4); + compare(loadRequestArray[2].status, WebEngineView.LoadStartedStatus); + compare(loadRequestArray[3].status, WebEngineView.LoadSucceededStatus); webEngineView.clear(); } diff --git a/tests/auto/quick/qmltests/data/tst_mouseClick.qml b/tests/auto/quick/qmltests/data/tst_mouseClick.qml index eaa012f86..6c314d44c 100644 --- a/tests/auto/quick/qmltests/data/tst_mouseClick.qml +++ b/tests/auto/quick/qmltests/data/tst_mouseClick.qml @@ -65,6 +65,7 @@ TestWebEngineView { TestCase { + id: testCase name: "WebEngineViewMouseClick" when: windowShown diff --git a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml index 96128574e..a24b8f0d4 100644 --- a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml +++ b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml @@ -79,6 +79,7 @@ TestWebEngineView { } TestCase { + id: testCase name: "WebEngineViewNavigationRequested" when: windowShown diff --git a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml index cce657f81..fd720befe 100644 --- a/tests/auto/quick/qmltests/data/tst_newViewRequest.qml +++ b/tests/auto/quick/qmltests/data/tst_newViewRequest.qml @@ -77,7 +77,7 @@ TestWebEngineView { } TestCase { - id: test + id: testCase name: "NewViewRequest" when: windowShown @@ -158,7 +158,7 @@ TestWebEngineView { " <button id='popupButton' onclick='popup()'>Pop Up!</button>" + "</body></html>"); verify(webEngineView.waitForLoadSucceeded()); - verifyElementHasFocus("popupButton"); + webEngineView.verifyElementHasFocus("popupButton"); keyPress(Qt.Key_Enter); tryCompare(newViewRequestedSpy, "count", 1); compare(newViewRequest.requestedUrl, url); @@ -176,7 +176,7 @@ TestWebEngineView { compare(loadRequestArray.length, 0); webEngineView.url = Qt.resolvedUrl("test2.html"); verify(webEngineView.waitForLoadSucceeded()); - var center = getElementCenter("link"); + var center = webEngineView.getElementCenter("link"); mouseClick(webEngineView, center.x, center.y, Qt.LeftButton, Qt.ControlModifier); tryCompare(newViewRequestedSpy, "count", 1); compare(newViewRequest.requestedUrl, Qt.resolvedUrl("test1.html")); diff --git a/tests/auto/quick/qmltests/data/tst_settings.qml b/tests/auto/quick/qmltests/data/tst_settings.qml index 2ff4f9c3c..b286a1dae 100644 --- a/tests/auto/quick/qmltests/data/tst_settings.qml +++ b/tests/auto/quick/qmltests/data/tst_settings.qml @@ -36,6 +36,7 @@ TestWebEngineView { height: 300 TestCase { + id: testCase name: "WebEngineViewSettings" function test_javascriptEnabled() { @@ -75,7 +76,7 @@ TestWebEngineView { } function test_settingsAffectCurrentViewOnly() { - var webEngineView2 = Qt.createQmlObject('TestWebEngineView {width: 400; height: 300;}', webEngineView); + var webEngineView2 = Qt.createQmlObject('TestWebEngineView {width: 400; height: 300;}', testCase); webEngineView.settings.javascriptEnabled = true; webEngineView2.settings.javascriptEnabled = true; diff --git a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml index 69aa76b77..5e163fc64 100644 --- a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml +++ b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml @@ -46,6 +46,7 @@ Item { focus: true } TestCase { + id: testCase name: "WebEngineViewUnhandledKeyEventPropagation" when: false diff --git a/tests/auto/quick/qmltests/data/tst_viewSoure.qml b/tests/auto/quick/qmltests/data/tst_viewSoure.qml index 870f6ee7b..1ee687f34 100644 --- a/tests/auto/quick/qmltests/data/tst_viewSoure.qml +++ b/tests/auto/quick/qmltests/data/tst_viewSoure.qml @@ -44,6 +44,7 @@ TestWebEngineView { errorPage.onLoadingChanged: function(load) { loadRequestArray.push({ "status": load.status, + "url": load.url }) } } @@ -51,6 +52,7 @@ TestWebEngineView { onLoadingChanged: function(load) { loadRequestArray.push({ "status": load.status, + "url": load.url }); } @@ -76,7 +78,7 @@ TestWebEngineView { } TestCase { - id: test + id: testCase name: "WebEngineViewSource" function init() { @@ -109,14 +111,16 @@ TestWebEngineView { WebEngine.settings.errorPageEnabled = true webEngineView.url = row.userInputUrl; + if (row.loadSucceed) { - tryVerify(function() { return loadRequestArray.length >= 2 }); + tryVerify(function() { return loadRequestArray.length == 2 }); compare(loadRequestArray[1].status, WebEngineView.LoadSucceededStatus); } else { - tryVerify(function() { return loadRequestArray.length >= 2 }); - compare(loadRequestArray[1].status, WebEngineView.LoadFailedStatus); - tryVerify(function() { return loadRequestArray.length == 4 }); - compare(loadRequestArray[3].status, WebEngineView.LoadSucceededStatus); + tryVerify(function() { return loadRequestArray.length == 4 }, 90000); + // error page load is done inside main load through test support + compare(loadRequestArray[2].status, WebEngineView.LoadSucceededStatus); + compare(loadRequestArray[2].url, "chrome-error://chromewebdata/") + compare(loadRequestArray[3].status, WebEngineView.LoadFailedStatus); } tryVerify(function() { return titleChangedSpy.count == 1; }); diff --git a/tests/auto/shared/data/loadprogress/page1.html b/tests/auto/shared/data/loadprogress/page1.html index 5cd479ab6..9b11ce887 100644 --- a/tests/auto/shared/data/loadprogress/page1.html +++ b/tests/auto/shared/data/loadprogress/page1.html @@ -3,6 +3,6 @@ <title>page1</title> </head> <body> - <h1>page1</h1> + <div><a href="page2.html#anchor">page2</a></div> </body> </html> diff --git a/tests/auto/shared/data/loadprogress/page2.html b/tests/auto/shared/data/loadprogress/page2.html index e3031f56a..223817c8c 100644 --- a/tests/auto/shared/data/loadprogress/page2.html +++ b/tests/auto/shared/data/loadprogress/page2.html @@ -9,6 +9,7 @@ } </style> <body> + <div><a href="#anchor">page2</a></div> <div class="fardown" id="anchor">page2 anchor</div> </body> </html> diff --git a/tests/auto/shared/data/loadprogress/page5.html b/tests/auto/shared/data/loadprogress/page5.html new file mode 100644 index 000000000..47709ff08 --- /dev/null +++ b/tests/auto/shared/data/loadprogress/page5.html @@ -0,0 +1,20 @@ +<html> + <head> + <title>page5</title> + </head> + <script> + addEventListener('DOMContentLoaded', (event) => { + document.getElementById('anchorLink').click(); + }); + </script> + <style> + .fardown { + position: absolute; + top: 2500px; + } + </style> + <body> + <div><a id="anchorLink" href="#anchor">go to the anchor</a></div> + <div class="fardown" id="anchor">here is the anchor</div> + </body> +</html> diff --git a/tests/auto/shared/data/loadprogress/page6.html b/tests/auto/shared/data/loadprogress/page6.html new file mode 100644 index 000000000..98042701a --- /dev/null +++ b/tests/auto/shared/data/loadprogress/page6.html @@ -0,0 +1,13 @@ +<html> + <head> + <title>page6</title> + </head> + <script> + addEventListener('DOMContentLoaded', (event) => { + document.getElementById('anchorLink').click(); + }); + </script> + <body> + <div><a id="anchorLink" href="page2.html#anchor">go to another page</a></div> + </body> +</html> diff --git a/tests/auto/shared/data/loadprogress/page7.html b/tests/auto/shared/data/loadprogress/page7.html new file mode 100644 index 000000000..42538c5de --- /dev/null +++ b/tests/auto/shared/data/loadprogress/page7.html @@ -0,0 +1,13 @@ +<html> + <head> + <title>page6</title> + </head> + <script> + setTimeout(function(){ + document.getElementById('anchorLink').click(); + },500); + </script> + <body> + <div><a id="anchorLink" href="page2.html#anchor">go to another page</a></div> + </body> +</html> diff --git a/tests/auto/shared/data/loadprogress/page8.html b/tests/auto/shared/data/loadprogress/page8.html new file mode 100644 index 000000000..8ebdddf97 --- /dev/null +++ b/tests/auto/shared/data/loadprogress/page8.html @@ -0,0 +1,20 @@ +<html> + <head> + <title>Page with js navigation in the end of document to anchor within the page</title> + </head> + <style> + .fardown { + position: absolute; + top: 2500px; + } + </style> + <body> + <div><a id="anchorLink" href="#anchor">go to the anchor</a></div> + <div class="fardown" id="anchor">here is the anchor</div> + <script> + addEventListener('load', (event) => { + window.location.replace(document.getElementById('anchorLink').href) + }) + </script> + </body> +</html> diff --git a/tests/auto/shared/httpserver.h b/tests/auto/shared/httpserver.h index 952ead220..3ec69f8ed 100644 --- a/tests/auto/shared/httpserver.h +++ b/tests/auto/shared/httpserver.h @@ -78,6 +78,8 @@ public: Q_INVOKABLE void setResourceDirs(const QStringList &dirs) { m_dirs = dirs; } + Q_INVOKABLE void setHostDomain(const QString &host) { m_url.setHost(host); } + Q_SIGNALS: // Emitted after a HTTP request has been successfully parsed. void newRequest(HttpReqRep *reqRep); diff --git a/tests/auto/widgets/certificateerror/tst_certificateerror.cpp b/tests/auto/widgets/certificateerror/tst_certificateerror.cpp index 063a53ae2..9865162cb 100644 --- a/tests/auto/widgets/certificateerror/tst_certificateerror.cpp +++ b/tests/auto/widgets/certificateerror/tst_certificateerror.cpp @@ -30,6 +30,7 @@ #include <QWebEngineCertificateError> #include <QWebEnginePage> +#include <QWebEngineProfile> #include <QWebEngineSettings> #include <QtTest/QtTest> @@ -128,6 +129,7 @@ void tst_CertificateError::handleError() void tst_CertificateError::fatalError() { PageWithCertificateErrorHandler page(false, false); + page.profile()->setUseForGlobalCertificateVerification(); page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false); QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished); diff --git a/tests/auto/widgets/loadsignals/BLACKLIST b/tests/auto/widgets/loadsignals/BLACKLIST deleted file mode 100644 index e5c625bd6..000000000 --- a/tests/auto/widgets/loadsignals/BLACKLIST +++ /dev/null @@ -1,17 +0,0 @@ -[secondLoadForError_WhenErrorPageEnabled:ErrorPageEnabled] -* - -# QTBUG-65223 -[loadStartedAndFinishedCount:WithAnchorClickedFromJS] -* - -# QTBUG-66869 (https://codereview.qt-project.org/#/c/222112/ is only a workaround) -[loadAfterInPageNavigation_qtbug66869] -* - -# QTBUG-66661 -[fileDownloadDoesNotTriggerLoadSignals_qtbug66661] -* - -[numberOfStartedAndFinishedSignalsIsSame] -b2qt diff --git a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp index b5140ec89..a0fa97e02 100644 --- a/tests/auto/widgets/loadsignals/tst_loadsignals.cpp +++ b/tests/auto/widgets/loadsignals/tst_loadsignals.cpp @@ -36,6 +36,43 @@ #include "qwebenginesettings.h" #include "qwebengineview.h" +enum { LoadStarted, LoadSucceeded, LoadFailed }; +static const QList<int> SignalsOrderOnce({ LoadStarted, LoadSucceeded}); +static const QList<int> SignalsOrderTwice({ LoadStarted, LoadSucceeded, LoadStarted, LoadSucceeded }); +static const QList<int> SignalsOrderOnceFailure({ LoadStarted, LoadFailed }); +static const QList<int> SignalsOrderTwiceWithFailure({ LoadStarted, LoadSucceeded, LoadStarted, LoadFailed }); + +class TestPage : public QWebEnginePage +{ +public: + QSet<QUrl> blacklist; + int navigationRequestCount = 0; + QList<int> signalsOrder; + QList<int> loadProgress; + + explicit TestPage(QObject *parent = nullptr) : TestPage(nullptr, parent) { } + TestPage(QWebEngineProfile *profile, QObject *parent = nullptr) : QWebEnginePage(profile, parent) { + connect(this, &QWebEnginePage::loadStarted, [this] () { signalsOrder.append(LoadStarted); }); + connect(this, &QWebEnginePage::loadProgress, [this] (int p) { loadProgress.append(p); }); + connect(this, &QWebEnginePage::loadFinished, [this] (bool r) { signalsOrder.append(r ? LoadSucceeded : LoadFailed); }); + } + + void reset() + { + blacklist.clear(); + navigationRequestCount = 0; + signalsOrder.clear(); + loadProgress.clear(); + } + +protected: + bool acceptNavigationRequest(const QUrl &url, NavigationType, bool) override + { + ++navigationRequestCount; + return !blacklist.contains(url); + } +}; + class tst_LoadSignals : public QObject { Q_OBJECT @@ -48,10 +85,13 @@ private Q_SLOTS: void monotonicity(); void loadStartedAndFinishedCount_data(); void loadStartedAndFinishedCount(); - void secondLoadForError_WhenErrorPageEnabled_data(); - void secondLoadForError_WhenErrorPageEnabled(); + void loadStartedAndFinishedCountClick_data(); + void loadStartedAndFinishedCountClick(); + void rejectNavigationRequest_data(); + void rejectNavigationRequest(); void loadAfterInPageNavigation_qtbug66869(); - void fileDownloadDoesNotTriggerLoadSignals_qtbug66661(); + void fileDownload(); + void numberOfStartedAndFinishedSignalsIsSame_data(); void numberOfStartedAndFinishedSignalsIsSame(); void loadFinishedAfterNotFoundError_data(); void loadFinishedAfterNotFoundError(); @@ -59,31 +99,45 @@ private Q_SLOTS: void errorPageTriggered(); private: + void clickLink(QPoint linkPos); + QWebEngineProfile profile; - QWebEnginePage page{&profile}; + TestPage page{&profile}; QWebEngineView view; QSignalSpy loadStartedSpy{&page, &QWebEnginePage::loadStarted}; - QSignalSpy loadProgressSpy{&page, &QWebEnginePage::loadProgress}; QSignalSpy loadFinishedSpy{&page, &QWebEnginePage::loadFinished}; + void resetSpies() { + loadStartedSpy.clear(); + loadFinishedSpy.clear(); + } }; void tst_LoadSignals::initTestCase() { view.setPage(&page); - view.resize(1024,768); + view.resize(640, 480); view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); } void tst_LoadSignals::init() { // Reset content - loadFinishedSpy.clear(); - view.load(QUrl("about:blank")); - QTRY_COMPARE(loadFinishedSpy.count(), 1); + if (!view.url().isEmpty()) { + loadFinishedSpy.clear(); + view.load(QUrl("about:blank")); + QTRY_COMPARE(loadFinishedSpy.count(), 1); + } + resetSpies(); + page.reset(); +} - loadStartedSpy.clear(); - loadProgressSpy.clear(); - loadFinishedSpy.clear(); +void tst_LoadSignals::clickLink(QPoint linkPos) +{ + // Simulate left-clicking on link. + QTRY_VERIFY(view.focusWidget()); + QWidget *renderWidget = view.focusWidget(); + QTest::mouseClick(renderWidget, Qt::LeftButton, {}, linkPos); } /** @@ -92,27 +146,124 @@ void tst_LoadSignals::init() void tst_LoadSignals::loadStartedAndFinishedCount_data() { QTest::addColumn<QUrl>("url"); - QTest::addColumn<int>("expectedLoadCount"); - QTest::newRow("Normal") << QUrl("qrc:///resources/page1.html") << 1; - QTest::newRow("WithAnchor") << QUrl("qrc:///resources/page2.html#anchor") << 1; - - // In this case, we get an unexpected additional loadStarted, but no corresponding - // loadFinished, so expectedLoadCount=2 would also not work. See also QTBUG-65223 - QTest::newRow("WithAnchorClickedFromJS") << QUrl("qrc:///resources/page3.html") << 1; + QTest::addColumn<QList<int>>("expectedSignals"); + QTest::newRow("Simple") << QUrl("qrc:///resources/page1.html") << SignalsOrderOnce; + QTest::newRow("SimpleWithAnchor") << QUrl("qrc:///resources/page2.html#anchor") << SignalsOrderOnce; + QTest::newRow("SamePageImmediate") << QUrl("qrc:///resources/page5.html") << SignalsOrderOnce; + QTest::newRow("SamePageDeferred") << QUrl("qrc:///resources/page3.html") << SignalsOrderOnce; + QTest::newRow("OtherPageImmediate") << QUrl("qrc:///resources/page6.html") << SignalsOrderOnce; + QTest::newRow("OtherPageDeferred") << QUrl("qrc:///resources/page7.html") << SignalsOrderTwice; + QTest::newRow("SamePageImmediateJS") << QUrl("qrc:///resources/page8.html") << SignalsOrderOnce; } void tst_LoadSignals::loadStartedAndFinishedCount() { QFETCH(QUrl, url); - QFETCH(int, expectedLoadCount); + QFETCH(QList<int>, expectedSignals); view.load(url); + + int expectedLoadCount = expectedSignals.size() / 2; + QTRY_COMPARE(loadStartedSpy.size(), expectedLoadCount); QTRY_COMPARE(loadFinishedSpy.size(), expectedLoadCount); + + // verify no more signals is emitted by waiting for another loadStarted or loadFinished + QTRY_LOOP_IMPL(loadStartedSpy.size() != expectedLoadCount || loadFinishedSpy.size() != expectedLoadCount, 1000, 100); + + // No further signals should have occurred within this time and expected number of signals is preserved + QCOMPARE(loadStartedSpy.size(), expectedLoadCount); + QCOMPARE(loadFinishedSpy.size(), expectedLoadCount); + QCOMPARE(page.signalsOrder, expectedSignals); +} + +/** + * Load a URL, then simulate a click to load a different URL. + */ +void tst_LoadSignals::loadStartedAndFinishedCountClick_data() +{ + QTest::addColumn<QUrl>("url"); + QTest::addColumn<int>("numberOfSignals"); + QTest::newRow("SamePage") << QUrl("qrc:///resources/page2.html") << 0; // in-page navigation to anchor shouldn't emit anything + QTest::newRow("OtherPage") << QUrl("qrc:///resources/page1.html") << 1; +} + +void tst_LoadSignals::loadStartedAndFinishedCountClick() +{ + QFETCH(QUrl, url); + QFETCH(int, numberOfSignals); + + view.load(url); + QTRY_COMPARE(loadStartedSpy.size(), 1); + QTRY_COMPARE(loadFinishedSpy.size(), 1); QVERIFY(loadFinishedSpy[0][0].toBool()); + resetSpies(); + + clickLink(QPoint(10, 10)); + if (numberOfSignals > 0) { + QTRY_COMPARE(loadStartedSpy.size(), numberOfSignals); + QTRY_COMPARE(loadFinishedSpy.size(), numberOfSignals); + QVERIFY(loadFinishedSpy[0][0].toBool()); + } + + // verify no more signals is emitted by waiting for another loadStarted or loadFinished + QTRY_LOOP_IMPL(loadStartedSpy.size() != numberOfSignals || loadFinishedSpy.size() != numberOfSignals, 1000, 100); + + // No further loadStarted should have occurred within this time + QCOMPARE(loadStartedSpy.size(), numberOfSignals); + QCOMPARE(loadFinishedSpy.size(), numberOfSignals); + QCOMPARE(page.signalsOrder, numberOfSignals > 0 ? SignalsOrderTwice : SignalsOrderOnce); +} + +void tst_LoadSignals::rejectNavigationRequest_data() +{ + QTest::addColumn<QUrl>("initialUrl"); + QTest::addColumn<QUrl>("rejectedUrl"); + QTest::addColumn<int>("expectedNavigations"); + QTest::addColumn<QList<int>>("expectedSignals"); + QTest::newRow("Simple") + << QUrl("qrc:///resources/page1.html") + << QUrl("qrc:///resources/page1.html") + << 1 << SignalsOrderOnceFailure; + QTest::newRow("SamePageImmediate") + << QUrl("qrc:///resources/page5.html") + << QUrl("qrc:///resources/page5.html#anchor") + << 1 << SignalsOrderOnce; + QTest::newRow("SamePageDeferred") + << QUrl("qrc:///resources/page3.html") + << QUrl("qrc:///resources/page3.html#anchor") + << 1 << SignalsOrderOnce; + QTest::newRow("OtherPageImmediate") + << QUrl("qrc:///resources/page6.html") + << QUrl("qrc:///resources/page2.html#anchor") + << 2 << SignalsOrderOnceFailure; + QTest::newRow("OtherPageDeferred") + << QUrl("qrc:///resources/page7.html") + << QUrl("qrc:///resources/page2.html#anchor") + << 2 << SignalsOrderTwiceWithFailure; +} - // Wait for 10 seconds (abort waiting if another loadStarted or loadFinished occurs) - QTRY_LOOP_IMPL((loadStartedSpy.size() != expectedLoadCount) - || (loadFinishedSpy.size() != expectedLoadCount), 10000, 100); +/** + * Returning false from acceptNavigationRequest means that the load + * fails, not that the load never starts. + * + * See QTBUG-75185. + */ +void tst_LoadSignals::rejectNavigationRequest() +{ + QFETCH(QUrl, initialUrl); + QFETCH(QUrl, rejectedUrl); + QFETCH(int, expectedNavigations); + QFETCH(QList<int>, expectedSignals); + + page.blacklist.insert(rejectedUrl); + page.load(initialUrl); + QTRY_COMPARE(page.navigationRequestCount, expectedNavigations); + int expectedLoadCount = expectedSignals.size() / 2; + QTRY_COMPARE(loadFinishedSpy.size(), expectedLoadCount); + QCOMPARE(page.signalsOrder, expectedSignals); + + // verify no more signals is emitted by waiting for another loadStarted or loadFinished + QTRY_LOOP_IMPL(loadStartedSpy.size() != expectedLoadCount || loadFinishedSpy.size() != expectedLoadCount, 1000, 100); // No further loadStarted should have occurred within this time QCOMPARE(loadStartedSpy.size(), expectedLoadCount); @@ -135,53 +286,19 @@ void tst_LoadSignals::monotonicity() QTRY_COMPARE(loadFinishedSpy.size(), 1); QVERIFY(loadFinishedSpy[0][0].toBool()); + QVERIFY(page.loadProgress.size() >= 3); // first loadProgress should have 0% progress - QCOMPARE(loadProgressSpy.takeFirst()[0].toInt(), 0); + QCOMPARE(page.loadProgress.first(), 0); // every loadProgress should have more progress than the one before - int progress = 0; - for (const auto &item : loadProgressSpy) { - QVERIFY(progress < item[0].toInt()); - progress = item[0].toInt(); + int progress = -1; + for (int p : page.loadProgress) { + QVERIFY(progress < p); + progress = p; } // last loadProgress should have 100% progress - QCOMPARE(loadProgressSpy.last()[0].toInt(), 100); -} - -/** - * Test that we get a second loadStarted and loadFinished signal - * for error-pages (unless error-pages are disabled) - */ -void tst_LoadSignals::secondLoadForError_WhenErrorPageEnabled_data() -{ - QTest::addColumn<bool>("enabled"); - // in this case, we get no second loadStarted and loadFinished, although we had - // agreed on making the navigation to an error page an individual load - QTest::newRow("ErrorPageEnabled") << true; - QTest::newRow("ErrorPageDisabled") << false; -} - -void tst_LoadSignals::secondLoadForError_WhenErrorPageEnabled() -{ - QFETCH(bool, enabled); - view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, enabled); - int expectedLoadCount = (enabled ? 2 : 1); - - // RFC 2606 guarantees that this will never become a valid domain - view.load(QUrl("http://nonexistent.invalid")); - QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), expectedLoadCount, 10000); - QVERIFY(!loadFinishedSpy[0][0].toBool()); - if (enabled) - QVERIFY(loadFinishedSpy[1][0].toBool()); - - // Wait for 10 seconds (abort waiting if another loadStarted or loadFinished occurs) - QTRY_LOOP_IMPL((loadStartedSpy.size() != expectedLoadCount) - || (loadFinishedSpy.size() != expectedLoadCount), 10000, 100); - - // No further loadStarted should have occurred within this time - QCOMPARE(loadStartedSpy.size(), expectedLoadCount); - QCOMPARE(loadFinishedSpy.size(), expectedLoadCount); + QCOMPARE(page.loadProgress.last(), 100); } /** @@ -195,27 +312,17 @@ void tst_LoadSignals::loadAfterInPageNavigation_qtbug66869() QVERIFY(loadFinishedSpy[0][0].toBool()); // page3 does an in-page navigation after 500ms - QTest::qWait(2000); - loadFinishedSpy.clear(); - loadProgressSpy.clear(); - loadStartedSpy.clear(); + QTRY_COMPARE(view.url(), QUrl("qrc:///resources/page3.html#anchor")); // second load view.load(QUrl("qrc:///resources/page1.html")); - QTRY_COMPARE(loadFinishedSpy.size(), 1); + QTRY_COMPARE(loadFinishedSpy.size(), 2); QVERIFY(loadFinishedSpy[0][0].toBool()); // loadStarted and loadFinished should have been signalled - QCOMPARE(loadStartedSpy.size(), 1); - - // reminder that we still need to solve the core issue - QFAIL("https://codereview.qt-project.org/#/c/222112/ only hides the symptom, the core issue still needs to be solved"); + QCOMPARE(loadStartedSpy.size(), 2); } -/** - * Test that file-downloads don't trigger loadStarted or loadFinished signals. - * See QTBUG-66661 - */ -void tst_LoadSignals::fileDownloadDoesNotTriggerLoadSignals_qtbug66661() +void tst_LoadSignals::fileDownload() { view.load(QUrl("qrc:///resources/page4.html")); QTRY_COMPARE(loadFinishedSpy.size(), 1); @@ -237,59 +344,55 @@ void tst_LoadSignals::fileDownloadDoesNotTriggerLoadSignals_qtbug66661() }); // trigger the download link that becomes focused on page4 - QTest::qWait(1000); QTest::sendKeyEvent(QTest::Press, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier); QTest::sendKeyEvent(QTest::Release, view.focusProxy(), Qt::Key_Return, QString("\r"), Qt::NoModifier); - // Wait for 10 seconds (abort waiting if another loadStarted or loadFinished occurs) - QTRY_LOOP_IMPL((loadStartedSpy.size() != 1) - || (loadFinishedSpy.size() != 1), 10000, 100); - // Download must have occurred QTRY_COMPARE(downloadState, QWebEngineDownloadRequest::DownloadCompleted); + QTRY_COMPARE(loadFinishedSpy.size() + loadStartedSpy.size(), 4); - // No further loadStarted should have occurred within this time - QCOMPARE(loadStartedSpy.size(), 1); - QCOMPARE(loadFinishedSpy.size(), 1); + // verify no more signals is emitted by waiting for another loadStarted or loadFinished + QTRY_LOOP_IMPL(loadStartedSpy.size() != 2 || loadFinishedSpy.size() != 2, 1000, 100); + + QCOMPARE(page.signalsOrder, SignalsOrderTwiceWithFailure); } -void tst_LoadSignals::numberOfStartedAndFinishedSignalsIsSame() { +void tst_LoadSignals::numberOfStartedAndFinishedSignalsIsSame_data() +{ + QTest::addColumn<bool>("imageFromServer"); + QTest::addColumn<QString>("imageResourceUrl"); + // triggers these calls in delegate internally: + // just two ordered triples DidStartNavigation/DidFinishNavigation/DidFinishLoad + QTest::newRow("no_image_resource") << false << ""; + // out of order: DidStartNavigation/DidFinishNavigation/DidStartNavigation/DidFailLoad/DidFinishNavigation/DidFinishLoad + QTest::newRow("with_invalid_image") << false << "https://non.existent.locahost/image.png"; + // out of order: DidStartNavigation/DidFinishNavigation/DidStartNavigation/DidFinishLoad/DidFinishNavigation/DidFinishLoad + QTest::newRow("with_server_image") << true << ""; +} + +void tst_LoadSignals::numberOfStartedAndFinishedSignalsIsSame() +{ + QFETCH(bool, imageFromServer); + QFETCH(QString, imageResourceUrl); HttpServer server; server.setResourceDirs({ TESTS_SOURCE_DIR "/qwebengineprofile/resources" }); - connect(&server, &HttpServer::newRequest, [] (HttpReqRep *) { - QTest::qWait(250); // just add delay to trigger some progress for every sub resource - }); QVERIFY(server.start()); - view.load(server.url("/hedgehog.png")); - QTRY_COMPARE(loadFinishedSpy.size(), 1); - QVERIFY(loadFinishedSpy[0][0].toBool()); - - loadStartedSpy.clear(); - loadFinishedSpy.clear(); - loadProgressSpy.clear(); - - view.page()->setHtml("<html><body>" - "<img src=\"" + server.url("/hedgehog.png").toEncoded() + "\">" - "<form method='GET' name='hiddenform' action='qrc:///resources/page1.html' />" - "<script language='javascript'>document.forms[0].submit();</script>" - "</body></html>"); + QUrl serverImage = server.url("/hedgehog.png"); + QString imageUrl(!imageFromServer && imageResourceUrl.isEmpty() + ? "" : (imageFromServer ? serverImage.toEncoded() : imageResourceUrl)); - QTRY_COMPARE(loadStartedSpy.size(), 2); - QTRY_COMPARE(loadFinishedSpy.size(), 2); + auto html = "<html><head><link rel='icon' href='data:,'></head><body>" + "%1" "<form method='GET' name='hiddenform' action='qrc:///resources/page1.html' />" + "<script language='javascript'>document.forms[0].submit();</script>" + "</body></html>"; + view.page()->setHtml(QString(html).arg(imageUrl.isEmpty() ? "" : "<img src='" + imageUrl + "'>")); + QTRY_COMPARE(loadFinishedSpy.size(), 1); - QTRY_VERIFY(!loadFinishedSpy[0][0].toBool()); - QTRY_VERIFY(loadFinishedSpy[1][0].toBool()); - - view.page()->setHtml("<html><body>" - "<form method='GET' name='hiddenform' action='qrc:///resources/page1.html' />" - "<script language='javascript'>document.forms[0].submit();</script>" - "</body></html>"); - QTRY_COMPARE(loadStartedSpy.size(), 4); - QTRY_COMPARE(loadFinishedSpy.size(), 4); - QVERIFY(loadFinishedSpy[2][0].toBool()); - QVERIFY(loadFinishedSpy[3][0].toBool()); + resetSpies(); + QTRY_LOOP_IMPL(loadStartedSpy.size() || loadFinishedSpy.size(), 1000, 100); + QCOMPARE(page.signalsOrder, SignalsOrderOnce); } void tst_LoadSignals::loadFinishedAfterNotFoundError_data() @@ -311,7 +414,6 @@ void tst_LoadSignals::loadFinishedAfterNotFoundError() server.reset(new HttpServer); QVERIFY(server->start()); } - view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false); auto url = server ? server->url("/not-found-page.html") @@ -321,6 +423,9 @@ void tst_LoadSignals::loadFinishedAfterNotFoundError() QVERIFY(!loadFinishedSpy.at(0).at(0).toBool()); QCOMPARE(toPlainTextSync(view.page()), QString()); QCOMPARE(loadFinishedSpy.count(), 1); + QCOMPARE(loadStartedSpy.count(), 1); + QVERIFY(std::is_sorted(page.loadProgress.begin(), page.loadProgress.end())); + page.loadProgress.clear(); view.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true); url = server @@ -329,9 +434,12 @@ void tst_LoadSignals::loadFinishedAfterNotFoundError() view.load(url); QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 2, 20000); QVERIFY(!loadFinishedSpy.at(1).at(0).toBool()); + QCOMPARE(loadStartedSpy.count(), 2); QEXPECT_FAIL("", "No more loads (like separate load for error pages) are expected", Continue); QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 3, 1000); + QCOMPARE(loadStartedSpy.count(), 2); + QVERIFY(std::is_sorted(page.loadProgress.begin(), page.loadProgress.end())); } void tst_LoadSignals::errorPageTriggered_data() @@ -388,6 +496,5 @@ void tst_LoadSignals::errorPageTriggered() loadFinishedSpy.clear(); } - QTEST_MAIN(tst_LoadSignals) #include "tst_loadsignals.moc" diff --git a/tests/auto/widgets/loadsignals/tst_loadsignals.qrc b/tests/auto/widgets/loadsignals/tst_loadsignals.qrc index 21c517154..b4ee36676 100644 --- a/tests/auto/widgets/loadsignals/tst_loadsignals.qrc +++ b/tests/auto/widgets/loadsignals/tst_loadsignals.qrc @@ -4,6 +4,10 @@ <file alias="page2.html">../../shared/data/loadprogress/page2.html</file> <file alias="page3.html">../../shared/data/loadprogress/page3.html</file> <file alias="page4.html">../../shared/data/loadprogress/page4.html</file> + <file alias="page5.html">../../shared/data/loadprogress/page5.html</file> + <file alias="page6.html">../../shared/data/loadprogress/page6.html</file> + <file alias="page7.html">../../shared/data/loadprogress/page7.html</file> + <file alias="page8.html">../../shared/data/loadprogress/page8.html</file> <file alias="downloadable.tar.gz">../../shared/data/loadprogress/downloadable.tar.gz</file> </qresource> </RCC> diff --git a/tests/auto/widgets/qwebenginepage/resources/redirect.html b/tests/auto/widgets/qwebenginepage/resources/redirect.html new file mode 100644 index 000000000..db06d73a7 --- /dev/null +++ b/tests/auto/widgets/qwebenginepage/resources/redirect.html @@ -0,0 +1,8 @@ +<html> +<body> +<script> +function doRedirect() { location.replace('qrc:///resources/content.html') } +document.addEventListener("DOMContentLoaded", doRedirect) +</script> +</body> +</html> diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 644d0f319..a8d0e1ac8 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -599,6 +599,39 @@ void tst_QWebEnginePage::acceptNavigationRequestNavigationType() << QWebEnginePage::NavigationTypeReload << QWebEnginePage::NavigationTypeTyped << QWebEnginePage::NavigationTypeRedirect; + + // client side redirect + page.load(QUrl("qrc:///resources/redirect.html")); + QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 7, 20000); + QTRY_COMPARE(page.navigations.count(), 8); + expectedList += { QWebEnginePage::NavigationTypeTyped, QWebEnginePage::NavigationTypeRedirect }; + + // server side redirect + HttpServer server; + server.setResourceDirs({ ":/resources" }); + connect(&server, &HttpServer::newRequest, &server, [&] (HttpReqRep *r) { + if (r->requestMethod() == "GET") { + if (r->requestPath() == "/redirect1.html") { + r->setResponseHeader("Location", server.url("/redirect2.html").toEncoded()); + r->setResponseBody("<html><body>Redirect1</body></html>"); + r->sendResponse(307); // Internal server redirect + } else if (r->requestPath() == "/redirect2.html") { + r->setResponseHeader("Location", server.url("/content.html").toEncoded()); + r->setResponseBody("<html><body>Redirect2</body></html>"); + r->sendResponse(301); // Moved permanently + } + } + }); + QVERIFY(server.start()); + page.load(QUrl(server.url("/redirect1.html"))); + QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 8, 20000); + QTRY_COMPARE(page.navigations.count(), 11); + expectedList += { + QWebEnginePage::NavigationTypeTyped, + QWebEnginePage::NavigationTypeRedirect, + QWebEnginePage::NavigationTypeRedirect + }; + QVERIFY(expectedList.count() == page.navigations.count()); for (int i = 0; i < expectedList.count(); ++i) { QCOMPARE(page.navigations[i].type, expectedList[i]); @@ -2913,11 +2946,7 @@ void tst_QWebEnginePage::loadInSignalHandlers() URLSetter setter(m_page, signal, type, urlForSetter); QSignalSpy spy(&setter, &URLSetter::finished); m_page->load(url); - // every loadStarted() call should have also loadFinished() - if (signal == URLSetter::LoadStarted) - QTRY_COMPARE(spy.count(), 2); - else - QTRY_COMPARE(spy.count(), 1); + QTRY_COMPARE(spy.count(), 1); QCOMPARE(m_page->url(), urlForSetter); } @@ -4068,8 +4097,7 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools() devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded); devToolsPage.setInspectedPage(&inspectedPage); QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active); - QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 2, 90000); - QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(false)); + QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 90000); QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true)); // keep DevTools open diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc index 013a307de..3480341e8 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc @@ -14,6 +14,7 @@ <file>resources/user.css</file> <file>resources/image.png</file> <file>resources/pasteimage.html</file> + <file>resources/redirect.html</file> <file>resources/reload.html</file> <file>resources/style.css</file> <file>resources/test1.html</file> diff --git a/tests/auto/widgets/qwebengineview/BLACKLIST b/tests/auto/widgets/qwebengineview/BLACKLIST index 05ebee4ce..c1a46e16d 100644 --- a/tests/auto/widgets/qwebengineview/BLACKLIST +++ b/tests/auto/widgets/qwebengineview/BLACKLIST @@ -6,3 +6,6 @@ windows [horizontalScrollbarTest] osx + +[mixLangLocale:eu_ES] +* diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 7af08dbde..284f84d9f 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -124,6 +124,7 @@ private Q_SLOTS: void doNotBreakLayout(); void changeLocale(); + void mixLangLocale_data(); void mixLangLocale(); void inputMethodsTextFormat_data(); void inputMethodsTextFormat(); @@ -1213,26 +1214,46 @@ void tst_QWebEngineView::changeLocale() QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar")); } +void tst_QWebEngineView::mixLangLocale_data() +{ + QTest::addColumn<QString>("locale"); + QTest::addColumn<QByteArray>("formattedNumber"); + QTest::newRow("en_DK") << "en-DK" << QByteArray("1.234.567.890"); + QTest::newRow("de") << "de" << QByteArray("1.234.567.890"); + QTest::newRow("de_CH") << "de-CH" << QByteArray("1’234’567’890"); + QTest::newRow("eu_ES") << "eu-ES" << QByteArray("1.234.567.890"); + QTest::newRow("hu_HU") << "hu-HU" << QByteArray("1\xC2\xA0""234\xC2\xA0""567\xC2\xA0""890"); // no-break spaces +} + void tst_QWebEngineView::mixLangLocale() { - for (QString locale : { "en_DK", "de_CH", "eu_ES" }) { - QLocale::setDefault(QLocale(locale)); - QWebEngineView view; - QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished); + QFETCH(QString, locale); + QFETCH(QByteArray, formattedNumber); - bool terminated = false; - auto sc = connect(view.page(), &QWebEnginePage::renderProcessTerminated, [&] () { terminated = true; }); + QLocale::setDefault(QLocale(locale)); - view.load(QUrl("qrc:///resources/dummy.html")); - QTRY_VERIFY(terminated || loadSpy.count() == 1); + QWebEngineView view; + QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished); - QVERIFY2(!terminated, - qPrintable(QString("Locale [%1] terminated: %2, loaded: %3").arg(locale).arg(terminated).arg(loadSpy.count()))); - QVERIFY(loadSpy.first().first().toBool()); + bool terminated = false; + auto sc = connect(view.page(), &QWebEnginePage::renderProcessTerminated, [&] () { terminated = true; }); + + view.load(QUrl("qrc:///resources/dummy.html")); + QTRY_VERIFY(terminated || loadSpy.count() == 1); + + QVERIFY2(!terminated, + qPrintable(QString("Locale [%1] terminated: %2, loaded: %3").arg(locale).arg(terminated).arg(loadSpy.count()))); + QVERIFY(loadSpy.first().first().toBool()); + + QString content = toPlainTextSync(view.page()); + QVERIFY2(!content.isEmpty() && content.contains("test content"), qPrintable(content)); + + QCOMPARE(evaluateJavaScriptSync(view.page(), "navigator.language").toString(), QLocale().bcp47Name()); + + if (locale == "eu-ES") + QEXPECT_FAIL("", "Basque number formatting is somehow dependent on environment", Continue); + QCOMPARE(evaluateJavaScriptSync(view.page(), "Number(1234567890).toLocaleString()").toByteArray(), formattedNumber); - QString content = toPlainTextSync(view.page()); - QVERIFY2(!content.isEmpty() && content.contains("test content"), qPrintable(content)); - } QLocale::setDefault(QLocale("en")); } |