diff options
Diffstat (limited to 'tests/auto/widgets')
19 files changed, 839 insertions, 1379 deletions
diff --git a/tests/auto/widgets/offscreen/offscreen.pro b/tests/auto/widgets/offscreen/offscreen.pro new file mode 100644 index 000000000..b8e5632f9 --- /dev/null +++ b/tests/auto/widgets/offscreen/offscreen.pro @@ -0,0 +1,6 @@ +include(../tests.pri) +QT += webengine +qpa.name = QT_QPA_PLATFORM +qpa.value = offscreen +QT_TOOL_ENV += qpa + diff --git a/tests/auto/widgets/offscreen/tst_offscreen.cpp b/tests/auto/widgets/offscreen/tst_offscreen.cpp new file mode 100644 index 000000000..98cbe55fe --- /dev/null +++ b/tests/auto/widgets/offscreen/tst_offscreen.cpp @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qtwebengineglobal.h" +#include <QTest> +#include <QSignalSpy> +#include <QWebEngineProfile> +#include <QWebEnginePage> +#include <QWebEngineView> + +class tst_OffScreen : public QObject { + Q_OBJECT +public: + tst_OffScreen(){} + +private slots: + void offscreen(); +}; + +void tst_OffScreen::offscreen() +{ + QWebEngineProfile profile; + QWebEnginePage page(&profile); + QWebEngineView view; + QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool))); + view.setPage(&page); + page.load(QUrl("http://qt.io")); + view.show(); + QTRY_COMPARE(view.isVisible(), true); + QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count() > 0, true, 20000); +} + +#include "tst_offscreen.moc" +QTEST_MAIN(tst_OffScreen) + diff --git a/tests/auto/widgets/origins/tst_origins.cpp b/tests/auto/widgets/origins/tst_origins.cpp index 59cbdae13..61d16bc8a 100644 --- a/tests/auto/widgets/origins/tst_origins.cpp +++ b/tests/auto/widgets/origins/tst_origins.cpp @@ -301,7 +301,7 @@ void tst_Origins::jsUrlOrigin() QCOMPARE(eval(QSL("new URL(\"qrc:/crysis.css\").origin")), QVariant(QSL("qrc://"))); QCOMPARE(eval(QSL("new URL(\"qrc://foo.com/crysis.css\").origin")), QVariant(QSL("qrc://"))); - // Same with unregistered schemes. + // Unregistered schemes behaves like opaque origins. QCOMPARE(eval(QSL("new URL(\"tst:/banana\").origin")), QVariant(QSL("tst://"))); QCOMPARE(eval(QSL("new URL(\"tst://foo.com/banana\").origin")), QVariant(QSL("tst://"))); @@ -564,8 +564,6 @@ private: // Try opening a WebSocket from pages loaded over various URL schemes. void tst_Origins::webSocket() { - const int kAbnormalClosure = 1006; - EchoServer echoServer; QWebChannel channel; channel.registerObject(QSL("echoServer"), &echoServer); @@ -578,9 +576,9 @@ void tst_Origins::webSocket() QVERIFY(load(QSL("qrc:/resources/websocket.html"))); QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok"))); - // Only registered schemes can open WebSockets. + // Unregistered schemes can also open WebSockets (since Chromium 71) QVERIFY(load(QSL("tst:/resources/websocket.html"))); - QTRY_COMPARE(eval(QSL("result")), QVariant(kAbnormalClosure)); + QTRY_COMPARE(eval(QSL("result")), QVariant(QSL("ok"))); // Even an insecure registered scheme can open WebSockets. QVERIFY(load(QSL("PathSyntax:/resources/websocket.html"))); @@ -599,11 +597,10 @@ void tst_Origins::dedicatedWorker() QTRY_VERIFY(eval(QSL("done")).toBool()); QCOMPARE(eval(QSL("result")), QVariant(42)); - // Unregistered schemes cannot create Workers. + // Unregistered schemes can also create Workers (since Chromium 71) QVERIFY(load(QSL("tst:/resources/dedicatedWorker.html"))); QTRY_VERIFY(eval(QSL("done")).toBool()); - QVERIFY(eval(QSL("error")).toString() - .contains(QSL("Access to dedicated workers is denied to origin 'tst://'"))); + QCOMPARE(eval(QSL("result")), QVariant(42)); // Even an insecure registered scheme can create Workers. QVERIFY(load(QSL("PathSyntax:/resources/dedicatedWorker.html"))); @@ -724,15 +721,9 @@ void tst_Origins::createObjectURL() QVERIFY(load(QSL("qrc:/resources/createObjectURL.html"))); QVERIFY(eval(QSL("result")).toString().startsWith(QSL("blob:qrc:"))); - // Illegal for unregistered schemes (renderer gets terminated). - qRegisterMetaType<QWebEnginePage::RenderProcessTerminationStatus>("RenderProcessTerminationStatus"); - QSignalSpy loadFinishedSpy(m_page, &QWebEnginePage::loadFinished); - QSignalSpy renderProcessTerminatedSpy(m_page, &QWebEnginePage::renderProcessTerminated); - m_page->load(QSL("tst:/resources/createObjectURL.html")); - QVERIFY(!renderProcessTerminatedSpy.empty() || renderProcessTerminatedSpy.wait(20000)); - QVERIFY(renderProcessTerminatedSpy.front().value(0).value<QWebEnginePage::RenderProcessTerminationStatus>() - != QWebEnginePage::NormalTerminationStatus); - QVERIFY(loadFinishedSpy.empty()); + // Also legal for unregistered schemes (since Chromium 71) + QVERIFY(load(QSL("tst:/resources/createObjectURL.html"))); + QVERIFY(eval(QSL("result")).toString().startsWith(QSL("blob:tst:"))); } QTEST_MAIN(tst_Origins) diff --git a/tests/auto/widgets/proxy/proxy.pro b/tests/auto/widgets/proxy/proxy.pro new file mode 100644 index 000000000..802dfad05 --- /dev/null +++ b/tests/auto/widgets/proxy/proxy.pro @@ -0,0 +1,9 @@ +include(../tests.pri) +QT += core-private webengine webengine-private + +HEADERS += \ + proxy_server.h + +SOURCES += \ + proxy_server.cpp + diff --git a/tests/auto/widgets/proxy/proxy_server.cpp b/tests/auto/widgets/proxy/proxy_server.cpp new file mode 100644 index 000000000..55f014914 --- /dev/null +++ b/tests/auto/widgets/proxy/proxy_server.cpp @@ -0,0 +1,90 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "proxy_server.h" +#include <QDataStream> +#include <QTcpSocket> +#include <QDebug> + +ProxyServer::ProxyServer(QObject *parent) : QObject(parent) +{ + connect(&m_server, &QTcpServer::newConnection, this, &ProxyServer::handleNewConnection); +} + +void ProxyServer::setCredentials(const QByteArray &user, const QByteArray password) +{ + m_auth.append(user); + m_auth.append(QChar(':')); + m_auth.append(password); + m_auth = m_auth.toBase64(); +} + +bool ProxyServer::isListening() +{ + return m_server.isListening(); +} + +void ProxyServer::run() +{ + if (!m_server.listen(QHostAddress::LocalHost, 5555)) + qFatal("Could not start the test server"); +} + +void ProxyServer::handleNewConnection() +{ + // do one connection at the time + Q_ASSERT(m_data.isEmpty()); + QTcpSocket *socket = m_server.nextPendingConnection(); + Q_ASSERT(socket); + connect(socket, &QAbstractSocket::disconnected, socket, &QObject::deleteLater); + connect(socket, &QAbstractSocket::readyRead, this, &ProxyServer::handleReadReady); +} + +void ProxyServer::handleReadReady() +{ + QTcpSocket *socket = qobject_cast<QTcpSocket*>(sender()); + Q_ASSERT(socket); + + m_data.append(socket->readAll()); + + if (!m_data.endsWith("\r\n\r\n")) + return; + + if (!m_data.contains(QByteArrayLiteral("Proxy-Authorization: Basic"))) { + socket->write("HTTP/1.1 407 Proxy Authentication Required\nProxy-Authenticate: " + "Basic realm=\"Proxy requires authentication\"\r\n" + "content-length: 0\r\n" + "\r\n"); + return; + } + + if (m_data.contains(m_auth)) { + emit success(); + } + m_data.clear(); +} diff --git a/tests/auto/widgets/proxy/proxy_server.h b/tests/auto/widgets/proxy/proxy_server.h new file mode 100644 index 000000000..cb7c30600 --- /dev/null +++ b/tests/auto/widgets/proxy/proxy_server.h @@ -0,0 +1,59 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef PROXY_SERVER_H +#define PROXY_SERVER_H + +#include <QObject> +#include <QTcpServer> + +class ProxyServer : public QObject +{ + Q_OBJECT + +public: + explicit ProxyServer(QObject *parent = nullptr); + void setCredentials(const QByteArray &user, const QByteArray password); + bool isListening(); + +public slots: + void run(); + +private slots: + void handleNewConnection(); + void handleReadReady(); + +signals: + void success(); +private: + QByteArray m_data; + QTcpServer m_server; + QByteArray m_auth; +}; + +#endif // PROXY_SERVER_H diff --git a/tests/auto/widgets/proxy/tst_proxy.cpp b/tests/auto/widgets/proxy/tst_proxy.cpp new file mode 100644 index 000000000..5f5dec016 --- /dev/null +++ b/tests/auto/widgets/proxy/tst_proxy.cpp @@ -0,0 +1,69 @@ +/**************************************************************************** +** +** Copyright (C) 2019 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "proxy_server.h" +#include <QTest> +#include <QSignalSpy> +#include <QNetworkProxy> +#include <QWebEnginePage> +#include <QWebEngineView> + + +class tst_Proxy : public QObject { + Q_OBJECT +public: + tst_Proxy(){} + +private slots: + void proxyAuthentication(); +}; + +void tst_Proxy::proxyAuthentication() +{ + QByteArray user(QByteArrayLiteral("test")); + QByteArray password(QByteArrayLiteral("pass")); + QNetworkProxy proxy; + proxy.setType(QNetworkProxy::HttpProxy); + proxy.setHostName("localhost"); + proxy.setPort(5555); + proxy.setUser(user); + proxy.setPassword(password); + QNetworkProxy::setApplicationProxy(proxy); + ProxyServer server; + server.setCredentials(user,password); + server.run(); + QTRY_VERIFY2(server.isListening(), "Could not setup authentication server"); + QWebEnginePage page; + QSignalSpy successSpy(&server, &ProxyServer::success); + page.load(QUrl("http://www.qt.io")); + QTRY_VERIFY2(successSpy.count() > 0, "Could not get authentication token"); +} + +#include "tst_proxy.moc" +QTEST_MAIN(tst_Proxy) + diff --git a/tests/auto/widgets/proxypac/proxypac.pro b/tests/auto/widgets/proxypac/proxypac.pro index 00ae90977..1c2958d3a 100644 --- a/tests/auto/widgets/proxypac/proxypac.pro +++ b/tests/auto/widgets/proxypac/proxypac.pro @@ -3,26 +3,8 @@ QT += webengine HEADERS += proxyserver.h SOURCES += proxyserver.cpp -# QTBUG-71229 -xgd_desktop.name=XDG_CURRENT_DESKTOP -xgd_desktop.value=KDE -QT_TOOL_ENV += xgd_desktop +proxy_pac.name = QTWEBENGINE_CHROMIUM_FLAGS +proxy_pac.value = --proxy-pac-url="file://$$PWD/proxy.pac" -kde_home.name=KDEHOME -kde_home.value=$$OUT_PWD -QT_TOOL_ENV += kde_home - -PROXY_CONFIG= \ - "[Proxy Settings]" \ - "Proxy Config Script=$$PWD/proxy.pac" \ - "ProxyType=2" - -mkpath($$OUT_PWD/share/config) -KDE_FILE = $$OUT_PWD/share/config/kioslaverc - -!build_pass { - write_file($$KDE_FILE, PROXY_CONFIG) -} - -QMAKE_DISTCLEAN += $$KDE_FILE +QT_TOOL_ENV += proxy_pac diff --git a/tests/auto/widgets/qwebenginedownloaditem/BLACKLIST b/tests/auto/widgets/qwebenginedownloaditem/BLACKLIST new file mode 100644 index 000000000..a51117ae0 --- /dev/null +++ b/tests/auto/widgets/qwebenginedownloaditem/BLACKLIST @@ -0,0 +1,2 @@ +[downloadToReadOnlyDir] +windows diff --git a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp index b30fc7258..ee1e6ee04 100644 --- a/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp +++ b/tests/auto/widgets/qwebenginedownloaditem/tst_qwebenginedownloaditem.cpp @@ -31,6 +31,7 @@ #include <QStandardPaths> #include <QTemporaryDir> #include <QTest> +#include <QRegularExpression> #include <QWebEngineDownloadItem> #include <QWebEnginePage> #include <QWebEngineProfile> @@ -70,6 +71,12 @@ private Q_SLOTS: void downloadFileNot2(); void downloadDeleted(); void downloadDeletedByProfile(); + void downloadUniqueFilename_data(); + void downloadUniqueFilename(); + void downloadUniqueFileNameWithTimeStamp(); + void downloadToDefaultLocation(); + void downloadToNonExistentDir(); + void downloadToReadOnlyDir(); private: void saveLink(QPoint linkPos); @@ -135,6 +142,8 @@ void tst_QWebEngineDownloadItem::cleanup() QTRY_COMPARE(m_requestedDownloads.count(), 0); QCOMPARE(m_finishedDownloads.count(), 0); QVERIFY(m_server->stop()); + // Set download path to default. + m_profile->setDownloadPath(""); } void tst_QWebEngineDownloadItem::cleanupTestCase() @@ -844,5 +853,264 @@ void tst_QWebEngineDownloadItem::downloadDeletedByProfile() QTRY_COMPARE(downloadItem.isNull(), true); } +void tst_QWebEngineDownloadItem::downloadUniqueFilename_data() +{ + QTest::addColumn<QString>("baseName"); + QTest::addColumn<QString>("extension"); + + QTest::newRow("txt") << QString("test(1.test)") << QString("txt"); + QTest::newRow("tar.gz") << QString("test(1.test)") << QString("tar.gz"); +} + +void tst_QWebEngineDownloadItem::downloadUniqueFilename() +{ + QFETCH(QString, baseName); + QFETCH(QString, extension); + QString fileName = QString("%1.%2").arg(baseName).arg(extension); + QString downloadedFilePath; + bool downloadFinished = false; + + QTemporaryDir tmpDir; + QVERIFY(tmpDir.isValid()); + m_profile->setDownloadPath(tmpDir.path()); + + // Set up HTTP server + ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { + if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) { + rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream")); + rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment")); + rr->setResponseBody(QByteArrayLiteral("a")); + rr->sendResponse(); + } else { + rr->setResponseStatus(404); + rr->sendResponse(); + } + }); + + // Set up profile and download handler + ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { + item->accept(); + connect(item, &QWebEngineDownloadItem::finished, [&, item]() { + QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted); + QCOMPARE(item->isFinished(), true); + QCOMPARE(item->totalBytes(), item->receivedBytes()); + QVERIFY(item->receivedBytes() > 0); + QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); + QCOMPARE(item->type(), QWebEngineDownloadItem::Attachment); + QCOMPARE(item->isSavePageDownload(), false); + downloadedFilePath = item->path(); + downloadFinished = true; + }); + }); + + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadFinished); + QVERIFY(QFile(downloadedFilePath).exists()); + QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + "." + extension); + + for (int i = 1; i <= 2; ++i) { + downloadFinished = false; + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadFinished); + QVERIFY(QFile(downloadedFilePath).exists()); + QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + " (" + QString::number(i) + ")." + extension); + } +} + +void tst_QWebEngineDownloadItem::downloadUniqueFileNameWithTimeStamp() +{ + // Set up HTTP server + QString baseName("test(1.test)"); + QString extension("txt"); + QString fileName = QString("%1.%2").arg(baseName).arg(extension); + QString downloadedFilePath; + bool downloadFinished = false; + + QTemporaryDir tmpDir; + QVERIFY(tmpDir.isValid()); + m_profile->setDownloadPath(tmpDir.path()); + + ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { + if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) { + rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream")); + rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment")); + rr->setResponseBody(QByteArrayLiteral("a")); + rr->sendResponse(); + } else { + rr->setResponseStatus(404); + rr->sendResponse(); + } + }); + + // Set up profile and download handler + ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { + item->accept(); + connect(item, &QWebEngineDownloadItem::finished, [&, item]() { + QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted); + QCOMPARE(item->isFinished(), true); + QCOMPARE(item->totalBytes(), item->receivedBytes()); + QVERIFY(item->receivedBytes() > 0); + QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); + QCOMPARE(item->page(), m_page); + downloadFinished = true; + downloadedFilePath = item->path(); + }); + }); + + // Create the first empty file without uniquifier. + { + QFile file(m_profile->downloadPath() + "/" + fileName); + file.open(QIODevice::ReadWrite); + } + + // Create 99 empty files with uniquifier. + for (int i = 1; i < 100; i++) { + QFile file(m_profile->downloadPath() + "/" + baseName + " (" + QString::number(i) + ")." + extension); + file.open(QIODevice::ReadWrite); + } + + // Create 100th (kMaxUniqueFiles) empty file with uniquifier. + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadFinished); + QVERIFY(QFile(downloadedFilePath).exists()); + QCOMPARE(downloadedFilePath, m_profile->downloadPath() + "/" + baseName + " (100)." + extension); + + // Check if the downloaded files are suffixed with timestamp after the 100th download. + for (int i = 101; i < 103; i++) { + downloadFinished = false; + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadFinished); + QVERIFY(QFile(downloadedFilePath).exists()); + QRegularExpression fileNameCheck("^.*" + QRegularExpression::escape(baseName) + " - (.*)[.]" + QRegularExpression::escape(extension) + "$"); + QRegularExpressionMatch match = fileNameCheck.match(downloadedFilePath); + QVERIFY(match.hasMatch()); + // ISO 8601 Date and time in UTC + QRegExp timeStamp("^(-?(?:[1-9][0-9]*)?[0-9]{4})-(1[0-2]|0[1-9])-(3[01]|0[1-9]|[12][0-9])T(2[0-3]|[01][0-9]):([0-5][0-9]):([0-5][0-9])([.][0-9]+)?(Z|[+-](?:2[0-3]|[01][0-9]):[0-5][0-9])?$"); + QVERIFY(timeStamp.exactMatch(match.captured(1))); + } +} + +void tst_QWebEngineDownloadItem::downloadToDefaultLocation() +{ + QTemporaryDir tmpDir; + QVERIFY(tmpDir.isValid()); + + QCOMPARE(m_profile->downloadPath(), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)); + + m_profile->setDownloadPath(""); + QCOMPARE(m_profile->downloadPath(), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)); + + m_profile->setDownloadPath(tmpDir.path()); + QCOMPARE(m_profile->downloadPath(), tmpDir.path()); + + m_profile->setDownloadPath(QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)); + QCOMPARE(m_profile->downloadPath(), QStandardPaths::writableLocation(QStandardPaths::DownloadLocation)); +} + +void tst_QWebEngineDownloadItem::downloadToNonExistentDir() +{ + QString baseName("test(1.test)"); + QString extension("txt"); + QString fileName = QString("%1.%2").arg(baseName).arg(extension); + QString downloadedFilePath; + bool downloadFinished = false; + + QTemporaryDir tmpDir; + QVERIFY(tmpDir.isValid()); + m_profile->setDownloadPath(tmpDir.path()); + + // Set up HTTP server + ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { + if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) { + rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream")); + rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment")); + rr->setResponseBody(QByteArrayLiteral("a")); + rr->sendResponse(); + } else { + rr->setResponseStatus(404); + rr->sendResponse(); + } + }); + + // Set up profile and download handler + ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { + item->accept(); + connect(item, &QWebEngineDownloadItem::finished, [&, item]() { + QCOMPARE(item->state(), QWebEngineDownloadItem::DownloadCompleted); + QCOMPARE(item->isFinished(), true); + QCOMPARE(item->totalBytes(), item->receivedBytes()); + QVERIFY(item->receivedBytes() > 0); + QCOMPARE(item->interruptReason(), QWebEngineDownloadItem::NoReason); + QCOMPARE(item->page(), m_page); + downloadFinished = true; + downloadedFilePath = item->path(); + }); + }); + + // Set a non-existent directory for the default download location. + QString nonExistentDownloadPath(m_profile->downloadPath() + "/non_existent_dir"); + m_profile->setDownloadPath(nonExistentDownloadPath); + QCOMPARE(m_profile->downloadPath(), nonExistentDownloadPath); + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadFinished); + QVERIFY(QFile(downloadedFilePath).exists()); + QCOMPARE(downloadedFilePath, nonExistentDownloadPath + "/" + fileName); +} + +void tst_QWebEngineDownloadItem::downloadToReadOnlyDir() +{ + QString baseName("test(1.test)"); + QString extension("txt"); + QString fileName = QString("%1.%2").arg(baseName).arg(extension); + QString downloadedFilePath; + bool downloadAccepted = false; + bool downloadFinished = false; + + QTemporaryDir tmpDir; + QVERIFY(tmpDir.isValid()); + m_profile->setDownloadPath(tmpDir.path()); + + // Set up HTTP server + ScopedConnection sc1 = connect(m_server, &HttpServer::newRequest, [&](HttpReqRep *rr) { + if (rr->requestMethod() == "GET" && rr->requestPath() == ("/" + fileName)) { + rr->setResponseHeader(QByteArrayLiteral("content-type"), QByteArrayLiteral("application/octet-stream")); + rr->setResponseHeader(QByteArrayLiteral("content-disposition"), QByteArrayLiteral("attachment")); + rr->setResponseBody(QByteArrayLiteral("a")); + rr->sendResponse(); + } else { + rr->setResponseStatus(404); + rr->sendResponse(); + } + }); + + QPointer<QWebEngineDownloadItem> downloadItem; + ScopedConnection sc2 = connect(m_profile, &QWebEngineProfile::downloadRequested, [&](QWebEngineDownloadItem *item) { + downloadItem = item; + item->accept(); + connect(item, &QWebEngineDownloadItem::finished, [&, item]() { + downloadFinished = true; + }); + downloadAccepted = true; + }); + + // Change permission for directory. + QFile(m_profile->downloadPath()).setPermissions(QFileDevice::ReadOwner); + QVERIFY(QFile(m_profile->downloadPath()).exists()); + + m_page->setUrl(m_server->url("/" + fileName)); + QTRY_VERIFY(downloadAccepted); + + QVERIFY(downloadItem); + QTRY_COMPARE(downloadItem->state(), QWebEngineDownloadItem::DownloadInterrupted); + QCOMPARE(downloadItem->isFinished(), false); + QCOMPARE(downloadItem->interruptReason(), QWebEngineDownloadItem::FileAccessDenied); + QVERIFY(!QFile(downloadedFilePath).exists()); + + // Clear m_requestedDownloads explicitly because download is accepted but never finished. + m_requestedDownloads.clear(); + QVERIFY(!downloadFinished); + QFile(m_profile->downloadPath()).setPermissions(QFileDevice::WriteOwner); +} + QTEST_MAIN(tst_QWebEngineDownloadItem) #include "tst_qwebenginedownloaditem.moc" diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST index 228efd61c..f3dc51fdd 100644 --- a/tests/auto/widgets/qwebenginepage/BLACKLIST +++ b/tests/auto/widgets/qwebenginepage/BLACKLIST @@ -1,9 +1,3 @@ -[comboBoxPopupPositionAfterMove] -* - -[comboBoxPopupPositionAfterChildMove] -* - [macCopyUnicodeToClipboard] osx diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 8c3b4002c..3792b5522 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -34,7 +34,6 @@ #include <QOpenGLWidget> #include <QPaintEngine> #include <QPushButton> -#include <QRegExp> #include <QScreen> #include <QStateMachine> #include <QtGui/QClipboard> @@ -50,6 +49,7 @@ #include <qwebenginedownloaditem.h> #include <qwebenginefullscreenrequest.h> #include <qwebenginehistory.h> +#include <qwebenginenotification.h> #include <qwebenginepage.h> #include <qwebengineprofile.h> #include <qwebenginequotarequest.h> @@ -90,11 +90,8 @@ public Q_SLOTS: private Q_SLOTS: void initTestCase(); void cleanupTestCase(); - void thirdPartyCookiePolicy(); void comboBoxPopupPositionAfterMove(); void comboBoxPopupPositionAfterChildMove(); - void contextMenuCopy(); - void contextMenuPopulatedOnce(); void acceptNavigationRequest(); void acceptNavigationRequestNavigationType(); void geolocationRequestJS_data(); @@ -103,26 +100,13 @@ private Q_SLOTS: void actionStates(); void pasteImage(); void popupFormSubmission(); - void userStyleSheet(); - void userStyleSheetFromLocalFileUrl(); - void userStyleSheetFromQrcUrl(); - void modified(); - void contextMenuCrash(); - void updatePositionDependentActionsCrash(); void callbackSpyDeleted(); void multipleProfilesAndLocalStorage(); - void cursorMovements(); void textSelection(); - void textEditing(); void backActionUpdate(); - void testOptionalJSObjects(); - void testLocalStorageVisibility(); - void testEnablePersistentStorage(); + void localStorageVisibility(); void consoleOutput(); - void errorPageExtension(); - void errorPageExtensionLoadFinished(); void userAgentNewlineStripping(); - void undoActionHaveCustomText(); void renderWidgetHostViewNotShowTopLevel(); void getUserMediaRequest_data(); void getUserMediaRequest(); @@ -134,30 +118,19 @@ private Q_SLOTS: void crashTests_LazyInitializationOfMainFrame(); - void screenshot_data(); - void screenshot(); - #if defined(ENABLE_WEBGL) && ENABLE_WEBGL void acceleratedWebGLScreenshotWithoutView(); void unacceleratedWebGLScreenshotWithoutView(); #endif void testJSPrompt(); - void testStopScheduledPageRefresh(); void findText(); void findTextResult(); void findTextSuccessiveShouldCallAllCallbacks(); - void supportedContentType(); - // [Qt] tst_QWebEnginePage::infiniteLoopJS() timeouts with DFG JIT - // https://bugs.webkit.org/show_bug.cgi?id=79040 - // void infiniteLoopJS(); void deleteQWebEngineViewTwice(); - void renderOnRepaintRequestedShouldNotRecurse(); void loadSignalsOrder_data(); void loadSignalsOrder(); void openWindowDefaultSize(); - void cssMediaTypeGlobalSetting(); - void cssMediaTypePageSetting(); #ifdef Q_OS_MAC void macCopyUnicodeToClipboard(); @@ -165,12 +138,12 @@ private Q_SLOTS: void runJavaScript(); void runJavaScriptDisabled(); + void runJavaScriptFromSlot(); void fullScreenRequested(); void quotaRequested(); // Tests from tst_QWebEngineFrame - void horizontalScrollAfterBack(); void symmetricUrl(); void progressSignal(); void urlChange(); @@ -182,8 +155,6 @@ private Q_SLOTS: void setHtmlWithStylesheetResource(); void setHtmlWithBaseURL(); void setHtmlWithJSAlert(); - void inputFieldFocus(); - void hitTestContent(); void baseUrl_data(); void baseUrl(); void scrollPosition(); @@ -191,7 +162,6 @@ private Q_SLOTS: void evaluateWillCauseRepaint(); void setContent_data(); void setContent(); - void setCacheLoadControlAttribute(); void setUrlWithPendingLoads(); void setUrlToEmpty(); void setUrlToInvalid(); @@ -227,6 +197,10 @@ private Q_SLOTS: void triggerActionWithoutMenu(); void dynamicFrame(); + void notificationRequest_data(); + void notificationRequest(); + void sendNotification(); + private: static QPoint elementCenter(QWebEnginePage *page, const QString &id); @@ -368,18 +342,6 @@ private: bool m_allowGeolocation; }; -// [Qt] tst_QWebEnginePage::infiniteLoopJS() timeouts with DFG JIT -// https://bugs.webkit.org/show_bug.cgi?id=79040 -/* -void tst_QWebEnginePage::infiniteLoopJS() -{ - JSTestPage newPage(m_view); - m_view->setPage(&newPage); - m_view->setHtml(QString("<html><body>test</body></html>"), QUrl()); - m_view->page()->evaluateJavaScript("var run = true; var a = 1; while (run) { a++; }"); -} -*/ - void tst_QWebEnginePage::geolocationRequestJS_data() { QTest::addColumn<bool>("allowed"); @@ -659,170 +621,6 @@ protected: } }; -void tst_QWebEnginePage::userStyleSheet() -{ -#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER) - QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER"); -#else - TestNetworkManager* networkManager = new TestNetworkManager(m_page); - m_page->setNetworkAccessManager(networkManager); - - m_page->settings()->setUserStyleSheetUrl(QUrl("data:text/css;charset=utf-8;base64," - + QByteArray("p { background-image: url('http://does.not/exist.png');}").toBase64())); - m_view->setHtml("<p>hello world</p>"); - QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished); - QVERIFY(spyFinished.wait()); - - QVERIFY(networkManager->requestedUrls.count() >= 1); - QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png")); -#endif -} - -void tst_QWebEnginePage::userStyleSheetFromLocalFileUrl() -{ -#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER) - QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER"); -#else - TestNetworkManager* networkManager = new TestNetworkManager(m_page); - m_page->setNetworkAccessManager(networkManager); - - QUrl styleSheetUrl = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginepage/resources/user.css")); - m_page->settings()->setUserStyleSheetUrl(styleSheetUrl); - m_view->setHtml("<p>hello world</p>"); - QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished); - QVERIFY(spyFinished.wait()); - - QVERIFY(networkManager->requestedUrls.count() >= 1); - QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png")); -#endif -} - -void tst_QWebEnginePage::userStyleSheetFromQrcUrl() -{ -#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER) - QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER"); -#else - TestNetworkManager* networkManager = new TestNetworkManager(m_page); - m_page->setNetworkAccessManager(networkManager); - - m_page->settings()->setUserStyleSheetUrl(QUrl("qrc:///resources/user.css")); - m_view->setHtml("<p>hello world</p>"); - QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished); - QVERIFY(spyFinished.wait()); - - QVERIFY(networkManager->requestedUrls.count() >= 1); - QCOMPARE(networkManager->requestedUrls.at(0), QUrl("http://does.not/exist.png")); -#endif -} - -void tst_QWebEnginePage::modified() -{ -#if !defined(QWEBENGINEPAGE_ISMODIFIED) - QSKIP("QWEBENGINEPAGE_ISMODIFIED"); -#else - m_page->setUrl(QUrl("data:text/html,<body>blub")); - QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished); - QVERIFY(spyFinished.wait()); - - m_page->setUrl(QUrl("data:text/html,<body id=foo contenteditable>blah")); - QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished); - QVERIFY(spyFinished.wait()); - - QVERIFY(!m_page->isModified()); - - m_page->runJavaScript("document.getElementById('foo').focus()"); - evaluateJavaScriptSync(m_page, "document.execCommand('InsertText', true, 'Test');"); - - QVERIFY(m_page->isModified()); - - evaluateJavaScriptSync(m_page, "document.execCommand('Undo', true);"); - - QVERIFY(!m_page->isModified()); - - evaluateJavaScriptSync(m_page, "document.execCommand('Redo', true);"); - - QVERIFY(m_page->isModified()); - - QVERIFY(m_page->history()->canGoBack()); - QVERIFY(!m_page->history()->canGoForward()); - QCOMPARE(m_page->history()->count(), 2); - QVERIFY(m_page->history()->backItem().isValid()); - QVERIFY(!m_page->history()->forwardItem().isValid()); - - m_page->history()->back(); - QSignalSpy spyFinished(m_view, &QWebEngineView::loadFinished); - QVERIFY(spyFinished.wait()); - - QVERIFY(!m_page->history()->canGoBack()); - QVERIFY(m_page->history()->canGoForward()); - - QVERIFY(!m_page->isModified()); - - QCOMPARE(m_page->history()->currentItemIndex(), 0); - - m_page->history()->setMaximumItemCount(3); - QCOMPARE(m_page->history()->maximumItemCount(), 3); - - QVariant variant("string test"); - m_page->history()->currentItem().setUserData(variant); - QVERIFY(m_page->history()->currentItem().userData().toString() == "string test"); - - m_page->setUrl(QUrl("data:text/html,<body>This is second page")); - m_page->setUrl(QUrl("data:text/html,<body>This is third page")); - QCOMPARE(m_page->history()->count(), 2); - m_page->setUrl(QUrl("data:text/html,<body>This is fourth page")); - QCOMPARE(m_page->history()->count(), 2); - m_page->setUrl(QUrl("data:text/html,<body>This is fifth page")); - QSignalSpy spy(m_page, &QWebEnginePage::saveFrameStateRequested); - QVERIFY(spy.wait()); -#endif -} - -// https://bugs.webkit.org/show_bug.cgi?id=51331 -void tst_QWebEnginePage::updatePositionDependentActionsCrash() -{ -#if !defined(QWEBENGINEPAGE_UPDATEPOSITIONDEPENDENTACTIONS) - QSKIP("QWEBENGINEPAGE_UPDATEPOSITIONDEPENDENTACTIONS"); -#else - QWebEngineView view; - view.setHtml("<p>test"); - QPoint pos(0, 0); - view.page()->updatePositionDependentActions(pos); - QMenu* contextMenu = 0; - const QList<QObject *> children = view.children(); - for (QObject *child : children) { - contextMenu = qobject_cast<QMenu*>(child); - if (contextMenu) - break; - } - QVERIFY(!contextMenu); -#endif -} - -// https://bugs.webkit.org/show_bug.cgi?id=20357 -void tst_QWebEnginePage::contextMenuCrash() -{ -#if !defined(QWEBENGINEPAGE_SWALLOWCONTEXTMENUEVENT) - QSKIP("QWEBENGINEPAGE_SWALLOWCONTEXTMENUEVENT"); -#else - QWebEngineView view; - view.setHtml("<p>test"); - QPoint pos(0, 0); - QContextMenuEvent event(QContextMenuEvent::Mouse, pos); - view.page()->swallowContextMenuEvent(&event); - view.page()->updatePositionDependentActions(pos); - QMenu* contextMenu = 0; - const QList<QObject *> children = view.children(); - for (QObject *child : children) { - contextMenu = qobject_cast<QMenu*>(child); - if (contextMenu) - break; - } - QVERIFY(contextMenu); - delete contextMenu; -#endif -} - void tst_QWebEnginePage::multipleProfilesAndLocalStorage() { QDir dir(tmpDirPath()); @@ -895,204 +693,6 @@ public: } }; -void tst_QWebEnginePage::cursorMovements() -{ -#if !defined(QWEBENGINEPAGE_SELECTEDTEXT) - QSKIP("QWEBENGINEPAGE_SELECTEDTEXT"); -#else - QScopedPointer<CursorTrackedPage> page(new CursorTrackedPage); - QString content("<html><body><p id=one>The quick brown fox</p><p id=two>jumps over the lazy dog</p><p>May the source<br/>be with you!</p></body></html>"); - page->setHtml(content); - - // this will select the first paragraph - QString script = "var range = document.createRange(); " \ - "var node = document.getElementById(\"one\"); " \ - "range.selectNode(node); " \ - "getSelection().addRange(range);"; - evaluateJavaScriptSync(page.data(), script); - QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox")); - - QRegExp regExp(" style=\".*\""); - regExp.setMinimal(true); - QCOMPARE(page->selectedHtml().trimmed().replace(regExp, ""), QString::fromLatin1("<p id=\"one\">The quick brown fox</p>")); - - // these actions must exist - QVERIFY(page->action(QWebEnginePage::MoveToNextChar) != 0); - QVERIFY(page->action(QWebEnginePage::MoveToPreviousChar) != 0); - QVERIFY(page->action(QWebEnginePage::MoveToNextWord) != 0); - QVERIFY(page->action(QWebEnginePage::MoveToPreviousWord) != 0); - QVERIFY(page->action(QWebEnginePage::MoveToNextLine) != 0); - QVERIFY(page->action(QWebEnginePage::MoveToPreviousLine) != 0); - QVERIFY(page->action(QWebEnginePage::MoveToStartOfLine) != 0); - QVERIFY(page->action(QWebEnginePage::MoveToEndOfLine) != 0); - QVERIFY(page->action(QWebEnginePage::MoveToStartOfBlock) != 0); - QVERIFY(page->action(QWebEnginePage::MoveToEndOfBlock) != 0); - QVERIFY(page->action(QWebEnginePage::MoveToStartOfDocument) != 0); - QVERIFY(page->action(QWebEnginePage::MoveToEndOfDocument) != 0); - - // right now they are disabled because contentEditable is false - QCOMPARE(page->action(QWebEnginePage::MoveToNextChar)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::MoveToPreviousChar)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::MoveToNextWord)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::MoveToPreviousWord)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::MoveToNextLine)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::MoveToPreviousLine)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::MoveToStartOfLine)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::MoveToEndOfLine)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::MoveToStartOfBlock)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::MoveToEndOfBlock)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::MoveToStartOfDocument)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::MoveToEndOfDocument)->isEnabled(), false); - - // make it editable before navigating the cursor - page->setContentEditable(true); - - // here the actions are enabled after contentEditable is true - QCOMPARE(page->action(QWebEnginePage::MoveToNextChar)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::MoveToPreviousChar)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::MoveToNextWord)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::MoveToPreviousWord)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::MoveToNextLine)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::MoveToPreviousLine)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::MoveToStartOfLine)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::MoveToEndOfLine)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::MoveToStartOfBlock)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::MoveToEndOfBlock)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::MoveToStartOfDocument)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::MoveToEndOfDocument)->isEnabled(), true); - - // cursor will be before the word "jump" - page->triggerAction(QWebEnginePage::MoveToNextChar); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 0); - - // cursor will be between 'j' and 'u' in the word "jump" - page->triggerAction(QWebEnginePage::MoveToNextChar); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 1); - - // cursor will be between 'u' and 'm' in the word "jump" - page->triggerAction(QWebEnginePage::MoveToNextChar); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 2); - - // cursor will be after the word "jump" - page->triggerAction(QWebEnginePage::MoveToNextWord); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 5); - - // cursor will be after the word "lazy" - page->triggerAction(QWebEnginePage::MoveToNextWord); - page->triggerAction(QWebEnginePage::MoveToNextWord); - page->triggerAction(QWebEnginePage::MoveToNextWord); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 19); - - // cursor will be between 'z' and 'y' in "lazy" - page->triggerAction(QWebEnginePage::MoveToPreviousChar); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 18); - - // cursor will be between 'a' and 'z' in "lazy" - page->triggerAction(QWebEnginePage::MoveToPreviousChar); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 17); - - // cursor will be before the word "lazy" - page->triggerAction(QWebEnginePage::MoveToPreviousWord); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 15); - - // cursor will be before the word "quick" - page->triggerAction(QWebEnginePage::MoveToPreviousWord); - page->triggerAction(QWebEnginePage::MoveToPreviousWord); - page->triggerAction(QWebEnginePage::MoveToPreviousWord); - page->triggerAction(QWebEnginePage::MoveToPreviousWord); - page->triggerAction(QWebEnginePage::MoveToPreviousWord); - page->triggerAction(QWebEnginePage::MoveToPreviousWord); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 4); - - // cursor will be between 'p' and 's' in the word "jumps" - page->triggerAction(QWebEnginePage::MoveToNextWord); - page->triggerAction(QWebEnginePage::MoveToNextWord); - page->triggerAction(QWebEnginePage::MoveToNextWord); - page->triggerAction(QWebEnginePage::MoveToNextChar); - page->triggerAction(QWebEnginePage::MoveToNextChar); - page->triggerAction(QWebEnginePage::MoveToNextChar); - page->triggerAction(QWebEnginePage::MoveToNextChar); - page->triggerAction(QWebEnginePage::MoveToNextChar); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 4); - - // cursor will be before the word "jumps" - page->triggerAction(QWebEnginePage::MoveToStartOfLine); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 0); - - // cursor will be after the word "dog" - page->triggerAction(QWebEnginePage::MoveToEndOfLine); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 23); - - // cursor will be between 'w' and 'n' in "brown" - page->triggerAction(QWebEnginePage::MoveToStartOfLine); - page->triggerAction(QWebEnginePage::MoveToPreviousWord); - page->triggerAction(QWebEnginePage::MoveToPreviousWord); - page->triggerAction(QWebEnginePage::MoveToNextChar); - page->triggerAction(QWebEnginePage::MoveToNextChar); - page->triggerAction(QWebEnginePage::MoveToNextChar); - page->triggerAction(QWebEnginePage::MoveToNextChar); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 14); - - // cursor will be after the word "fox" - page->triggerAction(QWebEnginePage::MoveToEndOfLine); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 19); - - // cursor will be before the word "The" - page->triggerAction(QWebEnginePage::MoveToStartOfDocument); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 0); - - // cursor will be after the word "you!" - page->triggerAction(QWebEnginePage::MoveToEndOfDocument); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 12); - - // cursor will be before the word "be" - page->triggerAction(QWebEnginePage::MoveToStartOfBlock); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 0); - - // cursor will be after the word "you!" - page->triggerAction(QWebEnginePage::MoveToEndOfBlock); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 12); - - // try to move before the document start - page->triggerAction(QWebEnginePage::MoveToStartOfDocument); - page->triggerAction(QWebEnginePage::MoveToPreviousChar); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 0); - page->triggerAction(QWebEnginePage::MoveToStartOfDocument); - page->triggerAction(QWebEnginePage::MoveToPreviousWord); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 0); - - // try to move past the document end - page->triggerAction(QWebEnginePage::MoveToEndOfDocument); - page->triggerAction(QWebEnginePage::MoveToNextChar); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 12); - page->triggerAction(QWebEnginePage::MoveToEndOfDocument); - page->triggerAction(QWebEnginePage::MoveToNextWord); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 12); -#endif -} - void tst_QWebEnginePage::textSelection() { QWebEngineView view; @@ -1107,35 +707,6 @@ void tst_QWebEnginePage::textSelection() // these actions must exist QVERIFY(page->action(QWebEnginePage::SelectAll) != 0); -#if defined(QWEBENGINEPAGE_SELECTACTIONS) - QVERIFY(page->action(QWebEnginePage::SelectNextChar) != 0); - QVERIFY(page->action(QWebEnginePage::SelectPreviousChar) != 0); - QVERIFY(page->action(QWebEnginePage::SelectNextWord) != 0); - QVERIFY(page->action(QWebEnginePage::SelectPreviousWord) != 0); - QVERIFY(page->action(QWebEnginePage::SelectNextLine) != 0); - QVERIFY(page->action(QWebEnginePage::SelectPreviousLine) != 0); - QVERIFY(page->action(QWebEnginePage::SelectStartOfLine) != 0); - QVERIFY(page->action(QWebEnginePage::SelectEndOfLine) != 0); - QVERIFY(page->action(QWebEnginePage::SelectStartOfBlock) != 0); - QVERIFY(page->action(QWebEnginePage::SelectEndOfBlock) != 0); - QVERIFY(page->action(QWebEnginePage::SelectStartOfDocument) != 0); - QVERIFY(page->action(QWebEnginePage::SelectEndOfDocument) != 0); - - // right now they are disabled because contentEditable is false and - // there isn't an existing selection to modify - QCOMPARE(page->action(QWebEnginePage::SelectNextChar)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SelectPreviousChar)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SelectNextWord)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SelectPreviousWord)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SelectNextLine)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SelectPreviousLine)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SelectStartOfLine)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SelectEndOfLine)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SelectStartOfBlock)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), false); -#endif // ..but SelectAll is awalys enabled QCOMPARE(page->action(QWebEnginePage::SelectAll)->isEnabled(), true); @@ -1150,173 +721,10 @@ void tst_QWebEnginePage::textSelection() "getSelection().addRange(range);"; evaluateJavaScriptSync(page, selectScript); QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox")); -#if defined(QWEBENGINEPAGE_SELECTEDHTML) - QRegExp regExp(" style=\".*\""); - regExp.setMinimal(true); - QCOMPARE(page->selectedHtml().trimmed().replace(regExp, ""), QString::fromLatin1("<p id=\"one\">The quick brown fox</p>")); -#endif // Make sure hasSelection returns true, since there is selected text now... QCOMPARE(page->hasSelection(), true); - -#if defined(QWEBENGINEPAGE_SELECTACTIONS) - // here the actions are enabled after a selection has been created - QCOMPARE(page->action(QWebEnginePage::SelectNextChar)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectPreviousChar)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectNextWord)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectPreviousWord)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectNextLine)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectPreviousLine)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectStartOfLine)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectEndOfLine)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectStartOfBlock)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), true); - - // make it editable before navigating the cursor - page->setContentEditable(true); - - // cursor will be before the word "The", this makes sure there is a charet - page->triggerAction(QWebEnginePage::MoveToStartOfDocument); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 0); - - // here the actions are enabled after contentEditable is true - QCOMPARE(page->action(QWebEnginePage::SelectNextChar)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectPreviousChar)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectNextWord)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectPreviousWord)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectNextLine)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectPreviousLine)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectStartOfLine)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectEndOfLine)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectStartOfBlock)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), true); -#endif } -void tst_QWebEnginePage::textEditing() -{ -#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT) - QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT"); -#else - QScopedPointer<CursorTrackedPage> page(new CursorTrackedPage); - QString content("<html><body><p id=one>The quick brown fox</p>" \ - "<p id=two>jumps over the lazy dog</p>" \ - "<p>May the source<br/>be with you!</p></body></html>"); - page->setHtml(content); - - // these actions must exist - QVERIFY(page->action(QWebEnginePage::Cut) != 0); - QVERIFY(page->action(QWebEnginePage::Copy) != 0); - QVERIFY(page->action(QWebEnginePage::Paste) != 0); - QVERIFY(page->action(QWebEnginePage::DeleteStartOfWord) != 0); - QVERIFY(page->action(QWebEnginePage::DeleteEndOfWord) != 0); - QVERIFY(page->action(QWebEnginePage::SetTextDirectionDefault) != 0); - QVERIFY(page->action(QWebEnginePage::SetTextDirectionLeftToRight) != 0); - QVERIFY(page->action(QWebEnginePage::SetTextDirectionRightToLeft) != 0); - QVERIFY(page->action(QWebEnginePage::ToggleBold) != 0); - QVERIFY(page->action(QWebEnginePage::ToggleItalic) != 0); - QVERIFY(page->action(QWebEnginePage::ToggleUnderline) != 0); - QVERIFY(page->action(QWebEnginePage::InsertParagraphSeparator) != 0); - QVERIFY(page->action(QWebEnginePage::InsertLineSeparator) != 0); - QVERIFY(page->action(QWebEnginePage::PasteAndMatchStyle) != 0); - QVERIFY(page->action(QWebEnginePage::RemoveFormat) != 0); - QVERIFY(page->action(QWebEnginePage::ToggleStrikethrough) != 0); - QVERIFY(page->action(QWebEnginePage::ToggleSubscript) != 0); - QVERIFY(page->action(QWebEnginePage::ToggleSuperscript) != 0); - QVERIFY(page->action(QWebEnginePage::InsertUnorderedList) != 0); - QVERIFY(page->action(QWebEnginePage::InsertOrderedList) != 0); - QVERIFY(page->action(QWebEnginePage::Indent) != 0); - QVERIFY(page->action(QWebEnginePage::Outdent) != 0); - QVERIFY(page->action(QWebEnginePage::AlignCenter) != 0); - QVERIFY(page->action(QWebEnginePage::AlignJustified) != 0); - QVERIFY(page->action(QWebEnginePage::AlignLeft) != 0); - QVERIFY(page->action(QWebEnginePage::AlignRight) != 0); - - // right now they are disabled because contentEditable is false - QCOMPARE(page->action(QWebEnginePage::Cut)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::Paste)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::DeleteStartOfWord)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::DeleteEndOfWord)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SetTextDirectionDefault)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SetTextDirectionLeftToRight)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::SetTextDirectionRightToLeft)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::ToggleBold)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::ToggleItalic)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::ToggleUnderline)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::InsertParagraphSeparator)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::InsertLineSeparator)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::PasteAndMatchStyle)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::RemoveFormat)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::ToggleStrikethrough)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::ToggleSubscript)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::ToggleSuperscript)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::InsertUnorderedList)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::InsertOrderedList)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::Indent)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::Outdent)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::AlignCenter)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::AlignJustified)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::AlignLeft)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::AlignRight)->isEnabled(), false); - - // Select everything - page->triggerAction(QWebEnginePage::SelectAll); - - // make sure it is enabled since there is a selection - QCOMPARE(page->action(QWebEnginePage::Copy)->isEnabled(), true); - - // make it editable before navigating the cursor - page->setContentEditable(true); - - // clear the selection - page->triggerAction(QWebEnginePage::MoveToStartOfDocument); - QVERIFY(page->isSelectionCollapsed()); - QCOMPARE(page->selectionStartOffset(), 0); - - // make sure it is disabled since there isn't a selection - QCOMPARE(page->action(QWebEnginePage::Copy)->isEnabled(), false); - - // here the actions are enabled after contentEditable is true - QCOMPARE(page->action(QWebEnginePage::Paste)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::DeleteStartOfWord)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::DeleteEndOfWord)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SetTextDirectionDefault)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SetTextDirectionLeftToRight)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::SetTextDirectionRightToLeft)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::ToggleBold)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::ToggleItalic)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::ToggleUnderline)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::InsertParagraphSeparator)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::InsertLineSeparator)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::PasteAndMatchStyle)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::ToggleStrikethrough)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::ToggleSubscript)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::ToggleSuperscript)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::InsertUnorderedList)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::InsertOrderedList)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::Indent)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::Outdent)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::AlignCenter)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::AlignJustified)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::AlignLeft)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::AlignRight)->isEnabled(), true); - - // make sure these are disabled since there isn't a selection - QCOMPARE(page->action(QWebEnginePage::Cut)->isEnabled(), false); - QCOMPARE(page->action(QWebEnginePage::RemoveFormat)->isEnabled(), false); - - // make sure everything is selected - page->triggerAction(QWebEnginePage::SelectAll); - - // this is only true if there is an editable selection - QCOMPARE(page->action(QWebEnginePage::Cut)->isEnabled(), true); - QCOMPARE(page->action(QWebEnginePage::RemoveFormat)->isEnabled(), true); -#endif -} void tst_QWebEnginePage::backActionUpdate() { @@ -1337,243 +745,39 @@ void tst_QWebEnginePage::backActionUpdate() QVERIFY(action->isEnabled()); } -#if defined(QWEBENGINEPAGE_SETTINGS) -static inline bool testFlag(QWebEnginePage& webPage, QWebEngineSettings::WebAttribute settingAttribute, const QString& jsObjectName, bool settingValue) +void tst_QWebEnginePage::localStorageVisibility() { - webPage.settings()->setAttribute(settingAttribute, settingValue); - return evaluateJavaScriptSync(&webPage, QString("(window.%1 != undefined)").arg(jsObjectName)).toBool(); -} -#endif - -void tst_QWebEnginePage::testOptionalJSObjects() -{ -#if !defined(QWEBENGINESETTINGS) - QSKIP("QWEBENGINSETTINGS"); -#else - // Once a feature is enabled and the JS object is accessed turning off the setting will not turn off - // the visibility of the JS object any more. For this reason this test uses two QWebEnginePage instances. - // Part of the test is to make sure that the QWebEnginePage instances do not interfere with each other so turning on - // a feature for one instance will not turn it on for another. - - QWebEnginePage webPage1; - QWebEnginePage webPage2; - - webPage1.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/")); - webPage2.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/")); - - QEXPECT_FAIL("","Feature enabled/disabled checking problem. Look at bugs.webkit.org/show_bug.cgi?id=29867", Continue); - QCOMPARE(testFlag(webPage1, QWebEngineSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), false); - QCOMPARE(testFlag(webPage2, QWebEngineSettings::OfflineWebApplicationCacheEnabled, "applicationCache", true), true); - QEXPECT_FAIL("","Feature enabled/disabled checking problem. Look at bugs.webkit.org/show_bug.cgi?id=29867", Continue); - QCOMPARE(testFlag(webPage1, QWebEngineSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), false); - QCOMPARE(testFlag(webPage2, QWebEngineSettings::OfflineWebApplicationCacheEnabled, "applicationCache", false), true); - - QCOMPARE(testFlag(webPage1, QWebEngineSettings::LocalStorageEnabled, "localStorage", false), false); - QCOMPARE(testFlag(webPage2, QWebEngineSettings::LocalStorageEnabled, "localStorage", true), true); - QCOMPARE(testFlag(webPage1, QWebEngineSettings::LocalStorageEnabled, "localStorage", false), false); - QCOMPARE(testFlag(webPage2, QWebEngineSettings::LocalStorageEnabled, "localStorage", false), true); -#endif -} - -#if defined(QWEBENGINEPAGE_SETTINGS) -static inline bool checkLocalStorageVisibility(QWebEnginePage& webPage, bool localStorageEnabled) -{ - webPage.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, localStorageEnabled); - return evaluateJavaScriptSync(&webPage, QString("(window.localStorage != undefined)")).toBool(); -} -#endif - -void tst_QWebEnginePage::testLocalStorageVisibility() -{ -#if !defined(QWEBENGINEPAGE_SETTINGS) - QSKIP("QWEBENGINEPAGE_SETTINGS"); -#else - // Local storage's visibility depends on its security origin, which depends on base url. - // Initially, it will test it with base urls that get a globally unique origin, which may not - // be able to use local storage even if the feature is enabled. Then later the same test is - // done but with urls that would get a valid origin, so local storage could be used. - // Before every test case it checks if local storage is not already visible. - - QWebEnginePage webPage; - - webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl()); - - QCOMPARE(checkLocalStorageVisibility(webPage, false), false); - QCOMPARE(checkLocalStorageVisibility(webPage, true), false); - - webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("invalid")); - - QCOMPARE(checkLocalStorageVisibility(webPage, false), false); - QCOMPARE(checkLocalStorageVisibility(webPage, true), false); - - webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("://misparsed.com")); - - QCOMPARE(checkLocalStorageVisibility(webPage, false), false); - QCOMPARE(checkLocalStorageVisibility(webPage, true), false); - - webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("http://")); - - QCOMPARE(checkLocalStorageVisibility(webPage, false), false); - QCOMPARE(checkLocalStorageVisibility(webPage, true), false); - - webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("about:blank")); - - QCOMPARE(checkLocalStorageVisibility(webPage, false), false); - QCOMPARE(checkLocalStorageVisibility(webPage, true), false); - - webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("data:text/html,test")); - - QCOMPARE(checkLocalStorageVisibility(webPage, false), false); - QCOMPARE(checkLocalStorageVisibility(webPage, true), false); - - webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("file:///")); - - QCOMPARE(checkLocalStorageVisibility(webPage, false), false); - QCOMPARE(checkLocalStorageVisibility(webPage, true), true); - - webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com")); - - QCOMPARE(checkLocalStorageVisibility(webPage, false), false); - QCOMPARE(checkLocalStorageVisibility(webPage, true), true); - - webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("https://www.example.com")); - - QCOMPARE(checkLocalStorageVisibility(webPage, false), false); - QCOMPARE(checkLocalStorageVisibility(webPage, true), true); - - webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("ftp://files.example.com")); - - QCOMPARE(checkLocalStorageVisibility(webPage, false), false); - QCOMPARE(checkLocalStorageVisibility(webPage, true), true); - - webPage.currentFrame()->setHtml(QString("<html><body>test</body></html>"), QUrl("file:///path/to/index.html")); - - QCOMPARE(checkLocalStorageVisibility(webPage, false), false); - QCOMPARE(checkLocalStorageVisibility(webPage, true), true); -#endif -} - -void tst_QWebEnginePage::testEnablePersistentStorage() -{ -#if !defined(QWEBENGINESETTINGS) - QSKIP("QWEBENGINESETTINGS"); -#else - QWebEnginePage webPage; - - // By default all persistent options should be disabled - QCOMPARE(webPage.settings()->testAttribute(QWebEngineSettings::LocalStorageEnabled), false); - QCOMPARE(webPage.settings()->testAttribute(QWebEngineSettings::OfflineStorageDatabaseEnabled), false); - QCOMPARE(webPage.settings()->testAttribute(QWebEngineSettings::OfflineWebApplicationCacheEnabled), false); - QVERIFY(webPage.settings()->iconDatabasePath().isEmpty()); - - QWebEngineSettings::enablePersistentStorage(); - - - QTRY_COMPARE(webPage.settings()->testAttribute(QWebEngineSettings::LocalStorageEnabled), true); - QTRY_COMPARE(webPage.settings()->testAttribute(QWebEngineSettings::OfflineStorageDatabaseEnabled), true); - QTRY_COMPARE(webPage.settings()->testAttribute(QWebEngineSettings::OfflineWebApplicationCacheEnabled), true); - - QTRY_VERIFY(!webPage.settings()->offlineStoragePath().isEmpty()); - QTRY_VERIFY(!webPage.settings()->offlineWebApplicationCachePath().isEmpty()); - QTRY_VERIFY(!webPage.settings()->iconDatabasePath().isEmpty()); -#endif -} - - -#if defined(QWEBENGINEPAGE_ERRORPAGEEXTENSION) -class ErrorPage : public QWebEnginePage -{ -public: - - ErrorPage(QWidget* parent = 0): QWebEnginePage(parent) - { - } - - virtual bool supportsExtension(Extension extension) const - { - return extension == ErrorPageExtension; - } - - virtual bool extension(Extension, const ExtensionOption* option, ExtensionReturn* output) - { - ErrorPageExtensionReturn* errorPage = static_cast<ErrorPageExtensionReturn*>(output); - - errorPage->contentType = "text/html"; - errorPage->content = "error"; - return true; - } -}; -#endif - -void tst_QWebEnginePage::errorPageExtension() -{ -#if !defined(QWEBENGINEPAGE_ERRORPAGEEXTENSION) - QSKIP("QWEBENGINEPAGE_ERRORPAGEEXTENSION"); -#else - ErrorPage page; - m_view->setPage(&page); - - QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool))); - - m_view->setUrl(QUrl("data:text/html,foo")); - QTRY_COMPARE(spyLoadFinished.count(), 1); - - page.setUrl(QUrl("http://non.existent/url")); - QTRY_COMPARE(spyLoadFinished.count(), 2); - QCOMPARE(toPlainTextSync(&page), QString("error")); - QCOMPARE(page.history()->count(), 2); - QCOMPARE(page.history()->currentItem().url(), QUrl("http://non.existent/url")); - QCOMPARE(page.history()->canGoBack(), true); - QCOMPARE(page.history()->canGoForward(), false); - - page.triggerAction(QWebEnginePage::Back); - QTRY_COMPARE(page.history()->canGoBack(), false); - QTRY_COMPARE(page.history()->canGoForward(), true); - - page.triggerAction(QWebEnginePage::Forward); - QTRY_COMPARE(page.history()->canGoBack(), true); - QTRY_COMPARE(page.history()->canGoForward(), false); - - page.triggerAction(QWebEnginePage::Back); - QTRY_COMPARE(page.history()->canGoBack(), false); - QTRY_COMPARE(page.history()->canGoForward(), true); - QTRY_COMPARE(page.history()->currentItem().url(), QUrl("data:text/html,foo")); - - m_view->setPage(0); -#endif -} - -void tst_QWebEnginePage::errorPageExtensionLoadFinished() -{ -#if !defined(QWEBENGINEPAGE_ERRORPAGEEXTENSION) - QSKIP("QWEBENGINEPAGE_ERRORPAGEEXTENSION"); -#else - ErrorPage page; - m_view->setPage(&page); - - QSignalSpy spyLoadFinished(m_view, SIGNAL(loadFinished(bool))); - QSignalSpy spyFrameLoadFinished(m_view->page(), SIGNAL(loadFinished(bool))); - - m_view->setUrl(QUrl("data:text/html,foo")); - QTRY_COMPARE(spyLoadFinished.count(), 1); - QTRY_COMPARE(spyFrameLoadFinished.count(), 1); - - const bool loadSucceded = spyLoadFinished.at(0).at(0).toBool(); - QVERIFY(loadSucceded); - const bool frameLoadSucceded = spyFrameLoadFinished.at(0).at(0).toBool(); - QVERIFY(frameLoadSucceded); - - m_view->page()->setUrl(QUrl("http://non.existent/url")); - QTRY_COMPARE(spyLoadFinished.count(), 2); - QTRY_COMPARE(spyFrameLoadFinished.count(), 2); - - const bool nonExistantLoadSucceded = spyLoadFinished.at(1).at(0).toBool(); - QVERIFY(nonExistantLoadSucceded); - const bool nonExistantFrameLoadSucceded = spyFrameLoadFinished.at(1).at(0).toBool(); - QVERIFY(nonExistantFrameLoadSucceded); - - m_view->setPage(0); -#endif + QWebEngineProfile profile; + QWebEnginePage webPage1(&profile); + QWebEnginePage webPage2(&profile); + + webPage1.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); + webPage2.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, false); + + QSignalSpy loadSpy1(&webPage1, &QWebEnginePage::loadFinished); + QSignalSpy loadSpy2(&webPage2, &QWebEnginePage::loadFinished); + webPage1.setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/")); + webPage2.setHtml(QString("<html><body>test</body></html>"), QUrl("http://www.example.com/")); + QTRY_COMPARE(loadSpy1.count(), 1); + QTRY_COMPARE(loadSpy2.count(), 1); + + // The attribute determines the visibility of the window.localStorage object. + QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool()); + QVERIFY(!evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool()); + + // Switching the feature off does not actively remove the object from webPage1. + webPage1.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, false); + webPage2.settings()->setAttribute(QWebEngineSettings::LocalStorageEnabled, true); + QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool()); + QVERIFY(evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool()); + + // The object disappears only after reloading. + webPage1.triggerAction(QWebEnginePage::Reload); + webPage2.triggerAction(QWebEnginePage::Reload); + QTRY_COMPARE(loadSpy1.count(), 2); + QTRY_COMPARE(loadSpy2.count(), 2); + QVERIFY(!evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool()); + QVERIFY(evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool()); } void tst_QWebEnginePage::userAgentNewlineStripping() @@ -1598,70 +802,9 @@ void tst_QWebEnginePage::crashTests_LazyInitializationOfMainFrame() webPage.selectedText(); } { -#if defined(QWEBENGINEPAGE_SELECTEDHTML) - QWebEnginePage webPage; - webPage.selectedHtml(); -#endif - } - { QWebEnginePage webPage; webPage.triggerAction(QWebEnginePage::Back, true); } - { -#if defined(QWEBENGINEPAGE_UPDATEPOSITIONDEPENDENTACTIONS) - QWebEnginePage webPage; - QPoint pos(10,10); - webPage.updatePositionDependentActions(pos); -#endif - } -} - -#if defined(QWEBENGINEPAGE_RENDER) -static void takeScreenshot(QWebEnginePage* page) -{ - page->setViewportSize(page->contentsSize()); - QImage image(page->viewportSize(), QImage::Format_ARGB32); - QPainter painter(&image); - page->render(&painter); - painter.end(); -} -#endif - -void tst_QWebEnginePage::screenshot_data() -{ - QTest::addColumn<QString>("html"); - QTest::newRow("WithoutPlugin") << "<html><body id='b'>text</body></html>"; - QTest::newRow("WindowedPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf'></embed></body></html>"); - QTest::newRow("WindowlessPlugin") << QString("<html><body id='b'>text<embed src='resources/test.swf' wmode='transparent'></embed></body></html>"); -} - -void tst_QWebEnginePage::screenshot() -{ -#if !defined(QWEBENGINESETTINGS) - QSKIP("QWEBENGINESETTINGS"); -#else - if (!QDir(TESTS_SOURCE_DIR).exists()) - W_QSKIP(QString("This test requires access to resources found in '%1'").arg(TESTS_SOURCE_DIR).toLatin1().constData(), SkipAll); - - QDir::setCurrent(TESTS_SOURCE_DIR); - - QFETCH(QString, html); - QWebEnginePage page; - page.settings()->setAttribute(QWebEngineSettings::PluginsEnabled, true); - page.setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR)); - QVERIFY(spyFinished.wait(2000)); - - // take screenshot without a view - takeScreenshot(&page); - - QWebEngineView view; - view.setPage(&page); - - // take screenshot when attached to a view - takeScreenshot(&page); - - QDir::setCurrent(QApplication::applicationDirPath()); -#endif } #if defined(ENABLE_WEBGL) && ENABLE_WEBGL @@ -1760,37 +903,6 @@ void tst_QWebEnginePage::testJSPrompt() QVERIFY(res); } -void tst_QWebEnginePage::testStopScheduledPageRefresh() -{ -#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER) - QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER"); -#else - // Without QWebEnginePage::StopScheduledPageRefresh - QWebEnginePage page1; - page1.setNetworkAccessManager(new TestNetworkManager(&page1)); - page1.setHtml("<html><head>" - "<meta http-equiv=\"refresh\"content=\"0;URL=qrc:///resources/index.html\">" - "</head><body><h1>Page redirects immediately...</h1>" - "</body></html>"); - QSignalSpy spyFinished(&page1, &QWebEnginePage::loadFinished); - QVERIFY(spyFinished.wait(); - QTest::qWait(500); - QCOMPARE(page1.url(), QUrl(QLatin1String("qrc:///resources/index.html"))); - - // With QWebEnginePage::StopScheduledPageRefresh - QWebEnginePage page2; - page2.setNetworkAccessManager(new TestNetworkManager(&page2)); - page2.setHtml("<html><head>" - "<meta http-equiv=\"refresh\"content=\"1;URL=qrc:///resources/index.html\">" - "</head><body><h1>Page redirect test with 1 sec timeout...</h1>" - "</body></html>"); - page2.triggerAction(QWebEnginePage::StopScheduledPageRefresh); - QTest::qWait(1500); - QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118673", Continue); - QCOMPARE(page2.url().toString(), QLatin1String("about:blank")); -#endif -} - void tst_QWebEnginePage::findText() { QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool))); @@ -1890,95 +1002,6 @@ void tst_QWebEnginePage::findTextSuccessiveShouldCallAllCallbacks() QVERIFY(spy5.wasCalled()); } -#if defined(QWEBENGINEPAGE_SUPPORTEDCONTENTTYPES) -static QString getMimeTypeForExtension(const QString &ext) -{ - QMimeType mimeType = QMimeDatabase().mimeTypeForFile(QStringLiteral("filename.") + ext.toLower(), QMimeDatabase::MatchExtension); - if (mimeType.isValid() && !mimeType.isDefault()) - return mimeType.name(); - - return QString(); -} -#endif - -void tst_QWebEnginePage::supportedContentType() -{ -#if !defined(QWEBENGINEPAGE_SUPPORTEDCONTENTTYPES) - QSKIP("QWEBENGINEPAGE_SUPPORTEDCONTENTTYPES"); -#else - QStringList contentTypes; - - // Add supported non image types... - contentTypes << "text/html" << "text/xml" << "text/xsl" << "text/plain" << "text/" - << "application/xml" << "application/xhtml+xml" << "application/vnd.wap.xhtml+xml" - << "application/rss+xml" << "application/atom+xml" << "application/json"; - -#if ENABLE_MHTML - contentTypes << "application/x-mimearchive"; -#endif - - // Add supported image types... - const QList<QByteArray> supportedImageFormats = QImageWriter::supportedImageFormats(); - for (const QByteArray &imageType : supportedImageFormats) { - const QString mimeType = getMimeTypeForExtension(imageType); - if (!mimeType.isEmpty()) - contentTypes << mimeType; - } - - // Get the mime types supported by webengine... - const QStringList supportedContentTypes = m_page->supportedContentTypes(); - - for (const QString &mimeType : qAsConst(contentTypes)) - QVERIFY2(supportedContentTypes.contains(mimeType), QString("'%1' is not a supported content type!").arg(mimeType).toLatin1()); - - for (const QString &mimeType : qAsConst(contentTypes)) - QVERIFY2(m_page->supportsContentType(mimeType), QString("Cannot handle content types '%1'!").arg(mimeType).toLatin1()); -#endif -} - -void tst_QWebEnginePage::thirdPartyCookiePolicy() -{ -#if !defined(DUMPRENDERTREESUPPORTQT) - QSKIP("DUMPRENDERTREESUPPORTQT"); -#else - QWebEngineSettings::globalSettings()->setThirdPartyCookiePolicy(QWebEngineSettings::AlwaysBlockThirdPartyCookies); - m_page->networkAccessManager()->setCookieJar(new QNetworkCookieJar()); - QVERIFY(m_page->networkAccessManager()->cookieJar()); - - // These are all first-party cookies, so should pass. - QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://www.example.com"), QUrl("http://example.com"))); - QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://www.example.com"), QUrl("http://doc.example.com"))); - QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://aaa.www.example.com"), QUrl("http://doc.example.com"))); - QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://example.com"), QUrl("http://www.example.com"))); - QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://www.example.co.uk"), QUrl("http://example.co.uk"))); - QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://www.example.co.uk"), QUrl("http://doc.example.co.uk"))); - QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://aaa.www.example.co.uk"), QUrl("http://doc.example.co.uk"))); - QVERIFY(DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://example.co.uk"), QUrl("http://www.example.co.uk"))); - - // These are all third-party cookies, so should fail. - QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://www.example.com"), QUrl("http://slashdot.org"))); - QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://example.com"), QUrl("http://anotherexample.com"))); - QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://anotherexample.com"), QUrl("http://example.com"))); - QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://www.example.co.uk"), QUrl("http://slashdot.co.uk"))); - QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://example.co.uk"), QUrl("http://anotherexample.co.uk"))); - QVERIFY(!DumpRenderTreeSupportQt::thirdPartyCookiePolicyAllows(m_page->handle(), - QUrl("http://anotherexample.co.uk"), QUrl("http://example.co.uk"))); -#endif -} - static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows) { const auto tlws = QGuiApplication::topLevelWindows(); @@ -1992,9 +1015,8 @@ static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows) void tst_QWebEnginePage::comboBoxPopupPositionAfterMove() { - QScreen *screen = QGuiApplication::primaryScreen(); QWebEngineView view; - view.move(screen->availableGeometry().topLeft()); + view.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft()); view.resize(640, 480); view.show(); @@ -2010,18 +1032,29 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove() QWindow *popup = nullptr; QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws)); + QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup)); + QTRY_VERIFY(!popup->position().isNull()); QPoint popupPos = popup->position(); // Close the popup by clicking somewhere into the page. QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(1, 1)); QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup)); + auto jsViewPosition = [&view]() { + QLatin1String script("(function() { return [window.screenX, window.screenY]; })()"); + QVariantList posList = evaluateJavaScriptSync(view.page(), script).toList(); + return QPoint(posList.at(0).toInt(), posList.at(1).toInt()); + }; + // Move the top-level QWebEngineView a little and check the popup's position. const QPoint offset(12, 13); - view.move(screen->availableGeometry().topLeft() + offset); + view.move(view.pos() + offset); + QTRY_COMPARE(jsViewPosition(), view.pos()); QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), elementCenter(view.page(), "foo")); QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws)); + QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup)); + QTRY_VERIFY(!popup->position().isNull()); QCOMPARE(popupPos + offset, popup->position()); } @@ -2031,7 +1064,6 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove() mainWidget.setLayout(new QHBoxLayout); QWidget spacer; - spacer.setMinimumWidth(50); mainWidget.layout()->addWidget(&spacer); QWebEngineView view; @@ -2054,6 +1086,8 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove() QWindow *popup = nullptr; QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws)); + QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup)); + QTRY_VERIFY(!popup->position().isNull()); QPoint popupPos = popup->position(); // Close the popup by clicking somewhere into the page. @@ -2061,11 +1095,22 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove() view.mapTo(view.window(), QPoint(1, 1))); QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup)); + int originalViewWidth = view.size().width(); + auto jsViewWidth = [&view]() { + QLatin1String script("(function() { return window.innerWidth; })()"); + int viewWidth = evaluateJavaScriptSync(view.page(), script).toInt(); + return viewWidth; + }; + // Resize the "spacer" widget, and implicitly change the global position of the QWebEngineView. - spacer.setMinimumWidth(100); + const int offset = 50; + spacer.setMinimumWidth(spacer.size().width() + offset); + QTRY_COMPARE(jsViewWidth(), originalViewWidth - offset); + QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), view.mapTo(view.window(), elementCenter(view.page(), "foo"))); QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws)); + QTRY_VERIFY(!popup->position().isNull()); QCOMPARE(popupPos + QPoint(50, 0), popup->position()); } @@ -2084,66 +1129,6 @@ void tst_QWebEnginePage::macCopyUnicodeToClipboard() } #endif -void tst_QWebEnginePage::contextMenuCopy() -{ -#if !defined(QWEBENGINEELEMENT) - QSKIP("QWEBENGINEELEMENT"); -#else - QWebEngineView view; - - view.setHtml("<a href=\"http://www.google.com\">You cant miss this</a>"); - - view.page()->triggerAction(QWebEnginePage::SelectAll); - QVERIFY(!view.page()->selectedText().isEmpty()); - - QWebEngineElement link = view.page()->mainFrame()->findFirstElement("a"); - QPoint pos(link.geometry().center()); - QContextMenuEvent event(QContextMenuEvent::Mouse, pos); - view.page()->swallowContextMenuEvent(&event); - view.page()->updatePositionDependentActions(pos); - - QList<QMenu*> contextMenus = view.findChildren<QMenu*>(); - QVERIFY(!contextMenus.isEmpty()); - QMenu* contextMenu = contextMenus.first(); - QVERIFY(contextMenu); - - QList<QAction *> list = contextMenu->actions(); - int index = list.indexOf(view.page()->action(QWebEnginePage::Copy)); - QVERIFY(index != -1); -#endif -} - -// https://bugs.webkit.org/show_bug.cgi?id=62139 -void tst_QWebEnginePage::contextMenuPopulatedOnce() -{ -#if !defined(QWEBENGINEELEMENT) - QSKIP("QWEBENGINEELEMENT"); -#else - QWebEngineView view; - - view.setHtml("<input type=\"text\">"); - - QWebEngineElement link = view.page()->mainFrame()->findFirstElement("input"); - QPoint pos(link.geometry().center()); - QContextMenuEvent event(QContextMenuEvent::Mouse, pos); - view.page()->swallowContextMenuEvent(&event); - view.page()->updatePositionDependentActions(pos); - - QList<QMenu*> contextMenus = view.findChildren<QMenu*>(); - QVERIFY(!contextMenus.isEmpty()); - QMenu* contextMenu = contextMenus.first(); - QVERIFY(contextMenu); - - QList<QAction *> list = contextMenu->actions(); - QStringList entries; - while (!list.isEmpty()) { - QString entry = list.takeFirst()->text(); - QVERIFY(!entries.contains(entry)); - entries << entry; - } -#endif -} - void tst_QWebEnginePage::deleteQWebEngineViewTwice() { for (int i = 0; i < 2; ++i) { @@ -2157,62 +1142,6 @@ void tst_QWebEnginePage::deleteQWebEngineViewTwice() } } -#if defined(QWEBENGINEPAGE_RENDER) -class RepaintRequestedRenderer : public QObject { - Q_OBJECT -public: - RepaintRequestedRenderer(QWebEnginePage* page, QPainter* painter) - : m_page(page) - , m_painter(painter) - , m_recursionCount(0) - { - connect(m_page, SIGNAL(repaintRequested(QRect)), this, SLOT(onRepaintRequested(QRect))); - } - -Q_SIGNALS: - void finished(); - -private Q_SLOTS: - void onRepaintRequested(const QRect& rect) - { - QCOMPARE(m_recursionCount, 0); - - m_recursionCount++; - m_page->render(m_painter, rect); - m_recursionCount--; - - QMetaObject::invokeMethod(this, "finished", Qt::QueuedConnection); - } - -private: - QWebEnginePage* m_page; - QPainter* m_painter; - int m_recursionCount; -}; -#endif - -void tst_QWebEnginePage::renderOnRepaintRequestedShouldNotRecurse() -{ -#if !defined(QWEBENGINEPAGE_RENDER) - QSKIP("QWEBENGINEPAGE_RENDER"); -#else - QSize viewportSize(720, 576); - QWebEnginePage page; - - QImage image(viewportSize, QImage::Format_ARGB32); - QPainter painter(&image); - - page.setPreferredContentsSize(viewportSize); - page.setViewportSize(viewportSize); - RepaintRequestedRenderer r(&page, &painter); - - page.setHtml("zalan loves trunk", QUrl()); - - QSignalSpy spyFinished(&r, &RepaintRequestedRenderer::finished); - QVERIFY(spyFinished.wait()); -#endif -} - class SpyForLoadSignalsOrder : public QStateMachine { Q_OBJECT public: @@ -2271,24 +1200,6 @@ void tst_QWebEnginePage::loadSignalsOrder() QTRY_VERIFY(loadSpy.isFinished()); } -void tst_QWebEnginePage::undoActionHaveCustomText() -{ -#if !defined(QWEBENGINEPAGE_UNDOACTION) - QSKIP("QWEBENGINEPAGE_UNDOACTION"); -#else - m_page->setHtml("<div id=test contenteditable></div>"); - evaluateJavaScriptSync(m_page, "document.getElementById('test').focus()"); - - evaluateJavaScriptSync(m_page, "document.execCommand('insertText', true, 'Test');"); - QString typingActionText = m_page->action(QWebEnginePage::Undo)->text(); - - evaluateJavaScriptSync(m_page, "document.execCommand('indent', true);"); - QString alignActionText = m_page->action(QWebEnginePage::Undo)->text(); - - QVERIFY(typingActionText != alignActionText); -#endif -} - void tst_QWebEnginePage::renderWidgetHostViewNotShowTopLevel() { QWebEnginePage page; @@ -2607,68 +1518,6 @@ void tst_QWebEnginePage::openWindowDefaultSize() QCOMPARE(requestedGeometry.height(), 100); } -void tst_QWebEnginePage::cssMediaTypeGlobalSetting() -{ -#if !defined(QWEBENGINESETTINGS_SETCSSMEDIATYPE) - QSKIP("QWEBENGINESETTINGS_SETCSSMEDIATYPE"); -#else - QString testHtml("<style>@media tv {body{background-color:red;}}@media handheld {body{background-color:green;}}@media screen {body{background-color:blue;}}</style>"); - QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool))); - - QWebEngineSettings::globalSettings()->setCSSMediaType("tv"); - // Clear page specific setting to read from global setting - m_view->page()->settings()->setCSSMediaType(QString()); - m_view->setHtml(testHtml); - QTRY_COMPARE(loadSpy.count(), 1); - QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('tv').matches == true").toBool()); - QVERIFY(QWebEngineSettings::globalSettings()->cssMediaType() == "tv"); - - QWebEngineSettings::globalSettings()->setCSSMediaType("handheld"); - // Clear page specific setting to read from global setting - m_view->page()->settings()->setCSSMediaType(QString()); - m_view->setHtml(testHtml); - QTRY_COMPARE(loadSpy.count(), 2); - QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('handheld').matches == true").toBool()); - QVERIFY(QWebEngineSettings::globalSettings()->cssMediaType() == "handheld"); - - QWebEngineSettings::globalSettings()->setCSSMediaType("screen"); - // Clear page specific setting to read from global setting - m_view->page()->settings()->setCSSMediaType(QString()); - m_view->setHtml(testHtml); - QTRY_COMPARE(loadSpy.count(), 3); - QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('screen').matches == true").toBool()); - QVERIFY(QWebEngineSettings::globalSettings()->cssMediaType() == "screen"); -#endif -} - -void tst_QWebEnginePage::cssMediaTypePageSetting() -{ -#if !defined(QWEBENGINESETTINGS_SETCSSMEDIATYPE) - QSKIP("QWEBENGINESETTINGS_SETCSSMEDIATYPE"); -#else - QString testHtml("<style>@media tv {body{background-color:red;}}@media handheld {body{background-color:green;}}@media screen {body{background-color:blue;}}</style>"); - QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool))); - - m_view->page()->settings()->setCSSMediaType("tv"); - m_view->setHtml(testHtml); - QTRY_COMPARE(loadSpy.count(), 1); - QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('tv').matches == true").toBool()); - QVERIFY(m_view->page()->settings()->cssMediaType() == "tv"); - - m_view->page()->settings()->setCSSMediaType("handheld"); - m_view->setHtml(testHtml); - QTRY_COMPARE(loadSpy.count(), 2); - QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('handheld').matches == true").toBool()); - QVERIFY(m_view->page()->settings()->cssMediaType() == "handheld"); - - m_view->page()->settings()->setCSSMediaType("screen"); - m_view->setHtml(testHtml); - QTRY_COMPARE(loadSpy.count(), 3); - QVERIFY(evaluateJavaScriptSync(m_view->page(), "window.matchMedia('screen').matches == true").toBool()); - QVERIFY(m_view->page()->settings()->cssMediaType() == "screen"); -#endif -} - class JavaScriptCallbackBase { public: @@ -2824,6 +1673,28 @@ void tst_QWebEnginePage::runJavaScriptDisabled() QVariant(2)); } +// Based on https://bugreports.qt.io/browse/QTBUG-73876 +void tst_QWebEnginePage::runJavaScriptFromSlot() +{ + QWebEngineProfile profile; + QWebEnginePage page(&profile); + + QSignalSpy loadFinishedSpy(&page, &QWebEnginePage::loadFinished); + page.setHtml("<html><body>" + " <input type='text' id='input1' value='QtWebEngine' size='50' />" + "</body></html>"); + QTRY_COMPARE(loadFinishedSpy.count(), 1); + + QVariant result(-1); + connect(&page, &QWebEnginePage::selectionChanged, [&]() { + result = evaluateJavaScriptSync(&page, QStringLiteral("2+2")); + }); + evaluateJavaScriptSync(&page, QStringLiteral("const input = document.getElementById('input1');" + "input.focus();" + "input.select();")); + QTRY_COMPARE(result, QVariant(4)); +} + void tst_QWebEnginePage::fullScreenRequested() { JavaScriptCallbackWatcher watcher; @@ -3250,55 +2121,6 @@ void tst_QWebEnginePage::setHtmlWithJSAlert() QCOMPARE(toHtmlSync(&page), html); } -void tst_QWebEnginePage::inputFieldFocus() -{ -#if !defined(QWEBENGINEELEMENT) - QSKIP("QWEBENGINEELEMENT"); -#else - QWebEngineView view; - view.setHtml("<html><body><input type=\"text\"></input></body></html>"); - view.resize(400, 100); - view.show(); - QTest::qWaitForWindowExposed(&view); - view.activateWindow(); - view.setFocus(); - QTRY_VERIFY(view.hasFocus()); - - // double the flashing time, should at least blink once already - int delay = qApp->cursorFlashTime() * 2; - - // focus the lineedit and check if it blinks - bool autoSipEnabled = qApp->autoSipEnabled(); - qApp->setAutoSipEnabled(false); - const QWebEngineElement inputElement = view.page()->documentElement().findFirst(QLatin1String("input[type=text]")); - QTest::mouseClick(&view, Qt::LeftButton, 0, inputElement.geometry().center()); - m_inputFieldsTestView = &view; - view.installEventFilter( this ); - QTest::qWait(delay); - QVERIFY2(m_inputFieldTestPaintCount >= 3, - "The input field should have a blinking caret"); - qApp->setAutoSipEnabled(autoSipEnabled); -#endif -} - -void tst_QWebEnginePage::hitTestContent() -{ -#if !defined(QWEBENGINEELEMENT) - QSKIP("QWEBENGINEELEMENT"); -#else - QString html("<html><body><p>A paragraph</p><br/><br/><br/><a href=\"about:blank\" target=\"_foo\" id=\"link\">link text</a></body></html>"); - - QWebEnginePage page; - page.setHtml(html); - page.setViewportSize(QSize(200, 0)); //no height so link is not visible - const QWebEngineElement linkElement = page.documentElement().findFirst(QLatin1String("a#link")); - QWebEngineHitTestResult result = page.hitTestContent(linkElement.geometry().center()); - QCOMPARE(result.linkText(), QString("link text")); - QWebEngineElement link = result.linkElement(); - QCOMPARE(link.attribute("target"), QString("_foo")); -#endif -} - void tst_QWebEnginePage::baseUrl_data() { QTest::addColumn<QString>("html"); @@ -3379,32 +2201,6 @@ void tst_QWebEnginePage::scrollbarsOff() QVERIFY(evaluateJavaScriptSync(view.page(), "innerWidth == document.documentElement.offsetWidth").toBool()); } -void tst_QWebEnginePage::horizontalScrollAfterBack() -{ -#if !defined(QWEBENGINESETTINGS) - QSKIP("QWEBENGINESETTINGS"); -#else - QWebEngineView view; - QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool))); - - view.page()->settings()->setMaximumPagesInCache(2); - view.page()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAsNeeded); - view.page()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAsNeeded); - - view.load(QUrl("qrc:/resources/testiframe2.html")); - view.resize(200, 200); - QTRY_COMPARE(loadSpy.count(), 1); - QTRY_VERIFY((view.page()->scrollBarGeometry(Qt::Horizontal)).height()); - - view.load(QUrl("qrc:/resources/testiframe.html")); - QTRY_COMPARE(loadSpy.count(), 2); - - view.page()->triggerAction(QWebEnginePage::Back); - QTRY_COMPARE(loadSpy.count(), 3); - QTRY_VERIFY((view.page()->scrollBarGeometry(Qt::Horizontal)).height()); -#endif -} - class WebView : public QWebEngineView { Q_OBJECT @@ -3499,35 +2295,6 @@ private: QNetworkRequest::CacheLoadControl m_lastCacheLoad; }; -void tst_QWebEnginePage::setCacheLoadControlAttribute() -{ -#if !defined(QWEBENGINEPAGE_SETNETWORKACCESSMANAGER) - QSKIP("QWEBENGINEPAGE_SETNETWORKACCESSMANAGER"); -#else - QWebEnginePage page; - CacheNetworkAccessManager* manager = new CacheNetworkAccessManager(&page); - page.setNetworkAccessManager(manager); - - QNetworkRequest request(QUrl("http://abcdef.abcdef/")); - - request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysCache); - page.load(request); - QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::AlwaysCache); - - request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferCache); - page.load(request); - QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferCache); - - request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::AlwaysNetwork); - page.load(request); - QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::AlwaysNetwork); - - request.setAttribute(QNetworkRequest::CacheLoadControlAttribute, QNetworkRequest::PreferNetwork); - page.load(request); - QCOMPARE(manager->lastCacheLoad(), QNetworkRequest::PreferNetwork); -#endif -} - void tst_QWebEnginePage::setUrlWithPendingLoads() { QWebEnginePage page; @@ -4491,6 +3258,99 @@ void tst_QWebEnginePage::dynamicFrame() QCOMPARE(toPlainTextSync(&page).trimmed(), QStringLiteral("foo")); } +struct NotificationPage : ConsolePage { + Q_OBJECT + const QWebEnginePage::PermissionPolicy policy; + +public: + NotificationPage(QWebEnginePage::PermissionPolicy ppolicy) : policy(ppolicy) { + connect(this, &QWebEnginePage::loadFinished, [load = spyLoad.ref()] (bool result) mutable { load(result); }); + + connect(this, &QWebEnginePage::featurePermissionRequested, + [this] (const QUrl &origin, QWebEnginePage::Feature feature) { + if (feature != QWebEnginePage::Notifications) + return; + if (spyRequest.wasCalled()) + QFAIL("request executed twise!"); + setFeaturePermission(origin, feature, policy); + spyRequest.ref()(origin); + }); + + load(QStringLiteral("qrc:///shared/notification.html")); + } + + CallbackSpy<bool> spyLoad; + CallbackSpy<QUrl> spyRequest; + + QString getPermission() { return evaluateJavaScriptSync(this, "getPermission()").toString(); } + void requestPermission() { runJavaScript("requestPermission()"); } + void resetPermission() { runJavaScript("resetPermission()"); } + void sendNotification(const QString &title, const QString &body) { + runJavaScript("sendNotification('" + title + "', '" + body + "')"); + } +}; + +void tst_QWebEnginePage::notificationRequest_data() +{ + QTest::addColumn<QWebEnginePage::PermissionPolicy>("policy"); + QTest::addColumn<QString>("permission"); + QTest::newRow("deny") << QWebEnginePage::PermissionDeniedByUser << "denied"; + QTest::newRow("grant") << QWebEnginePage::PermissionGrantedByUser << "granted"; +} + +void tst_QWebEnginePage::notificationRequest() +{ + QFETCH(QWebEnginePage::PermissionPolicy, policy); + QFETCH(QString, permission); + + NotificationPage page(policy); + QVERIFY(page.spyLoad.waitForResult()); + + page.resetPermission(); + QCOMPARE(page.getPermission(), "default"); + + page.requestPermission(); + page.spyRequest.waitForResult(); + QVERIFY(page.spyRequest.wasCalled()); + + QCOMPARE(page.getPermission(), permission); +} + +void tst_QWebEnginePage::sendNotification() +{ + NotificationPage page(QWebEnginePage::PermissionGrantedByUser); + QVERIFY(page.spyLoad.waitForResult()); + + page.resetPermission(); + page.requestPermission(); + auto origin = page.spyRequest.waitForResult(); + QVERIFY(page.spyRequest.wasCalled()); + QCOMPARE(page.getPermission(), "granted"); + + CallbackSpy<QWebEngineNotification> presenter; + page.profile()->setNotificationPresenter([callback = presenter.ref()] (const QWebEngineNotification ¬ification) mutable { callback(notification); }); + + QString title("Title"), message("Message"); + page.sendNotification(title, message); + + auto notification = presenter.waitForResult(); + QVERIFY(presenter.wasCalled()); + QVERIFY(notification.isValid()); + QCOMPARE(notification.title(), title); + QCOMPARE(notification.message(), message); + QCOMPARE(notification.origin(), origin); + QCOMPARE(notification.direction(), Qt::RightToLeft); + QCOMPARE(notification.language(), "de"); + QCOMPARE(notification.tag(), "tst"); + + notification.show(); + QTRY_VERIFY2(page.messages.contains("onshow"), page.messages.join("\n").toLatin1().constData()); + notification.click(); + QTRY_VERIFY2(page.messages.contains("onclick"), page.messages.join("\n").toLatin1().constData()); + notification.close(); + QTRY_VERIFY2(page.messages.contains("onclose"), page.messages.join("\n").toLatin1().constData()); +} + static QByteArrayList params = {QByteArrayLiteral("--use-fake-device-for-media-stream")}; W_QTEST_MAIN(tst_QWebEnginePage, params) diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc index f2bf8c6ff..cf32486e7 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc @@ -24,4 +24,7 @@ <file>resources/bar.txt</file> <file>resources/path with spaces.txt</file> </qresource> +<qresource prefix='/shared'> + <file alias='notification.html'>../../shared/data/notification.html</file> +</qresource> </RCC> diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp index 98b4fa6a8..8bd68bb97 100644 --- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp +++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp @@ -29,6 +29,7 @@ #include "../util.h" #include <QtCore/qbuffer.h> #include <QtTest/QtTest> +#include <QtWebEngineCore/qwebengineurlrequestinterceptor.h> #include <QtWebEngineCore/qwebengineurlrequestjob.h> #include <QtWebEngineCore/qwebenginecookiestore.h> #include <QtWebEngineCore/qwebengineurlschemehandler.h> @@ -53,12 +54,13 @@ private Q_SLOTS: void urlSchemeHandlerFailRequest(); void urlSchemeHandlerFailOnRead(); void urlSchemeHandlerStreaming(); + void urlSchemeHandlerRequestHeaders(); void customUserAgent(); void httpAcceptLanguage(); void downloadItem(); void changePersistentPath(); void initiator(); - void qtbug_72299(); // this should be the last test + void qtbug_71895(); // this should be the last test }; void tst_QWebEngineProfile::init() @@ -446,6 +448,65 @@ void tst_QWebEngineProfile::urlSchemeHandlerStreaming() QCOMPARE(toPlainTextSync(view.page()), QString::fromLatin1(result)); } +class ExtraHeaderInterceptor : public QWebEngineUrlRequestInterceptor +{ +public: + ExtraHeaderInterceptor() { } + + void setExtraHeader(const QByteArray &key, const QByteArray &value) + { + m_extraKey = key; + m_extraValue = value; + } + + void interceptRequest(QWebEngineUrlRequestInfo &info) override + { + if (info.requestUrl().scheme() == QLatin1String("myscheme")) + info.setHttpHeader(m_extraKey, m_extraValue); + } + + QByteArray m_extraKey; + QByteArray m_extraValue; +}; + +class RequestHeadersUrlSchemeHandler : public ReplyingUrlSchemeHandler +{ +public: + void setExpectedHeader(const QByteArray &key, const QByteArray &value) + { + m_expectedKey = key; + m_expectedValue = value; + } + void requestStarted(QWebEngineUrlRequestJob *job) override + { + const auto requestHeaders = job->requestHeaders(); + QVERIFY(requestHeaders.contains(m_expectedKey)); + QCOMPARE(requestHeaders.value(m_expectedKey), m_expectedValue); + ReplyingUrlSchemeHandler::requestStarted(job); + } + QByteArray m_expectedKey; + QByteArray m_expectedValue; +}; + +void tst_QWebEngineProfile::urlSchemeHandlerRequestHeaders() +{ + RequestHeadersUrlSchemeHandler handler; + ExtraHeaderInterceptor interceptor; + + handler.setExpectedHeader("Hello", "World"); + interceptor.setExtraHeader("Hello", "World"); + + QWebEngineProfile profile; + profile.installUrlSchemeHandler("myscheme", &handler); + profile.setRequestInterceptor(&interceptor); + + QWebEnginePage page(&profile); + QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool))); + page.load(QUrl(QStringLiteral("myscheme://whatever"))); + QVERIFY(loadFinishedSpy.wait()); +} + + void tst_QWebEngineProfile::customUserAgent() { QString defaultUserAgent = QWebEngineProfile::defaultProfile()->httpUserAgent(); @@ -570,7 +631,7 @@ void tst_QWebEngineProfile::initiator() QCOMPARE(handler.initiator, QUrl()); } -void tst_QWebEngineProfile::qtbug_72299() +void tst_QWebEngineProfile::qtbug_71895() { QWebEngineView view; view.setUrl(QUrl("https://www.qt.io")); diff --git a/tests/auto/widgets/qwebenginescript/BLACKLIST b/tests/auto/widgets/qwebenginescript/BLACKLIST new file mode 100644 index 000000000..b641aaf04 --- /dev/null +++ b/tests/auto/widgets/qwebenginescript/BLACKLIST @@ -0,0 +1,3 @@ +# FIXME post 72-merge +[webChannelWithBadString] +* diff --git a/tests/auto/widgets/qwebengineview/resources/image2.png b/tests/auto/widgets/qwebengineview/resources/image2.png Binary files differnew file mode 100644 index 000000000..8d703640c --- /dev/null +++ b/tests/auto/widgets/qwebengineview/resources/image2.png diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 5f05f70ab..17177c7fb 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -47,6 +47,7 @@ #include <QStyle> #include <QtWidgets/qaction.h> #include <QWebEngineProfile> +#include <QtCore/qregularexpression.h> #define VERIFY_INPUTMETHOD_HINTS(actual, expect) \ QVERIFY(actual == (expect | Qt::ImhNoPredictiveText | Qt::ImhNoTextHandles | Qt::ImhNoEditMenu)); @@ -269,7 +270,7 @@ void tst_QWebEngineView::getWebKitVersion() void tst_QWebEngineView::changePage_data() { QString html = "<html><head><title>%1</title>" - "<link rel='icon' href='file://" TESTS_SOURCE_DIR "/resources/image2.png'></head></html>"; + "<link rel='icon' href='qrc:///resources/image2.png'></head></html>"; QUrl urlFrom("data:text/html," + html.arg("TitleFrom")); QUrl urlTo("data:text/html," + html.arg("TitleTo")); QUrl nullPage("data:text/html,<html/>"); @@ -1182,7 +1183,7 @@ void tst_QWebEngineView::changeLocale() QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000); QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty()); - errorLines = toPlainTextSync(viewDE.page()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts); + errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts); QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar")); QLocale::setDefault(QLocale("en")); @@ -1192,7 +1193,7 @@ void tst_QWebEngineView::changeLocale() QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyEN.count(), 1, 20000); QTRY_VERIFY(!toPlainTextSync(viewEN.page()).isEmpty()); - errorLines = toPlainTextSync(viewEN.page()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts); + errorLines = toPlainTextSync(viewEN.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts); QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("This site can\xE2\x80\x99t be reached")); // Reset error page @@ -1205,7 +1206,7 @@ void tst_QWebEngineView::changeLocale() QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000); QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty()); - errorLines = toPlainTextSync(viewDE.page()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts); + errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts); QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar")); } @@ -2636,7 +2637,7 @@ void tst_QWebEngineView::imeJSInputEvents() view.show(); auto logLines = [&view]() -> QStringList { - return evaluateJavaScriptSync(view.page(), "log.textContent").toString().split("\n").filter(QRegExp(".+")); + return evaluateJavaScriptSync(view.page(), "log.textContent").toString().split("\n").filter(QRegularExpression(".+")); }; QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc index 53b11bca8..a09be0399 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc @@ -5,5 +5,6 @@ <file>resources/input_types.html</file> <file>resources/scrolltest_page.html</file> <file>resources/keyboardEvents.html</file> + <file>resources/image2.png</file> </qresource> </RCC> diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro index eec8bb389..15b3efd3b 100644 --- a/tests/auto/widgets/widgets.pro +++ b/tests/auto/widgets/widgets.pro @@ -8,7 +8,10 @@ SUBDIRS += \ devtools \ faviconmanager \ loadsignals \ + offscreen \ origins \ + proxy \ + proxypac \ schemes \ shutdown \ qwebenginedownloaditem \ @@ -27,9 +30,6 @@ qtConfig(webengine-printing-and-pdf) { SUBDIRS += printing } -# QTBUG-71229 -linux:!boot2qt: SUBDIRS += proxypac - qtConfig(webengine-spellchecker):!cross_compile { !qtConfig(webengine-native-spellchecker) { SUBDIRS += spellchecking @@ -40,7 +40,8 @@ qtConfig(webengine-spellchecker):!cross_compile { # QTBUG-60268 boot2qt: SUBDIRS -= accessibility defaultsurfaceformat devtools \ - faviconmanager qwebenginepage qwebenginehistory \ - qwebengineprofile qwebenginescript \ - qwebengineview qwebenginedownloaditem qwebenginesettings \ - schemes origins loadsignals + qwebenginepage \ + qwebengineprofile \ + qwebengineview \ + qwebenginescript \ + proxypac offscreen |