summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/qwebenginedownloads
diff options
context:
space:
mode:
authorJüri Valdmann <juri.valdmann@qt.io>2018-03-08 17:37:03 +0100
committerJüri Valdmann <juri.valdmann@qt.io>2018-04-03 08:14:00 +0000
commitcce649b65d31353754af9e34148c0e8d4068d3cf (patch)
tree3125ee37a7a6a30e2c1aa1fe9fb990e5253aae86 /tests/auto/widgets/qwebenginedownloads
parentef0bebc89a4d716d4bd3467bcbc971ca4101d974 (diff)
Stabilize tst_qwebenginedownloads
The waitForRequest/waitForSignal function used by these tests is broken: it assumes that calling QEventLoop::exit() will immediately exit from the event loop. In actuality this is not immediate and the event loop may continue to execute more signals handlers even after exit() has been called. This means that in e.g. waitForRequest the 'result' variable may be assigned to twice. Additionally there is a race condition in downloadTwoLinks, where we sometimes skip the first download. This is not a bug but simply one pending navigation being aborted in favor of another. Changes - Delete waitForRequest. Define one HTTP request handler per test, using state variables to communicate with the main body of the test. Ignore unknown requests (including favicon requests). Same for downloadRequested signals. - Expand downloadTwoLinks and fix expectations. - Add logging to HTTPServer. - Unblacklist. Task-number: QTBUG-66888 Change-Id: I718cac6c4b32a8cc68400fa8ee5b853686c77fcb Reviewed-by: Peter Varga <pvarga@inf.u-szeged.hu>
Diffstat (limited to 'tests/auto/widgets/qwebenginedownloads')
-rw-r--r--tests/auto/widgets/qwebenginedownloads/BLACKLIST4
-rw-r--r--tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp811
2 files changed, 426 insertions, 389 deletions
diff --git a/tests/auto/widgets/qwebenginedownloads/BLACKLIST b/tests/auto/widgets/qwebenginedownloads/BLACKLIST
deleted file mode 100644
index 1bf8c8b1f..000000000
--- a/tests/auto/widgets/qwebenginedownloads/BLACKLIST
+++ /dev/null
@@ -1,4 +0,0 @@
-[downloadLink]
-osx
-[downloadTwoLinks]
-*
diff --git a/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp b/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp
index e8ac9676f..4848038df 100644
--- a/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp
+++ b/tests/auto/widgets/qwebenginedownloads/tst_qwebenginedownloads.cpp
@@ -36,50 +36,150 @@
#include <QWebEngineProfile>
#include <QWebEngineView>
#include <httpserver.h>
-#include <waitforsignal.h>
-
-static std::unique_ptr<HttpReqRep> waitForFaviconRequest(HttpServer *server)
-{
- auto rr = waitForRequest(server);
- if (!rr ||
- rr->requestMethod() != QByteArrayLiteral("GET") ||
- rr->requestPath() != QByteArrayLiteral("/favicon.ico"))
- return nullptr;
- rr->setResponseStatus(404);
- rr->sendResponse();
- return std::move(rr);
-}
class tst_QWebEngineDownloads : public QObject
{
Q_OBJECT
+
+public:
+ enum UserAction {
+ SaveLink,
+ ClickLink,
+ };
+
+ enum FileAction {
+ FileIsDownloaded,
+ FileIsDisplayed,
+ };
+
private Q_SLOTS:
+ void initTestCase();
+ void init();
+ void cleanup();
+ void cleanupTestCase();
+
void downloadLink_data();
void downloadLink();
+ void downloadTwoLinks_data();
void downloadTwoLinks();
void downloadPage_data();
void downloadPage();
void downloadViaSetUrl();
void downloadFileNot1();
void downloadFileNot2();
-};
-enum DownloadTestUserAction {
- SaveLink,
- Navigate,
+private:
+ void saveLink(QPoint linkPos);
+ void clickLink(QPoint linkPos);
+ void simulateUserAction(QPoint linkPos, UserAction action);
+
+ QWebEngineDownloadItem::DownloadType expectedDownloadType(
+ UserAction userAction,
+ const QByteArray &contentDisposition = QByteArray());
+
+ HttpServer *m_server;
+ QWebEngineProfile *m_profile;
+ QWebEnginePage *m_page;
+ QWebEngineView *m_view;
+ QSet<QWebEngineDownloadItem *> m_downloads;
};
-enum DownloadTestFileAction {
- FileIsDownloaded,
- FileIsDisplayed,
+class ScopedConnection {
+public:
+ ScopedConnection(QMetaObject::Connection connection) : m_connection(std::move(connection)) {}
+ ~ScopedConnection() { QObject::disconnect(m_connection); }
+private:
+ QMetaObject::Connection m_connection;
};
-Q_DECLARE_METATYPE(DownloadTestUserAction);
-Q_DECLARE_METATYPE(DownloadTestFileAction);
+Q_DECLARE_METATYPE(tst_QWebEngineDownloads::UserAction)
+Q_DECLARE_METATYPE(tst_QWebEngineDownloads::FileAction)
+
+void tst_QWebEngineDownloads::initTestCase()
+{
+ m_server = new HttpServer();
+ m_profile = new QWebEngineProfile;
+ m_profile->setHttpCacheType(QWebEngineProfile::NoCache);
+ connect(m_profile, &QWebEngineProfile::downloadRequested, [this](QWebEngineDownloadItem *item) {
+ m_downloads.insert(item);
+ connect(item, &QWebEngineDownloadItem::destroyed, [this, item](){
+ m_downloads.remove(item);
+ });
+ connect(item, &QWebEngineDownloadItem::finished, [this, item](){
+ m_downloads.remove(item);
+ });
+ });
+ m_page = new QWebEnginePage(m_profile);
+ m_view = new QWebEngineView;
+ m_view->setPage(m_page);
+ m_view->show();
+}
+
+void tst_QWebEngineDownloads::init()
+{
+ QVERIFY(m_server->start());
+}
+
+void tst_QWebEngineDownloads::cleanup()
+{
+ QCOMPARE(m_downloads.count(), 0);
+ QVERIFY(m_server->stop());
+}
+
+void tst_QWebEngineDownloads::cleanupTestCase()
+{
+ delete m_view;
+ delete m_page;
+ delete m_profile;
+ delete m_server;
+}
+
+void tst_QWebEngineDownloads::saveLink(QPoint linkPos)
+{
+ // Simulate right-clicking on link and choosing "save link as" from menu.
+ QSignalSpy menuSpy(m_view, &QWebEngineView::customContextMenuRequested);
+ m_view->setContextMenuPolicy(Qt::CustomContextMenu);
+ auto event1 = new QContextMenuEvent(QContextMenuEvent::Mouse, linkPos);
+ auto event2 = new QMouseEvent(QEvent::MouseButtonPress, linkPos, Qt::RightButton, {}, {});
+ auto event3 = new QMouseEvent(QEvent::MouseButtonRelease, linkPos, Qt::RightButton, {}, {});
+ QTRY_VERIFY(m_view->focusWidget());
+ QWidget *renderWidget = m_view->focusWidget();
+ QCoreApplication::postEvent(renderWidget, event1);
+ QCoreApplication::postEvent(renderWidget, event2);
+ QCoreApplication::postEvent(renderWidget, event3);
+ QTRY_COMPARE(menuSpy.count(), 1);
+ m_page->triggerAction(QWebEnginePage::DownloadLinkToDisk);
+}
+
+void tst_QWebEngineDownloads::clickLink(QPoint linkPos)
+{
+ // Simulate left-clicking on link.
+ QTRY_VERIFY(m_view->focusWidget());
+ QWidget *renderWidget = m_view->focusWidget();
+ QTest::mouseClick(renderWidget, Qt::LeftButton, {}, linkPos);
+}
+
+void tst_QWebEngineDownloads::simulateUserAction(QPoint linkPos, UserAction action)
+{
+ switch (action) {
+ case SaveLink: return saveLink(linkPos);
+ case ClickLink: return clickLink(linkPos);
+ }
+}
+
+QWebEngineDownloadItem::DownloadType tst_QWebEngineDownloads::expectedDownloadType(
+ UserAction userAction, const QByteArray &contentDisposition)
+{
+ if (userAction == SaveLink)
+ return QWebEngineDownloadItem::UserRequested;
+ if (contentDisposition == QByteArrayLiteral("attachment"))
+ return QWebEngineDownloadItem::Attachment;
+ return QWebEngineDownloadItem::DownloadAttribute;
+}
void tst_QWebEngineDownloads::downloadLink_data()
{
- QTest::addColumn<DownloadTestUserAction>("userAction");
+ QTest::addColumn<UserAction>("userAction");
QTest::addColumn<bool>("anchorHasDownloadAttribute");
QTest::addColumn<QByteArray>("fileName");
QTest::addColumn<QByteArray>("fileContents");
@@ -87,7 +187,7 @@ void tst_QWebEngineDownloads::downloadLink_data()
QTest::addColumn<QByteArray>("fileMimeTypeDetected");
QTest::addColumn<QByteArray>("fileDisposition");
QTest::addColumn<bool>("fileHasReferer");
- QTest::addColumn<DownloadTestFileAction>("fileAction");
+ QTest::addColumn<FileAction>("fileAction");
QTest::addColumn<QWebEngineDownloadItem::DownloadType>("downloadType");
// SaveLink should always trigger a download, even for empty files.
@@ -100,8 +200,7 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("")
/* fileDisposition */ << QByteArrayLiteral("")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDownloaded
- /* downloadType */ << QWebEngineDownloadItem::UserRequested;
+ /* fileAction */ << FileIsDownloaded;
// SaveLink should always trigger a download, also for text files.
QTest::newRow("save link to text file")
@@ -113,8 +212,7 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain")
/* fileDisposition */ << QByteArrayLiteral("")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDownloaded
- /* downloadType */ << QWebEngineDownloadItem::UserRequested;
+ /* fileAction */ << FileIsDownloaded;
// ... adding the "download" attribute should have no effect.
QTest::newRow("save link to text file (attribute)")
@@ -126,8 +224,7 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain")
/* fileDisposition */ << QByteArrayLiteral("")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDownloaded
- /* downloadType */ << QWebEngineDownloadItem::UserRequested;
+ /* fileAction */ << FileIsDownloaded;
// ... adding the "attachment" content disposition should also have no effect.
QTest::newRow("save link to text file (attachment)")
@@ -139,8 +236,7 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain")
/* fileDisposition */ << QByteArrayLiteral("attachment")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDownloaded
- /* downloadType */ << QWebEngineDownloadItem::UserRequested;
+ /* fileAction */ << FileIsDownloaded;
// ... even adding both should have no effect.
QTest::newRow("save link to text file (attribute+attachment)")
@@ -152,12 +248,11 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain")
/* fileDisposition */ << QByteArrayLiteral("attachment")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDownloaded
- /* downloadType */ << QWebEngineDownloadItem::UserRequested;
+ /* fileAction */ << FileIsDownloaded;
// Navigating to an empty file should show an empty page.
QTest::newRow("navigate to empty file")
- /* userAction */ << Navigate
+ /* userAction */ << ClickLink
/* anchorHasDownloadAttribute */ << false
/* fileName */ << QByteArrayLiteral("foo.txt")
/* fileContents */ << QByteArrayLiteral("")
@@ -165,12 +260,11 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("")
/* fileDisposition */ << QByteArrayLiteral("")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDisplayed
- /* downloadType */ << QWebEngineDownloadItem::UserRequested;
+ /* fileAction */ << FileIsDisplayed;
// Navigating to a text file should show the text file.
QTest::newRow("navigate to text file")
- /* userAction */ << Navigate
+ /* userAction */ << ClickLink
/* anchorHasDownloadAttribute */ << false
/* fileName */ << QByteArrayLiteral("foo.txt")
/* fileContents */ << QByteArrayLiteral("bar")
@@ -178,12 +272,11 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain")
/* fileDisposition */ << QByteArrayLiteral("")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDisplayed
- /* downloadType */ << QWebEngineDownloadItem::UserRequested;
+ /* fileAction */ << FileIsDisplayed;
// ... unless the link has the "download" attribute: then the file should be downloaded.
QTest::newRow("navigate to text file (attribute)")
- /* userAction */ << Navigate
+ /* userAction */ << ClickLink
/* anchorHasDownloadAttribute */ << true
/* fileName */ << QByteArrayLiteral("foo.txt")
/* fileContents */ << QByteArrayLiteral("bar")
@@ -191,12 +284,11 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain")
/* fileDisposition */ << QByteArrayLiteral("")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDownloaded
- /* downloadType */ << QWebEngineDownloadItem::DownloadAttribute;
+ /* fileAction */ << FileIsDownloaded;
// ... same with the content disposition header save for the download type.
QTest::newRow("navigate to text file (attachment)")
- /* userAction */ << Navigate
+ /* userAction */ << ClickLink
/* anchorHasDownloadAttribute */ << false
/* fileName */ << QByteArrayLiteral("foo.txt")
/* fileContents */ << QByteArrayLiteral("bar")
@@ -204,12 +296,11 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain")
/* fileDisposition */ << QByteArrayLiteral("attachment")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDownloaded
- /* downloadType */ << QWebEngineDownloadItem::Attachment;
+ /* fileAction */ << FileIsDownloaded;
// ... and both.
QTest::newRow("navigate to text file (attribute+attachment)")
- /* userAction */ << Navigate
+ /* userAction */ << ClickLink
/* anchorHasDownloadAttribute */ << true
/* fileName */ << QByteArrayLiteral("foo.txt")
/* fileContents */ << QByteArrayLiteral("bar")
@@ -217,12 +308,11 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("text/plain")
/* fileDisposition */ << QByteArrayLiteral("attachment")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDownloaded
- /* downloadType */ << QWebEngineDownloadItem::Attachment;
+ /* fileAction */ << FileIsDownloaded;
// The file's extension has no effect.
QTest::newRow("navigate to supposed zip file")
- /* userAction */ << Navigate
+ /* userAction */ << ClickLink
/* anchorHasDownloadAttribute */ << false
/* fileName */ << QByteArrayLiteral("foo.zip")
/* fileContents */ << QByteArrayLiteral("bar")
@@ -230,12 +320,11 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("")
/* fileDisposition */ << QByteArrayLiteral("")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDisplayed
- /* downloadType */ << QWebEngineDownloadItem::DownloadAttribute;
+ /* fileAction */ << FileIsDisplayed;
// ... the file's mime type however does.
QTest::newRow("navigate to supposed zip file (application/zip)")
- /* userAction */ << Navigate
+ /* userAction */ << ClickLink
/* anchorHasDownloadAttribute */ << false
/* fileName */ << QByteArrayLiteral("foo.zip")
/* fileContents */ << QByteArrayLiteral("bar")
@@ -243,12 +332,11 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("application/zip")
/* fileDisposition */ << QByteArrayLiteral("")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDownloaded
- /* downloadType */ << QWebEngineDownloadItem::DownloadAttribute;
+ /* fileAction */ << FileIsDownloaded;
// ... but we're not very picky about the exact type.
QTest::newRow("navigate to supposed zip file (application/octet-stream)")
- /* userAction */ << Navigate
+ /* userAction */ << ClickLink
/* anchorHasDownloadAttribute */ << false
/* fileName */ << QByteArrayLiteral("foo.zip")
/* fileContents */ << QByteArrayLiteral("bar")
@@ -256,15 +344,14 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("application/octet-stream")
/* fileDisposition */ << QByteArrayLiteral("")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDownloaded
- /* downloadType */ << QWebEngineDownloadItem::DownloadAttribute;
+ /* fileAction */ << FileIsDownloaded;
// empty zip file (consisting only of "end of central directory record")
QByteArray zipFile = QByteArrayLiteral("PK\x05\x06") + QByteArray(18, 0);
// The mime type is guessed automatically if not provided by the server.
QTest::newRow("navigate to actual zip file")
- /* userAction */ << Navigate
+ /* userAction */ << ClickLink
/* anchorHasDownloadAttribute */ << false
/* fileName */ << QByteArrayLiteral("foo.zip")
/* fileContents */ << zipFile
@@ -272,12 +359,11 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("application/octet-stream")
/* fileDisposition */ << QByteArrayLiteral("")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDownloaded
- /* downloadType */ << QWebEngineDownloadItem::DownloadAttribute;
+ /* fileAction */ << FileIsDownloaded;
// The mime type is not guessed automatically if provided by the server.
QTest::newRow("navigate to actual zip file (application/zip)")
- /* userAction */ << Navigate
+ /* userAction */ << ClickLink
/* anchorHasDownloadAttribute */ << false
/* fileName */ << QByteArrayLiteral("foo.zip")
/* fileContents */ << zipFile
@@ -285,13 +371,12 @@ void tst_QWebEngineDownloads::downloadLink_data()
/* fileMimeTypeDetected */ << QByteArrayLiteral("application/zip")
/* fileDisposition */ << QByteArrayLiteral("")
/* fileHasReferer */ << true
- /* fileAction */ << FileIsDownloaded
- /* downloadType */ << QWebEngineDownloadItem::DownloadAttribute;
+ /* fileAction */ << FileIsDownloaded;
}
void tst_QWebEngineDownloads::downloadLink()
{
- QFETCH(DownloadTestUserAction, userAction);
+ QFETCH(UserAction, userAction);
QFETCH(bool, anchorHasDownloadAttribute);
QFETCH(QByteArray, fileName);
QFETCH(QByteArray, fileContents);
@@ -299,245 +384,225 @@ void tst_QWebEngineDownloads::downloadLink()
QFETCH(QByteArray, fileMimeTypeDetected);
QFETCH(QByteArray, fileDisposition);
QFETCH(bool, fileHasReferer);
- QFETCH(DownloadTestFileAction, fileAction);
- QFETCH(QWebEngineDownloadItem::DownloadType, downloadType);
-
- HttpServer server;
- QWebEngineProfile profile;
- profile.setHttpCacheType(QWebEngineProfile::NoCache);
- QWebEnginePage page(&profile);
- QWebEngineView view;
- view.setPage(&page);
-
- // 1. Load an HTML page with a link
- //
- // The only variation being whether the <a> element has a "download"
- // attribute or not.
- view.load(server.url());
- view.show();
- auto indexRR = waitForRequest(&server);
- QVERIFY(indexRR);
- QCOMPARE(indexRR->requestMethod(), QByteArrayLiteral("GET"));
- QCOMPARE(indexRR->requestPath(), QByteArrayLiteral("/"));
- indexRR->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html"));
- QByteArray html;
- html += QByteArrayLiteral("<html><body><a href=\"");
- html += fileName;
- html += QByteArrayLiteral("\" ");
- if (anchorHasDownloadAttribute)
- html += QByteArrayLiteral("download");
- html += QByteArrayLiteral(">Link</a></body></html>");
- indexRR->setResponseBody(html);
- indexRR->sendResponse();
- bool loadOk = false;
- QVERIFY(waitForSignal(&page, &QWebEnginePage::loadFinished, [&](bool ok) { loadOk = ok; }));
- QVERIFY(loadOk);
-
- // 1.1. Ignore favicon request
- auto favIconRR = waitForFaviconRequest(&server);
- QVERIFY(favIconRR);
-
- // 2. Simulate user action
- //
- // - Navigate: user left-clicks on link
- // - SaveLink: user right-clicks on link and chooses "save link as" from menu
- QTRY_VERIFY(view.focusWidget());
- QWidget *renderWidget = view.focusWidget();
- QPoint linkPos(10, 10);
- if (userAction == SaveLink) {
- view.setContextMenuPolicy(Qt::CustomContextMenu);
- auto event1 = new QContextMenuEvent(QContextMenuEvent::Mouse, linkPos);
- auto event2 = new QMouseEvent(QEvent::MouseButtonPress, linkPos, Qt::RightButton, {}, {});
- auto event3 = new QMouseEvent(QEvent::MouseButtonRelease, linkPos, Qt::RightButton, {}, {});
- QCoreApplication::postEvent(renderWidget, event1);
- QCoreApplication::postEvent(renderWidget, event2);
- QCoreApplication::postEvent(renderWidget, event3);
- QVERIFY(waitForSignal(&view, &QWidget::customContextMenuRequested));
- page.triggerAction(QWebEnginePage::DownloadLinkToDisk);
- } else
- QTest::mouseClick(renderWidget, Qt::LeftButton, {}, linkPos);
-
- // 3. Deliver requested file
- //
- // Request/response headers vary.
- auto fileRR = waitForRequest(&server);
- QVERIFY(fileRR);
- QCOMPARE(fileRR->requestMethod(), QByteArrayLiteral("GET"));
- QCOMPARE(fileRR->requestPath(), QByteArrayLiteral("/") + fileName);
- if (fileHasReferer)
- QCOMPARE(fileRR->requestHeader(QByteArrayLiteral("referer")), server.url().toEncoded());
- else
- QCOMPARE(fileRR->requestHeader(QByteArrayLiteral("referer")), QByteArray());
- if (!fileDisposition.isEmpty())
- fileRR->setResponseHeader(QByteArrayLiteral("content-disposition"), fileDisposition);
- if (!fileMimeTypeDeclared.isEmpty())
- fileRR->setResponseHeader(QByteArrayLiteral("content-type"), fileMimeTypeDeclared);
- fileRR->setResponseBody(fileContents);
- fileRR->sendResponse();
-
- // 4a. File is displayed and not downloaded - end test
- if (fileAction == FileIsDisplayed) {
- QVERIFY(waitForSignal(&page, &QWebEnginePage::loadFinished, [&](bool ok) { loadOk = ok; }));
- QVERIFY(loadOk);
- return;
- }
+ QFETCH(FileAction, fileAction);
+
+ // Set up HTTP server
+ int indexRequestCount = 0;
+ int fileRequestCount = 0;
+ QByteArray fileRequestReferer;
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == "/") {
+ indexRequestCount++;
+
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html"));
+ QByteArray html;
+ html += QByteArrayLiteral("<html><body><a href=\"");
+ html += fileName;
+ html += QByteArrayLiteral("\" ");
+ if (anchorHasDownloadAttribute)
+ html += QByteArrayLiteral("download");
+ html += QByteArrayLiteral(">Link</a></body></html>");
+ rr->setResponseBody(html);
+ rr->sendResponse();
+ } else if (rr->requestMethod() == "GET" && rr->requestPath() == "/" + fileName) {
+ fileRequestCount++;
+ fileRequestReferer = rr->requestHeader(QByteArrayLiteral("referer"));
+
+ if (!fileDisposition.isEmpty())
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), fileDisposition);
+ if (!fileMimeTypeDeclared.isEmpty())
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), fileMimeTypeDeclared);
+ rr->setResponseBody(fileContents);
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
- // 4b. File is downloaded - check QWebEngineDownloadItem attributes
+ // Set up profile and download handler
QTemporaryDir tmpDir;
QVERIFY(tmpDir.isValid());
QByteArray slashFileName = QByteArrayLiteral("/") + fileName;
QString suggestedPath =
QStandardPaths::writableLocation(QStandardPaths::DownloadLocation) + slashFileName;
QString downloadPath = tmpDir.path() + slashFileName;
- QUrl downloadUrl = server.url(slashFileName);
- QWebEngineDownloadItem *downloadItem = nullptr;
- QVERIFY(waitForSignal(&profile, &QWebEngineProfile::downloadRequested,
- [&](QWebEngineDownloadItem *item) {
+ QUrl downloadUrl = m_server->url(slashFileName);
+ int acceptedCount = 0;
+ int finishedCount = 0;
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested);
QCOMPARE(item->isFinished(), false);
QCOMPARE(item->totalBytes(), -1);
QCOMPARE(item->receivedBytes(), 0);
QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
- QCOMPARE(item->type(), downloadType);
+ QCOMPARE(item->type(), expectedDownloadType(userAction, fileDisposition));
QCOMPARE(item->isSavePageDownload(), false);
QCOMPARE(item->mimeType(), QString(fileMimeTypeDetected));
QCOMPARE(item->path(), suggestedPath);
QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat);
QCOMPARE(item->url(), downloadUrl);
+
+ connect(item, &QWebEngineDownloadItem::finished, [&, item]() {
+ QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
+ QCOMPARE(item->isFinished(), true);
+ QCOMPARE(item->totalBytes(), fileContents.size());
+ QCOMPARE(item->receivedBytes(), fileContents.size());
+ QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
+ QCOMPARE(item->type(), expectedDownloadType(userAction, fileDisposition));
+ QCOMPARE(item->isSavePageDownload(), false);
+ QCOMPARE(item->mimeType(), QString(fileMimeTypeDetected));
+ QCOMPARE(item->path(), downloadPath);
+ QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat);
+ QCOMPARE(item->url(), downloadUrl);
+
+ finishedCount++;
+ });
item->setPath(downloadPath);
item->accept();
- downloadItem = item;
- }));
- QVERIFY(downloadItem);
- bool finishOk = false;
- QVERIFY(waitForSignal(downloadItem, &QWebEngineDownloadItem::finished, [&]() {
- auto item = downloadItem;
- QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted);
- QCOMPARE(item->isFinished(), true);
- QCOMPARE(item->totalBytes(), fileContents.size());
- QCOMPARE(item->receivedBytes(), fileContents.size());
- QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
- QCOMPARE(item->type(), downloadType);
- QCOMPARE(item->isSavePageDownload(), false);
- QCOMPARE(item->mimeType(), QString(fileMimeTypeDetected));
- QCOMPARE(item->path(), downloadPath);
- QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat);
- QCOMPARE(item->url(), downloadUrl);
- finishOk = true;
- }));
- QVERIFY(finishOk);
- // 5. Check actual file contents
+ acceptedCount++;
+ });
+
+ // Load an HTML page with a link
+ //
+ // The only variation being whether the <a> element has a "download"
+ // attribute or not.
+ QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
+ m_view->load(m_server->url());
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
+ QCOMPARE(indexRequestCount, 1);
+
+ simulateUserAction(QPoint(10, 10), userAction);
+
+ // If file is expected to be displayed and not downloaded then end test
+ if (fileAction == FileIsDisplayed) {
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
+ QCOMPARE(acceptedCount, 0);
+ return;
+ }
+
+ // Otherwise file is downloaded
+ QTRY_COMPARE(acceptedCount, 1);
+ QTRY_COMPARE(finishedCount, 1);
+ QCOMPARE(fileRequestCount, 1);
+ if (fileHasReferer)
+ QCOMPARE(fileRequestReferer, m_server->url().toEncoded());
+ else
+ QCOMPARE(fileRequestReferer, QByteArray());
QFile file(downloadPath);
QVERIFY(file.open(QIODevice::ReadOnly));
QCOMPARE(file.readAll(), fileContents);
}
+void tst_QWebEngineDownloads::downloadTwoLinks_data()
+{
+ QTest::addColumn<UserAction>("action1");
+ QTest::addColumn<UserAction>("action2");
+ QTest::newRow("Save+Save") << SaveLink << SaveLink;
+ QTest::newRow("Save+Click") << SaveLink << ClickLink;
+ QTest::newRow("Click+Save") << ClickLink << SaveLink;
+ QTest::newRow("Click+Click") << ClickLink << ClickLink;
+}
+
void tst_QWebEngineDownloads::downloadTwoLinks()
{
- HttpServer server;
- QSignalSpy requestSpy(&server, &HttpServer::newRequest);
- QList<HttpReqRep*> results;
- connect(&server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
- rr->setParent(nullptr);
- results.append(rr);
+ QFETCH(UserAction, action1);
+ QFETCH(UserAction, action2);
+
+ // Set up HTTP server
+ int file1RequestCount = 0;
+ int file2RequestCount = 0;
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == "/") {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html"));
+ rr->setResponseBody(QByteArrayLiteral("<html><body><a href=\"file1\" download>Link1</a><br/><a href=\"file2\">Link2</a></body></html>"));
+ rr->sendResponse();
+ } else if (rr->requestMethod() == "GET" && rr->requestPath() == "/file1") {
+ file1RequestCount++;
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/plain"));
+ rr->setResponseBody(QByteArrayLiteral("file1"));
+ rr->sendResponse();
+ } else if (rr->requestMethod() == "GET" && rr->requestPath() == "/file2") {
+ file2RequestCount++;
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/plain"));
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ rr->setResponseBody(QByteArrayLiteral("file2"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
});
+ // Set up profile and download handler
QTemporaryDir tmpDir;
QVERIFY(tmpDir.isValid());
QString standardDir = QStandardPaths::writableLocation(QStandardPaths::DownloadLocation);
-
- QWebEngineProfile profile;
- profile.setHttpCacheType(QWebEngineProfile::NoCache);
- QList<QPointer<QWebEngineDownloadItem>> downloadItems;
- connect(&profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ int acceptedCount = 0;
+ int finishedCount = 0;
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested);
QCOMPARE(item->isFinished(), false);
QCOMPARE(item->totalBytes(), -1);
QCOMPARE(item->receivedBytes(), 0);
QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
+ QCOMPARE(item->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat);
+ QCOMPARE(item->mimeType(), QStringLiteral("text/plain"));
QString filePart = QChar('/') + item->url().fileName();
QCOMPARE(item->path(), standardDir + filePart);
+
+ // type() is broken due to race condition in DownloadManagerDelegateQt
+ if (action1 == ClickLink && action2 == ClickLink) {
+ if (filePart == QStringLiteral("/file1"))
+ QCOMPARE(item->type(), expectedDownloadType(action1));
+ else if (filePart == QStringLiteral("/file2"))
+ QCOMPARE(item->type(), expectedDownloadType(action2, QByteArrayLiteral("attachment")));
+ else
+ QFAIL(qPrintable("Unexpected file name: " + filePart));
+ }
+
+ connect(item, &QWebEngineDownloadItem::finished, [&]() {
+ finishedCount++;
+ });
item->setPath(tmpDir.path() + filePart);
item->accept();
- downloadItems.append(item);
+
+ acceptedCount++;
});
- QWebEnginePage page(&profile);
- QWebEngineView view;
- view.setPage(&page);
-
- view.load(server.url());
- view.show();
- QTRY_COMPARE(requestSpy.count(), 1);
- std::unique_ptr<HttpReqRep> indexRR(results.takeFirst());
- QVERIFY(indexRR);
- QCOMPARE(indexRR->requestMethod(), QByteArrayLiteral("GET"));
- QCOMPARE(indexRR->requestPath(), QByteArrayLiteral("/"));
- indexRR->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html"));
- indexRR->setResponseBody(QByteArrayLiteral("<html><body><a href=\"file1\" download>Link1</a><br/><a href=\"file2\">Link2</a></body></html>"));
- indexRR->sendResponse();
- bool loadOk = false;
- QVERIFY(waitForSignal(&page, &QWebEnginePage::loadFinished, [&](bool ok){ loadOk = ok; }));
- QVERIFY(loadOk);
-
- QTRY_COMPARE(requestSpy.count(), 2);
- std::unique_ptr<HttpReqRep> favIconRR(results.takeFirst());
- QVERIFY(favIconRR);
- favIconRR->setResponseStatus(404);
- favIconRR->sendResponse();
-
- QTRY_VERIFY(view.focusWidget());
- QWidget *renderWidget = view.focusWidget();
- QTest::mouseClick(renderWidget, Qt::LeftButton, {}, QPoint(10, 10));
- QTest::mouseClick(renderWidget, Qt::LeftButton, {}, QPoint(10, 30));
-
- QTRY_VERIFY(requestSpy.count() >= 3);
- std::unique_ptr<HttpReqRep> file1RR(results.takeFirst());
- QVERIFY(file1RR);
- QCOMPARE(file1RR->requestMethod(), QByteArrayLiteral("GET"));
- QTRY_COMPARE(requestSpy.count(), 4);
- std::unique_ptr<HttpReqRep> file2RR(results.takeFirst());
- QVERIFY(file2RR);
- QCOMPARE(file2RR->requestMethod(), QByteArrayLiteral("GET"));
-
- // Handle one request overtaking the other
- if (file1RR->requestPath() == QByteArrayLiteral("/file2"))
- std::swap(file1RR, file2RR);
-
- QCOMPARE(file1RR->requestPath(), QByteArrayLiteral("/file1"));
- QCOMPARE(file2RR->requestPath(), QByteArrayLiteral("/file2"));
-
- file1RR->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/plain"));
- file1RR->setResponseBody(QByteArrayLiteral("file1"));
- file1RR->sendResponse();
- file2RR->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/plain"));
- file2RR->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
- file2RR->setResponseBody(QByteArrayLiteral("file2"));
- file2RR->sendResponse();
-
- // Now wait for downloadRequested signals:
- QTRY_VERIFY(downloadItems.count() >= 2);
- QScopedPointer<QWebEngineDownloadItem> item1(downloadItems.takeFirst());
- QScopedPointer<QWebEngineDownloadItem> item2(downloadItems.takeFirst());
- QVERIFY(item1);
- QVERIFY(item2);
-
- // Handle one request overtaking the other
- if (item1->url().fileName() == QByteArrayLiteral("file2"))
- qSwap(item1, item2);
-
- QCOMPARE(item1->type(), QWebEngineDownloadItem::DownloadAttribute);
- QCOMPARE(item1->mimeType(), QStringLiteral("text/plain"));
- QCOMPARE(item1->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat);
- QCOMPARE(item1->url(), server.url(QByteArrayLiteral("/file1")));
- QTRY_COMPARE(item1->state(), QWebEngineDownloadItem::DownloadCompleted);
-
- QCOMPARE(item2->type(), QWebEngineDownloadItem::Attachment);
- QCOMPARE(item2->mimeType(), QStringLiteral("text/plain"));
- QCOMPARE(item2->savePageFormat(), QWebEngineDownloadItem::UnknownSaveFormat);
- QCOMPARE(item2->url(), server.url(QByteArrayLiteral("/file2")));
- QTRY_COMPARE(item2->state(), QWebEngineDownloadItem::DownloadCompleted);
+ QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
+ m_view->load(m_server->url());
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
+
+ // Trigger downloads
+ simulateUserAction(QPoint(10, 10), action1);
+ simulateUserAction(QPoint(10, 30), action2);
+
+ // Wait for downloads
+ if (action1 == action2 && action1 == ClickLink) {
+ // With two clicks, sometimes both files get downloaded, sometimes only
+ // the second file, depending on the timing. This is expected and
+ // follows Chromium's behavior. We check here only that the second file
+ // is downloaded correctly (and that we do not crash).
+ //
+ // The first download may be aborted before or after the HTTP request is
+ // made. In the latter case we will have both a file1 and a file2
+ // request, but still only one accepted download.
+ QTRY_COMPARE(file2RequestCount, 1);
+ QTRY_VERIFY(acceptedCount >= 1);
+ QTRY_VERIFY(finishedCount >= 1);
+ QTRY_COMPARE(m_downloads.count(), 0);
+ } else {
+ // Otherwise both files should always be downloaded correctly.
+ QTRY_COMPARE(file1RequestCount, 1);
+ QTRY_COMPARE(file2RequestCount, 1);
+ QTRY_COMPARE(acceptedCount, 2);
+ QTRY_COMPARE(finishedCount, 2);
+ }
}
void tst_QWebEngineDownloads::downloadPage_data()
@@ -552,37 +617,28 @@ void tst_QWebEngineDownloads::downloadPage()
{
QFETCH(QWebEngineDownloadItem::SavePageFormat, savePageFormat);
- HttpServer server;
- QWebEngineProfile profile;
- QWebEnginePage page(&profile);
- QWebEngineView view;
- view.setPage(&page);
-
- view.load(server.url());
- view.show();
- auto indexRR = waitForRequest(&server);
- QVERIFY(indexRR);
- QCOMPARE(indexRR->requestMethod(), QByteArrayLiteral("GET"));
- QCOMPARE(indexRR->requestPath(), QByteArrayLiteral("/"));
- indexRR->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html"));
- indexRR->setResponseBody(QByteArrayLiteral("<html><body>Hello</body></html>"));
- indexRR->sendResponse();
- bool loadOk = false;
- QVERIFY(waitForSignal(&page, &QWebEnginePage::loadFinished, [&](bool ok){ loadOk = ok; }));
- QVERIFY(loadOk);
-
- auto favIconRR = waitForFaviconRequest(&server);
- QVERIFY(favIconRR);
+ // Set up HTTP server
+ int indexRequestCount = 0;
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == "/") {
+ indexRequestCount++;
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html"));
+ rr->setResponseBody(QByteArrayLiteral("<html><body>Hello</body></html>"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
+ // Set up profile and download handler
QTemporaryDir tmpDir;
QVERIFY(tmpDir.isValid());
QString downloadPath = tmpDir.path() + QStringLiteral("/test.html");
- page.save(downloadPath, savePageFormat);
-
- QWebEngineDownloadItem *downloadItem = nullptr;
- QUrl downloadUrl = server.url("/");
- QVERIFY(waitForSignal(&profile, &QWebEngineProfile::downloadRequested,
- [&](QWebEngineDownloadItem *item) {
+ QUrl downloadUrl = m_server->url("/");
+ int acceptedCount = 0;
+ int finishedCount = 0;
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadInProgress);
QCOMPARE(item->isFinished(), false);
QCOMPARE(item->totalBytes(), -1);
@@ -590,33 +646,43 @@ void tst_QWebEngineDownloads::downloadPage()
QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason);
QCOMPARE(item->type(), QWebEngineDownloadItem::SavePage);
QCOMPARE(item->isSavePageDownload(), true);
- // FIXME why is mimeType always the same?
+ // FIXME(juvaldma): why is mimeType always the same?
QCOMPARE(item->mimeType(), QStringLiteral("application/x-mimearchive"));
QCOMPARE(item->path(), downloadPath);
QCOMPARE(item->savePageFormat(), savePageFormat);
QCOMPARE(item->url(), downloadUrl);
// no need to call item->accept()
- downloadItem = item;
- }));
- QVERIFY(downloadItem);
- bool finishOk = false;
- QVERIFY(waitForSignal(downloadItem, &QWebEngineDownloadItem::finished, [&]() {
- auto item = downloadItem;
- 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->type(), QWebEngineDownloadItem::SavePage);
- QCOMPARE(item->isSavePageDownload(), true);
- QCOMPARE(item->mimeType(), QStringLiteral("application/x-mimearchive"));
- QCOMPARE(item->path(), downloadPath);
- QCOMPARE(item->savePageFormat(), savePageFormat);
- QCOMPARE(item->url(), downloadUrl);
- finishOk = true;
- }));
- QVERIFY(finishOk);
+ 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->type(), QWebEngineDownloadItem::SavePage);
+ QCOMPARE(item->isSavePageDownload(), true);
+ QCOMPARE(item->mimeType(), QStringLiteral("application/x-mimearchive"));
+ QCOMPARE(item->path(), downloadPath);
+ QCOMPARE(item->savePageFormat(), savePageFormat);
+ QCOMPARE(item->url(), downloadUrl);
+
+ finishedCount++;
+ });
+
+ acceptedCount++;
+ });
+
+ // Load some HTML
+ QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
+ m_page->load(m_server->url());
+ QTRY_COMPARE(loadSpy.count(), 1);
+ QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
+ QCOMPARE(indexRequestCount, 1);
+
+ // Save some HTML
+ m_page->save(downloadPath, savePageFormat);
+ QTRY_COMPARE(acceptedCount, 1);
+ QTRY_COMPARE(finishedCount, 1);
QFile file(downloadPath);
QVERIFY(file.exists());
}
@@ -626,31 +692,33 @@ void tst_QWebEngineDownloads::downloadViaSetUrl()
// Reproduce the scenario described in QTBUG-63388 by triggering downloads
// of the same file multiple times via QWebEnginePage::setUrl
- HttpServer server;
- QWebEngineProfile profile;
- QWebEnginePage page(&profile);
- QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
- QSignalSpy urlSpy(&page, &QWebEnginePage::urlChanged);
- const QUrl indexUrl = server.url();
- const QUrl fileUrl = server.url(QByteArrayLiteral("/file"));
-
- // Set up the test scenario by trying to load some unrelated HTML.
-
- page.setUrl(indexUrl);
-
- auto indexRR = waitForRequest(&server);
- QVERIFY(indexRR);
- QCOMPARE(indexRR->requestMethod(), QByteArrayLiteral("GET"));
- QCOMPARE(indexRR->requestPath(), QByteArrayLiteral("/"));
- indexRR->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html"));
- indexRR->setResponseBody(QByteArrayLiteral("<html><body>Hello</body></html>"));
- indexRR->sendResponse();
+ // Set up HTTP server
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestMethod() == "GET" && rr->requestPath() == "/") {
+ rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("text/html"));
+ rr->setResponseBody(QByteArrayLiteral("<html><body>Hello</body></html>"));
+ rr->sendResponse();
+ } else if (rr->requestMethod() == "GET" && rr->requestPath() == "/file") {
+ rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
+ rr->setResponseBody(QByteArrayLiteral("redacted"));
+ rr->sendResponse();
+ } else {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ }
+ });
- auto indexFavRR = waitForFaviconRequest(&server);
- QVERIFY(indexFavRR);
- indexRR.reset();
- indexFavRR.reset();
+ // Set up profile and download handler
+ QVector<QUrl> downloadUrls;
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
+ downloadUrls.append(item->url());
+ });
+ // Set up the test scenario by trying to load some unrelated HTML.
+ QSignalSpy loadSpy(m_page, &QWebEnginePage::loadFinished);
+ QSignalSpy urlSpy(m_page, &QWebEnginePage::urlChanged);
+ const QUrl indexUrl = m_server->url();
+ m_page->setUrl(indexUrl);
QTRY_COMPARE(loadSpy.count(), 1);
QTRY_COMPARE(urlSpy.count(), 1);
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
@@ -658,37 +726,18 @@ void tst_QWebEngineDownloads::downloadViaSetUrl()
// Download files via setUrl. With QTBUG-63388 after the first iteration the
// downloads would be triggered for indexUrl and not fileUrl.
-
- QVector<QUrl> downloadUrls;
- QObject::connect(&profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
- downloadUrls.append(item->url());
- });
-
+ const QUrl fileUrl = m_server->url(QByteArrayLiteral("/file"));
for (int i = 0; i != 3; ++i) {
- page.setUrl(fileUrl);
- QCOMPARE(page.url(), fileUrl);
-
- auto fileRR = waitForRequest(&server);
- QVERIFY(fileRR);
- QCOMPARE(fileRR->requestMethod(), QByteArrayLiteral("GET"));
- QCOMPARE(fileRR->requestPath(), QByteArrayLiteral("/file"));
- fileRR->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment"));
- fileRR->setResponseBody(QByteArrayLiteral("redacted"));
- fileRR->sendResponse();
-
-// Since 63 we no longer get favicon requests here:
-// auto fileFavRR = waitForFaviconRequest(&server);
-// QVERIFY(fileFavRR);
-
+ m_page->setUrl(fileUrl);
+ QCOMPARE(m_page->url(), fileUrl);
QTRY_COMPARE(loadSpy.count(), 1);
QTRY_COMPARE(urlSpy.count(), 2);
QTRY_COMPARE(downloadUrls.count(), 1);
- fileRR.reset();
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), false);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), fileUrl);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), indexUrl);
QCOMPARE(downloadUrls.takeFirst(), fileUrl);
- QCOMPARE(page.url(), indexUrl);
+ QCOMPARE(m_page->url(), indexUrl);
}
}
@@ -696,26 +745,22 @@ void tst_QWebEngineDownloads::downloadFileNot1()
{
// Trigger file download via download() but don't accept().
- HttpServer server;
- QWebEngineProfile profile;
- QWebEnginePage page(&profile);
- const auto filePath = QByteArrayLiteral("/file");
- const auto fileUrl = server.url(filePath);
-
- page.download(fileUrl);
- auto fileRR = waitForRequest(&server);
- QVERIFY(fileRR);
- QCOMPARE(fileRR->requestMethod(), QByteArrayLiteral("GET"));
- QCOMPARE(fileRR->requestPath(), filePath);
- fileRR->sendResponse();
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ });
QPointer<QWebEngineDownloadItem> downloadItem;
- QVERIFY(waitForSignal(&profile, &QWebEngineProfile::downloadRequested,
- [&](QWebEngineDownloadItem *item) {
+ int downloadCount = 0;
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
QVERIFY(item);
QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested);
downloadItem = item;
- }));
+ downloadCount++;
+ });
+
+ m_page->download(m_server->url(QByteArrayLiteral("/file")));
+ QTRY_COMPARE(downloadCount, 1);
QVERIFY(!downloadItem);
}
@@ -723,27 +768,23 @@ void tst_QWebEngineDownloads::downloadFileNot2()
{
// Trigger file download via download() but call cancel() instead of accept().
- HttpServer server;
- QWebEngineProfile profile;
- QWebEnginePage page(&profile);
- const auto filePath = QByteArrayLiteral("/file");
- const auto fileUrl = server.url(filePath);
-
- page.download(fileUrl);
- auto fileRR = waitForRequest(&server);
- QVERIFY(fileRR);
- QCOMPARE(fileRR->requestMethod(), QByteArrayLiteral("GET"));
- QCOMPARE(fileRR->requestPath(), filePath);
- fileRR->sendResponse();
+ ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ rr->setResponseStatus(404);
+ rr->sendResponse();
+ });
QPointer<QWebEngineDownloadItem> downloadItem;
- QVERIFY(waitForSignal(&profile, &QWebEngineProfile::downloadRequested,
- [&](QWebEngineDownloadItem *item) {
+ int downloadCount = 0;
+ ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) {
QVERIFY(item);
QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadRequested);
item->cancel();
downloadItem = item;
- }));
+ downloadCount++;
+ });
+
+ m_page->download(m_server->url(QByteArrayLiteral("/file")));
+ QTRY_COMPARE(downloadCount, 1);
QVERIFY(downloadItem);
QCOMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadCancelled);
}