diff options
Diffstat (limited to 'tests/auto')
12 files changed, 323 insertions, 6 deletions
diff --git a/tests/auto/core/CMakeLists.txt b/tests/auto/core/CMakeLists.txt index 5908756b4..eb8e9266f 100644 --- a/tests/auto/core/CMakeLists.txt +++ b/tests/auto/core/CMakeLists.txt @@ -2,6 +2,7 @@ # SPDX-License-Identifier: BSD-3-Clause add_subdirectory(qwebenginecookiestore) +add_subdirectory(qwebengineframe) add_subdirectory(qwebengineloadinginfo) add_subdirectory(qwebenginesettings) if(QT_FEATURE_ssl) diff --git a/tests/auto/core/certificateerror/tst_certificateerror.cpp b/tests/auto/core/certificateerror/tst_certificateerror.cpp index 67e2d8ae4..61201e250 100644 --- a/tests/auto/core/certificateerror/tst_certificateerror.cpp +++ b/tests/auto/core/certificateerror/tst_certificateerror.cpp @@ -19,6 +19,7 @@ private Q_SLOTS: void handleError_data(); void handleError(); void fatalError(); + void resourceError(); }; struct PageWithCertificateErrorHandler : QWebEnginePage @@ -130,5 +131,20 @@ void tst_CertificateError::fatalError() } } +void tst_CertificateError::resourceError() +{ + PageWithCertificateErrorHandler page(false, false); + page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false); + + page.setHtml("<img src=\"https://expired.badssl.com\">"); + if (!page.loadSpy.wait(10000)) { + QVERIFY2(!page.error, "There shouldn't be any certificate error if not loaded due to missing internet access!"); + QSKIP("Couldn't load page from network, skipping test."); + } + + QTRY_VERIFY(page.error); + QCOMPARE(page.error->isMainFrame(), false); +} + QTEST_MAIN(tst_CertificateError) #include <tst_certificateerror.moc> diff --git a/tests/auto/core/qwebengineframe/CMakeLists.txt b/tests/auto/core/qwebengineframe/CMakeLists.txt new file mode 100644 index 000000000..d02b4307d --- /dev/null +++ b/tests/auto/core/qwebengineframe/CMakeLists.txt @@ -0,0 +1,22 @@ +# Copyright (C) 2024 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause + +include(../../util/util.cmake) + +qt_internal_add_test(tst_qwebengineframe + SOURCES + tst_qwebengineframe.cpp + LIBRARIES + Qt::WebEngineCore + Qt::WebEngineWidgets + Test::Util +) + +qt_internal_add_resource(tst_qwebengineframe "tst_qwebengineframe" + PREFIX + "/" + FILES + "resources/frameset.html" + "resources/iframes.html" + "resources/nesting-iframe.html" +) diff --git a/tests/auto/core/qwebengineframe/resources/frameset.html b/tests/auto/core/qwebengineframe/resources/frameset.html new file mode 100644 index 000000000..53f5e6638 --- /dev/null +++ b/tests/auto/core/qwebengineframe/resources/frameset.html @@ -0,0 +1,20 @@ +<!doctype html> +<html> + <head><title>Test-title</title></head> + <script> + window.name = 'test-main-frame' + onload = (e) => { + const frames = window.frames; + for (let i = 0; i < frames.length; i++) { + frames[i].name = 'test-subframe' + i; + } + }; + </script> + <frameset cols="50%, 50%"> + <frameset cols="50%, 50%"> + <frame style="border: red dashed 1em;"/> + <frame style="border: green dashed 1em;"/> + </frameset> + <frame style="border: blue solid 1em;"/> + </frameset> +</html> diff --git a/tests/auto/core/qwebengineframe/resources/iframes.html b/tests/auto/core/qwebengineframe/resources/iframes.html new file mode 100644 index 000000000..648acb166 --- /dev/null +++ b/tests/auto/core/qwebengineframe/resources/iframes.html @@ -0,0 +1,17 @@ +<!doctype html> +<html> + <head><title>Test-title</title></head> + <script> + window.name = 'test-main-frame' + onload = (e) => { + const frames = window.frames; + for (let i = 0; i < frames.length; i++) { + frames[i].name = 'test-subframe' + i; + } + }; + </script> + <body> + <iframe name="iframe0-300x200" width="300" height="200"></iframe> + <iframe name="iframe1-350x250" width="350" height="250"></iframe> + </body> +</html> diff --git a/tests/auto/core/qwebengineframe/resources/nesting-iframe.html b/tests/auto/core/qwebengineframe/resources/nesting-iframe.html new file mode 100644 index 000000000..cd784e3dd --- /dev/null +++ b/tests/auto/core/qwebengineframe/resources/nesting-iframe.html @@ -0,0 +1,7 @@ +<!doctype html> +<html> + <head><title>Test-title</title></head> + <body> + <iframe name="iframe2-parent" src="iframes.html"></iframe> + </body> +</html> diff --git a/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp b/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp new file mode 100644 index 000000000..b70a655d3 --- /dev/null +++ b/tests/auto/core/qwebengineframe/tst_qwebengineframe.cpp @@ -0,0 +1,180 @@ +/* + Copyright (C) 2024 The Qt Company Ltd. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include <util.h> + +#include <QtTest/QtTest> + +#include <QtWebEngineCore/qwebengineframe.h> + +class tst_QWebEngineFrame : public QObject +{ + Q_OBJECT + +private Q_SLOTS: + void mainFrame(); + void findFrameByName(); + void isValid(); + void name(); + void htmlName(); + void children(); + void childrenOfInvalidFrame(); + void url(); + void size(); + +private: +}; + +void tst_QWebEngineFrame::mainFrame() +{ + QWebEnginePage page; + QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) }; + page.load(QUrl("qrc:/resources/frameset.html")); + QTRY_COMPARE(loadSpy.size(), 1); + auto frame = page.mainFrame(); + QVERIFY(frame.isValid()); +} + +void tst_QWebEngineFrame::findFrameByName() +{ + QWebEnginePage page; + QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) }; + page.load(QUrl("qrc:/resources/iframes.html")); + QTRY_COMPARE(loadSpy.size(), 1); + auto maybeFrame = page.findFrameByName("test-subframe0"); + QVERIFY(maybeFrame.has_value()); + QCOMPARE(maybeFrame->name(), "test-subframe0"); + QVERIFY(!page.findFrameByName("foobar").has_value()); +} + +void tst_QWebEngineFrame::isValid() +{ + QWebEnginePage page; + QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) }; + page.load(QUrl("qrc:/resources/iframes.html")); + QTRY_COMPARE(loadSpy.size(), 1); + auto firstPageSubframe = page.findFrameByName("test-subframe0"); + QVERIFY(firstPageSubframe && firstPageSubframe->isValid()); + + page.load(QUrl("qrc:/resources/frameset.html")); + QTRY_COMPARE(loadSpy.size(), 2); + QVERIFY(!firstPageSubframe->isValid()); +} + +void tst_QWebEngineFrame::name() +{ + QWebEnginePage page; + QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) }; + page.load(QUrl("qrc:/resources/frameset.html")); + QTRY_COMPARE(loadSpy.size(), 1); + QCOMPARE(page.mainFrame().name(), "test-main-frame"); + auto children = page.mainFrame().children(); + QCOMPARE(children.at(0).name(), "test-subframe0"); + QCOMPARE(children.at(1).name(), "test-subframe1"); + QCOMPARE(children.at(2).name(), "test-subframe2"); + + page.load(QUrl("qrc:/resources/iframes.html")); + QTRY_COMPARE(loadSpy.size(), 2); + QVERIFY(!children.at(0).isValid()); + QCOMPARE(children.at(0).name(), QString()); +} + +void tst_QWebEngineFrame::htmlName() +{ + QWebEnginePage page; + QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) }; + page.load(QUrl("qrc:/resources/iframes.html")); + QTRY_COMPARE(loadSpy.size(), 1); + auto children = page.mainFrame().children(); + QCOMPARE(children.at(0).name(), "test-subframe0"); + QCOMPARE(children.at(0).htmlName(), "iframe0-300x200"); + QCOMPARE(children.at(1).name(), "test-subframe1"); + QCOMPARE(children.at(1).htmlName(), "iframe1-350x250"); + + page.load(QUrl("qrc:/resources/frameset.html")); + QTRY_COMPARE(loadSpy.size(), 2); + QVERIFY(!children.at(0).isValid()); + QCOMPARE(children.at(0).htmlName(), QString()); +} + +void tst_QWebEngineFrame::children() +{ + QWebEnginePage page; + QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) }; + page.load(QUrl("qrc:/resources/frameset.html")); + QTRY_COMPARE(loadSpy.size(), 1); + auto frame = page.mainFrame(); + auto children = frame.children(); + QCOMPARE(children.size(), 3); + for (auto child : children) { + QVERIFY(child.isValid()); + } +} + +void tst_QWebEngineFrame::childrenOfInvalidFrame() +{ + QWebEnginePage page; + QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) }; + page.load(QUrl("qrc:/resources/nesting-iframe.html")); + QTRY_COMPARE(loadSpy.size(), 1); + auto nestedFrame = page.mainFrame().children().at(0); + QCOMPARE(nestedFrame.children().size(), 2); + + page.load(QUrl("qrc:/resources/frameset.html")); + QTRY_COMPARE(loadSpy.size(), 2); + QVERIFY(!nestedFrame.isValid()); + QVERIFY(nestedFrame.children().empty()); +} + +void tst_QWebEngineFrame::url() +{ + QWebEnginePage page; + QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) }; + page.load(QUrl("qrc:/resources/nesting-iframe.html")); + QTRY_COMPARE(loadSpy.size(), 1); + auto children = page.mainFrame().children(); + QCOMPARE(children.at(0).url(), QUrl("qrc:/resources/iframes.html")); + + page.load(QUrl("qrc:/resources/frameset.html")); + QTRY_COMPARE(loadSpy.size(), 2); + QVERIFY(!children.at(0).isValid()); + QCOMPARE(children.at(0).url(), QUrl()); +} + +void tst_QWebEngineFrame::size() +{ + QWebEnginePage page; + QSignalSpy loadSpy{ &page, SIGNAL(loadFinished(bool)) }; + page.load(QUrl("qrc:/resources/iframes.html")); + QTRY_COMPARE(loadSpy.size(), 1); + auto frame1 = *page.findFrameByName("test-subframe0"); + auto size1 = frame1.size(); + auto size2 = page.findFrameByName("test-subframe1")->size(); + QCOMPARE(size1, QSizeF(300, 200)); + QCOMPARE(size2, QSizeF(350, 250)); + + page.load(QUrl("qrc:/resources/frameset.html")); + QTRY_COMPARE(loadSpy.size(), 2); + QVERIFY(!frame1.isValid()); + QCOMPARE(frame1.size(), QSizeF()); +} + +QTEST_MAIN(tst_QWebEngineFrame) + +#include "tst_qwebengineframe.moc" diff --git a/tests/auto/core/qwebengineglobalsettings/CMakeLists.txt b/tests/auto/core/qwebengineglobalsettings/CMakeLists.txt index fa81ba8df..dd2f28857 100644 --- a/tests/auto/core/qwebengineglobalsettings/CMakeLists.txt +++ b/tests/auto/core/qwebengineglobalsettings/CMakeLists.txt @@ -8,6 +8,7 @@ qt_internal_add_test(tst_qwebengineglobalsettings SOURCES tst_qwebengineglobalsettings.cpp LIBRARIES + Qt::Network Qt::WebEngineCore Test::HttpServer Qt::WebEngineWidgets diff --git a/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp b/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp index 0af85a711..5b6b64778 100644 --- a/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp +++ b/tests/auto/core/qwebengineglobalsettings/tst_qwebengineglobalsettings.cpp @@ -3,6 +3,8 @@ #include <QtTest> #include <widgetutil.h> +#include <QNetworkAccessManager> +#include <QNetworkRequest> #include <QWebEngineProfile> #include <QWebEnginePage> #include <QWebEngineGlobalSettings> @@ -68,6 +70,15 @@ void tst_QWebEngineGlobalSettings::dnsOverHttps_data() void tst_QWebEngineGlobalSettings::dnsOverHttps() { + const QUrl url = QStringLiteral("https://google.com/"); + // Verify network access with NAM because the result of loadFinished signal + // is used to verify that the DNS resolution was successful. + QNetworkAccessManager nam; + QSignalSpy namSpy(&nam, &QNetworkAccessManager::finished); + QScopedPointer<QNetworkReply> reply(nam.get(QNetworkRequest(url))); + if (!namSpy.wait(20000) || reply->error() != QNetworkReply::NoError) + QSKIP("Couldn't load page from network, skipping test."); + QFETCH(QWebEngineGlobalSettings::SecureDnsMode, dnsMode); QFETCH(QString, uriTemplate); QFETCH(bool, isMockDnsServerCalledExpected); @@ -105,10 +116,8 @@ void tst_QWebEngineGlobalSettings::dnsOverHttps() connect(&page, &QWebEnginePage::loadFinished, this, [&isLoadSuccessful](bool ok) { isLoadSuccessful = ok; }); - page.load(QUrl("https://google.com/")); - if (!loadSpy.wait(20000)) { - QSKIP("Couldn't load page from network, skipping test."); - } + page.load(url); + QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000); QTRY_COMPARE(isMockDnsServerCalled, isMockDnsServerCalledExpected); QCOMPARE(isLoadSuccessful, isDnsResolutionSuccessExpected); diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp index cfa75f0bf..d3358cab4 100644 --- a/tests/auto/quick/publicapi/tst_publicapi.cpp +++ b/tests/auto/quick/publicapi/tst_publicapi.cpp @@ -25,6 +25,7 @@ #include <QtWebEngineCore/QWebEngineScript> #include <QtWebEngineCore/QWebEngineLoadingInfo> #include <QtWebEngineCore/QWebEngineWebAuthUxRequest> +#include <QtWebEngineCore/QWebEngineFrame> #include <private/qquickwebengineview_p.h> #include <private/qquickwebengineaction_p.h> #include <private/qquickwebengineclientcertificateselection_p.h> @@ -76,6 +77,7 @@ static const QList<const QMetaObject *> typesToCheck = QList<const QMetaObject * << &QQuickWebEngineTouchSelectionMenuRequest::staticMetaObject << &QWebEngineWebAuthUxRequest::staticMetaObject << &QWebEngineWebAuthPinRequest::staticMetaObject + << &QWebEngineFrame::staticMetaObject ; static QList<QMetaEnum> knownEnumNames = QList<QMetaEnum>() @@ -132,6 +134,7 @@ static const QStringList expectedAPI = QStringList() << "QWebEngineCertificateError.defer() --> void" << "QWebEngineCertificateError.description --> QString" << "QWebEngineCertificateError.type --> QWebEngineCertificateError::Type" + << "QWebEngineCertificateError.isMainFrame --> bool" << "QWebEngineCertificateError.acceptCertificate() --> void" << "QWebEngineCertificateError.overridable --> bool" << "QWebEngineCertificateError.rejectCertificate() --> void" @@ -328,6 +331,7 @@ static const QStringList expectedAPI = QStringList() << "QWebEngineNavigationRequest.action --> QWebEngineNavigationRequest::NavigationRequestAction" << "QWebEngineNavigationRequest.actionChanged() --> void" << "QWebEngineNavigationRequest.isMainFrame --> bool" + << "QWebEngineNavigationRequest.hasFormData --> bool" << "QWebEngineNavigationRequest.navigationType --> QWebEngineNavigationRequest::NavigationType" << "QWebEngineNavigationRequest.url --> QUrl" << "QWebEngineNavigationRequest.AcceptRequest --> NavigationRequestAction" @@ -714,6 +718,7 @@ static const QStringList expectedAPI = QStringList() << "QQuickWebEngineView.featurePermissionRequested(QUrl,QQuickWebEngineView::Feature) --> void" << "QQuickWebEngineView.fileDialogRequested(QQuickWebEngineFileDialogRequest*) --> void" << "QQuickWebEngineView.fileSystemAccessRequested(QWebEngineFileSystemAccessRequest) --> void" + << "QQuickWebEngineView.findFrameByName(QString) --> QWebEngineFrame" << "QQuickWebEngineView.findText(QString) --> void" << "QQuickWebEngineView.findText(QString,FindFlags) --> void" << "QQuickWebEngineView.findText(QString,FindFlags,QJSValue) --> void" @@ -743,6 +748,7 @@ static const QStringList expectedAPI = QStringList() << "QQuickWebEngineView.loadProgressChanged() --> void" << "QQuickWebEngineView.loading --> bool" << "QQuickWebEngineView.loadingChanged(QWebEngineLoadingInfo) --> void" + << "QQuickWebEngineView.mainFrame --> QWebEngineFrame" << "QQuickWebEngineView.navigationRequested(QWebEngineNavigationRequest*) --> void" << "QQuickWebEngineView.newWindowRequested(QQuickWebEngineNewWindowRequest*) --> void" << "QQuickWebEngineView.AcceptRequest --> NavigationRequestAction" @@ -879,6 +885,11 @@ static const QStringList expectedAPI = QStringList() << "QQuickWebEngineSettings.DisallowImageAnimation --> ImageAnimationPolicy" << "QQuickWebEngineSettings.imageAnimationPolicy --> QQuickWebEngineSettings::ImageAnimationPolicy" << "QQuickWebEngineSettings.imageAnimationPolicyChanged() --> void" + << "QWebEngineFrame.htmlName --> QString" + << "QWebEngineFrame.isValid --> bool" + << "QWebEngineFrame.name --> QString" + << "QWebEngineFrame.size --> QSizeF" + << "QWebEngineFrame.url --> QUrl" ; static bool isCheckedEnum(QMetaType t) diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 39a28759c..f1d64776b 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -117,6 +117,7 @@ private Q_SLOTS: void comboBoxPopupPositionAfterChildMove_data(); void comboBoxPopupPositionAfterChildMove(); void acceptNavigationRequest(); + void acceptNavigationRequestWithFormData(); void acceptNavigationRequestNavigationType(); void acceptNavigationRequestRelativeToNothing(); #ifndef Q_OS_MACOS @@ -636,6 +637,7 @@ public: QWebEngineNavigationRequest::NavigationType type; QUrl url; bool isMainFrame; + bool hasFormData; }; QList<Navigation> navigations; @@ -653,6 +655,7 @@ private Q_SLOTS: n.url = request.url(); n.type = request.navigationType(); n.isMainFrame = request.isMainFrame(); + n.hasFormData = request.hasFormData(); navigations.append(n); request.accept(); } @@ -670,9 +673,33 @@ private Q_SLOTS: } }; -void tst_QWebEnginePage::acceptNavigationRequestNavigationType() +void tst_QWebEnginePage::acceptNavigationRequestWithFormData() { + QWebEngineProfile profile; + profile.installUrlSchemeHandler("echo", new EchoingUrlSchemeHandler(&profile)); + TestPage page(nullptr, &profile); + QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool))); + + page.setHtml(QString("<html><body><form name='tstform' action='foo' method='post'>" + "<input type='text'><input type='submit'></form></body></html>"), + QUrl("echo:/")); + QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000); + QCOMPARE(page.navigations[0].type, QWebEngineNavigationRequest::TypedNavigation); + QVERIFY(!page.navigations[0].hasFormData); + evaluateJavaScriptSync(&page, "tstform.submit();"); + QTRY_COMPARE(loadSpy.size(), 2); + QCOMPARE(page.navigations[1].type, QWebEngineNavigationRequest::FormSubmittedNavigation); + QVERIFY(page.navigations[1].hasFormData); + + page.triggerAction(QWebEnginePage::Reload); + QTRY_COMPARE(loadSpy.size(), 3); + QCOMPARE(page.navigations[2].type, QWebEngineNavigationRequest::ReloadNavigation); + QVERIFY(page.navigations[2].hasFormData); +} + +void tst_QWebEnginePage::acceptNavigationRequestNavigationType() +{ TestPage page; QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool))); diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp index 095d4c8f2..cebdaaa47 100644 --- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp +++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp @@ -188,6 +188,7 @@ void tst_QWebEngineProfile::clearDataFromCache() QVERIFY(server.start()); AutoDir cacheDir("./tst_QWebEngineProfile_clearDataFromCache"); + QVERIFY(!cacheDir.exists("Cache")); QWebEngineProfile profile(QStringLiteral("clearDataFromCache")); QSignalSpy cacheSpy(&profile, &QWebEngineProfile::clearHttpCacheCompleted); @@ -201,9 +202,14 @@ void tst_QWebEngineProfile::clearDataFromCache() QVERIFY(cacheDir.exists("Cache")); qint64 sizeBeforeClear = totalSize(cacheDir); + QCOMPARE_GT(sizeBeforeClear, 0); profile.clearHttpCache(); QTRY_COMPARE(cacheSpy.size(), 1); - QVERIFY(sizeBeforeClear > totalSize(cacheDir)); +#if defined(Q_OS_WIN) + QTRY_COMPARE_GT(sizeBeforeClear, totalSize(cacheDir)); +#else + QCOMPARE_GT(sizeBeforeClear, totalSize(cacheDir)); +#endif (void)server.stop(); } |