diff options
Diffstat (limited to 'tests')
6 files changed, 274 insertions, 0 deletions
diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro b/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro index e99c7f493..9c239f1a7 100644 --- a/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro +++ b/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro @@ -1 +1,2 @@ include(../tests.pri) +include(../../shared/http.pri) diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp index 5629998fd..7d3ad1440 100644 --- a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp +++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp @@ -34,6 +34,9 @@ #include <QtWebEngineWidgets/qwebengineprofile.h> #include <QtWebEngineWidgets/qwebenginesettings.h> +#include <httpserver.h> +#include <httpreqrep.h> + class tst_QWebEngineUrlRequestInterceptor : public QObject { Q_OBJECT @@ -61,6 +64,7 @@ private Q_SLOTS: void requestInterceptorByResourceType_data(); void requestInterceptorByResourceType(); void firstPartyUrlHttp(); + void passRefererHeader(); }; tst_QWebEngineUrlRequestInterceptor::tst_QWebEngineUrlRequestInterceptor() @@ -99,6 +103,9 @@ struct RequestInfo { int resourceType; }; +static const QByteArray kHttpHeaderReferrerValue = QByteArrayLiteral("http://somereferrer.com/"); +static const QByteArray kHttpHeaderRefererName = QByteArrayLiteral("referer"); + class TestRequestInterceptor : public QWebEngineUrlRequestInterceptor { public: @@ -115,6 +122,9 @@ public: if (shouldIntercept && info.requestUrl().toString().endsWith(QLatin1String("__placeholder__"))) info.redirect(QUrl("qrc:///resources/content.html")); + // Set referrer header + info.setHttpHeader(kHttpHeaderRefererName, kHttpHeaderReferrerValue); + requestInfos.append(info); } @@ -510,5 +520,38 @@ void tst_QWebEngineUrlRequestInterceptor::firstPartyUrlHttp() QCOMPARE(info.firstPartyUrl, firstPartyUrl); } +void tst_QWebEngineUrlRequestInterceptor::passRefererHeader() +{ + // Create HTTP Server to parse the request. + HttpServer httpServer; + + if (!httpServer.start()) + QSKIP("Failed to start http server"); + + bool succeeded = false; + connect(&httpServer, &HttpServer::newRequest, [&succeeded](HttpReqRep *rr) { + const QByteArray headerValue = rr->requestHeader(kHttpHeaderRefererName); + QCOMPARE(headerValue, kHttpHeaderReferrerValue); + succeeded = headerValue == kHttpHeaderReferrerValue; + rr->setResponseStatus(200); + rr->sendResponse(); + }); + + QWebEngineProfile profile; + TestRequestInterceptor interceptor(true); + profile.setUrlRequestInterceptor(&interceptor); + + QWebEnginePage page(&profile); + QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); + QWebEngineHttpRequest httpRequest; + QUrl requestUrl = httpServer.url(); + httpRequest.setUrl(requestUrl); + page.load(httpRequest); + + QVERIFY(spy.wait()); + (void) httpServer.stop(); + QVERIFY(succeeded); +} + QTEST_MAIN(tst_QWebEngineUrlRequestInterceptor) #include "tst_qwebengineurlrequestinterceptor.moc" diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp index 3a38c115d..bc474457a 100644 --- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp +++ b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp @@ -77,6 +77,7 @@ private Q_SLOTS: void downloadToDefaultLocation(); void downloadToNonExistentDir(); void downloadToReadOnlyDir(); + void downloadPathValidation(); private: void saveLink(QPoint linkPos); @@ -1115,5 +1116,127 @@ void tst_QWebEngineDownloadItem::downloadToReadOnlyDir() QFile(m_profile->downloadPath()).setPermissions(QFileDevice::WriteOwner); } +void tst_QWebEngineDownloadItem::downloadPathValidation() +{ + const QString fileName = "test.txt"; + QString downloadPath; + QString originalDownloadPath; + + QTemporaryDir tmpDir; + QVERIFY(tmpDir.isValid()); + + // 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 + QPointer<QWebEngineDownloadItem> downloadItem; + ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { + downloadItem = item; + originalDownloadPath = item->path(); + + item->setPath(downloadPath); + // TODO: Do not cancel download from 5.13. This is for not messing up system download path. + // Use m_profile->setDownloadPath(tmpDir.path()) at initialization. + if (item->path() != downloadPath) + item->cancel(); + else + item->accept(); + + connect(item, &QWebEngineDownloadItem::stateChanged, [&, item](QWebEngineDownloadItem::DownloadState downloadState) { + if (downloadState == QWebEngineDownloadItem::DownloadInterrupted) { + item->cancel(); + } + }); + + connect(item, &QWebEngineDownloadItem::finished, [&, item]() { + QCOMPARE(item->isFinished(), true); + QCOMPARE(item->totalBytes(), item->receivedBytes()); + QVERIFY(item->receivedBytes() > 0); + QCOMPARE(item->page(), m_page); + }); + }); + + QString oldPath = QDir::currentPath(); + QDir::setCurrent(tmpDir.path()); + + // Set only the file name. + downloadItem.clear(); + originalDownloadPath = ""; + downloadPath = fileName; + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadItem); + QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCompleted); + QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::NoReason); + QCOMPARE(downloadItem->path(), fileName); + + // Set only the directory path. + downloadItem.clear(); + originalDownloadPath = ""; + downloadPath = tmpDir.path(); + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadItem); + QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled); + QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::UserCanceled); + QCOMPARE(downloadItem->path(), originalDownloadPath); + + // Set only the directory path with separator. + downloadItem.clear(); + originalDownloadPath = ""; + downloadPath = tmpDir.path() + QDir::separator(); + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadItem); + QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled); + QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::UserCanceled); + QCOMPARE(downloadItem->path(), originalDownloadPath); + + // Set only the directory with the current directory path without ending separator. + downloadItem.clear(); + originalDownloadPath = ""; + downloadPath = "."; + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadItem); + QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled); + QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::UserCanceled); + QCOMPARE(downloadItem->path(), originalDownloadPath); + + // Set only the directory with the current directory path with ending separator. + downloadItem.clear(); + originalDownloadPath = ""; + downloadPath = "./"; + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadItem); + QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled); + QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::UserCanceled); + QCOMPARE(downloadItem->path(), originalDownloadPath); + + + + downloadItem.clear(); + originalDownloadPath = ""; + downloadPath = "..."; + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadItem); + QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled); +#if !defined(Q_OS_WIN) + QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::FileFailed); + QCOMPARE(downloadItem->path(), downloadPath); +#else + // Windows interprets the "..." path as a valid path. It will be the current path. + QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::UserCanceled); + QCOMPARE(downloadItem->path(), originalDownloadPath); +#endif // !defined(Q_OS_WIN) + QDir::setCurrent(oldPath); +} + QTEST_MAIN(tst_QWebEngineDownloadItem) #include "tst_qwebenginedownloaditem.moc" diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 19f9b6df1..dd1140a4f 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -1656,6 +1656,18 @@ void tst_QWebEnginePage::runJavaScript() JavaScriptCallbackUndefined callbackUndefined; page.runJavaScript("undefined", QWebEngineCallback<const QVariant&>(callbackUndefined)); + JavaScriptCallback callbackDate(QVariant(42.0)); + page.runJavaScript("new Date(42000)", QWebEngineCallback<const QVariant&>(callbackDate)); + + JavaScriptCallback callbackBlob(QVariant(QByteArray(8, 0))); + page.runJavaScript("new ArrayBuffer(8)", QWebEngineCallback<const QVariant&>(callbackBlob)); + + JavaScriptCallbackUndefined callbackFunction; + page.runJavaScript("(function(){})", QWebEngineCallback<const QVariant&>(callbackFunction)); + + JavaScriptCallback callbackPromise(QVariant(QVariantMap{})); + page.runJavaScript("new Promise(function(){})", QWebEngineCallback<const QVariant&>(callbackPromise)); + QVERIFY(watcher.wait()); } diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp index 1822069be..8b75067ee 100644 --- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp +++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp @@ -32,6 +32,7 @@ #include <QtWebEngineCore/qwebengineurlrequestinterceptor.h> #include <QtWebEngineCore/qwebengineurlrequestjob.h> #include <QtWebEngineCore/qwebenginecookiestore.h> +#include <QtWebEngineCore/qwebengineurlscheme.h> #include <QtWebEngineCore/qwebengineurlschemehandler.h> #include <QtWebEngineWidgets/qwebengineprofile.h> #include <QtWebEngineWidgets/qwebenginepage.h> @@ -44,6 +45,7 @@ class tst_QWebEngineProfile : public QObject Q_OBJECT private Q_SLOTS: + void initTestCase(); void init(); void cleanup(); void privateProfile(); @@ -55,14 +57,33 @@ private Q_SLOTS: void urlSchemeHandlerFailOnRead(); void urlSchemeHandlerStreaming(); void urlSchemeHandlerRequestHeaders(); + void urlSchemeHandlerInstallation(); void customUserAgent(); void httpAcceptLanguage(); void downloadItem(); void changePersistentPath(); void initiator(); + void badDeleteOrder(); void qtbug_71895(); // this should be the last test }; +void tst_QWebEngineProfile::initTestCase() +{ + QWebEngineUrlScheme foo("foo"); + QWebEngineUrlScheme stream("stream"); + QWebEngineUrlScheme letterto("letterto"); + QWebEngineUrlScheme aviancarrier("aviancarrier"); + foo.setSyntax(QWebEngineUrlScheme::Syntax::Host); + stream.setSyntax(QWebEngineUrlScheme::Syntax::HostAndPort); + stream.setDefaultPort(8080); + letterto.setSyntax(QWebEngineUrlScheme::Syntax::Path); + aviancarrier.setSyntax(QWebEngineUrlScheme::Syntax::Path); + QWebEngineUrlScheme::registerScheme(foo); + QWebEngineUrlScheme::registerScheme(stream); + QWebEngineUrlScheme::registerScheme(letterto); + QWebEngineUrlScheme::registerScheme(aviancarrier); +} + void tst_QWebEngineProfile::init() { //make sure defualt global profile is 'default' across all the tests @@ -84,6 +105,7 @@ void tst_QWebEngineProfile::cleanup() profile->setCachePath(QString()); profile->setPersistentStoragePath(QString()); profile->setHttpCacheType(QWebEngineProfile::DiskHttpCache); + profile->removeAllUrlSchemeHandlers(); } void tst_QWebEngineProfile::privateProfile() @@ -505,6 +527,46 @@ void tst_QWebEngineProfile::urlSchemeHandlerRequestHeaders() QVERIFY(loadFinishedSpy.wait()); } +void tst_QWebEngineProfile::urlSchemeHandlerInstallation() +{ + FailingUrlSchemeHandler handler; + QWebEngineProfile profile; + + // Builtin schemes that *cannot* be overridden. + for (auto scheme : { "about", "blob", "data", "javascript", "qrc", "https", "http", "file", + "ftp", "wss", "ws", "filesystem", "FileSystem" }) { + QTest::ignoreMessage( + QtWarningMsg, + QRegularExpression("Cannot install a URL scheme handler overriding internal scheme.*")); + auto prevHandler = profile.urlSchemeHandler(scheme); + profile.installUrlSchemeHandler(scheme, &handler); + QCOMPARE(profile.urlSchemeHandler(scheme), prevHandler); + } + + // Builtin schemes that *can* be overridden. + for (auto scheme : { "gopher", "GOPHER" }) { + profile.installUrlSchemeHandler(scheme, &handler); + QCOMPARE(profile.urlSchemeHandler(scheme), &handler); + profile.removeUrlScheme(scheme); + } + + // Other schemes should be registered with QWebEngineUrlScheme first, but + // handler installation still succeeds to preserve backwards compatibility. + QTest::ignoreMessage( + QtWarningMsg, + QRegularExpression("Please register the custom scheme.*")); + profile.installUrlSchemeHandler("tst", &handler); + QCOMPARE(profile.urlSchemeHandler("tst"), &handler); + + // Existing handler cannot be overridden. + FailingUrlSchemeHandler handler2; + QTest::ignoreMessage( + QtWarningMsg, + QRegularExpression("URL scheme handler already installed.*")); + profile.installUrlSchemeHandler("tst", &handler2); + QCOMPARE(profile.urlSchemeHandler("tst"), &handler); + profile.removeUrlScheme("tst"); +} void tst_QWebEngineProfile::customUserAgent() { @@ -630,6 +692,24 @@ void tst_QWebEngineProfile::initiator() QCOMPARE(handler.initiator, QUrl()); } +void tst_QWebEngineProfile::badDeleteOrder() +{ + QWebEngineProfile *profile = new QWebEngineProfile(); + QWebEngineView *view = new QWebEngineView(); + view->resize(640, 480); + view->show(); + QVERIFY(QTest::qWaitForWindowExposed(view)); + QWebEnginePage *page = new QWebEnginePage(profile, view); + view->setPage(page); + + QSignalSpy spyLoadFinished(page, SIGNAL(loadFinished(bool))); + page->setHtml(QStringLiteral("<html><body><h1>Badly handled page!</h1></body></html>")); + QTRY_COMPARE(spyLoadFinished.count(), 1); + + delete profile; + delete view; +} + void tst_QWebEngineProfile::qtbug_71895() { QWebEngineView view; diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 74adbaba9..d3ea27fc2 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -197,6 +197,7 @@ private Q_SLOTS: void closeOpenerTab(); void switchPage(); void setPageDeletesImplicitPage(); + void setPageDeletesImplicitPage2(); void setViewDeletesImplicitPage(); void setPagePreservesExplicitPage(); void setViewPreservesExplicitPage(); @@ -3211,6 +3212,20 @@ void tst_QWebEngineView::setPageDeletesImplicitPage() QVERIFY(!implicitPage); // should be deleted } +void tst_QWebEngineView::setPageDeletesImplicitPage2() +{ + QWebEngineView view1; + QWebEngineView view2; + QPointer<QWebEnginePage> implicitPage = view1.page(); + view2.setPage(view1.page()); + QVERIFY(implicitPage); + QVERIFY(view1.page() != implicitPage); + QWebEnginePage explicitPage; + view2.setPage(&explicitPage); + QCOMPARE(view2.page(), &explicitPage); + QVERIFY(!implicitPage); // should be deleted +} + void tst_QWebEngineView::setViewDeletesImplicitPage() { QWebEngineView view; |