summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/qwebenginepage
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets/qwebenginepage')
-rw-r--r--tests/auto/widgets/qwebenginepage/BLACKLIST15
-rw-r--r--tests/auto/widgets/qwebenginepage/CMakeLists.txt68
-rw-r--r--tests/auto/widgets/qwebenginepage/qwebenginepage.pro3
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/fontaccess.html14
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/image2.pngbin0 -> 14743 bytes
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/redirect.html8
-rw-r--r--tests/auto/widgets/qwebenginepage/resources/reload.html2
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp2219
-rw-r--r--tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc31
9 files changed, 1755 insertions, 605 deletions
diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST
index 02b297d5a..01d1ffe3d 100644
--- a/tests/auto/widgets/qwebenginepage/BLACKLIST
+++ b/tests/auto/widgets/qwebenginepage/BLACKLIST
@@ -5,8 +5,15 @@ osx
windows
macos # Can't move cursor (QTBUG-76312)
-[devTools]
-msvc-2019
+[comboBoxPopupPositionAfterMove]
+macos
+
+[comboBoxPopupPositionAfterChildMove]
+macos
+
+[backgroundColor]
+macos
+
+[dynamicFrame]
+ubuntu-22.04
-[setLifecycleStateWithDevTools]
-msvc-2019
diff --git a/tests/auto/widgets/qwebenginepage/CMakeLists.txt b/tests/auto/widgets/qwebenginepage/CMakeLists.txt
new file mode 100644
index 000000000..f63d6211c
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/CMakeLists.txt
@@ -0,0 +1,68 @@
+# Copyright (C) 2022 The Qt Company Ltd.
+# SPDX-License-Identifier: BSD-3-Clause
+
+include(../../httpserver/httpserver.cmake)
+include(../../util/util.cmake)
+
+qt_internal_add_test(tst_qwebenginepage
+ SOURCES
+ tst_qwebenginepage.cpp
+ LIBRARIES
+ Qt::CorePrivate
+ Qt::NetworkPrivate
+ Qt::WebEngineCorePrivate
+ Qt::WebEngineWidgets
+ Test::HttpServer
+ Test::Util
+)
+
+get_target_property(sharedData Test::HttpServer SHARED_DATA)
+
+set(tst_qwebenginepage_resource_files
+ "resources/redirect.html"
+ "resources/bar.txt"
+ "resources/content.html"
+ "resources/dynamicFrame.html"
+ "resources/foo.txt"
+ "resources/fontaccess.html"
+ "resources/frame_a.html"
+ "resources/frame_c.html"
+ "resources/framedindex.html"
+ "resources/fullscreen.html"
+ "resources/iframe.html"
+ "resources/iframe2.html"
+ "resources/iframe3.html"
+ "resources/image.png"
+ "resources/index.html"
+ "resources/lifecycle.html"
+ "resources/pasteimage.html"
+ "resources/path with spaces.txt"
+ "resources/reload.html"
+ "resources/script.html"
+ "resources/style.css"
+ "resources/test1.html"
+ "resources/test2.html"
+ "resources/testiframe.html"
+ "resources/testiframe2.html"
+ "resources/user.css"
+)
+
+qt_internal_add_resource(tst_qwebenginepage "tst_qwebenginepage"
+ PREFIX
+ "/"
+ FILES
+ ${tst_qwebenginepage_resource_files}
+)
+set_source_files_properties("${sharedData}/notification.html"
+ PROPERTIES QT_RESOURCE_ALIAS "notification.html"
+)
+set(tst_qwebenginepage1_resource_files
+ "${sharedData}/notification.html"
+)
+
+qt_internal_add_resource(tst_qwebenginepage "tst_qwebenginepage1"
+ PREFIX
+ "/shared"
+ FILES
+ ${tst_qwebenginepage1_resource_files}
+)
diff --git a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
deleted file mode 100644
index 18a66c466..000000000
--- a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro
+++ /dev/null
@@ -1,3 +0,0 @@
-include(../tests.pri)
-include(../../shared/http.pri)
-QT *= core-private
diff --git a/tests/auto/widgets/qwebenginepage/resources/fontaccess.html b/tests/auto/widgets/qwebenginepage/resources/fontaccess.html
new file mode 100644
index 000000000..1a0fe8af9
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/fontaccess.html
@@ -0,0 +1,14 @@
+<html>
+<body onkeypress='onKeyPress()'>
+<a>This is test content</a>
+<script>
+var done = false;
+var fonts;
+var activated = false;
+function onKeyPress() {
+ activated = true;
+ window.queryLocalFonts().then(f => { fonts = f; done = true; });
+}
+</script>
+</body>
+</html>
diff --git a/tests/auto/widgets/qwebenginepage/resources/image2.png b/tests/auto/widgets/qwebenginepage/resources/image2.png
new file mode 100644
index 000000000..8d703640c
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/image2.png
Binary files differ
diff --git a/tests/auto/widgets/qwebenginepage/resources/redirect.html b/tests/auto/widgets/qwebenginepage/resources/redirect.html
new file mode 100644
index 000000000..db06d73a7
--- /dev/null
+++ b/tests/auto/widgets/qwebenginepage/resources/redirect.html
@@ -0,0 +1,8 @@
+<html>
+<body>
+<script>
+function doRedirect() { location.replace('qrc:///resources/content.html') }
+document.addEventListener("DOMContentLoaded", doRedirect)
+</script>
+</body>
+</html>
diff --git a/tests/auto/widgets/qwebenginepage/resources/reload.html b/tests/auto/widgets/qwebenginepage/resources/reload.html
index d9c33dfcd..062d06807 100644
--- a/tests/auto/widgets/qwebenginepage/resources/reload.html
+++ b/tests/auto/widgets/qwebenginepage/resources/reload.html
@@ -1,6 +1,6 @@
<html>
<head>
-<meta http-equiv="refresh" content="2">
+<meta http-equiv="refresh" content="2;url=qrc:///resources/content.html">
</head>
<body>
This is test content
diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
index f530fefbb..e7f2ce1cd 100644
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
+++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp
@@ -1,5 +1,5 @@
/*
- Copyright (C) 2016 The Qt Company Ltd.
+ Copyright (C) 2023 The Qt Company Ltd.
Copyright (C) 2009 Girish Ramakrishnan <girish@forwardbias.in>
Copyright (C) 2010 Holger Hans Peter Freyther
@@ -19,8 +19,10 @@
Boston, MA 02110-1301, USA.
*/
-#include "../util.h"
+#include <widgetutil.h>
+#include <QtNetwork/private/qtnetworkglobal_p.h>
#include <QtWebEngineCore/qtwebenginecore-config.h>
+#include <QtWebEngineCore/private/qtwebenginecoreglobal_p.h>
#include <QByteArray>
#include <QClipboard>
#include <QDir>
@@ -34,6 +36,7 @@
#include <QPaintEngine>
#include <QPushButton>
#include <QScreen>
+#include <QWheelEvent>
#if defined(QT_STATEMACHINE_LIB)
# include <QStateMachine>
#endif
@@ -47,10 +50,15 @@
#include <qnetworkcookiejar.h>
#include <qnetworkreply.h>
#include <qnetworkrequest.h>
+#include <qwebengineclienthints.h>
#include <qwebenginedownloadrequest.h>
+#include <qwebenginedesktopmediarequest.h>
+#include <qwebenginefilesystemaccessrequest.h>
#include <qwebenginefindtextresult.h>
#include <qwebenginefullscreenrequest.h>
#include <qwebenginehistory.h>
+#include <qwebenginenavigationrequest.h>
+#include <qwebenginenewwindowrequest.h>
#include <qwebenginenotification.h>
#include <qwebenginepage.h>
#include <qwebengineprofile.h>
@@ -59,14 +67,22 @@
#include <qwebenginescript.h>
#include <qwebenginescriptcollection.h>
#include <qwebenginesettings.h>
+#include <qwebengineurlrequestinterceptor.h>
+#include <qwebengineurlrequestjob.h>
+#include <qwebengineurlscheme.h>
+#include <qwebengineurlschemehandler.h>
#include <qwebengineview.h>
+#include <qwebenginepermission.h>
#include <qimagewriter.h>
+#include <QColorSpace>
+#include <QQuickRenderControl>
+#include <QQuickWindow>
static void removeRecursive(const QString& dirname)
{
QDir dir(dirname);
QFileInfoList entries(dir.entryInfoList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot));
- for (int i = 0; i < entries.count(); ++i)
+ for (int i = 0; i < entries.size(); ++i)
if (entries[i].isDir())
removeRecursive(entries[i].filePath());
else
@@ -74,6 +90,13 @@ static void removeRecursive(const QString& dirname)
QDir().rmdir(dirname);
}
+struct TestBasePage : QWebEnginePage
+{
+ explicit TestBasePage(QWebEngineProfile *profile, QObject *parent = nullptr) : QWebEnginePage(profile, parent) { }
+ explicit TestBasePage(QObject *parent = nullptr) : QWebEnginePage(parent) { }
+ QSignalSpy loadSpy { this, &QWebEnginePage::loadFinished };
+};
+
class tst_QWebEnginePage : public QObject
{
Q_OBJECT
@@ -90,13 +113,18 @@ public Q_SLOTS:
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
+ void comboBoxPopupPositionAfterMove_data();
void comboBoxPopupPositionAfterMove();
+ void comboBoxPopupPositionAfterChildMove_data();
void comboBoxPopupPositionAfterChildMove();
void acceptNavigationRequest();
+ void acceptNavigationRequestWithFormData();
void acceptNavigationRequestNavigationType();
void acceptNavigationRequestRelativeToNothing();
+#ifndef Q_OS_MACOS
void geolocationRequestJS_data();
void geolocationRequestJS();
+#endif
void loadFinished();
void actionStates();
void pasteImage();
@@ -137,7 +165,7 @@ private Q_SLOTS:
#endif
void openWindowDefaultSize();
-#ifdef Q_OS_MAC
+#ifdef Q_OS_MACOS
void macCopyUnicodeToClipboard();
#endif
@@ -145,7 +173,8 @@ private Q_SLOTS:
void runJavaScriptDisabled();
void runJavaScriptFromSlot();
void fullScreenRequested();
- void quotaRequested();
+ void requestQuota_data();
+ void requestQuota();
// Tests from tst_QWebEngineFrame
@@ -177,7 +206,6 @@ private Q_SLOTS:
void setUrlUsingStateObject();
void setUrlThenLoads_data();
void setUrlThenLoads();
- void loadFinishedAfterNotFoundError();
void loadInSignalHandlers_data();
void loadInSignalHandlers();
void loadFromQrc();
@@ -208,7 +236,13 @@ private Q_SLOTS:
void notificationPermission_data();
void notificationPermission();
void sendNotification();
+ void clipboardReadWritePermissionInitialState_data();
+ void clipboardReadWritePermissionInitialState();
+ void clipboardReadWritePermission_data();
+ void clipboardReadWritePermission();
void contentsSize();
+ void localFontAccessPermission_data();
+ void localFontAccessPermission();
void setLifecycleState();
void setVisible();
@@ -229,6 +263,8 @@ private Q_SLOTS:
void editActionsWithoutSelection();
void customUserAgentInNewTab();
+ void openNewTabInDifferentProfile_data();
+ void openNewTabInDifferentProfile();
void renderProcessCrashed();
void renderProcessPid();
void backgroundColor();
@@ -237,20 +273,54 @@ private Q_SLOTS:
void isSafeRedirect_data();
void isSafeRedirect();
+ void testChooseFilesParameters_data();
+ void testChooseFilesParameters();
+ void fileSystemAccessDialog();
+
+ void localToRemoteNavigation();
+ void clientHints_data();
+ void clientHints();
+ void childFrameInput();
+ void openLinkInNewPageWithWebWindowType_data();
+ void openLinkInNewPageWithWebWindowType();
+ void keepInterceptorAfterNewWindowRequested();
+ void chooseDesktopMedia();
+
private:
- static QPoint elementCenter(QWebEnginePage *page, const QString &id);
static bool isFalseJavaScriptResult(QWebEnginePage *page, const QString &javaScript);
static bool isTrueJavaScriptResult(QWebEnginePage *page, const QString &javaScript);
static bool isEmptyListJavaScriptResult(QWebEnginePage *page, const QString &javaScript);
QWebEngineView* m_view;
QWebEnginePage* m_page;
+ QScopedPointer<QPointingDevice> s_touchDevice =
+ QScopedPointer<QPointingDevice>(QTest::createTouchDevice());
+
QString tmpDirPath() const
{
static QString tmpd = QDir::tempPath() + "/tst_qwebenginepage-"
+ QDateTime::currentDateTime().toString(QLatin1String("yyyyMMddhhmmss"));
return tmpd;
}
+
+ void makeClick(const QPointer<QWindow> window, bool withTouch = false,
+ const QPoint &p = QPoint())
+ {
+ QVERIFY2(window, "window is gone");
+ if (!withTouch) {
+ QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), p);
+ } else {
+ QTest::touchEvent(window, s_touchDevice.get()).press(1, p);
+ QTest::touchEvent(window, s_touchDevice.get()).release(1, p);
+ }
+ };
+
+ void makeScroll(QWidget *target, QPointF pos, QPoint globalPos, QPoint angleDelta)
+ {
+ QWheelEvent ev(pos, globalPos, QPoint(0, 0), angleDelta, Qt::NoButton, Qt::NoModifier,
+ Qt::NoScrollPhase, false);
+ QGuiApplication::sendEvent(target, &ev);
+ }
};
tst_QWebEnginePage::tst_QWebEnginePage()
@@ -292,6 +362,18 @@ void tst_QWebEnginePage::initTestCase()
#endif
searchPath += QStringLiteral("/../../../plugins");
QCoreApplication::addLibraryPath(searchPath);
+
+ QWebEngineUrlScheme echo("echo");
+ echo.setSyntax(QWebEngineUrlScheme::Syntax::Path);
+ QWebEngineUrlScheme::registerScheme(echo);
+
+ QWebEngineUrlScheme local("local");
+ local.setFlags(QWebEngineUrlScheme::LocalScheme);
+ QWebEngineUrlScheme::registerScheme(local);
+
+ QWebEngineUrlScheme remote("remote");
+ remote.setFlags(QWebEngineUrlScheme::CorsEnabled);
+ QWebEngineUrlScheme::registerScheme(remote);
}
void tst_QWebEnginePage::cleanupTestCase()
@@ -299,6 +381,23 @@ void tst_QWebEnginePage::cleanupTestCase()
cleanupFiles(); // Be nice
}
+class EchoingUrlSchemeHandler : public QWebEngineUrlSchemeHandler
+{
+public:
+ EchoingUrlSchemeHandler(QObject *parent = nullptr)
+ : QWebEngineUrlSchemeHandler(parent)
+ {
+ }
+ ~EchoingUrlSchemeHandler() = default;
+
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ QBuffer *buffer = new QBuffer(job);
+ buffer->setData(job->requestUrl().toString(QUrl::RemoveScheme).toUtf8());
+ job->reply("text/plain;charset=utf-8", buffer);
+ }
+};
+
class NavigationRequestOverride : public QWebEnginePage
{
public:
@@ -306,7 +405,7 @@ public:
bool m_acceptNavigationRequest;
protected:
- virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
+ bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame) override
{
Q_UNUSED(url);
Q_UNUSED(isMainFrame);
@@ -319,24 +418,26 @@ protected:
void tst_QWebEnginePage::acceptNavigationRequest()
{
QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("echo", new EchoingUrlSchemeHandler(&profile));
NavigationRequestOverride page(&profile, false);
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
- page.setHtml(QString("<html><body><form name='tstform' action='data:text/html,foo'method='get'>"
- "<input type='text'><input type='submit'></form></body></html>"), QUrl());
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ page.setHtml(QString("<html><body><form name='tstform' action='foo' method='get'>"
+ "<input type='text'><input type='submit'></form></body></html>"),
+ QUrl("echo:/"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
evaluateJavaScriptSync(&page, "tstform.submit();");
- QTRY_COMPARE(loadSpy.count(), 2);
+ QTRY_COMPARE(loadSpy.size(), 2);
// Content hasn't changed so the form submit will still work
page.m_acceptNavigationRequest = true;
evaluateJavaScriptSync(&page, "tstform.submit();");
- QTRY_COMPARE(loadSpy.count(), 3);
+ QTRY_COMPARE(loadSpy.size(), 3);
// Now the content has changed
- QCOMPARE(toPlainTextSync(&page), QString("foo?"));
+ QCOMPARE(toPlainTextSync(&page), QString("/foo?"));
}
class JSTestPage : public QWebEnginePage
@@ -351,12 +452,12 @@ public:
return true;
}
public Q_SLOTS:
- void requestPermission(const QUrl &origin, QWebEnginePage::Feature feature)
+ void requestPermission(QWebEnginePermission permission)
{
if (m_allowGeolocation)
- setFeaturePermission(origin, feature, PermissionGrantedByUser);
+ permission.grant();
else
- setFeaturePermission(origin, feature, PermissionDeniedByUser);
+ permission.deny();
}
public:
@@ -369,6 +470,7 @@ private:
bool m_allowGeolocation;
};
+#ifndef Q_OS_MACOS
void tst_QWebEnginePage::geolocationRequestJS_data()
{
QTest::addColumn<bool>("allowed");
@@ -383,15 +485,16 @@ void tst_QWebEnginePage::geolocationRequestJS()
QFETCH(int, errorCode);
QWebEngineView view;
JSTestPage *newPage = new JSTestPage(&view);
- newPage->setView(&view);
+ view.setPage(newPage);
+ newPage->profile()->setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
newPage->setGeolocationPermission(allowed);
- connect(newPage, SIGNAL(featurePermissionRequested(const QUrl&, QWebEnginePage::Feature)),
- newPage, SLOT(requestPermission(const QUrl&, QWebEnginePage::Feature)));
+ connect(newPage, SIGNAL(permissionRequested(QWebEnginePermission)),
+ newPage, SLOT(requestPermission(QWebEnginePermission)));
QSignalSpy spyLoadFinished(newPage, SIGNAL(loadFinished(bool)));
newPage->setHtml(QString("<html><body>test</body></html>"), QUrl("qrc://secure/origin"));
- QTRY_COMPARE_WITH_TIMEOUT(spyLoadFinished.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spyLoadFinished.size(), 1, 20000);
// Geolocation is only enabled for visible WebContents.
view.show();
@@ -408,6 +511,7 @@ void tst_QWebEnginePage::geolocationRequestJS()
QEXPECT_FAIL("", "No location service available.", Continue);
QCOMPARE(result, errorCode);
}
+#endif
void tst_QWebEnginePage::loadFinished()
{
@@ -418,19 +522,19 @@ void tst_QWebEnginePage::loadFinished()
page.load(QUrl("data:text/html,<frameset cols=\"25%,75%\"><frame src=\"data:text/html,"
"<head><meta http-equiv='refresh' content='1'></head>foo \">"
"<frame src=\"data:text/html,bar\"></frameset>"));
- QTRY_COMPARE_WITH_TIMEOUT(spyLoadFinished.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spyLoadFinished.size(), 1, 20000);
QEXPECT_FAIL("", "Behavior change: Load signals are emitted only for the main frame in QtWebEngine.", Continue);
- QTRY_VERIFY_WITH_TIMEOUT(spyLoadStarted.count() > 1, 100);
+ QTRY_VERIFY_WITH_TIMEOUT(spyLoadStarted.size() > 1, 100);
QEXPECT_FAIL("", "Behavior change: Load signals are emitted only for the main frame in QtWebEngine.", Continue);
- QTRY_VERIFY_WITH_TIMEOUT(spyLoadFinished.count() > 1, 100);
+ QTRY_VERIFY_WITH_TIMEOUT(spyLoadFinished.size() > 1, 100);
spyLoadFinished.clear();
page.load(QUrl("data:text/html,<frameset cols=\"25%,75%\"><frame src=\"data:text/html,"
"foo \"><frame src=\"data:text/html,bar\"></frameset>"));
- QTRY_COMPARE(spyLoadFinished.count(), 1);
- QCOMPARE(spyLoadFinished.count(), 1);
+ QTRY_COMPARE(spyLoadFinished.size(), 1);
+ QCOMPARE(spyLoadFinished.size(), 1);
}
void tst_QWebEnginePage::actionStates()
@@ -487,6 +591,7 @@ void tst_QWebEnginePage::pasteImage()
QByteArray data = evaluateJavaScriptSync(page, "window.myImageDataURL").toByteArray();
data.remove(0, data.indexOf(";base64,") + 8);
QImage image = QImage::fromData(QByteArray::fromBase64(data), "PNG");
+ image.setColorSpace(origImage.colorSpace());
if (image.format() == QImage::Format_RGB32)
image.reinterpretAsFormat(QImage::Format_ARGB32);
QCOMPARE(image, origImage);
@@ -497,7 +602,7 @@ class ConsolePage : public QWebEnginePage
public:
ConsolePage(QObject* parent = 0) : QWebEnginePage(parent) {}
- virtual void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID)
+ void javaScriptConsoleMessage(JavaScriptConsoleMessageLevel level, const QString& message, int lineNumber, const QString& sourceID) override
{
levels.append(level);
messages.append(message);
@@ -516,42 +621,29 @@ void tst_QWebEnginePage::consoleOutput()
ConsolePage page;
// We don't care about the result but want this to be synchronous
evaluateJavaScriptSync(&page, "this is not valid JavaScript");
- QCOMPARE(page.messages.count(), 1);
+ QCOMPARE(page.messages.size(), 1);
QCOMPARE(page.lineNumbers.at(0), 1);
}
class TestPage : public QWebEnginePage {
Q_OBJECT
public:
- TestPage(QObject* parent = 0) : QWebEnginePage(parent)
+ TestPage(QObject *parent = nullptr, QWebEngineProfile *profile = nullptr) : QWebEnginePage(profile, parent)
{
- connect(this, SIGNAL(geometryChangeRequested(QRect)), this, SLOT(slotGeometryChangeRequested(QRect)));
+ connect(this, &QWebEnginePage::geometryChangeRequested, this, &TestPage::slotGeometryChangeRequested);
+ connect(this, &QWebEnginePage::navigationRequested, this, &TestPage::slotNavigationRequested);
+ connect(this, &QWebEnginePage::newWindowRequested, this, &TestPage::slotNewWindowRequested);
}
struct Navigation {
- NavigationType type;
+ QWebEngineNavigationRequest::NavigationType type;
QUrl url;
bool isMainFrame;
+ bool hasFormData;
};
QList<Navigation> navigations;
- virtual bool acceptNavigationRequest(const QUrl &url, NavigationType type, bool isMainFrame)
- {
- Navigation n;
- n.url = url;
- n.type = type;
- n.isMainFrame = isMainFrame;
- navigations.append(n);
- return true;
- }
-
QList<TestPage*> createdWindows;
- virtual QWebEnginePage* createWindow(WebWindowType) {
- TestPage* page = new TestPage(this);
- createdWindows.append(page);
- emit windowCreated();
- return page;
- }
QRect requestedGeometry;
@@ -559,51 +651,127 @@ signals:
void windowCreated();
private Q_SLOTS:
- void slotGeometryChangeRequested(const QRect& geom) {
+ void slotNavigationRequested(QWebEngineNavigationRequest &request)
+ {
+ Navigation n;
+ n.url = request.url();
+ n.type = request.navigationType();
+ n.isMainFrame = request.isMainFrame();
+ n.hasFormData = request.hasFormData();
+ navigations.append(n);
+ request.accept();
+ }
+ void slotNewWindowRequested(QWebEngineNewWindowRequest &request)
+ {
+ TestPage *page = new TestPage(this, profile());
+ createdWindows.append(page);
+ emit windowCreated();
+ request.openIn(page);
+ }
+
+ void slotGeometryChangeRequested(const QRect &geom)
+ {
requestedGeometry = geom;
}
};
-void tst_QWebEnginePage::acceptNavigationRequestNavigationType()
+void tst_QWebEnginePage::acceptNavigationRequestWithFormData()
{
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("echo", new EchoingUrlSchemeHandler(&profile));
+ TestPage page(nullptr, &profile);
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+
+ page.setHtml(QString("<html><body><form name='tstform' action='foo' method='post'>"
+ "<input type='text'><input type='submit'></form></body></html>"),
+ QUrl("echo:/"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
+ QCOMPARE(page.navigations[0].type, QWebEngineNavigationRequest::TypedNavigation);
+ QVERIFY(!page.navigations[0].hasFormData);
+
+ evaluateJavaScriptSync(&page, "tstform.submit();");
+ QTRY_COMPARE(loadSpy.size(), 2);
+ QCOMPARE(page.navigations[1].type, QWebEngineNavigationRequest::FormSubmittedNavigation);
+ QVERIFY(page.navigations[1].hasFormData);
+
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(loadSpy.size(), 3);
+ QCOMPARE(page.navigations[2].type, QWebEngineNavigationRequest::ReloadNavigation);
+ QVERIFY(page.navigations[2].hasFormData);
+}
+void tst_QWebEnginePage::acceptNavigationRequestNavigationType()
+{
TestPage page;
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.load(QUrl("qrc:///resources/script.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
- QTRY_COMPARE(page.navigations.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
+ QTRY_COMPARE(page.navigations.size(), 1);
page.load(QUrl("qrc:///resources/content.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 2, 20000);
- QTRY_COMPARE(page.navigations.count(), 2);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 2, 20000);
+ QTRY_COMPARE(page.navigations.size(), 2);
page.triggerAction(QWebEnginePage::Stop);
QVERIFY(page.history()->canGoBack());
page.triggerAction(QWebEnginePage::Back);
- QTRY_COMPARE(loadSpy.count(), 3);
- QTRY_COMPARE(page.navigations.count(), 3);
+ QTRY_COMPARE(loadSpy.size(), 3);
+ QTRY_COMPARE(page.navigations.size(), 3);
page.triggerAction(QWebEnginePage::Reload);
- QTRY_COMPARE(loadSpy.count(), 4);
- QTRY_COMPARE(page.navigations.count(), 4);
+ QTRY_COMPARE(loadSpy.size(), 4);
+ QTRY_COMPARE(page.navigations.size(), 4);
+
+ QList<QWebEngineNavigationRequest::NavigationType> expectedList;
+ expectedList << QWebEngineNavigationRequest::TypedNavigation
+ << QWebEngineNavigationRequest::TypedNavigation
+ << QWebEngineNavigationRequest::BackForwardNavigation
+ << QWebEngineNavigationRequest::ReloadNavigation;
+ // client side redirect
page.load(QUrl("qrc:///resources/reload.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 6, 20000);
- QTRY_COMPARE(page.navigations.count(), 6);
-
- QList<QWebEnginePage::NavigationType> expectedList;
- expectedList << QWebEnginePage::NavigationTypeTyped
- << QWebEnginePage::NavigationTypeTyped
- << QWebEnginePage::NavigationTypeBackForward
- << QWebEnginePage::NavigationTypeReload
- << QWebEnginePage::NavigationTypeTyped
- << QWebEnginePage::NavigationTypeRedirect;
- QVERIFY(expectedList.count() == page.navigations.count());
- for (int i = 0; i < expectedList.count(); ++i) {
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 6, 20000);
+ QTRY_COMPARE(page.navigations.size(), 6);
+ expectedList += { QWebEngineNavigationRequest::TypedNavigation, QWebEngineNavigationRequest::RedirectNavigation };
+
+
+ page.load(QUrl("qrc:///resources/redirect.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 7, 20000);
+ QTRY_COMPARE(page.navigations.size(), 8);
+ expectedList += { QWebEngineNavigationRequest::TypedNavigation, QWebEngineNavigationRequest::RedirectNavigation };
+
+ // server side redirect
+ HttpServer server;
+ server.setResourceDirs({ ":/resources" });
+ connect(&server, &HttpServer::newRequest, &server, [&] (HttpReqRep *r) {
+ if (r->requestMethod() == "GET") {
+ if (r->requestPath() == "/redirect1.html") {
+ r->setResponseHeader("Location", server.url("/redirect2.html").toEncoded());
+ r->setResponseBody("<html><body>Redirect1</body></html>");
+ r->sendResponse(307); // Internal server redirect
+ } else if (r->requestPath() == "/redirect2.html") {
+ r->setResponseHeader("Location", server.url("/content.html").toEncoded());
+ r->setResponseBody("<html><body>Redirect2</body></html>");
+ r->sendResponse(301); // Moved permanently
+ }
+ }
+ });
+ QVERIFY(server.start());
+ page.load(QUrl(server.url("/redirect1.html")));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 8, 20000);
+ expectedList += {
+ QWebEngineNavigationRequest::TypedNavigation,
+ QWebEngineNavigationRequest::RedirectNavigation,
+ QWebEngineNavigationRequest::RedirectNavigation
+ };
+
+ for (int i = 0; i < expectedList.size(); ++i) {
+ QTRY_VERIFY(i < page.navigations.size());
QCOMPARE(page.navigations[i].type, expectedList[i]);
}
+ QVERIFY(expectedList.size() == page.navigations.size());
}
// Relative url without base url.
@@ -616,48 +784,49 @@ void tst_QWebEnginePage::acceptNavigationRequestRelativeToNothing()
page.setHtml(QString("<html><body><a id='link' href='S0'>limited time offer</a></body></html>"),
/* baseUrl: */ QUrl());
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 2, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 2, 20000);
page.setHtml(QString("<html><body><a id='link' href='S0'>limited time offer</a></body></html>"),
/* baseUrl: */ QString("qrc:/"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 3, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 3, 20000);
page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 4, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 4, 20000);
// The two setHtml and the second click are counted, while the
// first click is ignored due to the empty base url.
- QCOMPARE(page.navigations.count(), 3);
- QCOMPARE(page.navigations[0].type, QWebEnginePage::NavigationTypeTyped);
- QCOMPARE(page.navigations[1].type, QWebEnginePage::NavigationTypeTyped);
- QCOMPARE(page.navigations[2].type, QWebEnginePage::NavigationTypeLinkClicked);
+ QCOMPARE(page.navigations.size(), 3);
+ QCOMPARE(page.navigations[0].type, QWebEngineNavigationRequest::TypedNavigation);
+ QCOMPARE(page.navigations[1].type, QWebEngineNavigationRequest::TypedNavigation);
+ QCOMPARE(page.navigations[2].type, QWebEngineNavigationRequest::LinkClickedNavigation);
QCOMPARE(page.navigations[2].url, QUrl(QString("qrc:/S0")));
}
void tst_QWebEnginePage::popupFormSubmission()
{
- TestPage page;
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("echo", new EchoingUrlSchemeHandler(&profile));
+ TestPage page(nullptr, &profile);
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
QSignalSpy windowCreatedSpy(&page, SIGNAL(windowCreated()));
page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
page.setHtml("<form name='form1' method=get action='' target='myNewWin'>"
" <input type='hidden' name='foo' value='bar'>"
- "</form>");
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 20000);
+ "</form>", QUrl("echo:"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 20000);
page.runJavaScript("window.open('', 'myNewWin', 'width=500,height=300,toolbar=0');");
evaluateJavaScriptSync(&page, "document.form1.submit();");
- QTRY_COMPARE(windowCreatedSpy.count(), 1);
+ QTRY_COMPARE(windowCreatedSpy.size(), 1);
// The number of popup created should be one.
QVERIFY(page.createdWindows.size() == 1);
QTRY_VERIFY(!page.createdWindows[0]->url().isEmpty());
- QString url = page.createdWindows[0]->url().toString();
// Check if the form submission was OK.
- QVERIFY(url.contains("?foo=bar"));
+ QTRY_VERIFY(page.createdWindows[0]->url().toString().contains("?foo=bar"));
}
class TestNetworkManager : public QNetworkAccessManager
@@ -669,7 +838,8 @@ public:
QList<QNetworkRequest> requests;
protected:
- virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest &request, QIODevice* outgoingData) {
+ QNetworkReply* createRequest(Operation op, const QNetworkRequest &request, QIODevice* outgoingData) override
+ {
requests.append(request);
requestedUrls.append(request.url());
return QNetworkAccessManager::createRequest(op, request, outgoingData);
@@ -697,16 +867,16 @@ void tst_QWebEnginePage::multipleProfilesAndLocalStorage()
page1.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
page2.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy1.count(), 1, 20000);
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy2.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy1.size(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy2.size(), 1, 20000);
evaluateJavaScriptSync(&page1, "localStorage.setItem('test', 'value1');");
evaluateJavaScriptSync(&page2, "localStorage.setItem('test', 'value2');");
page1.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
page2.setHtml(QString("<html><body> </body></html>"), QUrl("http://wwww.example.com"));
- QTRY_COMPARE(loadSpy1.count(), 2);
- QTRY_COMPARE(loadSpy2.count(), 2);
+ QTRY_COMPARE(loadSpy1.size(), 2);
+ QTRY_COMPARE(loadSpy2.size(), 2);
QVariant s1 = evaluateJavaScriptSync(&page1, "localStorage.getItem('test')");
QCOMPARE(s1.toString(), QString("value1"));
@@ -755,7 +925,7 @@ void tst_QWebEnginePage::textSelection()
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.setHtml(content);
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
// these actions must exist
QVERIFY(page.action(QWebEnginePage::SelectAll) != 0);
@@ -782,7 +952,7 @@ void tst_QWebEnginePage::textSelection()
// navigate away and check that selection is cleared
page.load(QUrl("about:blank"));
- QTRY_COMPARE(loadSpy.count(), 2);
+ QTRY_COMPARE(loadSpy.size(), 2);
QVERIFY(!page.hasSelection());
QVERIFY(page.selectedText().isEmpty());
@@ -803,7 +973,7 @@ void tst_QWebEnginePage::backActionUpdate()
QVERIFY(!action->isEnabled());
page->load(QUrl("qrc:///resources/framedindex.html"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
QVERIFY(!action->isEnabled());
auto firstAnchorCenterInFrame = [](QWebEnginePage *page, const QString &frameName) {
@@ -815,7 +985,7 @@ void tst_QWebEnginePage::backActionUpdate()
"return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
"})()").toList();
- if (rectList.count() != 2) {
+ if (rectList.size() != 2) {
qWarning("firstAnchorCenterInFrame failed.");
return QPoint();
}
@@ -842,8 +1012,8 @@ void tst_QWebEnginePage::localStorageVisibility()
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_WITH_TIMEOUT(loadSpy1.count(), 1, 20000);
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy2.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy1.size(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy2.size(), 1, 20000);
// The attribute determines the visibility of the window.localStorage object.
QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
@@ -856,13 +1026,14 @@ void tst_QWebEnginePage::localStorageVisibility()
// ...first check second page (for storage to appear) as applying settings is batched and done asynchronously
QTRY_VERIFY(evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());
// Switching the feature off does not actively remove the object from webPage1.
- QVERIFY(evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
+// FIXME: 94-based: now it does
+// QVERIFY(evaluateJavaScriptSync(&webPage1, 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);
+ QTRY_COMPARE(loadSpy1.size(), 2);
+ QTRY_COMPARE(loadSpy2.size(), 2);
QVERIFY(!evaluateJavaScriptSync(&webPage1, QString("(window.localStorage != undefined)")).toBool());
QVERIFY(evaluateJavaScriptSync(&webPage2, QString("(window.localStorage != undefined)")).toBool());
}
@@ -936,7 +1107,7 @@ public:
JSPromptPage()
{}
- bool javaScriptPrompt(const QUrl &securityOrigin, const QString& msg, const QString& defaultValue, QString* result)
+ bool javaScriptPrompt(const QUrl &securityOrigin, const QString& msg, const QString& defaultValue, QString* result) override
{
if (msg == QLatin1String("test1")) {
*result = QString();
@@ -963,7 +1134,7 @@ void tst_QWebEnginePage::testJSPrompt()
bool res;
QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
page.setHtml(QStringLiteral("<html><body></body></html>"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
// OK + QString()
res = evaluateJavaScriptSync(&page,
@@ -997,7 +1168,7 @@ void tst_QWebEnginePage::findText()
// Showing is required, otherwise all find operations fail.
m_view->show();
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
// Select whole page contents.
QTRY_VERIFY(m_view->page()->action(QWebEnginePage::SelectAll)->isEnabled());
@@ -1007,22 +1178,22 @@ void tst_QWebEnginePage::findText()
// Invoking a stopFinding operation will not change or clear the currently selected text,
// if nothing was found beforehand.
{
- CallbackSpy<bool> callbackSpy;
+ CallbackSpy<QWebEngineFindTextResult> callbackSpy;
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
m_view->findText("", {}, callbackSpy.ref());
QVERIFY(callbackSpy.wasCalled());
- QCOMPARE(signalSpy.count(), 1);
+ QCOMPARE(signalSpy.size(), 1);
QTRY_COMPARE(m_view->selectedText(), QString("foo bar"));
}
// Invoking a startFinding operation with text that won't be found, will clear the current
// selection.
{
- CallbackSpy<bool> callbackSpy;
+ CallbackSpy<QWebEngineFindTextResult> callbackSpy;
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
m_view->findText("Will not be found", {}, callbackSpy.ref());
- QCOMPARE(callbackSpy.waitForResult(), false);
- QTRY_COMPARE(signalSpy.count(), 1);
+ QCOMPARE(callbackSpy.waitForResult().numberOfMatches(), 0);
+ QTRY_COMPARE(signalSpy.size(), 1);
auto result = signalSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 0);
QTRY_VERIFY(m_view->selectedText().isEmpty());
@@ -1035,22 +1206,22 @@ void tst_QWebEnginePage::findText()
// Invoking a startFinding operation with text that will be found, will clear the current
// selection as well.
{
- CallbackSpy<bool> callbackSpy;
+ CallbackSpy<QWebEngineFindTextResult> callbackSpy;
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
m_view->findText("foo", {}, callbackSpy.ref());
- QVERIFY(callbackSpy.waitForResult());
- QTRY_COMPARE(signalSpy.count(), 1);
+ QVERIFY(callbackSpy.waitForResult().numberOfMatches() > 0);
+ QTRY_COMPARE(signalSpy.size(), 1);
QTRY_VERIFY(m_view->selectedText().isEmpty());
}
// Invoking a stopFinding operation after text was found, will set the selected text to the
// found text.
{
- CallbackSpy<bool> callbackSpy;
+ CallbackSpy<QWebEngineFindTextResult> callbackSpy;
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
m_view->findText("", {}, callbackSpy.ref());
QTRY_VERIFY(callbackSpy.wasCalled());
- QTRY_COMPARE(signalSpy.count(), 1);
+ QTRY_COMPARE(signalSpy.size(), 1);
QTRY_COMPARE(m_view->selectedText(), QString("foo"));
}
@@ -1060,7 +1231,7 @@ void tst_QWebEnginePage::findText()
QSignalSpy signalSpy(m_view->page(), &QWebEnginePage::findTextFinished);
m_view->findText("foo", {});
m_view->findText("foo", {});
- QTRY_COMPARE(signalSpy.count(), 2);
+ QTRY_COMPARE(signalSpy.size(), 2);
QTRY_VERIFY(m_view->selectedText().isEmpty());
QCOMPARE(signalSpy.at(0).value(0).value<QWebEngineFindTextResult>().numberOfMatches(), 0);
@@ -1072,7 +1243,7 @@ void tst_QWebEnginePage::findTextResult()
{
QSignalSpy findTextSpy(m_view->page(), &QWebEnginePage::findTextFinished);
auto signalResult = [&findTextSpy]() -> QList<int> {
- if (findTextSpy.count() != 1)
+ if (findTextSpy.size() != 1)
return QList<int>({-1, -1});
auto r = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
return QList<int>({ r.numberOfMatches(), r.activeMatch() });
@@ -1084,7 +1255,7 @@ void tst_QWebEnginePage::findTextResult()
QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(findTextSync(m_page, ""), false);
QCOMPARE(signalResult(), QList<int>({0, 0}));
@@ -1106,14 +1277,14 @@ void tst_QWebEnginePage::findTextResult()
void tst_QWebEnginePage::findTextSuccessiveShouldCallAllCallbacks()
{
- CallbackSpy<bool> spy1;
- CallbackSpy<bool> spy2;
- CallbackSpy<bool> spy3;
- CallbackSpy<bool> spy4;
- CallbackSpy<bool> spy5;
+ CallbackSpy<QWebEngineFindTextResult> spy1;
+ CallbackSpy<QWebEngineFindTextResult> spy2;
+ CallbackSpy<QWebEngineFindTextResult> spy3;
+ CallbackSpy<QWebEngineFindTextResult> spy4;
+ CallbackSpy<QWebEngineFindTextResult> spy5;
QSignalSpy loadSpy(m_view, SIGNAL(loadFinished(bool)));
m_view->setHtml(QString("<html><head></head><body><div>abcdefg abcdefg abcdefg abcdefg abcdefg</div></body></html>"));
- QTRY_COMPARE_WITH_TIMEOUT(loadSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
m_page->findText("abcde", {}, spy1.ref());
m_page->findText("abcd", {}, spy2.ref());
m_page->findText("abc", {}, spy3.ref());
@@ -1135,15 +1306,15 @@ void tst_QWebEnginePage::findTextCalledOnMatch()
m_view->resize(800, 600);
m_view->show();
m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
// CALLBACK
bool callbackCalled = false;
- m_view->page()->findText("foo", {}, [this, &callbackCalled](bool found) {
- QVERIFY(found);
+ m_view->page()->findText("foo", {}, [this, &callbackCalled](QWebEngineFindTextResult result) {
+ QVERIFY(result.numberOfMatches());
- m_view->page()->findText("bar", {}, [&callbackCalled](bool found) {
- QVERIFY(found);
+ m_view->page()->findText("bar", {}, [&callbackCalled](QWebEngineFindTextResult result) {
+ QVERIFY(result.numberOfMatches());
callbackCalled = true;
});
});
@@ -1172,12 +1343,12 @@ void tst_QWebEnginePage::findTextActiveMatchOrdinal()
m_view->resize(800, 600);
m_view->show();
m_view->setHtml(QString("<html><head></head><body><div>foo bar foo bar foo</div></body></html>"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
// Iterate over all "foo" matches.
for (int i = 1; i <= 3; ++i) {
m_view->page()->findText("foo", {});
- QTRY_COMPARE(findTextSpy.count(), 1);
+ QTRY_COMPARE(findTextSpy.size(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 3);
QCOMPARE(result.activeMatch(), i);
@@ -1185,28 +1356,28 @@ void tst_QWebEnginePage::findTextActiveMatchOrdinal()
// The last match is followed by the fist one.
m_view->page()->findText("foo", {});
- QTRY_COMPARE(findTextSpy.count(), 1);
+ QTRY_COMPARE(findTextSpy.size(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 3);
QCOMPARE(result.activeMatch(), 1);
// The first match is preceded by the last one.
m_view->page()->findText("foo", QWebEnginePage::FindBackward);
- QTRY_COMPARE(findTextSpy.count(), 1);
+ QTRY_COMPARE(findTextSpy.size(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 3);
QCOMPARE(result.activeMatch(), 3);
// Finding another word resets the activeMatch.
m_view->page()->findText("bar", {});
- QTRY_COMPARE(findTextSpy.count(), 1);
+ QTRY_COMPARE(findTextSpy.size(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 2);
QCOMPARE(result.activeMatch(), 1);
// If no match activeMatch is 0.
m_view->page()->findText("bla", {});
- QTRY_COMPARE(findTextSpy.count(), 1);
+ QTRY_COMPARE(findTextSpy.size(), 1);
result = findTextSpy.takeFirst().value(0).value<QWebEngineFindTextResult>();
QCOMPARE(result.numberOfMatches(), 0);
QCOMPARE(result.activeMatch(), 0);
@@ -1216,45 +1387,60 @@ static QWindow *findNewTopLevelWindow(const QWindowList &oldTopLevelWindows)
{
const auto tlws = QGuiApplication::topLevelWindows();
for (auto w : tlws) {
- if (!oldTopLevelWindows.contains(w)) {
+ // note 'offscreen' window is a top-level window
+ if (!oldTopLevelWindows.contains(w)
+ && !QQuickRenderControl::renderWindowFor(qobject_cast<QQuickWindow *>(w))) {
return w;
}
}
return nullptr;
}
+void tst_QWebEnginePage::comboBoxPopupPositionAfterMove_data()
+{
+ QTest::addColumn<bool>("withTouch");
+ QTest::addRow("mouse") << false;
+ QTest::addRow("touch") << true;
+}
+
void tst_QWebEnginePage::comboBoxPopupPositionAfterMove()
{
+#if defined(Q_OS_MACOS) && (defined(__arm64__) || defined(__aarch64__))
+ QSKIP("This test crashes for Apple M1");
+#endif
QWebEngineView view;
+ QTRY_VERIFY(QGuiApplication::primaryScreen());
view.move(QGuiApplication::primaryScreen()->availableGeometry().topLeft());
view.resize(640, 480);
view.show();
-
- QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QSignalSpy spyLoadFinished(&view, SIGNAL(loadFinished(bool)));
view.setHtml(QLatin1String("<html><head></head><body><select id='foo'>"
"<option>fran</option><option>troz</option>"
"</select></body></html>"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(spyLoadFinished.size(), 1);
const auto oldTlws = QGuiApplication::topLevelWindows();
- QWindow *window = view.windowHandle();
- QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
- elementCenter(view.page(), "foo"));
-
+ QFETCH(bool, withTouch);
+ QPointer<QWindow> window = view.windowHandle();
+ auto pos = elementCenter(view.page(), "foo");
+ makeClick(window, withTouch, pos);
QWindow *popup = nullptr;
- QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ QTRY_VERIFY((popup = findNewTopLevelWindow(oldTlws)));
+ QVERIFY(QTest::qWaitForWindowExposed(popup));
+ QTRY_VERIFY(popup->width() > 0 && popup->height() > 0);
QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
QTRY_VERIFY(!popup->position().isNull());
QPoint popupPos = popup->position();
-
+ QPointer<QWindow> pw(popup);
// Close the popup by clicking somewhere into the page.
- QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(1, 1));
+ makeClick(window, withTouch, QPoint(1, 1));
QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
-
+ QTRY_VERIFY(!pw);
auto jsViewPosition = [&view]() {
QLatin1String script("(function() { return [window.screenX, window.screenY]; })()");
QVariantList posList = evaluateJavaScriptSync(view.page(), script).toList();
- if (posList.count() != 2) {
+ if (posList.size() != 2) {
qWarning("jsViewPosition failed.");
return QPoint();
}
@@ -1266,18 +1452,28 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterMove()
const QPoint offset(12, 13);
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));
+ makeClick(window, withTouch, elementCenter(view.page(), "foo"));
+ QTRY_VERIFY((popup = findNewTopLevelWindow(oldTlws)));
+ QTRY_VERIFY(popup->width() > 0 && popup->height() > 0);
QTRY_VERIFY(QGuiApplication::topLevelWindows().contains(popup));
QTRY_VERIFY(!popup->position().isNull());
QCOMPARE(popupPos + offset, popup->position());
- QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(), QPoint(1, 1));
+ makeClick(window, withTouch, QPoint(1, 1));
QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
}
+void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove_data()
+{
+ QTest::addColumn<bool>("withTouch");
+ QTest::addRow("mouse") << false;
+ QTest::addRow("touch") << true;
+}
+
void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
{
+#if defined(Q_OS_MACOS) && (defined(__arm64__) || defined(__aarch64__))
+ QSKIP("This test crashes for Apple M1");
+#endif
QWidget mainWidget;
mainWidget.setLayout(new QHBoxLayout);
@@ -1288,29 +1484,33 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
mainWidget.layout()->addWidget(&view);
QScreen *screen = QGuiApplication::primaryScreen();
+ Q_ASSERT(screen);
mainWidget.move(screen->availableGeometry().topLeft());
mainWidget.resize(640, 480);
mainWidget.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&mainWidget));
QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
view.setHtml(QLatin1String("<html><head></head><body><select autofocus id='foo'>"
"<option value=\"narf\">narf</option><option>zort</option>"
"</select></body></html>"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
const auto oldTlws = QGuiApplication::topLevelWindows();
- QWindow *window = view.window()->windowHandle();
- QTest::mouseClick(window, Qt::LeftButton, Qt::KeyboardModifiers(),
- view.mapTo(view.window(), elementCenter(view.page(), "foo")));
+
+ QFETCH(bool, withTouch);
+ QPointer<QWindow> window = view.window()->windowHandle();
+ makeClick(window, withTouch, view.mapTo(view.window(), elementCenter(view.page(), "foo")));
QWindow *popup = nullptr;
- QTRY_VERIFY(popup = findNewTopLevelWindow(oldTlws));
+ QTRY_VERIFY((popup = findNewTopLevelWindow(oldTlws)));
+ QVERIFY(QTest::qWaitForWindowExposed(popup));
+ QTRY_VERIFY(popup->width() > 0 && popup->height() > 0);
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(),
- view.mapTo(view.window(), QPoint(1, 1)));
+ makeClick(window, withTouch, view.mapTo(view.window(), QPoint(1, 1)));
QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
int originalViewWidth = view.size().width();
@@ -1320,19 +1520,25 @@ void tst_QWebEnginePage::comboBoxPopupPositionAfterChildMove()
return viewWidth;
};
+ QCOMPARE(jsViewWidth(), originalViewWidth);
+
// Resize the "spacer" widget, and implicitly change the global position of the QWebEngineView.
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));
+ makeClick(window, withTouch, view.mapTo(view.window(), elementCenter(view.page(), "foo")));
+ QTRY_VERIFY((popup = findNewTopLevelWindow(oldTlws)));
+ QVERIFY(QTest::qWaitForWindowExposed(popup));
+ QTRY_VERIFY(popup->width() > 0 && popup->height() > 0);
QTRY_VERIFY(!popup->position().isNull());
- QCOMPARE(popupPos + QPoint(50, 0), popup->position());
+ QCOMPARE(popupPos + QPoint(offset, 0), popup->position());
+ makeClick(window, withTouch, QPoint(1, 1));
+ QTRY_VERIFY(!QGuiApplication::topLevelWindows().contains(popup));
}
-#ifdef Q_OS_MAC
+#ifdef Q_OS_MACOS
void tst_QWebEnginePage::macCopyUnicodeToClipboard()
{
QString unicodeText = QString::fromUtf8("αβγδεζηθικλμπ");
@@ -1451,11 +1657,13 @@ public:
GetUserMediaTestPage()
: m_gotRequest(false)
, m_loadSucceeded(false)
+ , m_permission(nullptr)
{
- connect(this, &QWebEnginePage::featurePermissionRequested, this, &GetUserMediaTestPage::onFeaturePermissionRequested);
+ connect(this, &QWebEnginePage::permissionRequested, this, &GetUserMediaTestPage::onPermissionRequested);
connect(this, &QWebEnginePage::loadFinished, [this](bool success){
m_loadSucceeded = success;
});
+ profile()->setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
// We need to load content from a resource in order for the securityOrigin to be valid.
load(QUrl("qrc:///resources/content.html"));
}
@@ -1489,18 +1697,20 @@ public:
void rejectPendingRequest()
{
- setFeaturePermission(m_requestSecurityOrigin, m_requestedFeature, QWebEnginePage::PermissionDeniedByUser);
+ QVERIFY(m_permission);
+ m_permission->deny();
m_gotRequest = false;
}
void acceptPendingRequest()
{
- setFeaturePermission(m_requestSecurityOrigin, m_requestedFeature, QWebEnginePage::PermissionGrantedByUser);
+ QVERIFY(m_permission);
+ m_permission->grant();
m_gotRequest = false;
}
- bool gotFeatureRequest(QWebEnginePage::Feature feature)
+ bool gotFeatureRequest(QWebEnginePermission::Feature feature)
{
- return m_gotRequest && m_requestedFeature == feature;
+ return m_gotRequest && m_permission && m_permission->feature() == feature;
}
bool gotFeatureRequest() const
@@ -1514,50 +1724,47 @@ public:
}
private Q_SLOTS:
- void onFeaturePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature)
+ void onPermissionRequested(QWebEnginePermission permission)
{
- m_requestedFeature = feature;
- m_requestSecurityOrigin = securityOrigin;
+ m_permission.reset(new QWebEnginePermission(permission));
m_gotRequest = true;
}
private:
bool m_gotRequest;
bool m_loadSucceeded;
- QWebEnginePage::Feature m_requestedFeature;
- QUrl m_requestSecurityOrigin;
-
+ std::unique_ptr<QWebEnginePermission> m_permission;
};
void tst_QWebEnginePage::getUserMediaRequest_data()
{
QTest::addColumn<QString>("call");
- QTest::addColumn<QWebEnginePage::Feature>("feature");
+ QTest::addColumn<QWebEnginePermission::Feature>("feature");
QTest::addRow("device audio")
- << "getUserMedia({audio: true})" << QWebEnginePage::MediaAudioCapture;
+ << "getUserMedia({audio: true})" << QWebEnginePermission::MediaAudioCapture;
QTest::addRow("device video")
- << "getUserMedia({video: true})" << QWebEnginePage::MediaVideoCapture;
+ << "getUserMedia({video: true})" << QWebEnginePermission::MediaVideoCapture;
QTest::addRow("device audio+video")
- << "getUserMedia({audio: true, video: true})" << QWebEnginePage::MediaAudioVideoCapture;
+ << "getUserMedia({audio: true, video: true})" << QWebEnginePermission::MediaAudioVideoCapture;
QTest::addRow("desktop video")
<< "getUserMedia({video: { mandatory: { chromeMediaSource: 'desktop' }}})"
- << QWebEnginePage::DesktopVideoCapture;
+ << QWebEnginePermission::DesktopVideoCapture;
QTest::addRow("desktop audio+video")
<< "getUserMedia({audio: { mandatory: { chromeMediaSource: 'desktop' }}, video: { mandatory: { chromeMediaSource: 'desktop' }}})"
- << QWebEnginePage::DesktopAudioVideoCapture;
+ << QWebEnginePermission::DesktopAudioVideoCapture;
QTest::addRow("display video")
- << "getDisplayMedia()" << QWebEnginePage::DesktopVideoCapture;
+ << "getDisplayMedia()" << QWebEnginePermission::DesktopVideoCapture;
}
void tst_QWebEnginePage::getUserMediaRequest()
{
QFETCH(QString, call);
- QFETCH(QWebEnginePage::Feature, feature);
+ QFETCH(QWebEnginePermission::Feature, feature);
GetUserMediaTestPage page;
QWebEngineView view;
- if (feature == QWebEnginePage::DesktopVideoCapture || feature == QWebEnginePage::DesktopAudioVideoCapture) {
+ if (feature == QWebEnginePermission::DesktopVideoCapture || feature == QWebEnginePermission::DesktopAudioVideoCapture) {
// Desktop capture needs to be on a desktop.
view.setPage(&page);
view.resize(640, 480);
@@ -1627,7 +1834,7 @@ void tst_QWebEnginePage::getUserMediaRequestSettingDisabled()
void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyPages()
{
const QString constraints = QStringLiteral("{video: { mandatory: { chromeMediaSource: 'desktop' }}}");
- const QWebEnginePage::Feature feature = QWebEnginePage::DesktopVideoCapture;
+ const QWebEnginePermission::Feature feature = QWebEnginePermission::DesktopVideoCapture;
std::vector<GetUserMediaTestPage> pages(10);
// Desktop capture needs to be on a desktop
@@ -1660,7 +1867,7 @@ void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyPages()
void tst_QWebEnginePage::getUserMediaRequestDesktopVideoManyRequests()
{
const QString constraints = QStringLiteral("{video: { mandatory: { chromeMediaSource: 'desktop' }}}");
- const QWebEnginePage::Feature feature = QWebEnginePage::DesktopVideoCapture;
+ const QWebEnginePermission::Feature feature = QWebEnginePermission::DesktopVideoCapture;
GetUserMediaTestPage page;
// Desktop capture needs to be on a desktop
@@ -1719,18 +1926,21 @@ void tst_QWebEnginePage::savePage()
void tst_QWebEnginePage::openWindowDefaultSize()
{
TestPage page;
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
QSignalSpy windowCreatedSpy(&page, SIGNAL(windowCreated()));
QWebEngineView view;
- page.setView(&view);
+ view.setPage(&page);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
+ view.setUrl(QUrl("about:blank"));
view.show();
+ QTRY_COMPARE(spyFinished.size(), 1);
- page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
// Open a default window.
page.runJavaScript("window.open()");
- QTRY_COMPARE(windowCreatedSpy.count(), 1);
+ QTRY_COMPARE(windowCreatedSpy.size(), 1);
// Open a too small window.
evaluateJavaScriptSync(&page, "window.open('','about:blank','width=10,height=10')");
- QTRY_COMPARE(windowCreatedSpy.count(), 2);
+ QTRY_COMPARE(windowCreatedSpy.size(), 2);
// The number of popups created should be two.
QCOMPARE(page.createdWindows.size(), 2);
@@ -1801,7 +2011,7 @@ void tst_QWebEnginePage::runJavaScriptDisabled()
// Settings changes take effect asynchronously. The load and wait ensure
// that the settings are applied by the time we start to execute JavaScript.
page.load(QStringLiteral("about:blank"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 20000);
QCOMPARE(evaluateJavaScriptSyncInWorld(&page, QStringLiteral("1+1"), QWebEngineScript::MainWorld),
QVariant());
QCOMPARE(evaluateJavaScriptSyncInWorld(&page, QStringLiteral("1+1"), QWebEngineScript::ApplicationWorld),
@@ -1818,7 +2028,7 @@ void tst_QWebEnginePage::runJavaScriptFromSlot()
page.setHtml("<html><body>"
" <input type='text' id='input1' value='QtWebEngine' size='50' />"
"</body></html>");
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
bool done = false;
connect(&page, &QWebEnginePage::selectionChanged, [&]() {
@@ -1842,7 +2052,7 @@ void tst_QWebEnginePage::fullScreenRequested()
QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
page->load(QUrl("qrc:///resources/fullscreen.html"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QTRY_VERIFY(isTrueJavaScriptResult(page, "document.webkitFullscreenEnabled"));
QVERIFY(isFalseJavaScriptResult(page, "document.webkitIsFullScreen"));
@@ -1859,7 +2069,7 @@ void tst_QWebEnginePage::fullScreenRequested()
QTest::mouseMove(view.windowHandle(), QPoint(10,10));
QTest::mouseClick(view.windowHandle(), Qt::RightButton);
- QTRY_COMPARE(view.findChildren<QMenu *>().count(), 1);
+ QTRY_COMPARE(view.findChildren<QMenu *>().size(), 1);
auto menu = view.findChildren<QMenu *>().first();
QVERIFY(menu->actions().contains(page->action(QWebEnginePage::ExitFullScreen)));
@@ -1873,8 +2083,18 @@ void tst_QWebEnginePage::fullScreenRequested()
QTRY_VERIFY(isFalseJavaScriptResult(page, "document.webkitIsFullScreen"));
}
-void tst_QWebEnginePage::quotaRequested()
+void tst_QWebEnginePage::requestQuota_data()
{
+ QTest::addColumn<QString>("storage");
+ QTest::addRow("webkitPersistentStorage") << "navigator.webkitPersistentStorage";
+ QTest::addRow("webkitTemporaryStorage") << "navigator.webkitTemporaryStorage";
+
+}
+
+void tst_QWebEnginePage::requestQuota()
+{
+ QFETCH(QString, storage);
+
ConsolePage page;
QWebEngineView view;
view.setPage(&page);
@@ -1882,35 +2102,23 @@ void tst_QWebEnginePage::quotaRequested()
page.load(QUrl("qrc:///resources/content.html"));
QVERIFY(loadFinishedSpy.wait());
- connect(&page, &QWebEnginePage::quotaRequested,
- [] (QWebEngineQuotaRequest request)
- {
- if (request.requestedSize() <= 5000)
- request.accept();
- else
- request.reject();
- });
-
- evaluateJavaScriptSync(&page,
- "navigator.webkitPersistentStorage.requestQuota(1024, function(grantedSize) {" \
- "console.log(grantedSize);" \
- "});");
- QTRY_COMPARE(page.messages.count(), 1);
+ evaluateJavaScriptSync(&page, QString(
+ "var storage = %1;"
+ "storage.requestQuota(1024, function(grantedSize) {"
+ " console.log(grantedSize);"
+ "});").arg(storage));
+ QTRY_COMPARE(page.messages.size(), 1);
QTRY_COMPARE(page.messages[0], QString("1024"));
- evaluateJavaScriptSync(&page,
- "navigator.webkitPersistentStorage.requestQuota(6000, function(grantedSize) {" \
- "console.log(grantedSize);" \
- "});");
- QTRY_COMPARE(page.messages.count(), 2);
- QTRY_COMPARE(page.messages[1], QString("1024"));
-
- evaluateJavaScriptSync(&page,
- "navigator.webkitPersistentStorage.queryUsageAndQuota(function(usedBytes, grantedBytes) {" \
- "console.log(usedBytes + ', ' + grantedBytes);" \
- "});");
- QTRY_COMPARE(page.messages.count(), 3);
- QTRY_COMPARE(page.messages[2], QString("0, 1024"));
+ evaluateJavaScriptSync(&page, QString(
+ "var storage = %1;"
+ "storage.queryUsageAndQuota(function(usedBytes, grantedBytes) {"
+ " console.log(usedBytes);"
+ " console.log(grantedBytes);"
+ "});").arg(storage));
+ QTRY_COMPARE(page.messages.size(), 3);
+ QTRY_COMPARE(page.messages[1], QString("0"));
+ QTRY_VERIFY(page.messages[2].toLongLong() >= 1024);
}
void tst_QWebEnginePage::symmetricUrl()
@@ -1925,13 +2133,14 @@ void tst_QWebEnginePage::symmetricUrl()
QUrl dataUrl("data:text/html,<h1>Test");
view.setUrl(dataUrl);
+ view.show();
QCOMPARE(view.url(), dataUrl);
QCOMPARE(view.history()->count(), 0);
// loading is _not_ immediate, so the text isn't set just yet.
QVERIFY(toPlainTextSync(view.page()).isEmpty());
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 20000);
QCOMPARE(view.history()->count(), 1);
QCOMPARE(toPlainTextSync(view.page()), QString("Test"));
@@ -1945,8 +2154,8 @@ void tst_QWebEnginePage::symmetricUrl()
QCOMPARE(view.url(), dataUrl3);
// setUrl(dataUrl3) might override the pending load for dataUrl2. Or not.
- QTRY_VERIFY(loadFinishedSpy.count() >= 2);
- QTRY_VERIFY(loadFinishedSpy.count() <= 3);
+ QTRY_VERIFY(loadFinishedSpy.size() >= 2);
+ QTRY_VERIFY(loadFinishedSpy.size() <= 3);
// setUrl(dataUrl3) might stop Chromium from adding a navigation entry for dataUrl2,
// depending on whether the load of dataUrl2 could be completed in time.
@@ -2024,7 +2233,7 @@ public:
setAttribute(QNetworkRequest::RedirectionTargetAttribute, QUrl("qrc:/test2.html"));
QTimer::singleShot(0, this, SLOT(continueRedirect()));
}
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
else if (request.url() == QUrl("qrc:/fake-ssl-error.html")) {
setError(QNetworkReply::SslHandshakeFailedError, tr("Fake error!"));
QTimer::singleShot(0, this, SLOT(continueError()));
@@ -2045,11 +2254,11 @@ public:
{
close();
}
- virtual void abort() {}
- virtual void close() {}
+ void abort() override {}
+ void close() override {}
protected:
- qint64 readData(char*, qint64)
+ qint64 readData(char*, qint64) override
{
return 0;
}
@@ -2077,11 +2286,11 @@ public:
FakeNetworkManager(QObject* parent) : QNetworkAccessManager(parent) { }
protected:
- virtual QNetworkReply* createRequest(Operation op, const QNetworkRequest& request, QIODevice* outgoingData)
+ QNetworkReply* createRequest(Operation op, const QNetworkRequest& request, QIODevice* outgoingData) override
{
QString url = request.url().toString();
if (op == QNetworkAccessManager::GetOperation) {
-#ifndef QT_NO_OPENSSL
+#if QT_CONFIG(openssl)
if (url == "qrc:/fake-ssl-error.html") {
FakeReply* reply = new FakeReply(request, this);
QList<QSslError> errors;
@@ -2105,7 +2314,7 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures()
const QUrl first("http://abcdef.abcdef/");
page.setUrl(first);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 20000);
QCOMPARE(page.url(), first);
QCOMPARE(page.requestedUrl(), first);
QVERIFY(!spy.at(0).first().toBool());
@@ -2114,7 +2323,7 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures()
QVERIFY(first != second);
page.load(second);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 2, 20000);
QCOMPARE(page.url(), first);
QCOMPARE(page.requestedUrl(), second);
QVERIFY(!spy.at(1).first().toBool());
@@ -2160,7 +2369,7 @@ void tst_QWebEnginePage::setHtmlWithImageResource()
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setHtml(html, QUrl("file:///path/to/file"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 12000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 12000);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
@@ -2169,7 +2378,7 @@ void tst_QWebEnginePage::setHtmlWithImageResource()
// Now we test the opposite: without a baseUrl as a local file, we can still request qrc resources.
page.setHtml(html);
- QTRY_COMPARE(spy.count(), 2);
+ QTRY_COMPARE(spy.size(), 2);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128);
@@ -2210,10 +2419,15 @@ void tst_QWebEnginePage::setHtmlWithBaseURL()
// This tests if baseUrl is indeed affecting the relative paths from resources.
// As we are using a local file as baseUrl, its security origin should be able to load local resources.
- 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);
+ if (!QDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()).exists())
+ W_QSKIP(QString("This test requires access to resources found in '%1'")
+ .arg(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath())
+ .toLatin1()
+ .constData(),
+ SkipAll);
- QDir::setCurrent(TESTS_SOURCE_DIR);
+ QDir::setCurrent(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath());
+ qDebug()<<QDir::current();
QString html("<html><body><p>hello world</p><img src='resources/image2.png'/></body></html>");
@@ -2222,10 +2436,12 @@ void tst_QWebEnginePage::setHtmlWithBaseURL()
// in few seconds, the image should be completey loaded
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
- page.setHtml(html, QUrl::fromLocalFile(TESTS_SOURCE_DIR));
+ page.setHtml(html,
+ QUrl::fromLocalFile(
+ QString("%1/foo.html").arg(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath())));
QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
QVERIFY(spyFinished.wait());
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128);
@@ -2242,7 +2458,7 @@ public:
int alerts;
protected:
- virtual void javaScriptAlert(const QUrl &securityOrigin, const QString &msg)
+ void javaScriptAlert(const QUrl &securityOrigin, const QString &msg) override
{
alerts++;
QCOMPARE(securityOrigin, QUrl(QStringLiteral("http://test.origin.com/")));
@@ -2288,7 +2504,7 @@ void tst_QWebEnginePage::setHtmlWithModuleImport()
QWebEnginePage page;
QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
page.setHtml(html, server.url());
- QVERIFY(spy.count() || spy.wait());
+ QVERIFY(spy.size() || spy.wait());
QCOMPARE(evaluateJavaScriptSync(&page, "fib7"), QVariant(13));
}
@@ -2324,7 +2540,7 @@ void tst_QWebEnginePage::baseUrl()
QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool)));
m_page->setHtml(html, loadUrl);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(m_page->url(), url);
QEXPECT_FAIL("null", "Slight change: We now translate QUrl() to about:blank for the virtual url, but not for the baseUrl", Continue);
QCOMPARE(baseUrlSync(m_page), baseUrl);
@@ -2333,7 +2549,8 @@ void tst_QWebEnginePage::baseUrl()
void tst_QWebEnginePage::scrollPosition()
{
// enlarged image in a small viewport, to provoke the scrollbars to appear
- QString html("<html><body><img src='qrc:/image.png' height=500 width=500/></body></html>");
+ QString html(
+ "<html><body><img src='qrc:/resources/image.png' height=500 width=500/></body></html>");
QWebEngineView view;
view.setFixedSize(200,200);
@@ -2343,12 +2560,12 @@ void tst_QWebEnginePage::scrollPosition()
QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool)));
view.setHtml(html);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
// try to set the scroll offset programmatically
view.page()->runJavaScript("window.scrollTo(23, 29);");
- QTRY_COMPARE(view.page()->scrollPosition().x(), 23 * view.windowHandle()->devicePixelRatio());
- QCOMPARE(view.page()->scrollPosition().y(), 29 * view.windowHandle()->devicePixelRatio());
+ QTRY_COMPARE(view.page()->scrollPosition().x(), 23);
+ QCOMPARE(view.page()->scrollPosition().y(), 29);
int x = evaluateJavaScriptSync(view.page(), "window.scrollX").toInt();
int y = evaluateJavaScriptSync(view.page(), "window.scrollY").toInt();
@@ -2369,7 +2586,7 @@ void tst_QWebEnginePage::scrollbarsOff()
QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
view.setHtml(html);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QVERIFY(evaluateJavaScriptSync(view.page(), "innerWidth == document.documentElement.offsetWidth").toBool());
}
@@ -2380,7 +2597,8 @@ signals:
void repaintRequested();
protected:
- bool event(QEvent *event) {
+ bool event(QEvent *event) override
+ {
if (event->type() == QEvent::UpdateRequest)
emit repaintRequested();
@@ -2403,7 +2621,7 @@ void tst_QWebEnginePage::evaluateWillCauseRepaint()
QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool)));
view.setHtml(html);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
evaluateJavaScriptSync(view.page(), "document.getElementById('junk').style.display = 'none';");
QSignalSpy repaintSpy(&view, &WebView::repaintRequested);
@@ -2452,7 +2670,7 @@ public:
{
}
- virtual QNetworkReply* createRequest(Operation, const QNetworkRequest& request, QIODevice*)
+ QNetworkReply* createRequest(Operation, const QNetworkRequest& request, QIODevice*) override
{
QVariant cacheLoad = request.attribute(QNetworkRequest::CacheLoadControlAttribute);
if (cacheLoad.isValid())
@@ -2497,7 +2715,7 @@ void tst_QWebEnginePage::setUrlToEmpty()
expectedLoadFinishedCount++;
QVERIFY(spy.wait());
- QCOMPARE(spy.count(), expectedLoadFinishedCount);
+ QCOMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(page.url(), url);
QCOMPARE(page.requestedUrl(), url);
QCOMPARE(baseUrlSync(&page), url);
@@ -2506,7 +2724,7 @@ void tst_QWebEnginePage::setUrlToEmpty()
page.setUrl(QUrl());
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(page.url(), aboutBlank);
QCOMPARE(page.requestedUrl(), QUrl());
QCOMPARE(baseUrlSync(&page), aboutBlank);
@@ -2515,7 +2733,7 @@ void tst_QWebEnginePage::setUrlToEmpty()
page.setUrl(url);
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(page.url(), url);
QCOMPARE(page.requestedUrl(), url);
QCOMPARE(baseUrlSync(&page), url);
@@ -2524,7 +2742,7 @@ void tst_QWebEnginePage::setUrlToEmpty()
page.load(QUrl());
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(page.url(), aboutBlank);
QCOMPARE(page.requestedUrl(), QUrl());
QCOMPARE(baseUrlSync(&page), aboutBlank);
@@ -2579,9 +2797,9 @@ void tst_QWebEnginePage::setUrlToBadDomain()
page.setUrl(url1);
- QTRY_COMPARE(urlSpy.count(), 1);
- QTRY_COMPARE_WITH_TIMEOUT(titleSpy.count(), 1, 20000);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(urlSpy.size(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(titleSpy.size(), 1, 20000);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url1);
QCOMPARE(titleSpy.takeFirst().value(0).toString(), url1.host());
@@ -2592,9 +2810,9 @@ void tst_QWebEnginePage::setUrlToBadDomain()
page.setUrl(url2);
- QTRY_COMPARE(urlSpy.count(), 1);
- QTRY_COMPARE_WITH_TIMEOUT(titleSpy.count(), 1, 20000);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(urlSpy.size(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(titleSpy.size(), 1, 20000);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url2);
QCOMPARE(titleSpy.takeFirst().value(0).toString(), url2.host());
@@ -2618,9 +2836,9 @@ void tst_QWebEnginePage::setUrlToBadPort()
page.setUrl(url1);
- QTRY_COMPARE(urlSpy.count(), 1);
- QTRY_COMPARE(titleSpy.count(), 2);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(urlSpy.size(), 1);
+ QTRY_COMPARE(titleSpy.size(), 2);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url1);
QCOMPARE(titleSpy.takeFirst().value(0).toString(), url1.authority());
@@ -2632,9 +2850,9 @@ void tst_QWebEnginePage::setUrlToBadPort()
page.setUrl(url2);
- QTRY_COMPARE(urlSpy.count(), 1);
- QTRY_COMPARE(titleSpy.count(), 2);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(urlSpy.size(), 1);
+ QTRY_COMPARE(titleSpy.size(), 2);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(urlSpy.takeFirst().value(0).toUrl(), url2);
QCOMPARE(titleSpy.takeFirst().value(0).toString(), url2.authority());
@@ -2665,7 +2883,7 @@ void tst_QWebEnginePage::setUrlHistory()
m_page->setUrl(QUrl());
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(m_page->url(), aboutBlank);
QCOMPARE(m_page->requestedUrl(), QUrl());
// Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank.
@@ -2674,7 +2892,7 @@ void tst_QWebEnginePage::setUrlHistory()
url = QUrl("http://url.invalid/");
m_page->setUrl(url);
expectedLoadFinishedCount++;
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), expectedLoadFinishedCount, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), expectedLoadFinishedCount, 20000);
// When error page is disabled in case of LoadFail the entry of the unavailable page is not stored.
// We expect the url of the previously loaded page here.
QCOMPARE(m_page->url(), aboutBlank);
@@ -2685,14 +2903,14 @@ void tst_QWebEnginePage::setUrlHistory()
url = QUrl("qrc:/resources/test1.html");
m_page->setUrl(url);
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(m_page->url(), url);
QCOMPARE(m_page->requestedUrl(), url);
QCOMPARE(collectHistoryUrls(m_page->history()), QStringList() << aboutBlank.toString() << QStringLiteral("qrc:/resources/test1.html"));
m_page->setUrl(QUrl());
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(m_page->url(), aboutBlank);
QCOMPARE(m_page->requestedUrl(), QUrl());
// Chromium stores navigation entry for every successful loads. The load of the empty page is committed and stored as about:blank.
@@ -2704,7 +2922,7 @@ void tst_QWebEnginePage::setUrlHistory()
url = QUrl("qrc:/resources/test1.html");
m_page->setUrl(url);
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(m_page->url(), url);
QCOMPARE(m_page->requestedUrl(), url);
// The history count DOES change since the about:blank is in the list.
@@ -2717,7 +2935,7 @@ void tst_QWebEnginePage::setUrlHistory()
url = QUrl("qrc:/resources/test2.html");
m_page->setUrl(url);
expectedLoadFinishedCount++;
- QTRY_COMPARE(spy.count(), expectedLoadFinishedCount);
+ QTRY_COMPARE(spy.size(), expectedLoadFinishedCount);
QCOMPARE(m_page->url(), url);
QCOMPARE(m_page->requestedUrl(), url);
QCOMPARE(collectHistoryUrls(m_page->history()), QStringList()
@@ -2732,6 +2950,7 @@ void tst_QWebEnginePage::setUrlUsingStateObject()
{
QUrl url;
QSignalSpy urlChangedSpy(m_page, SIGNAL(urlChanged(QUrl)));
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
int expectedUrlChangeCount = 0;
QCOMPARE(m_page->history()->count(), 0);
@@ -2739,20 +2958,22 @@ void tst_QWebEnginePage::setUrlUsingStateObject()
url = QUrl("qrc:/resources/test1.html");
m_page->setUrl(url);
expectedUrlChangeCount++;
- QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QTRY_COMPARE(urlChangedSpy.size(), expectedUrlChangeCount);
+ QCOMPARE(m_page->url(), url);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(m_page->url(), url);
- QTRY_COMPARE(m_page->history()->count(), 1);
+ QCOMPARE(m_page->history()->count(), 1);
evaluateJavaScriptSync(m_page, "window.history.pushState(null, 'push', 'navigate/to/here')");
expectedUrlChangeCount++;
- QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QTRY_COMPARE(urlChangedSpy.size(), expectedUrlChangeCount);
QCOMPARE(m_page->url(), QUrl("qrc:/resources/navigate/to/here"));
QCOMPARE(m_page->history()->count(), 2);
QVERIFY(m_page->history()->canGoBack());
evaluateJavaScriptSync(m_page, "window.history.replaceState(null, 'replace', 'another/location')");
expectedUrlChangeCount++;
- QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QTRY_COMPARE(urlChangedSpy.size(), expectedUrlChangeCount);
QCOMPARE(m_page->url(), QUrl("qrc:/resources/navigate/to/another/location"));
QCOMPARE(m_page->history()->count(), 2);
QVERIFY(!m_page->history()->canGoForward());
@@ -2760,7 +2981,7 @@ void tst_QWebEnginePage::setUrlUsingStateObject()
evaluateJavaScriptSync(m_page, "window.history.back()");
expectedUrlChangeCount++;
- QTRY_COMPARE(urlChangedSpy.count(), expectedUrlChangeCount);
+ QTRY_COMPARE(urlChangedSpy.size(), expectedUrlChangeCount);
QCOMPARE(m_page->url(), QUrl("qrc:/resources/test1.html"));
QVERIFY(m_page->history()->canGoForward());
QVERIFY(!m_page->history()->canGoBack());
@@ -2789,9 +3010,9 @@ void tst_QWebEnginePage::setUrlThenLoads()
QSignalSpy finishedSpy(m_page, SIGNAL(loadFinished(bool)));
m_page->setUrl(url);
- QTRY_COMPARE(startedSpy.count(), 1);
- QTRY_COMPARE(urlChangedSpy.count(), 1);
- QTRY_COMPARE(finishedSpy.count(), 1);
+ QTRY_COMPARE(startedSpy.size(), 1);
+ QTRY_COMPARE(urlChangedSpy.size(), 1);
+ QTRY_COMPARE(finishedSpy.size(), 1);
QVERIFY(finishedSpy.at(0).first().toBool());
QCOMPARE(m_page->url(), url);
QCOMPARE(m_page->requestedUrl(), url);
@@ -2805,11 +3026,11 @@ void tst_QWebEnginePage::setUrlThenLoads()
QTRY_COMPARE(m_page->requestedUrl(), urlToLoad1);
// baseUrlSync spins an event loop and this sometimes return the next result.
// QCOMPARE(baseUrlSync(m_page), baseUrl);
- QTRY_COMPARE(startedSpy.count(), 2);
+ QTRY_COMPARE(startedSpy.size(), 2);
// After first URL changed.
- QTRY_COMPARE(urlChangedSpy.count(), 2);
- QTRY_COMPARE(finishedSpy.count(), 2);
+ QTRY_COMPARE(urlChangedSpy.size(), 2);
+ QTRY_COMPARE(finishedSpy.size(), 2);
QVERIFY(finishedSpy.at(1).first().toBool());
QCOMPARE(m_page->url(), urlToLoad1);
QCOMPARE(m_page->requestedUrl(), urlToLoad1);
@@ -2819,31 +3040,17 @@ void tst_QWebEnginePage::setUrlThenLoads()
QCOMPARE(m_page->url(), urlToLoad1);
QCOMPARE(m_page->requestedUrl(), urlToLoad2);
QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad1));
- QTRY_COMPARE(startedSpy.count(), 3);
+ QTRY_COMPARE(startedSpy.size(), 3);
// After second URL changed.
- QTRY_COMPARE(urlChangedSpy.count(), 3);
- QTRY_COMPARE(finishedSpy.count(), 3);
+ QTRY_COMPARE(urlChangedSpy.size(), 3);
+ QTRY_COMPARE(finishedSpy.size(), 3);
QVERIFY(finishedSpy.at(2).first().toBool());
QCOMPARE(m_page->url(), urlToLoad2);
QCOMPARE(m_page->requestedUrl(), urlToLoad2);
QCOMPARE(baseUrlSync(m_page), extractBaseUrl(urlToLoad2));
}
-void tst_QWebEnginePage::loadFinishedAfterNotFoundError()
-{
- QWebEnginePage page;
- QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
-
- page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
- page.setUrl(QUrl("http://non.existent/url"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
-
- page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
- page.setUrl(QUrl("http://another.non.existent/url"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 20000);
-}
-
class URLSetter : public QObject {
Q_OBJECT
@@ -2925,11 +3132,7 @@ void tst_QWebEnginePage::loadInSignalHandlers()
URLSetter setter(m_page, signal, type, urlForSetter);
QSignalSpy spy(&setter, &URLSetter::finished);
m_page->load(url);
- // every loadStarted() call should have also loadFinished()
- if (signal == URLSetter::LoadStarted)
- QTRY_COMPARE(spy.count(), 2);
- else
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_VERIFY_WITH_TIMEOUT(spy.size() >= 1, 20000);
QCOMPARE(m_page->url(), urlForSetter);
}
@@ -2940,31 +3143,31 @@ void tst_QWebEnginePage::loadFromQrc()
// Standard case.
page.load(QStringLiteral("qrc:///resources/foo.txt"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().value(0).toBool(), true);
QCOMPARE(toPlainTextSync(&page), QStringLiteral("foo\n"));
// Query and fragment parts are ignored.
page.load(QStringLiteral("qrc:///resources/bar.txt?foo=1#bar"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().value(0).toBool(), true);
QCOMPARE(toPlainTextSync(&page), QStringLiteral("bar\n"));
// Literal spaces are OK.
page.load(QStringLiteral("qrc:///resources/path with spaces.txt"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().value(0).toBool(), true);
QCOMPARE(toPlainTextSync(&page), QStringLiteral("contents with spaces\n"));
// Escaped spaces are OK too.
page.load(QStringLiteral("qrc:///resources/path%20with%20spaces.txt"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(spy.takeFirst().value(0).toBool(), true);
QCOMPARE(toPlainTextSync(&page), QStringLiteral("contents with spaces\n"));
// Resource not found, loading fails.
page.load(QStringLiteral("qrc:///nope"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 10000);
QCOMPARE(spy.takeFirst().value(0).toBool(), false);
}
@@ -2981,7 +3184,7 @@ void tst_QWebEnginePage::restoreHistory()
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.load(QUrl(QStringLiteral("qrc:/resources/test1.html")));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(page.webChannel(), &channel);
QVERIFY(page.scripts().contains(script));
@@ -2991,7 +3194,7 @@ void tst_QWebEnginePage::restoreHistory()
out << *page.history();
QDataStream in(&data, QIODevice::ReadOnly);
in >> *page.history();
- QTRY_COMPARE(spy.count(), 2);
+ QTRY_COMPARE(spy.size(), 2);
QCOMPARE(page.webChannel(), &channel);
QVERIFY(page.scripts().contains(script));
@@ -3014,42 +3217,59 @@ void tst_QWebEnginePage::toPlainTextLoadFinishedRace()
QSignalSpy spy(page.data(), SIGNAL(loadFinished(bool)));
page->load(QUrl("data:text/plain,foobarbaz"));
- QTRY_VERIFY(spy.count() == 1);
+ QTRY_VERIFY(spy.size() == 1);
QCOMPARE(toPlainTextSync(page.data()), QString("foobarbaz"));
page->load(QUrl("http://fail.invalid/"));
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 2, 20000);
QString s = toPlainTextSync(page.data());
QVERIFY(s.contains("foobarbaz") == !enableErrorPage);
page->load(QUrl("data:text/plain,lalala"));
- QTRY_COMPARE(spy.count(), 3);
+ QTRY_COMPARE(spy.size(), 3);
QTRY_COMPARE(toPlainTextSync(page.data()), QString("lalala"));
page.reset();
- QCOMPARE(spy.count(), 3);
+ QCOMPARE(spy.size(), 3);
}
void tst_QWebEnginePage::setZoomFactor()
{
- QWebEnginePage page;
+ TestBasePage page, page2;
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 1.0));
+ QCOMPARE(page.zoomFactor(), 1.0);
page.setZoomFactor(2.5);
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
-
- const QUrl urlToLoad("qrc:/resources/test1.html");
-
- QSignalSpy finishedSpy(&page, SIGNAL(loadFinished(bool)));
- page.load(urlToLoad);
- QTRY_COMPARE(finishedSpy.count(), 1);
- QVERIFY(finishedSpy.at(0).first().toBool());
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
-
- page.setZoomFactor(5.5);
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
+ QCOMPARE(page.zoomFactor(), 2.5);
+
+ const QUrl url1("qrc:/resources/test1.html"), url2(QUrl("qrc:/resources/test2.html"));
+
+ page.load(url1);
+ QTRY_COMPARE(page.loadSpy.size(), 1);
+ QVERIFY(page.loadSpy.at(0).first().toBool());
+ QCOMPARE(page.zoomFactor(), 2.5);
+
+ page.setZoomFactor(5.5); // max accepted zoom: kMaximumPageZoomFactor = 5.0
+ QCOMPARE(page.zoomFactor(), 2.5);
+
+ page.setZoomFactor(0.1); // min accepted zoom: kMinimumPageZoomFactor = 0.25
+ QCOMPARE(page.zoomFactor(), 2.5);
+
+ // try loading different url and check new values after load
+ page.loadSpy.clear();
+ for (auto &&p : {
+ qMakePair(&page, 2.5), // navigating away to different url should keep zoom
+ qMakePair(&page2, 1.0), // same url navigation in diffent page shouldn't be affected
+ }) {
+ auto &&page = *p.first; auto zoomFactor = p.second;
+ page.load(url2);
+ QTRY_COMPARE(page.loadSpy.size(), 1);
+ QVERIFY(page.loadSpy.last().first().toBool());
+ QCOMPARE(page.zoomFactor(), zoomFactor);
+ }
- page.setZoomFactor(0.1);
- QVERIFY(qFuzzyCompare(page.zoomFactor(), 2.5));
+ // should have no influence on first page
+ page2.setZoomFactor(3.5);
+ for (auto &&p : { qMakePair(&page, 2.5), qMakePair(&page2, 3.5), })
+ QCOMPARE(p.first->zoomFactor(), p.second);
}
void tst_QWebEnginePage::mouseButtonTranslation()
@@ -3069,17 +3289,20 @@ void tst_QWebEnginePage::mouseButtonTranslation()
view.resize(640, 480);
view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
- QTRY_VERIFY(spy.count() == 1);
+ QTRY_VERIFY(spy.size() == 1);
QVERIFY(view.focusProxy() != nullptr);
- QMouseEvent evpres(QEvent::MouseButtonPress, view.rect().center(), Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
+ const QPoint mousePos = view.rect().center();
+ QMouseEvent evpres(QEvent::MouseButtonPress, mousePos, view.mapToGlobal(mousePos),
+ Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
QGuiApplication::sendEvent(view.focusProxy(), &evpres);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.button").toInt(), 0);
QCOMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.buttons").toInt(), 1);
- QMouseEvent evpres2(QEvent::MouseButtonPress, view.rect().center(), Qt::RightButton, Qt::LeftButton | Qt::RightButton, Qt::NoModifier);
+ QMouseEvent evpres2(QEvent::MouseButtonPress, mousePos, view.mapToGlobal(mousePos),
+ Qt::RightButton, Qt::LeftButton | Qt::RightButton, Qt::NoModifier);
QGuiApplication::sendEvent(view.focusProxy(), &evpres2);
QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "lastEvent.button").toInt(), 2);
@@ -3108,34 +3331,17 @@ void tst_QWebEnginePage::mouseMovementProperties()
loadFinishedSpy.wait();
QTest::mouseMove(&view, QPoint(20, 20));
- QTRY_COMPARE(page.messages.count(), 1);
+ QTRY_COMPARE(page.messages.size(), 1);
QTest::mouseMove(&view, QPoint(30, 30));
- QTRY_COMPARE(page.messages.count(), 2);
+ QTRY_COMPARE(page.messages.size(), 2);
QTRY_COMPARE(page.messages[1], QString("10, 10"));
QTest::mouseMove(&view, QPoint(20, 20));
- QTRY_COMPARE(page.messages.count(), 3);
+ QTRY_COMPARE(page.messages.size(), 3);
QTRY_COMPARE(page.messages[2], QString("-10, -10"));
}
-QPoint tst_QWebEnginePage::elementCenter(QWebEnginePage *page, const QString &id)
-{
- QVariantList rectList = evaluateJavaScriptSync(page,
- "(function(){"
- "var elem = document.getElementById('" + id + "');"
- "var rect = elem.getBoundingClientRect();"
- "return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];"
- "})()").toList();
-
- if (rectList.count() != 2) {
- qWarning("elementCenter failed.");
- return QPoint();
- }
-
- return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt());
-}
-
void tst_QWebEnginePage::viewSource()
{
TestPage page;
@@ -3144,12 +3350,12 @@ void tst_QWebEnginePage::viewSource()
const QUrl url("qrc:/resources/test1.html");
page.load(url);
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(page.title(), QStringLiteral("Test page 1"));
QVERIFY(page.action(QWebEnginePage::ViewSource)->isEnabled());
page.triggerAction(QWebEnginePage::ViewSource);
- QTRY_COMPARE(windowCreatedSpy.count(), 1);
+ QTRY_COMPARE(windowCreatedSpy.size(), 1);
QCOMPARE(page.createdWindows.size(), 1);
QTRY_COMPARE(page.createdWindows[0]->url().toString(), QStringLiteral("view-source:%1").arg(url.toString()));
@@ -3170,7 +3376,8 @@ void tst_QWebEnginePage::viewSourceURL_data()
QTest::newRow("view-source:") << QUrl("view-source:") << true << QUrl("view-source:") << QUrl("about:blank") << QString("view-source:");
QTest::newRow("view-source:about:blank") << QUrl("view-source:about:blank") << true << QUrl("view-source:about:blank") << QUrl("about:blank") << QString("view-source:about:blank");
- QString localFilePath = QString("%1qwebenginepage/resources/test1.html").arg(TESTS_SOURCE_DIR);
+ QString localFilePath =
+ QString("%1/resources/test1.html").arg(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath());
QUrl testLocalUrl = QUrl(QString("view-source:%1").arg(QUrl::fromLocalFile(localFilePath).toString()));
QUrl testLocalUrlWithoutScheme = QUrl(QString("view-source:%1").arg(localFilePath));
QTest::newRow(testLocalUrl.toString().toStdString().c_str()) << testLocalUrl << true << testLocalUrl << QUrl::fromLocalFile(localFilePath) << QString("test1.html");
@@ -3186,8 +3393,12 @@ void tst_QWebEnginePage::viewSourceURL_data()
void tst_QWebEnginePage::viewSourceURL()
{
- 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);
+ if (!QDir(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath()).exists())
+ W_QSKIP(QString("This test requires access to resources found in '%1'")
+ .arg(QDir(QT_TESTCASE_SOURCEDIR).canonicalPath())
+ .toLatin1()
+ .constData(),
+ SkipAll);
QFETCH(QUrl, userInputUrl);
QFETCH(bool, loadSucceed);
@@ -3199,7 +3410,7 @@ void tst_QWebEnginePage::viewSourceURL()
QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
page.load(userInputUrl);
- QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 12000);
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 12000);
QList<QVariant> arguments = loadFinishedSpy.takeFirst();
QCOMPARE(arguments.at(0).toBool(), loadSucceed);
@@ -3234,7 +3445,7 @@ void tst_QWebEnginePage::viewSourceCredentials()
QVERIFY(page.action(QWebEnginePage::ViewSource)->isEnabled());
page.triggerAction(QWebEnginePage::ViewSource);
- QTRY_COMPARE(windowCreatedSpy.count(), 1);
+ QTRY_COMPARE(windowCreatedSpy.size(), 1);
QCOMPARE(page.createdWindows.size(), 1);
QTRY_COMPARE(page.createdWindows[0]->url().toString(), QString("view-source:" + url.toDisplayString(QUrl::RemoveUserInfo)));
@@ -3256,7 +3467,7 @@ void tst_QWebEnginePage::proxyConfigWithUnexpectedHostPortPair()
QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
m_page->load(QStringLiteral("http://127.0.0.1:245/"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
}
void tst_QWebEnginePage::registerProtocolHandler_data()
@@ -3283,12 +3494,13 @@ void tst_QWebEnginePage::registerProtocolHandler()
});
QVERIFY(server.start());
- QWebEnginePage page;
+ QWebEngineProfile profile(QStringLiteral("registerProtocolHandler%1").arg(QTest::currentDataTag()));
+ QWebEnginePage page(&profile, nullptr);
QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
QSignalSpy permissionSpy(&page, &QWebEnginePage::registerProtocolHandlerRequested);
page.setUrl(server.url("/"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), true);
QString callFormat = QStringLiteral("window.navigator.registerProtocolHandler(\"%1\", \"%2\", \"%3\")");
@@ -3298,7 +3510,7 @@ void tst_QWebEnginePage::registerProtocolHandler()
QString call = callFormat.arg(scheme).arg(url).arg(title);
page.runJavaScript(call);
- QTRY_COMPARE(permissionSpy.count(), 1);
+ QTRY_COMPARE(permissionSpy.size(), 1);
auto request = permissionSpy.takeFirst().value(0).value<QWebEngineRegisterProtocolHandlerRequest>();
QCOMPARE(request.origin(), QUrl(url));
QCOMPARE(request.scheme(), scheme);
@@ -3309,7 +3521,7 @@ void tst_QWebEnginePage::registerProtocolHandler()
page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0).toBool(), permission);
QCOMPARE(mailRequestCount, permission ? 1 : 0);
QVERIFY(server.stop());
@@ -3320,22 +3532,12 @@ void tst_QWebEnginePage::dataURLFragment()
m_view->resize(800, 600);
m_view->show();
QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
-
- m_page->setHtml("<html><body>"
- "<a id='link' href='#anchor'>anchor</a>"
- "</body></html>");
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
-
QSignalSpy urlChangedSpy(m_page, SIGNAL(urlChanged(QUrl)));
- QTest::mouseClick(m_view->focusProxy(), Qt::LeftButton, {}, elementCenter(m_page, "link"));
- QVERIFY(urlChangedSpy.wait());
- QCOMPARE(m_page->url().fragment(), QStringLiteral("anchor"));
-
m_page->setHtml("<html><body>"
"<a id='link' href='#anchor'>anchor</a>"
"</body></html>", QUrl("http://test.qt.io/mytest.html"));
- QTRY_COMPARE(loadFinishedSpy.count(), 2);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QTest::mouseClick(m_view->focusProxy(), Qt::LeftButton, {}, elementCenter(m_page, "link"));
QVERIFY(urlChangedSpy.wait());
@@ -3359,7 +3561,7 @@ void tst_QWebEnginePage::devTools()
QCOMPARE(devToolsPage.devToolsPage(), nullptr);
QCOMPARE(devToolsPage.inspectedPage(), &inspectedPage1);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 90000);
QVERIFY(spy.takeFirst().value(0).toBool());
devToolsPage.setInspectedPage(&inspectedPage2);
@@ -3371,7 +3573,7 @@ void tst_QWebEnginePage::devTools()
QCOMPARE(devToolsPage.devToolsPage(), nullptr);
QCOMPARE(devToolsPage.inspectedPage(), &inspectedPage2);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 90000);
QVERIFY(spy.takeFirst().value(0).toBool());
devToolsPage.setInspectedPage(nullptr);
@@ -3382,19 +3584,20 @@ void tst_QWebEnginePage::devTools()
QCOMPARE(inspectedPage2.inspectedPage(), nullptr);
QCOMPARE(devToolsPage.devToolsPage(), nullptr);
QCOMPARE(devToolsPage.inspectedPage(), nullptr);
+
+ QVERIFY(!inspectedPage1.devToolsId().isEmpty());
}
void tst_QWebEnginePage::openLinkInDifferentProfile()
{
- class Page : public QWebEnginePage {
- public:
- QWebEnginePage *targetPage = nullptr;
- Page(QWebEngineProfile *profile) : QWebEnginePage(profile) {}
- private:
- QWebEnginePage *createWindow(WebWindowType) override { return targetPage; }
- };
+ QWebEnginePage *targetPage = nullptr;
QWebEngineProfile profile1, profile2;
- Page page1(&profile1), page2(&profile2);
+ profile1.installUrlSchemeHandler("echo", new EchoingUrlSchemeHandler(&profile1));
+ profile2.installUrlSchemeHandler("echo", new EchoingUrlSchemeHandler(&profile2));
+ QWebEnginePage page1(&profile1), page2(&profile2);
+ connect(&page1, &QWebEnginePage::newWindowRequested, [&](QWebEngineNewWindowRequest &request) {
+ request.openIn(targetPage);
+ });
QWebEngineView view;
view.resize(500, 500);
view.setPage(&page1);
@@ -3402,13 +3605,13 @@ void tst_QWebEnginePage::openLinkInDifferentProfile()
QVERIFY(QTest::qWaitForWindowExposed(&view));
QSignalSpy spy1(&page1, &QWebEnginePage::loadFinished), spy2(&page2, &QWebEnginePage::loadFinished);
page1.setHtml("<html><body>"
- "<a id='link' href='data:,hello'>link</a>"
- "</body></html>");
- QTRY_COMPARE(spy1.count(), 1);
+ "<a id='link' href='hello'>link</a>"
+ "</body></html>", QUrl("echo:/"));
+ QTRY_COMPARE(spy1.size(), 1);
QVERIFY(spy1.takeFirst().value(0).toBool());
- page1.targetPage = &page2;
+ targetPage = &page2;
QTest::mouseClick(view.focusProxy(), Qt::MiddleButton, {}, elementCenter(&page1, "link"));
- QTRY_COMPARE(spy2.count(), 1);
+ QTRY_COMPARE(spy2.size(), 1);
QVERIFY(spy2.takeFirst().value(0).toBool());
}
@@ -3468,7 +3671,7 @@ void tst_QWebEnginePage::openLinkInNewPage_data()
// the disposition and performing the navigation request normally.
QTest::newRow("BlockPopup") << Decision::ReturnNull << Cause::TargetBlank << Effect::Blocked;
- QTest::newRow("IgnoreIntent") << Decision::ReturnNull << Cause::MiddleClick << Effect::LoadInSelf;
+ QTest::newRow("IgnoreIntent") << Decision::ReturnNull << Cause::MiddleClick << Effect::Blocked;
QTest::newRow("OverridePopup") << Decision::ReturnSelf << Cause::TargetBlank << Effect::LoadInSelf;
QTest::newRow("OverrideIntent") << Decision::ReturnSelf << Cause::MiddleClick << Effect::LoadInSelf;
QTest::newRow("AcceptPopup") << Decision::ReturnOther << Cause::TargetBlank << Effect::LoadInOther;
@@ -3506,6 +3709,7 @@ void tst_QWebEnginePage::openLinkInNewPage()
QFETCH(Effect, effect);
QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("echo", new EchoingUrlSchemeHandler(&profile));
Page page1(&profile);
Page page2(&profile);
View view1(&page1);
@@ -3515,9 +3719,9 @@ void tst_QWebEnginePage::openLinkInNewPage()
QVERIFY(QTest::qWaitForWindowExposed(&view1));
page1.setHtml("<html><body>"
- "<a id='link' href='data:,hello' target='_blank'>link</a>"
- "</body></html>");
- QTRY_COMPARE(page1.spy.count(), 1);
+ "<a id='link' href='hello' target='_blank'>link</a>"
+ "</body></html>", QUrl("echo:/"));
+ QTRY_COMPARE(page1.spy.size(), 1);
QVERIFY(page1.spy.takeFirst().value(0).toBool());
switch (decision) {
@@ -3532,7 +3736,7 @@ void tst_QWebEnginePage::openLinkInNewPage()
break;
}
- Qt::MouseButton button;
+ Qt::MouseButton button = Qt::NoButton;
switch (cause) {
case Cause::TargetBlank:
button = Qt::LeftButton;
@@ -3545,12 +3749,15 @@ void tst_QWebEnginePage::openLinkInNewPage()
switch (effect) {
case Effect::Blocked:
- // Nothing to test
+ // Test nothing new loaded
+ QTest::qWait(500);
+ QCOMPARE(page1.spy.size(), 0);
+ QCOMPARE(page2.spy.size(), 0);
break;
case Effect::LoadInSelf:
- QTRY_COMPARE(page1.spy.count(), 1);
+ QTRY_COMPARE(page1.spy.size(), 1);
QVERIFY(page1.spy.takeFirst().value(0).toBool());
- QCOMPARE(page2.spy.count(), 0);
+ QCOMPARE(page2.spy.size(), 0);
if (decision == Decision::ReturnSelf && cause == Cause::TargetBlank)
// History was discarded due to AddNewContents
QCOMPARE(page1.history()->count(), 1);
@@ -3559,9 +3766,9 @@ void tst_QWebEnginePage::openLinkInNewPage()
QCOMPARE(page2.history()->count(), 0);
break;
case Effect::LoadInOther:
- QTRY_COMPARE(page2.spy.count(), 1);
+ QTRY_COMPARE(page2.spy.size(), 1);
QVERIFY(page2.spy.takeFirst().value(0).toBool());
- QCOMPARE(page1.spy.count(), 0);
+ QCOMPARE(page1.spy.size(), 0);
QCOMPARE(page1.history()->count(), 1);
QCOMPARE(page2.history()->count(), 1);
break;
@@ -3583,26 +3790,38 @@ void tst_QWebEnginePage::dynamicFrame()
page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
page.load(QStringLiteral("qrc:/resources/dynamicFrame.html"));
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(toPlainTextSync(&page).trimmed(), QStringLiteral("foo"));
}
struct NotificationPage : ConsolePage {
Q_OBJECT
- const QWebEnginePage::PermissionPolicy policy;
+ const QWebEnginePermission::State policy;
public:
- NotificationPage(QWebEnginePage::PermissionPolicy ppolicy) : policy(ppolicy) {
+ NotificationPage(QWebEnginePermission::State 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)
+ connect(this, &QWebEnginePage::permissionRequested,
+ [this] (QWebEnginePermission permission) {
+ if (permission.feature() != QWebEnginePermission::Notifications)
return;
if (spyRequest.wasCalled())
QFAIL("request executed twise!");
- setFeaturePermission(origin, feature, policy);
- spyRequest.ref()(origin);
+ switch (policy) {
+ case QWebEnginePermission::Granted:
+ permission.grant();
+ break;
+ case QWebEnginePermission::Denied:
+ permission.deny();
+ break;
+ case QWebEnginePermission::Ask:
+ permission.reset();
+ break;
+ default:
+ break;
+ }
+ spyRequest.ref()(permission.origin());
});
load(QStringLiteral("qrc:///shared/notification.html"));
@@ -3622,49 +3841,62 @@ public:
void tst_QWebEnginePage::notificationPermission_data()
{
QTest::addColumn<bool>("setOnInit");
- QTest::addColumn<QWebEnginePage::PermissionPolicy>("policy");
+ QTest::addColumn<QWebEnginePermission::State>("policy");
QTest::addColumn<QString>("permission");
- QTest::newRow("denyOnInit") << true << QWebEnginePage::PermissionDeniedByUser << "denied";
- QTest::newRow("deny") << false << QWebEnginePage::PermissionDeniedByUser << "denied";
- QTest::newRow("grant") << false << QWebEnginePage::PermissionGrantedByUser << "granted";
- QTest::newRow("grantOnInit") << true << QWebEnginePage::PermissionGrantedByUser << "granted";
+ QTest::newRow("denyOnInit") << true << QWebEnginePermission::Denied << "denied";
+ QTest::newRow("deny") << false << QWebEnginePermission::Denied << "denied";
+ QTest::newRow("grant") << false << QWebEnginePermission::Granted << "granted";
+ QTest::newRow("grantOnInit") << true << QWebEnginePermission::Granted << "granted";
}
void tst_QWebEnginePage::notificationPermission()
{
QFETCH(bool, setOnInit);
- QFETCH(QWebEnginePage::PermissionPolicy, policy);
+ QFETCH(QWebEnginePermission::State, policy);
QFETCH(QString, permission);
QWebEngineProfile otr;
+ otr.setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
QWebEnginePage page(&otr, nullptr);
QUrl baseUrl("https://www.example.com/somepage.html");
bool permissionRequested = false, errorState = false;
- connect(&page, &QWebEnginePage::featurePermissionRequested, &page, [&] (const QUrl &o, QWebEnginePage::Feature f) {
- if (f != QWebEnginePage::Notifications)
+ connect(&page, &QWebEnginePage::permissionRequested, &page, [&] (QWebEnginePermission permission) {
+ if (permission.feature() != QWebEnginePermission::Notifications)
return;
- if (permissionRequested || o != baseUrl.url(QUrl::RemoveFilename)) {
- qWarning() << "Unexpected case. Can't proceed." << setOnInit << permissionRequested << o;
+ if (permissionRequested || permission.origin() != baseUrl.url(QUrl::RemoveFilename)) {
+ qWarning() << "Unexpected case. Can't proceed." << setOnInit << permissionRequested << permission.origin();
errorState = true;
return;
}
permissionRequested = true;
- page.setFeaturePermission(o, f, policy);
+
+ if (policy == QWebEnginePermission::Granted)
+ permission.grant();
+ else
+ permission.deny();
});
- if (setOnInit)
- page.setFeaturePermission(baseUrl, QWebEnginePage::Notifications, policy);
+ QWebEnginePermission permissionObject = otr.getPermission(baseUrl, QWebEnginePermission::Notifications);
+ if (setOnInit) {
+ if (policy == QWebEnginePermission::Granted)
+ permissionObject.grant();
+ else
+ permissionObject.deny();
+ }
QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
page.setHtml(QString("<html><body>Test</body></html>"), baseUrl);
- QTRY_COMPARE(spy.count(), 1);
+ QTRY_COMPARE(spy.size(), 1);
QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), setOnInit ? permission : QLatin1String("default"));
if (!setOnInit) {
- page.setFeaturePermission(baseUrl, QWebEnginePage::Notifications, policy);
+ if (policy == QWebEnginePermission::Granted)
+ permissionObject.grant();
+ else
+ permissionObject.deny();
QTRY_COMPARE(evaluateJavaScriptSync(&page, QStringLiteral("Notification.permission")), permission);
}
@@ -3678,7 +3910,7 @@ void tst_QWebEnginePage::notificationPermission()
void tst_QWebEnginePage::sendNotification()
{
- NotificationPage page(QWebEnginePage::PermissionGrantedByUser);
+ NotificationPage page(QWebEnginePermission::Granted);
QVERIFY(page.spyLoad.waitForResult());
page.resetPermission();
@@ -3717,6 +3949,176 @@ void tst_QWebEnginePage::sendNotification()
QTRY_VERIFY2(page.messages.contains("onclose"), page.messages.join("\n").toLatin1().constData());
}
+static QString clipboardPermissionQuery(QString variableName, QString permissionName)
+{
+ return QString("var %1; navigator.permissions.query({ name:'%2' }).then((p) => { %1 = p.state; "
+ "});")
+ .arg(variableName)
+ .arg(permissionName);
+}
+
+
+void tst_QWebEnginePage::clipboardReadWritePermissionInitialState_data()
+{
+ QTest::addColumn<bool>("canAccessClipboard");
+ QTest::addColumn<bool>("canPaste");
+ QTest::addColumn<QString>("permission");
+ QTest::newRow("access and paste should grant") << true << true << "granted";
+ QTest::newRow("no access should prompt") << false << true << "prompt";
+ QTest::newRow("no paste should prompt") << true << false << "prompt";
+ QTest::newRow("no access or paste should prompt") << false << false << "prompt";
+}
+
+void tst_QWebEnginePage::clipboardReadWritePermissionInitialState()
+{
+ QFETCH(bool, canAccessClipboard);
+ QFETCH(bool, canPaste);
+ QFETCH(QString, permission);
+
+ QWebEngineProfile otr;
+ otr.setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
+ QWebEngineView view(&otr);
+ QWebEnginePage &page = *view.page();
+ view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanAccessClipboard,
+ canAccessClipboard);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanPaste, canPaste);
+
+ QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
+ QUrl baseUrl("https://www.example.com/somepage.html");
+ page.setHtml(QString("<html><body>Test</body></html>"), baseUrl);
+ QTRY_COMPARE(spy.size(), 1);
+
+ evaluateJavaScriptSync(&page, clipboardPermissionQuery("readPermission", "clipboard-read"));
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("readPermission")), permission);
+ evaluateJavaScriptSync(&page, clipboardPermissionQuery("writePermission", "clipboard-write"));
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("writePermission")), permission);
+}
+
+void tst_QWebEnginePage::clipboardReadWritePermission_data()
+{
+ QTest::addColumn<bool>("canAccessClipboard");
+ QTest::addColumn<QWebEnginePermission::State>("initialPolicy");
+ QTest::addColumn<QString>("initialPermission");
+ QTest::addColumn<QWebEnginePermission::State>("requestPolicy");
+ QTest::addColumn<QString>("finalPermission");
+
+ QTest::newRow("noAccessGrantGrant")
+ << false << QWebEnginePermission::Granted << "granted"
+ << QWebEnginePermission::Granted << "granted";
+ QTest::newRow("noAccessGrantDeny")
+ << false << QWebEnginePermission::Granted << "granted"
+ << QWebEnginePermission::Denied << "denied";
+ QTest::newRow("noAccessDenyGrant")
+ << false << QWebEnginePermission::Denied << "denied"
+ << QWebEnginePermission::Granted << "granted";
+ QTest::newRow("noAccessDenyDeny") << false << QWebEnginePermission::Denied << "denied"
+ << QWebEnginePermission::Denied << "denied";
+ QTest::newRow("noAccessAskGrant") << false << QWebEnginePermission::Ask << "prompt"
+ << QWebEnginePermission::Granted << "granted";
+
+ // All policies are ignored and overridden by setting JsCanAccessClipboard and JsCanPaste to
+ // true
+ QTest::newRow("accessGrantGrant")
+ << true << QWebEnginePermission::Granted << "granted"
+ << QWebEnginePermission::Granted << "granted";
+ QTest::newRow("accessDenyDeny") << true << QWebEnginePermission::Denied << "granted"
+ << QWebEnginePermission::Denied << "granted";
+ QTest::newRow("accessAskAsk") << true << QWebEnginePermission::Ask << "granted"
+ << QWebEnginePermission::Ask << "granted";
+}
+
+void tst_QWebEnginePage::clipboardReadWritePermission()
+{
+ QFETCH(bool, canAccessClipboard);
+ QFETCH(QWebEnginePermission::State, initialPolicy);
+ QFETCH(QString, initialPermission);
+ QFETCH(QWebEnginePermission::State, requestPolicy);
+ QFETCH(QString, finalPermission);
+
+ QWebEngineProfile otr;
+ otr.setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
+ QWebEngineView view(&otr);
+ QWebEnginePage &page = *view.page();
+ view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanAccessClipboard,
+ canAccessClipboard);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanPaste, true);
+
+ QUrl baseUrl("https://www.example.com/somepage.html");
+
+ int permissionRequestCount = 0;
+ bool errorState = false;
+
+ // if JavascriptCanAccessClipboard is true, this never fires
+ connect(&page, &QWebEnginePage::permissionRequested, &page,
+ [&](QWebEnginePermission permission) {
+ if (permission.feature() != QWebEnginePermission::ClipboardReadWrite)
+ return;
+ if (permission.origin() != baseUrl.url(QUrl::RemoveFilename)) {
+ qWarning() << "Unexpected case. Can't proceed." << permission.origin();
+ errorState = true;
+ return;
+ }
+ permissionRequestCount++;
+ switch (requestPolicy) {
+ case QWebEnginePermission::Granted:
+ permission.grant();
+ break;
+ case QWebEnginePermission::Denied:
+ permission.deny();
+ break;
+ case QWebEnginePermission::Ask:
+ permission.reset();
+ break;
+ default:
+ break;
+ }
+ });
+
+ QWebEnginePermission permissionObject = otr.getPermission(baseUrl, QWebEnginePermission::ClipboardReadWrite);
+ switch (initialPolicy) {
+ case QWebEnginePermission::Granted:
+ permissionObject.grant();
+ break;
+ case QWebEnginePermission::Denied:
+ permissionObject.deny();
+ break;
+ case QWebEnginePermission::Ask:
+ permissionObject.reset();
+ break;
+ default:
+ break;
+ }
+
+ QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
+ page.setHtml(QString("<html><body>Test</body></html>"), baseUrl);
+ QTRY_COMPARE(spy.size(), 1);
+
+ evaluateJavaScriptSync(&page, clipboardPermissionQuery("readPermission", "clipboard-read"));
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("readPermission")), initialPermission);
+ evaluateJavaScriptSync(&page, clipboardPermissionQuery("writePermission", "clipboard-write"));
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("writePermission")), initialPermission);
+
+ auto triggerRequest = [&page](QString variableName, QString apiCall)
+ {
+ auto js = QString("var %1; navigator.clipboard.%2.then((v) => { %1 = 'granted' }, (v) => { %1 = "
+ "'denied' });")
+ .arg(variableName)
+ .arg(apiCall);
+ evaluateJavaScriptSync(&page, js);
+ };
+
+ // permission is not 'remembered' from api standpoint, hence is not suppressed on explicit call
+ // from JS
+ triggerRequest("readState", "readText()");
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, "readState"), finalPermission);
+ triggerRequest("writeState", "writeText('foo')");
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, "writeState"), finalPermission);
+ QCOMPARE(permissionRequestCount, canAccessClipboard ? 0 : 2);
+ QVERIFY(!errorState);
+}
+
void tst_QWebEnginePage::contentsSize()
{
m_view->resize(800, 600);
@@ -3727,8 +4129,8 @@ void tst_QWebEnginePage::contentsSize()
m_view->setHtml(QString("<html><body style=\"width: 1600px; height: 1200px;\"><p>hi</p></body></html>"));
- QTRY_COMPARE(loadSpy.count(), 1);
- QTRY_COMPARE(contentsSizeChangedSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
+ QTRY_COMPARE(contentsSizeChangedSpy.size(), 1);
// Verify the page's contents size is not limited by the view's size.
QCOMPARE(m_page->contentsSize().width(), 1608);
@@ -3745,6 +4147,62 @@ void tst_QWebEnginePage::contentsSize()
QCOMPARE(m_page->contentsSize().height(), 1216);
}
+void tst_QWebEnginePage::localFontAccessPermission_data()
+{
+ QTest::addColumn<QWebEnginePermission::State>("policy");
+ QTest::addColumn<bool>("ignore");
+ QTest::addColumn<bool>("shouldBeEmpty");
+
+ QTest::newRow("ignore") << QWebEnginePermission::Denied << true << true;
+ QTest::newRow("setDeny") << QWebEnginePermission::Denied << false << true;
+ QTest::newRow("setGrant") << QWebEnginePermission::Granted << false << false;
+}
+
+void tst_QWebEnginePage::localFontAccessPermission() {
+ QFETCH(QWebEnginePermission::State, policy);
+ QFETCH(bool, ignore);
+ QFETCH(bool, shouldBeEmpty);
+
+ QWebEngineView view;
+ QWebEnginePage page(&view);
+ page.profile()->setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
+ view.setPage(&page);
+
+ connect(&page, &QWebEnginePage::permissionRequested, &page, [&] (QWebEnginePermission permission) {
+ if (permission.feature() != QWebEnginePermission::LocalFontsAccess)
+ return;
+
+ if (!ignore) {
+ if (policy == QWebEnginePermission::Granted)
+ permission.grant();
+ else
+ permission.deny();
+ }
+ });
+
+ QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
+ page.load(QUrl("qrc:///resources/fontaccess.html"));
+ QTRY_COMPARE(spy.size(), 1);
+
+ // Font access is only enabled for visible WebContents.
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ if (evaluateJavaScriptSync(&page, QStringLiteral("!window.queryLocalFonts")).toBool())
+ W_QSKIP("Local fonts access is not supported.", SkipSingle);
+
+ // Access to the API requires recent user interaction
+ QTest::keyPress(view.focusProxy(), Qt::Key_Space);
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, QStringLiteral("activated")).toBool(), true);
+
+ if (ignore) {
+ QTRY_COMPARE_NE_WITH_TIMEOUT(evaluateJavaScriptSync(&page, QStringLiteral("done")).toBool(), true, 1000);
+ } else {
+ QTRY_VERIFY_WITH_TIMEOUT(evaluateJavaScriptSync(&page, QStringLiteral("done")).toBool() == true, 1000);
+ QVERIFY((evaluateJavaScriptSync(&page, QStringLiteral("fonts.length")).toInt() == 0) == shouldBeEmpty);
+ }
+}
+
void tst_QWebEnginePage::setLifecycleState()
{
qRegisterMetaType<QWebEnginePage::LifecycleState>("LifecycleState");
@@ -3756,64 +4214,64 @@ void tst_QWebEnginePage::setLifecycleState()
QSignalSpy visibleSpy(&page, &QWebEnginePage::visibleChanged);
page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
// Active -> Frozen
page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Frozen);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(1));
// Frozen -> Active
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
// Active -> Discarded
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
QTest::ignoreMessage(QtWarningMsg, "runJavaScript: disabled in Discarded state");
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant());
QTest::ignoreMessage(QtWarningMsg, "runJavaScript: disabled in Discarded state");
QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant());
- QCOMPARE(loadSpy.count(), 0);
+ QCOMPARE(loadSpy.size(), 0);
// Discarded -> Frozen (illegal!)
QTest::ignoreMessage(QtWarningMsg,
"setLifecycleState: failed to transition from Discarded to Frozen state: "
"illegal transition");
page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
// Discarded -> Active
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(true));
QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
@@ -3822,21 +4280,21 @@ void tst_QWebEnginePage::setLifecycleState()
page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QCOMPARE(lifecycleSpy.count(), 3);
+ QCOMPARE(lifecycleSpy.size(), 3);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(true));
QCOMPARE(evaluateJavaScriptSync(&page, "frozenness"), QVariant(0));
// Reload clears document.wasDiscarded
page.triggerAction(QWebEnginePage::Reload);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
QCOMPARE(evaluateJavaScriptSync(&page, "document.wasDiscarded"), QVariant(false));
}
@@ -3852,18 +4310,18 @@ void tst_QWebEnginePage::setVisible()
QSignalSpy visibleSpy(&page, &QWebEnginePage::visibleChanged);
page.load(QStringLiteral("about:blank"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 0);
+ QCOMPARE(visibleSpy.size(), 0);
QCOMPARE(page.isVisible(), false);
// hidden -> visible
page.setVisible(true);
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.size(), 1);
QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(true));
QCOMPARE(page.isVisible(), true);
@@ -3872,28 +4330,28 @@ void tst_QWebEnginePage::setVisible()
QtWarningMsg,
"setLifecycleState: failed to transition from Active to Frozen state: page is visible");
page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
// visible -> hidden
page.setVisible(false);
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.size(), 1);
QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(false));
QCOMPARE(page.isVisible(), false);
// Active -> Frozen
page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Frozen);
// hidden -> visible (triggers Frozen -> Active)
page.setVisible(true);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.size(), 1);
QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(true));
QCOMPARE(page.isVisible(), true);
@@ -3902,31 +4360,31 @@ void tst_QWebEnginePage::setVisible()
"setLifecycleState: failed to transition from Active to Discarded state: "
"page is visible");
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
// visible -> hidden
page.setVisible(false);
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.size(), 1);
QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(false));
QCOMPARE(page.isVisible(), false);
// Active -> Discarded
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
// hidden -> visible (triggers Discarded -> Active)
page.setVisible(true);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(visibleSpy.count(), 1);
+ QCOMPARE(visibleSpy.size(), 1);
QCOMPARE(visibleSpy.takeFirst().value(0), QVariant(true));
QCOMPARE(page.isVisible(), true);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
}
@@ -3937,7 +4395,7 @@ void tst_QWebEnginePage::discardPreservesProperties()
QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
page.load(QStringLiteral("about:blank"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
// Change as many properties as possible to non-default values
@@ -3974,7 +4432,7 @@ void tst_QWebEnginePage::discardPreservesProperties()
// Discard + undiscard
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
// Property changes should be preserved
@@ -4013,7 +4471,7 @@ void tst_QWebEnginePage::automaticUndiscard()
QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
page.load(QStringLiteral("about:blank"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
// setUrl
@@ -4038,16 +4496,16 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
// Ensure pages are initialized
inspectedPage.load(QStringLiteral("about:blank"));
devToolsPage.load(QStringLiteral("about:blank"));
- QTRY_COMPARE_WITH_TIMEOUT(inspectedSpy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(inspectedSpy.size(), 1, 90000);
QCOMPARE(inspectedSpy.takeFirst().value(0), QVariant(true));
- QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.count(), 1, 30000);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.size(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
// Open DevTools with Frozen inspectedPage
inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
inspectedPage.setDevToolsPage(&devToolsPage);
QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(devToolsSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.size(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
inspectedPage.setDevToolsPage(nullptr);
@@ -4055,9 +4513,9 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
inspectedPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
inspectedPage.setDevToolsPage(&devToolsPage);
QCOMPARE(inspectedPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(devToolsSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.size(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
- QTRY_COMPARE(inspectedSpy.count(), 1);
+ QTRY_COMPARE(inspectedSpy.size(), 1);
QCOMPARE(inspectedSpy.takeFirst().value(0), QVariant(true));
inspectedPage.setDevToolsPage(nullptr);
@@ -4065,7 +4523,7 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
devToolsPage.setInspectedPage(&inspectedPage);
QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(devToolsSpy.count(), 1);
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.size(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
devToolsPage.setInspectedPage(nullptr);
@@ -4073,8 +4531,7 @@ void tst_QWebEnginePage::setLifecycleStateWithDevTools()
devToolsPage.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
devToolsPage.setInspectedPage(&inspectedPage);
QCOMPARE(devToolsPage.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(devToolsSpy.count(), 2);
- QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(false));
+ QTRY_COMPARE_WITH_TIMEOUT(devToolsSpy.size(), 1, 90000);
QCOMPARE(devToolsSpy.takeFirst().value(0), QVariant(true));
// keep DevTools open
@@ -4112,35 +4569,35 @@ void tst_QWebEnginePage::discardPreservesCommittedLoad()
QString url = QStringLiteral("qrc:/resources/lifecycle.html");
page.setUrl(url);
- QTRY_COMPARE(loadStartedSpy.count(), 1);
+ QTRY_COMPARE(loadStartedSpy.size(), 1);
loadStartedSpy.clear();
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(urlChangedSpy.count(), 1);
+ QCOMPARE(urlChangedSpy.size(), 1);
QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url)));
QCOMPARE(page.url(), url);
- QCOMPARE(titleChangedSpy.count(), 2);
+ QCOMPARE(titleChangedSpy.size(), 2);
QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(url));
QString title = QStringLiteral("Lifecycle");
QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(title));
QCOMPARE(page.title(), title);
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
- QCOMPARE(loadStartedSpy.count(), 0);
- QCOMPARE(loadFinishedSpy.count(), 0);
- QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(loadStartedSpy.size(), 0);
+ QCOMPARE(loadFinishedSpy.size(), 0);
+ QCOMPARE(urlChangedSpy.size(), 0);
QCOMPARE(page.url(), QUrl(url));
- QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(titleChangedSpy.size(), 0);
QCOMPARE(page.title(), title);
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QTRY_COMPARE(loadStartedSpy.count(), 1);
+ QTRY_COMPARE(loadStartedSpy.size(), 1);
loadStartedSpy.clear();
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(urlChangedSpy.size(), 0);
QCOMPARE(page.url(), url);
- QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(titleChangedSpy.size(), 0);
QCOMPARE(page.title(), title);
}
@@ -4157,21 +4614,21 @@ void tst_QWebEnginePage::discardAbortsPendingLoad()
[&]() { page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded); });
QUrl url = QStringLiteral("qrc:/resources/lifecycle.html");
page.setUrl(url);
- QTRY_COMPARE(loadStartedSpy.count(), 1);
+ QTRY_COMPARE(loadStartedSpy.size(), 1);
loadStartedSpy.clear();
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(false));
- QCOMPARE(urlChangedSpy.count(), 2);
+ QCOMPARE(urlChangedSpy.size(), 2);
QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(url));
QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl()));
- QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(titleChangedSpy.size(), 0);
QCOMPARE(page.url(), QUrl());
QCOMPARE(page.title(), QString());
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QCOMPARE(loadStartedSpy.count(), 0);
- QCOMPARE(loadFinishedSpy.count(), 0);
- QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(loadStartedSpy.size(), 0);
+ QCOMPARE(loadFinishedSpy.size(), 0);
+ QCOMPARE(urlChangedSpy.size(), 0);
QCOMPARE(page.url(), QUrl());
QCOMPARE(page.title(), QString());
}
@@ -4187,14 +4644,14 @@ void tst_QWebEnginePage::discardAbortsPendingLoadAndPreservesCommittedLoad()
QString url1 = QStringLiteral("qrc:/resources/lifecycle.html");
page.setUrl(url1);
- QTRY_COMPARE(loadStartedSpy.count(), 1);
+ QTRY_COMPARE(loadStartedSpy.size(), 1);
loadStartedSpy.clear();
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(urlChangedSpy.count(), 1);
+ QCOMPARE(urlChangedSpy.size(), 1);
QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url1)));
QCOMPARE(page.url(), url1);
- QCOMPARE(titleChangedSpy.count(), 2);
+ QCOMPARE(titleChangedSpy.size(), 2);
QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(url1));
QString title = QStringLiteral("Lifecycle");
QCOMPARE(titleChangedSpy.takeFirst().value(0), QVariant(title));
@@ -4204,21 +4661,21 @@ void tst_QWebEnginePage::discardAbortsPendingLoadAndPreservesCommittedLoad()
[&]() { page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded); });
QString url2 = QStringLiteral("about:blank");
page.setUrl(url2);
- QTRY_COMPARE(loadStartedSpy.count(), 1);
+ QTRY_COMPARE(loadStartedSpy.size(), 1);
loadStartedSpy.clear();
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QCOMPARE(loadFinishedSpy.takeFirst().value(0), QVariant(false));
- QCOMPARE(urlChangedSpy.count(), 2);
+ QCOMPARE(urlChangedSpy.size(), 2);
QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url2)));
QCOMPARE(urlChangedSpy.takeFirst().value(0), QVariant(QUrl(url1)));
- QCOMPARE(titleChangedSpy.count(), 0);
+ QCOMPARE(titleChangedSpy.size(), 0);
QCOMPARE(page.url(), url1);
QCOMPARE(page.title(), title);
page.setLifecycleState(QWebEnginePage::LifecycleState::Active);
- QCOMPARE(loadStartedSpy.count(), 0);
- QCOMPARE(loadFinishedSpy.count(), 0);
- QCOMPARE(urlChangedSpy.count(), 0);
+ QCOMPARE(loadStartedSpy.size(), 0);
+ QCOMPARE(loadFinishedSpy.size(), 0);
+ QCOMPARE(urlChangedSpy.size(), 0);
QCOMPARE(page.url(), url1);
QCOMPARE(page.title(), title);
}
@@ -4314,32 +4771,32 @@ void tst_QWebEnginePage::recommendedStateAuto()
connect(&page, &QWebEnginePage::recommendedStateChanged, &page, &QWebEnginePage::setLifecycleState);
page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
- QTRY_COMPARE(lifecycleSpy.count(), 2);
+ QTRY_COMPARE(lifecycleSpy.size(), 2);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
page.setVisible(true);
- QTRY_COMPARE(lifecycleSpy.count(), 1);
+ QTRY_COMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
page.setVisible(false);
- QTRY_COMPARE(lifecycleSpy.count(), 2);
+ QTRY_COMPARE(lifecycleSpy.size(), 2);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
page.triggerAction(QWebEnginePage::Reload);
- QTRY_COMPARE(lifecycleSpy.count(), 3);
+ QTRY_COMPARE(lifecycleSpy.size(), 3);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
QWebEnginePage devTools;
page.setDevToolsPage(&devTools);
- QTRY_COMPARE(lifecycleSpy.count(), 1);
+ QTRY_COMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
page.setDevToolsPage(nullptr);
- QTRY_COMPARE(lifecycleSpy.count(), 2);
+ QTRY_COMPARE(lifecycleSpy.size(), 2);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
}
@@ -4354,33 +4811,33 @@ void tst_QWebEnginePage::setLifecycleStateAndReload()
QSignalSpy lifecycleSpy(&page, &QWebEnginePage::lifecycleStateChanged);
page.load(QStringLiteral("qrc:/resources/lifecycle.html"));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
- QCOMPARE(lifecycleSpy.count(), 0);
+ QCOMPARE(lifecycleSpy.size(), 0);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
page.setLifecycleState(QWebEnginePage::LifecycleState::Frozen);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Frozen);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Frozen));
page.triggerAction(QWebEnginePage::Reload);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
page.setLifecycleState(QWebEnginePage::LifecycleState::Discarded);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Discarded));
page.triggerAction(QWebEnginePage::Reload);
QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Active);
- QCOMPARE(lifecycleSpy.count(), 1);
+ QCOMPARE(lifecycleSpy.size(), 1);
QCOMPARE(lifecycleSpy.takeFirst().value(0), QVariant::fromValue(QWebEnginePage::LifecycleState::Active));
- QTRY_COMPARE(loadSpy.count(), 1);
+ QTRY_COMPARE(loadSpy.size(), 1);
QCOMPARE(loadSpy.takeFirst().value(0), QVariant(true));
}
@@ -4399,20 +4856,20 @@ void tst_QWebEnginePage::editActionsWithExplicitFocus()
QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());
page->setHtml(QString("<html><body><div>foo bar</div></body></html>"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
// Still no focus because focus on navigation is disabled. Edit actions don't do anything (should not crash).
QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());
view.page()->triggerAction(QWebEnginePage::SelectAll);
- QCOMPARE(selectionChangedSpy.count(), 0);
+ QCOMPARE(selectionChangedSpy.size(), 0);
QCOMPARE(page->hasSelection(), false);
// Focus content by focusing window from JavaScript. Edit actions should be enabled and functional.
evaluateJavaScriptSync(page, "window.focus();");
- QTRY_COMPARE(actionChangedSpy.count(), 1);
+ QTRY_COMPARE(actionChangedSpy.size(), 1);
QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
view.page()->triggerAction(QWebEnginePage::SelectAll);
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
QCOMPARE(page->hasSelection(), true);
QCOMPARE(page->selectedText(), QStringLiteral("foo bar"));
}
@@ -4432,13 +4889,13 @@ void tst_QWebEnginePage::editActionsWithInitialFocus()
QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());
page->setHtml(QString("<html><body><div>foo bar</div></body></html>"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
// Content gets initial focus.
- QTRY_COMPARE(actionChangedSpy.count(), 1);
+ QTRY_COMPARE(actionChangedSpy.size(), 1);
QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
view.page()->triggerAction(QWebEnginePage::SelectAll);
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
QCOMPARE(page->hasSelection(), true);
QCOMPARE(page->selectedText(), QStringLiteral("foo bar"));
}
@@ -4458,15 +4915,15 @@ void tst_QWebEnginePage::editActionsWithFocusOnIframe()
QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());
page->load(QUrl("qrc:///resources/iframe2.html"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
QVERIFY(!page->action(QWebEnginePage::SelectAll)->isEnabled());
// Focusing an iframe.
evaluateJavaScriptSync(page, "document.getElementsByTagName('iframe')[0].contentWindow.focus()");
- QTRY_COMPARE(actionChangedSpy.count(), 1);
+ QTRY_COMPARE(actionChangedSpy.size(), 1);
QVERIFY(page->action(QWebEnginePage::SelectAll)->isEnabled());
view.page()->triggerAction(QWebEnginePage::SelectAll);
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
QCOMPARE(page->hasSelection(), true);
QCOMPARE(page->selectedText(), QStringLiteral("inner"));
}
@@ -4482,8 +4939,8 @@ void tst_QWebEnginePage::editActionsWithoutSelection()
QSignalSpy actionChangedSpy(page->action(QWebEnginePage::SelectAll), &QAction::changed);
page->setHtml(QString("<html><body><div>foo bar</div></body></html>"));
- QTRY_COMPARE(loadFinishedSpy.count(), 1);
- QTRY_COMPARE(actionChangedSpy.count(), 1);
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QTRY_COMPARE(actionChangedSpy.size(), 1);
QVERIFY(!page->action(QWebEnginePage::Cut)->isEnabled());
QVERIFY(!page->action(QWebEnginePage::Copy)->isEnabled());
@@ -4495,7 +4952,7 @@ void tst_QWebEnginePage::editActionsWithoutSelection()
QVERIFY(!page->action(QWebEnginePage::Unselect)->isEnabled());
page->triggerAction(QWebEnginePage::SelectAll);
- QTRY_COMPARE(selectionChangedSpy.count(), 1);
+ QTRY_COMPARE(selectionChangedSpy.size(), 1);
QCOMPARE(page->hasSelection(), true);
QCOMPARE(page->selectedText(), QStringLiteral("foo bar"));
@@ -4509,6 +4966,28 @@ void tst_QWebEnginePage::editActionsWithoutSelection()
QVERIFY(page->action(QWebEnginePage::Unselect)->isEnabled());
}
+struct PageWithNewWindowHandler : QWebEnginePage
+{
+ QScopedPointer<PageWithNewWindowHandler> newPage;
+ bool handleInSignal;
+ QWebEngineProfile *targetProfile = nullptr;
+ QSignalSpy loadSpy { this, &QWebEnginePage::loadFinished };
+ PageWithNewWindowHandler(QWebEngineProfile *p, bool inSignal = false, QWebEngineProfile *tp = nullptr)
+ : QWebEnginePage(p), handleInSignal(inSignal), targetProfile(tp) {
+ if (handleInSignal)
+ connect(this, &QWebEnginePage::newWindowRequested, this, [this] (QWebEngineNewWindowRequest &r) {
+ newPage.reset(new PageWithNewWindowHandler(targetProfile ? targetProfile : profile(), handleInSignal));
+ newPage->acceptAsNewWindow(r);
+ });
+ }
+ QWebEnginePage *createWindow(WebWindowType) override {
+ if (handleInSignal)
+ return nullptr;
+ newPage.reset(new PageWithNewWindowHandler(targetProfile ? targetProfile : profile(), handleInSignal));
+ return newPage.get();
+ }
+};
+
void tst_QWebEnginePage::customUserAgentInNewTab()
{
HttpServer server;
@@ -4521,55 +5000,84 @@ void tst_QWebEnginePage::customUserAgentInNewTab()
});
QVERIFY(server.start());
- class Page : public QWebEnginePage {
- public:
- QWebEngineProfile *targetProfile = nullptr;
- QScopedPointer<QWebEnginePage> newPage;
- Page(QWebEngineProfile *profile) : QWebEnginePage(profile) {}
- private:
- QWebEnginePage *createWindow(WebWindowType) override
- {
- newPage.reset(new QWebEnginePage(targetProfile ? targetProfile : profile(), nullptr));
- return newPage.data();
- }
- };
- QWebEngineProfile profile1, profile2;
- profile1.setHttpUserAgent(QStringLiteral("custom 1"));
- profile2.setHttpUserAgent(QStringLiteral("custom 2"));
- Page page(&profile1);
- QWebEngineView view;
- view.resize(500, 500);
- view.setPage(&page);
- view.show();
+ QString expectedUserAgent("custom 1");
+ QWebEngineProfile profile;
+ profile.setHttpUserAgent(expectedUserAgent);
+
+ PageWithNewWindowHandler page(&profile);
+ QWebEngineView view; view.resize(500, 500); view.setPage(&page); view.show();
QVERIFY(QTest::qWaitForWindowExposed(&view));
- QSignalSpy spy(&page, &QWebEnginePage::loadFinished);
// First check we can get the user-agent passed through normally
page.setHtml(QString("<html><body><a id='link' target='_blank' href='") +
server.url("/test1").toEncoded() +
QString("'>link</a></body></html>"));
- QTRY_COMPARE(spy.count(), 1);
- QVERIFY(spy.takeFirst().value(0).toBool());
- QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("navigator.userAgent")).toString(), profile1.httpUserAgent());
+ QTRY_COMPARE(page.loadSpy.size(), 1);
+ QVERIFY(page.loadSpy.takeFirst().value(0).toBool());
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("navigator.userAgent")).toString(), expectedUserAgent);
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
QTRY_VERIFY(page.newPage);
+ QTRY_COMPARE(page.newPage->loadSpy.size(), 1);
QTRY_VERIFY(!lastUserAgent.isEmpty());
- QCOMPARE(lastUserAgent, profile1.httpUserAgent().toUtf8());
+ QCOMPARE(lastUserAgent, expectedUserAgent);
+ QCOMPARE(evaluateJavaScriptSync(page.newPage.get(), QStringLiteral("navigator.userAgent")).toString(), expectedUserAgent);
// Now check we can get the new user-agent of the profile
page.newPage.reset();
- page.targetProfile = &profile2;
- spy.clear();
+ expectedUserAgent = "custom 2";
+ profile.setHttpUserAgent(expectedUserAgent);
+ page.loadSpy.clear();
lastUserAgent = { };
page.setHtml(QString("<html><body><a id='link' target='_blank' href='") +
server.url("/test2").toEncoded() +
QString("'>link</a></body></html>"));
- QTRY_COMPARE(spy.count(), 1);
- QVERIFY(spy.takeFirst().value(0).toBool());
+ QTRY_COMPARE(page.loadSpy.size(), 1);
+ QVERIFY(page.loadSpy.takeFirst().value(0).toBool());
QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
QTRY_VERIFY(page.newPage);
+ QTRY_COMPARE(page.newPage->loadSpy.size(), 1);
QTRY_VERIFY(!lastUserAgent.isEmpty());
- QCOMPARE(lastUserAgent, profile2.httpUserAgent().toUtf8());
+ QCOMPARE(lastUserAgent, expectedUserAgent);
+ QCOMPARE(evaluateJavaScriptSync(&page, QStringLiteral("navigator.userAgent")).toString(), expectedUserAgent);
+ QCOMPARE(evaluateJavaScriptSync(page.newPage.get(), QStringLiteral("navigator.userAgent")).toString(), expectedUserAgent);
+}
+
+void tst_QWebEnginePage::openNewTabInDifferentProfile_data()
+{
+ QTest::addColumn<bool>("handleInSignal");
+ QTest::addRow("handleInSignal") << true;
+ QTest::addRow("handleInOverride") << false;
+}
+
+void tst_QWebEnginePage::openNewTabInDifferentProfile()
+{
+ QFETCH(bool, handleInSignal);
+
+ HttpServer server;
+ QStringList receivedRequests;
+ connect(&server, &HttpServer::newRequest, [&] (HttpReqRep *r) {
+ receivedRequests.append(r->requestPath());
+ r->setResponseBody("DUMMY");
+ r->sendResponse();
+ });
+ QVERIFY(server.start());
+
+ QWebEngineProfile profile1, profile2;
+ PageWithNewWindowHandler page(&profile1, handleInSignal, &profile2);
+ QWebEngineView view; view.setPage(&page); view.resize(320, 240); view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ page.setHtml(QString("<html><body><a id='link' target='_blank' href='%1'>link</a></body></html>").arg(server.url("/first.html").toEncoded()));
+ QTRY_COMPARE(page.loadSpy.size(), 1);
+ QVERIFY(page.loadSpy.takeFirst().value(0).toBool());
+
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
+ QTRY_VERIFY(page.newPage);
+ QVERIFY(page.profile() == &profile1);
+ QVERIFY(page.newPage->profile() == &profile2);
+ // not load should occur or requests to server issued since web_contents is not expected to be adopted from other profile
+ QTRY_LOOP_IMPL(page.newPage->loadSpy.size() != 0, 1000, 100);
+ QVERIFY2(receivedRequests.isEmpty(), qPrintable(receivedRequests.join(", ")));
}
void tst_QWebEnginePage::renderProcessCrashed()
@@ -4610,6 +5118,141 @@ void tst_QWebEnginePage::renderProcessPid()
QCOMPARE(m_page->renderProcessPid(), 0);
}
+class FileSelectionTestPage : public QWebEnginePage {
+public:
+ FileSelectionTestPage() : m_tempDir(QDir::tempPath() + "/tst_qwebenginepage-XXXXXX") { }
+
+ QStringList chooseFiles(FileSelectionMode mode, const QStringList &oldFiles, const QStringList &acceptedMimeTypes) override
+ {
+ Q_UNUSED(oldFiles);
+ chosenFileSelectionMode = mode;
+ chosenAcceptedMimeTypes = acceptedMimeTypes;
+ return QStringList() << (m_tempDir.path() + "/file.txt");
+ }
+
+ QTemporaryDir m_tempDir;
+ int chosenFileSelectionMode = -1;
+ QStringList chosenAcceptedMimeTypes;
+};
+
+void tst_QWebEnginePage::testChooseFilesParameters_data()
+{
+ QTest::addColumn<QString>("uploadAttribute");
+ QTest::addColumn<QString>("mimeTypeAttribute");
+ QTest::addColumn<QWebEnginePage::FileSelectionMode>("expectedFileSelectionMode");
+ QTest::addColumn<QStringList>("expectedMimeType");
+ QStringList mimeTypes;
+
+ QTest::addRow("Single file upload") << QString() << QString()
+ << QWebEnginePage::FileSelectOpen << QStringList();
+ QTest::addRow("Multiple file upload") << QString("multiple") << QString()
+ << QWebEnginePage::FileSelectOpenMultiple << QStringList();
+ QTest::addRow("Folder upload") << QString("multiple webkitdirectory") << QString()
+ << QWebEnginePage::FileSelectUploadFolder << QStringList();
+ QTest::addRow("Save file") << QString("") << QString()
+ << QWebEnginePage::FileSelectSave << QStringList();
+ mimeTypes = QStringList() << "audio/*";
+ QTest::addRow("MIME type: audio") << QString() << QString("accept='%1'").arg(mimeTypes.join(','))
+ << QWebEnginePage::FileSelectOpen << mimeTypes;
+ mimeTypes = QStringList() << "video/*";
+ QTest::addRow("MIME type: video") << QString() << QString("accept='%1'").arg(mimeTypes.join(','))
+ << QWebEnginePage::FileSelectOpen << mimeTypes;
+ mimeTypes = QStringList() << "image/*";
+ QTest::addRow("MIME type: image") << QString() << QString("accept='%1'").arg(mimeTypes.join(','))
+ << QWebEnginePage::FileSelectOpen << mimeTypes;
+ mimeTypes = QStringList() << ".txt" << ".html";
+ QTest::addRow("MIME type: custom") << QString() << QString("accept='%1'").arg(mimeTypes.join(','))
+ << QWebEnginePage::FileSelectOpen << mimeTypes;
+ mimeTypes = QStringList() << "audio/*" << "video/*" << "image/*" << ".txt" << ".html";
+ QTest::addRow("Multiple MIME types") << QString() << QString("accept='%1'").arg(mimeTypes.join(','))
+ << QWebEnginePage::FileSelectOpen << mimeTypes;
+}
+
+void tst_QWebEnginePage::testChooseFilesParameters()
+{
+ QFETCH(QString, uploadAttribute);
+ QFETCH(QString, mimeTypeAttribute);
+ QFETCH(QWebEnginePage::FileSelectionMode, expectedFileSelectionMode);
+ QFETCH(QStringList, expectedMimeType);
+
+ FileSelectionTestPage page;
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+
+ QWebEngineView view;
+ view.resize(500, 500);
+ view.setPage(&page);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ if (expectedFileSelectionMode != QWebEnginePage::FileSelectSave) {
+ page.setHtml(QString("<html><body>"
+ "<input id='filePicker' type='file' name='filePicker' %1 %2 />"
+ "</body></html>").arg(uploadAttribute, mimeTypeAttribute));
+ } else {
+ page.setHtml(QString("<html><body>"
+ "<button id='filePicker' value='trigger' "
+ "onclick='window.showSaveFilePicker()'"
+ "</body></html>"), QString("qrc:/"));
+ }
+ QVERIFY(spyFinished.wait());
+ QTRY_COMPARE(spyFinished.size(), 1);
+
+ evaluateJavaScriptSync(view.page(), "document.getElementById('filePicker').focus()");
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("filePicker"));
+ QTest::keyClick(view.focusProxy(), Qt::Key_Enter);
+
+ QTRY_COMPARE(page.chosenFileSelectionMode, expectedFileSelectionMode);
+ QTRY_COMPARE(page.chosenAcceptedMimeTypes, expectedMimeType);
+}
+
+void tst_QWebEnginePage::fileSystemAccessDialog()
+{
+ FileSelectionTestPage page;
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
+
+ QWebEngineView view;
+ view.resize(500, 500);
+ view.setPage(&page);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ connect(&page, &QWebEnginePage::fileSystemAccessRequested,
+ [](QWebEngineFileSystemAccessRequest request) {
+ QCOMPARE(request.accessFlags(),
+ QWebEngineFileSystemAccessRequest::Read
+ | QWebEngineFileSystemAccessRequest::Write);
+ request.accept();
+ });
+
+ page.setHtml(QString("<html><head><script>"
+ "async function getTemporaryDir() {"
+ " const newHandle = await window.showSaveFilePicker();"
+ " const writable = await newHandle.createWritable();"
+ " await writable.write(new Blob(['New value']));"
+ " await writable.close();"
+ ""
+ " const fileData = await newHandle.getFile();"
+ " document.title = await fileData.text();"
+ "}"
+ "</script></head><body>"
+ "<button id='triggerDialog' value='trigger' "
+ "onclick='getTemporaryDir()'"
+ "</body></html>"),
+ QString("qrc:/"));
+ QVERIFY(spyFinished.wait());
+ QTRY_COMPARE(spyFinished.size(), 1);
+
+ evaluateJavaScriptSync(view.page(), "document.getElementById('triggerDialog').focus()");
+ QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(),
+ QStringLiteral("triggerDialog"));
+ QTest::keyClick(view.focusProxy(), Qt::Key_Enter);
+
+ QTRY_COMPARE(page.title(), "New value");
+
+ QTRY_COMPARE(page.chosenFileSelectionMode, QWebEnginePage::FileSelectSave);
+ QTRY_COMPARE(page.chosenAcceptedMimeTypes, QStringList());
+}
+
void tst_QWebEnginePage::backgroundColor()
{
QWebEngineProfile profile;
@@ -4663,24 +5306,27 @@ void tst_QWebEnginePage::audioMuted()
page.setAudioMuted(true);
loadSync(&page, QUrl("about:blank"));
QCOMPARE(page.isAudioMuted(), true);
- QCOMPARE(spy.count(), 1);
+ QCOMPARE(spy.size(), 1);
QCOMPARE(spy[0][0], QVariant(true));
page.setAudioMuted(false);
QCOMPARE(page.isAudioMuted(), false);
- QCOMPARE(spy.count(), 2);
+ QCOMPARE(spy.size(), 2);
QCOMPARE(spy[1][0], QVariant(false));
}
void tst_QWebEnginePage::closeContents()
{
TestPage page;
+ QSignalSpy spyFinished(&page, &QWebEnginePage::loadFinished);
QSignalSpy windowCreatedSpy(&page, &TestPage::windowCreated);
+ page.setUrl(QUrl("about:blank"));
+ QTRY_COMPARE(spyFinished.size(), 1);
page.runJavaScript("var dialog = window.open('', '', 'width=100, height=100');");
- QTRY_COMPARE(windowCreatedSpy.count(), 1);
+ QTRY_COMPARE(windowCreatedSpy.size(), 1);
QWebEngineView *dialogView = new QWebEngineView;
QWebEnginePage *dialogPage = page.createdWindows[0];
- dialogPage->setView(dialogView);
+ dialogView->setPage(dialogPage);
QCOMPARE(dialogPage->lifecycleState(), QWebEnginePage::LifecycleState::Active);
// This should not crash.
@@ -4703,8 +5349,8 @@ void tst_QWebEnginePage::isSafeRedirect_data()
fileScheme += "/";
#endif
- QString tempDir(fileScheme + QDir::tempPath());
- QTest::newRow(qPrintable(tempDir)) << QUrl(tempDir) << QUrl(tempDir + "/");
+ QString tempDir(fileScheme + QDir::tempPath() + "/");
+ QTest::newRow(qPrintable(tempDir)) << QUrl(tempDir) << QUrl(tempDir);
QTest::newRow(qPrintable(tempDir + QString("/foo/bar"))) << QUrl(tempDir + "/foo/bar") << QUrl(tempDir + "/foo/bar");
QTest::newRow("filesystem:http://foo.com/bar") << QUrl("filesystem:http://foo.com/bar") << QUrl("filesystem:http://foo.com/bar/");
}
@@ -4717,11 +5363,452 @@ void tst_QWebEnginePage::isSafeRedirect()
TestPage page;
QSignalSpy spy(&page, SIGNAL(loadFinished(bool)));
page.setUrl(requestedUrl);
- QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 20000);
+ QTRY_COMPARE_WITH_TIMEOUT(spy.size(), 1, 20000);
QCOMPARE(page.url(), expectedUrl);
spy.clear();
}
+class LocalRemoteUrlSchemeHandler : public QWebEngineUrlSchemeHandler
+{
+public:
+ LocalRemoteUrlSchemeHandler(QObject *parent = nullptr)
+ : QWebEngineUrlSchemeHandler(parent)
+ {
+ }
+ ~LocalRemoteUrlSchemeHandler() = default;
+
+ void requestStarted(QWebEngineUrlRequestJob *job) override
+ {
+ QBuffer *buffer = new QBuffer(job);
+ buffer->setData("<html><body><a href='remote://test.html' id='link'>Click link</a></body></html>");
+ job->reply("text/html", buffer);
+ loaded = true;
+ }
+ bool loaded = false;
+};
+
+void tst_QWebEnginePage::localToRemoteNavigation()
+{
+ LocalRemoteUrlSchemeHandler local;
+ LocalRemoteUrlSchemeHandler remote;
+ QWebEngineProfile profile;
+ profile.installUrlSchemeHandler("local", &local);
+ profile.installUrlSchemeHandler("remote", &remote);
+
+ QWebEnginePage page(&profile);
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+ QWebEngineView view;
+ view.resize(640, 480);
+ view.show();
+ view.setPage(&page);
+ page.setUrl(QUrl("local://test.html"));
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
+ QVERIFY(local.loaded);
+
+ // Should navigate:
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 2, 20000);
+ QVERIFY(remote.loaded);
+ local.loaded = false;
+ remote.loaded = false;
+
+ page.setUrl(QUrl("local://test.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 3, 20000);
+ QVERIFY(local.loaded && !remote.loaded);
+
+ // Should not navigate:
+ page.runJavaScript(QStringLiteral("document.getElementById(\"link\").click()"));
+ QTest::qWait(500);
+ QVERIFY(!remote.loaded);
+}
+
+void tst_QWebEnginePage::clientHints_data()
+{
+ QTest::addColumn<bool>("clientHintsEnabled");
+ QTest::addColumn<QString>("arch");
+ QTest::addColumn<QString>("platform");
+ QTest::addColumn<QString>("model");
+ QTest::addColumn<bool>("isMobile");
+ QTest::addColumn<QString>("fullVersion");
+ QTest::addColumn<QString>("platformVersion");
+ QTest::addColumn<QString>("bitness");
+ QTest::addColumn<bool>("isWOW64");
+ QTest::addColumn<QHash<QString, QString>>("fullVersionList");
+
+ QTest::newRow("Modify values") << true << "Abc" << "AmigaOS" << "Ultra" << true << "1.99" << "3" << "x64" << true << QHash<QString, QString>({{"APITest", "1.0.0"}, {"App", "5.0"}});
+ QTest::newRow("Empty values") << true << "" << "" << "" << false << "" << "" << "" << false << QHash<QString, QString>();
+ QTest::newRow("Disable headers") << false << "" << "" << "" << false << "" << "" << "" << false << QHash<QString, QString>();
+}
+
+void tst_QWebEnginePage::clientHints()
+{
+ QFETCH(bool, clientHintsEnabled);
+ QFETCH(QString, arch);
+ QFETCH(QString, platform);
+ QFETCH(QString, model);
+ QFETCH(bool, isMobile);
+ QFETCH(QString, fullVersion);
+ QFETCH(QString, platformVersion);
+ QFETCH(QString, bitness);
+ QFETCH(bool, isWOW64);
+ typedef QHash<QString, QString> brandVersionPairs;
+ QFETCH(brandVersionPairs, fullVersionList);
+
+ QWebEnginePage page;
+ QSignalSpy loadSpy(&page, SIGNAL(loadFinished(bool)));
+
+ QWebEngineClientHints *clientHints = page.profile()->clientHints();
+ clientHints->setAllClientHintsEnabled(clientHintsEnabled);
+
+ HttpServer server;
+ int requestCount = 0;
+ connect(&server, &HttpServer::newRequest, [&] (HttpReqRep *r) {
+ // Platform and Mobile hints are always sent and can't be disabled with this API
+ QVERIFY(r->hasRequestHeader("Sec-CH-UA-Platform"));
+ QVERIFY(r->hasRequestHeader("Sec-CH-UA-Mobile"));
+ if (!clientHintsEnabled) {
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Arch"));
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Model"));
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Full-Version"));
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Platform-Version"));
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Bitness"));
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Wow64"));
+ QVERIFY(!r->hasRequestHeader("Sec-CH-UA-Full-Version-List"));
+ }
+
+ // The first request header won't contain any hints, only after a response with "Accept-CH"
+ if (requestCount > 1 && clientHintsEnabled) {
+ // All hint values are lower case in the headers
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Arch")).remove("\""), arch.toLower());
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Platform")).remove("\""), platform.toLower());
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Model")).remove("\""), model.toLower());
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Mobile")).remove("\""), isMobile ? "?1" : "?0");
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Full-Version")).remove("\""), fullVersion.toLower());
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Platform-Version")).remove("\""), platformVersion.toLower());
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Bitness")).remove("\""), bitness.toLower());
+ QCOMPARE(QString(r->requestHeader("Sec-CH-UA-Wow64")).remove("\""), isWOW64 ? "?1" : "?0");
+ for (auto i = fullVersionList.cbegin(), end = fullVersionList.cend(); i != end; ++i)
+ QVERIFY(QString(r->requestHeader("Sec-CH-UA-Full-Version-List")).contains(i.key().toLower()));
+ }
+
+ r->setResponseHeader("Accept-CH", "Sec-CH-UA-Arch, Sec-CH-UA-Bitness, Sec-CH-UA-Full-Version, Sec-CH-UA-Full-Version-List, Sec-CH-UA-Mobile, Sec-CH-UA-Model, Sec-CH-UA-Platform-Version, Sec-CH-UA-Platform, Sec-CH-UA-Wow64, Sec-CH-UA");
+ r->sendResponse();
+ requestCount++;
+ });
+ QVERIFY(server.start());
+
+ clientHints->setArch(arch);
+ clientHints->setPlatform(platform);
+ clientHints->setModel(model);
+ clientHints->setIsMobile(isMobile);
+ clientHints->setFullVersion(fullVersion);
+ clientHints->setPlatformVersion(platformVersion);
+ clientHints->setBitness(bitness);
+ clientHints->setIsWow64(isWOW64);
+ clientHints->setFullVersionList(fullVersionList);
+
+ page.setUrl(server.url());
+ QTRY_COMPARE(loadSpy.size(), 1);
+ QVERIFY(loadSpy.takeFirst().value(0).toBool());
+
+ QCOMPARE(clientHints->arch(), arch);
+ QCOMPARE(clientHints->platform(), platform);
+ QCOMPARE(clientHints->model(), model);
+ QCOMPARE(clientHints->isMobile(), isMobile);
+ QCOMPARE(clientHints->fullVersion(), fullVersion);
+ QCOMPARE(clientHints->platformVersion(), platformVersion);
+ QCOMPARE(clientHints->bitness(), bitness);
+ QCOMPARE(clientHints->isWow64(), isWOW64);
+ for (auto i = fullVersionList.cbegin(), end = fullVersionList.cend(); i != end; ++i)
+ QCOMPARE(clientHints->fullVersionList()[i.key()], i.value());
+
+ // A new user agent string should not override/disable client hints
+ page.profile()->setHttpUserAgent(QStringLiteral("Custom user agent"));
+ page.triggerAction(QWebEnginePage::Reload);
+ QTRY_COMPARE(loadSpy.size(), 1);
+
+ // Reset all to default values
+ clientHints->resetAll();
+ QCOMPARE_NE(clientHints->arch(), arch);
+#ifdef Q_OS_LINUX
+ QCOMPARE(clientHints->platform().toLower(), "linux");
+#elif defined (Q_OS_MACOS)
+ QCOMPARE(clientHints->platform().toLower(), "macos");
+#elif defined (Q_OS_WIN)
+ QCOMPARE(clientHints->platform().toLower(), "windows");
+#endif
+ QCOMPARE_NE(clientHints->fullVersion(), fullVersion);
+ QCOMPARE_NE(clientHints->platformVersion(), platformVersion);
+ QCOMPARE_NE(clientHints->bitness(), bitness);
+ for (auto i = fullVersionList.cbegin(), end = fullVersionList.cend(); i != end; ++i)
+ QVERIFY(!clientHints->fullVersionList().contains(i.key()));
+ QVERIFY(clientHints->fullVersionList().contains("Chromium"));
+}
+
+void tst_QWebEnginePage::childFrameInput()
+{
+ HttpServer server;
+ server.setHostDomain("localhost");
+
+ // The cross-origin policy blocks scripting this frame with QWebEnginePage::runJavaScript.
+ // Use console messages to validate events.
+ QString innerHtml(
+ "<html><head><style>body{height:1200px;width:1200px;}</style></head><body>test<script>"
+ " let lastX, lastY = 0;"
+ " document.onscroll = (e) => {"
+ " if (window.scrollY > lastY) console.log(\"Down\");"
+ " if (window.scrollY < lastY) console.log(\"Up\");"
+ " if (window.scrollX > lastX) console.log(\"Right\");"
+ " if (window.scrollX < lastX) console.log(\"Left\");"
+ " lastX = window.scrollX;"
+ " lastY = window.scrollY;"
+ " };"
+ " window.onload = () => {console.log('loaded');};"
+ "</script></body></html>");
+
+ QVERIFY(server.start());
+ connect(&server, &HttpServer::newRequest, [&](HttpReqRep *rr) {
+ if (rr->requestPath() == "/main.html") {
+ // the Origin-Agent-Cluster header enables dedicated processes for origins
+ rr->setResponseHeader("Origin-Agent-Cluster", "?1");
+ // the same-site-cross-origin page forces to create the frame in a different process
+ server.setHostDomain("sub.localhost");
+ rr->setResponseBody(("<html><body>"
+ "<iframe id=\"iframe\" width=90% height=90% src=\""
+ + server.url().toString().toUtf8()
+ + "inner.html\"></iframe>"
+ "</body></html>"));
+ }
+ if (rr->requestPath() == "/inner.html")
+ rr->setResponseBody(innerHtml.toUtf8());
+ rr->sendResponse();
+ });
+
+ QWebEngineView view;
+ ConsolePage page;
+ view.setPage(&page);
+ view.resize(640, 480);
+ QSignalSpy loadSpy(&page, &QWebEnginePage::loadFinished);
+ page.load(server.url("/main.html"));
+ QTRY_COMPARE_WITH_TIMEOUT(loadSpy.size(), 1, 20000);
+
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+ QTRY_VERIFY(evaluateJavaScriptSync(&page, "window.originAgentCluster").toBool());
+
+ // make sure the frame is loaded
+ QTRY_COMPARE(page.messages.size(), 1);
+ QTRY_COMPARE(page.messages[0], QString("loaded"));
+
+ // focus
+ evaluateJavaScriptSync(&page, "document.getElementById('iframe').contentWindow.focus()");
+ QTRY_COMPARE(evaluateJavaScriptSync(&page, "document.activeElement.id").toString(),
+ QStringLiteral("iframe"));
+
+ QPoint globalPos = view.windowHandle()->position();
+ QPoint p = elementCenter(&page, QString("iframe"));
+
+ // Even if the document is loaded, it is not necessarily drawn.
+ // Hit-testing (in Viz) for pointer events will be flacky in this scenario.
+ // Send keyClick events first so the target frame will be cached for wheel events.
+ QTest::keyClick(view.focusProxy(), Qt::Key_Down);
+ QTRY_COMPARE(page.messages.size(), 2);
+ QTRY_COMPARE(page.messages[1], QString("Down"));
+
+ QTest::keyClick(view.focusProxy(), Qt::Key_Up);
+ QTRY_COMPARE(page.messages.size(), 3);
+ QTRY_COMPARE(page.messages[2], QString("Up"));
+
+ QTest::keyClick(view.focusProxy(), Qt::Key_Right);
+ QTRY_COMPARE(page.messages.size(), 4);
+ QTRY_COMPARE(page.messages[3], QString("Right"));
+
+ QTest::keyClick(view.focusProxy(), Qt::Key_Left);
+ QTRY_COMPARE(page.messages.size(), 5);
+ QTRY_COMPARE(page.messages[4], QString("Left"));
+
+ makeScroll(view.focusProxy(), p, globalPos, QPoint(0, -120));
+ QTRY_COMPARE(page.messages.size(), 6);
+ QTRY_COMPARE(page.messages[5], QString("Down"));
+
+ makeScroll(view.focusProxy(), p, globalPos, QPoint(0, 120));
+ QTRY_COMPARE(page.messages.size(), 7);
+ QTRY_COMPARE(page.messages[6], QString("Up"));
+
+ makeScroll(view.focusProxy(), p, globalPos, QPoint(-120, 0));
+ QTRY_COMPARE(page.messages.size(), 8);
+ QTRY_COMPARE(page.messages[7], QString("Right"));
+
+ makeScroll(view.focusProxy(), p, globalPos, QPoint(120, 0));
+ QTRY_COMPARE(page.messages.size(), 9);
+ QTRY_COMPARE(page.messages[8], QString("Left"));
+}
+
+void tst_QWebEnginePage::openLinkInNewPageWithWebWindowType_data()
+{
+ QTest::addColumn<QWebEnginePage::WebWindowType>("webWindowType");
+ QTest::addColumn<QString>("elementId");
+ QTest::addColumn<Qt::MouseButton>("button");
+ QTest::addColumn<Qt::KeyboardModifier>("keyboardModififer");
+ QTest::newRow("webBrowserWindow")
+ << QWebEnginePage::WebBrowserWindow << "link" << Qt::LeftButton << Qt::ShiftModifier;
+ QTest::newRow("webBrowserTab")
+ << QWebEnginePage::WebBrowserTab << "link" << Qt::LeftButton << Qt::NoModifier;
+ QTest::newRow("webDialog") << QWebEnginePage::WebDialog << "openWindow" << Qt::LeftButton
+ << Qt::NoModifier;
+ QTest::newRow("webBrowserBackgroundTab") << QWebEnginePage::WebBrowserBackgroundTab << "link"
+ << Qt::MiddleButton << Qt::NoModifier;
+}
+
+class WebWindowTypeTestPage : public QWebEnginePage
+{
+ Q_OBJECT
+
+public:
+ WebWindowType windowType;
+
+signals:
+ void windowCreated();
+
+private:
+ QWebEnginePage *createWindow(WebWindowType type) override
+ {
+ windowType = type;
+ emit windowCreated();
+ return nullptr;
+ }
+};
+
+void tst_QWebEnginePage::openLinkInNewPageWithWebWindowType()
+{
+ QFETCH(QWebEnginePage::WebWindowType, webWindowType);
+ QFETCH(QString, elementId);
+ QFETCH(Qt::MouseButton, button);
+ QFETCH(Qt::KeyboardModifier, keyboardModififer);
+
+ WebWindowTypeTestPage page;
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ QSignalSpy windowCreatedSpy(&page, &WebWindowTypeTestPage::windowCreated);
+ QWebEngineView view(&page);
+ view.resize(640, 480);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptEnabled, true);
+ page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true);
+ QString html = "<html><body>"
+ "<a id='link' href='hello' target='_blank'>link</a>"
+ "<br><br>"
+ "<button id='openWindow' onclick='myFunction()'>Try it</button>"
+ "<script>"
+ "function myFunction() {"
+ " const myWindow = window.open('', '', 'width=300,height=300');"
+ "}"
+ "</script>"
+ "</body></html>";
+
+ page.setHtml(html);
+ QVERIFY(loadFinishedSpy.wait());
+
+ QTest::mouseClick(view.focusProxy(), button, keyboardModififer,
+ elementCenter(&page, elementId));
+ QVERIFY(windowCreatedSpy.wait());
+ QCOMPARE(page.windowType, webWindowType);
+}
+
+class DoNothingInterceptor : public QWebEngineUrlRequestInterceptor
+{
+public:
+ DoNothingInterceptor() { }
+
+ void interceptRequest(QWebEngineUrlRequestInfo &) override
+ {
+ ran = true;
+ }
+ bool ran = false;
+};
+
+void tst_QWebEnginePage::keepInterceptorAfterNewWindowRequested()
+{
+ DoNothingInterceptor interceptor;
+ QWebEnginePage page;
+ page.setUrlRequestInterceptor(&interceptor);
+ connect(&page, &QWebEnginePage::newWindowRequested, [&](QWebEngineNewWindowRequest &request) {
+ request.openIn(&page);
+ });
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+
+ QWebEngineView view;
+ view.resize(500, 500);
+ view.setPage(&page);
+ view.show();
+ QVERIFY(QTest::qWaitForWindowExposed(&view));
+
+ page.setHtml("<html><body>"
+ "<a id='link' href='hello' target='_blank'>link</a>"
+ "</body></html>");
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QVERIFY(loadFinishedSpy.takeFirst().value(0).toBool());
+ QVERIFY(interceptor.ran);
+ interceptor.ran = false;
+
+ QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, elementCenter(&page, "link"));
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QVERIFY(loadFinishedSpy.takeFirst().value(0).toBool());
+ QVERIFY(!interceptor.ran);
+
+ page.setHtml("<html><body></body></html>");
+ QTRY_COMPARE(loadFinishedSpy.size(), 1);
+ QVERIFY(loadFinishedSpy.takeFirst().value(0).toBool());
+ QVERIFY(interceptor.ran);
+}
+
+void tst_QWebEnginePage::chooseDesktopMedia()
+{
+#if QT_CONFIG(webengine_extensions) && QT_CONFIG(webengine_webrtc)
+ HttpServer server;
+ server.setHostDomain("localhost");
+ connect(&server, &HttpServer::newRequest, &server, [&] (HttpReqRep *r) {
+ if (r->requestMethod() == "GET")
+ r->setResponseBody("<html></html>");
+ });
+ QVERIFY(server.start());
+
+ QWebEnginePage page;
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.settings()->setAttribute(QWebEngineSettings::ScreenCaptureEnabled, true);
+ page.profile()->setPersistentPermissionsPolicy(QWebEngineProfile::NoPersistentPermissions);
+
+ bool desktopMediaRequested = false;
+ bool permissionRequested = false;
+
+ connect(&page, &QWebEnginePage::desktopMediaRequested,
+ [&](const QWebEngineDesktopMediaRequest &) {
+ desktopMediaRequested = true;
+ });
+
+ connect(&page, &QWebEnginePage::permissionRequested,
+ [&](QWebEnginePermission permission) {
+ permissionRequested = true;
+ // Handle permission to 'complete' the media request
+ permission.grant();
+ });
+
+ page.load(QUrl(server.url()));
+ QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.size(), 1, 20000);
+
+ const QString extensionId("nkeimhogjdpnpccoofpliimaahmaaome");
+ page.runJavaScript(QString("(() => {"
+ " let port = chrome.runtime.connect(\"%1\", {name: \"chooseDesktopMedia\"});"
+ " port.postMessage({method: \"chooseDesktopMedia\"});"
+ "})()").arg(extensionId));
+
+ QTRY_VERIFY(desktopMediaRequested);
+ QTRY_VERIFY(permissionRequested);
+#endif // QT_CONFIG(webengine_extensions) && QT_CONFIG(webengine_webrtc)
+}
+
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
deleted file mode 100644
index 013a307de..000000000
--- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc
+++ /dev/null
@@ -1,31 +0,0 @@
-<!DOCTYPE RCC><RCC version="1.0">
-<qresource>
- <file>resources/content.html</file>
- <file>resources/dynamicFrame.html</file>
- <file>resources/index.html</file>
- <file>resources/frame_a.html</file>
- <file>resources/frame_c.html</file>
- <file>resources/iframe.html</file>
- <file>resources/iframe2.html</file>
- <file>resources/iframe3.html</file>
- <file>resources/framedindex.html</file>
- <file>resources/fullscreen.html</file>
- <file>resources/script.html</file>
- <file>resources/user.css</file>
- <file>resources/image.png</file>
- <file>resources/pasteimage.html</file>
- <file>resources/reload.html</file>
- <file>resources/style.css</file>
- <file>resources/test1.html</file>
- <file>resources/test2.html</file>
- <file>resources/testiframe.html</file>
- <file>resources/testiframe2.html</file>
- <file>resources/foo.txt</file>
- <file>resources/bar.txt</file>
- <file>resources/path with spaces.txt</file>
- <file>resources/lifecycle.html</file>
-</qresource>
-<qresource prefix='/shared'>
- <file alias='notification.html'>../../shared/data/notification.html</file>
-</qresource>
-</RCC>