summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets')
-rw-r--r--tests/auto/widgets/positionplugin/plugin.cpp29
-rw-r--r--tests/auto/widgets/qwebenginefaviconmanager/qwebenginefaviconmanager.pro2
-rw-r--r--tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-misc.html11
-rw-r--r--tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-shortcut.html10
-rw-r--r--tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-single.html9
-rw-r--r--tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-touch.html10
-rw-r--r--tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-unavailable.html9
-rw-r--r--tests/auto/widgets/qwebenginefaviconmanager/resources/icons/qt144.pngbin0 -> 8315 bytes
-rw-r--r--tests/auto/widgets/qwebenginefaviconmanager/resources/icons/qt32.icobin0 -> 4286 bytes
-rw-r--r--tests/auto/widgets/qwebenginefaviconmanager/resources/test1.html1
-rw-r--r--tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.cpp279
-rw-r--r--tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.qrc12
-rw-r--r--tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp101
-rw-r--r--tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp72
-rw-r--r--tests/auto/widgets/resources/qwebchannel.js408
-rw-r--r--tests/auto/widgets/resources/tests.qrc5
-rw-r--r--tests/auto/widgets/tests.pri1
-rw-r--r--tests/auto/widgets/util.h7
-rw-r--r--tests/auto/widgets/widgets.pro1
19 files changed, 931 insertions, 36 deletions
diff --git a/tests/auto/widgets/positionplugin/plugin.cpp b/tests/auto/widgets/positionplugin/plugin.cpp
index 74d30469d..ca2e7eb45 100644
--- a/tests/auto/widgets/positionplugin/plugin.cpp
+++ b/tests/auto/widgets/positionplugin/plugin.cpp
@@ -1,31 +1,26 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL21$
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 2.1 or version 3 as published by the Free
-** Software Foundation and appearing in the file LICENSE.LGPLv21 and
-** LICENSE.LGPLv3 included in the packaging of this file. Please review the
-** following information to ensure the GNU Lesser General Public License
-** requirements will be met: https://www.gnu.org/licenses/lgpl.html and
-** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
-**
-** As a special exception, The Qt Company gives you certain additional
-** rights. These rights are described in The Qt Company LGPL Exception
-** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
diff --git a/tests/auto/widgets/qwebenginefaviconmanager/qwebenginefaviconmanager.pro b/tests/auto/widgets/qwebenginefaviconmanager/qwebenginefaviconmanager.pro
new file mode 100644
index 000000000..70786e70f
--- /dev/null
+++ b/tests/auto/widgets/qwebenginefaviconmanager/qwebenginefaviconmanager.pro
@@ -0,0 +1,2 @@
+include(../tests.pri)
+QT *= core-private gui-private
diff --git a/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-misc.html b/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-misc.html
new file mode 100644
index 000000000..9e788bdf4
--- /dev/null
+++ b/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-misc.html
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <title>Favicon Test</title>
+ <link rel="shortcut icon" href="icons/qt32.ico" />
+ <link rel="apple-touch-icon" href="icons/qt144.png" />
+ <link rel="shortcut icon" href="icons/unavailable.ico" />
+ </head>
+ <body>
+ <h1>Favicon Test</h1>
+ </body>
+</html>
diff --git a/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-shortcut.html b/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-shortcut.html
new file mode 100644
index 000000000..786cdb816
--- /dev/null
+++ b/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-shortcut.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <title>Favicon Test</title>
+ <link rel="shortcut icon" href="icons/qt32.ico" />
+ <link rel="shortcut icon" href="icons/qt144.png" />
+ </head>
+ <body>
+ <h1>Favicon Test</h1>
+ </body>
+</html>
diff --git a/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-single.html b/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-single.html
new file mode 100644
index 000000000..eb4675c75
--- /dev/null
+++ b/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-single.html
@@ -0,0 +1,9 @@
+<html>
+ <head>
+ <title>Favicon Test</title>
+ <link rel="shortcut icon" href="icons/qt32.ico" />
+ </head>
+ <body>
+ <h1>Favicon Test</h1>
+ </body>
+</html>
diff --git a/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-touch.html b/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-touch.html
new file mode 100644
index 000000000..271783434
--- /dev/null
+++ b/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-touch.html
@@ -0,0 +1,10 @@
+<html>
+ <head>
+ <title>Favicon Test</title>
+ <link rel="apple-touch-icon" href="icons/qt32.ico" />
+ <link rel="apple-touch-icon" href="icons/qt144.png" />
+ </head>
+ <body>
+ <h1>Favicon Test</h1>
+ </body>
+</html>
diff --git a/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-unavailable.html b/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-unavailable.html
new file mode 100644
index 000000000..c45664294
--- /dev/null
+++ b/tests/auto/widgets/qwebenginefaviconmanager/resources/favicon-unavailable.html
@@ -0,0 +1,9 @@
+<html>
+ <head>
+ <title>Favicon Test</title>
+ <link rel="shortcut icon" href="icons/unavailable.ico" />
+ </head>
+ <body>
+ <h1>Favicon Test</h1>
+ </body>
+</html>
diff --git a/tests/auto/widgets/qwebenginefaviconmanager/resources/icons/qt144.png b/tests/auto/widgets/qwebenginefaviconmanager/resources/icons/qt144.png
new file mode 100644
index 000000000..050b1e066
--- /dev/null
+++ b/tests/auto/widgets/qwebenginefaviconmanager/resources/icons/qt144.png
Binary files differ
diff --git a/tests/auto/widgets/qwebenginefaviconmanager/resources/icons/qt32.ico b/tests/auto/widgets/qwebenginefaviconmanager/resources/icons/qt32.ico
new file mode 100644
index 000000000..2f6fcb5bc
--- /dev/null
+++ b/tests/auto/widgets/qwebenginefaviconmanager/resources/icons/qt32.ico
Binary files differ
diff --git a/tests/auto/widgets/qwebenginefaviconmanager/resources/test1.html b/tests/auto/widgets/qwebenginefaviconmanager/resources/test1.html
new file mode 100644
index 000000000..b323f966e
--- /dev/null
+++ b/tests/auto/widgets/qwebenginefaviconmanager/resources/test1.html
@@ -0,0 +1 @@
+<html><body><p>Some text 1</p></body></html>
diff --git a/tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.cpp b/tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.cpp
new file mode 100644
index 000000000..ececb0efd
--- /dev/null
+++ b/tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.cpp
@@ -0,0 +1,279 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebEngine module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+#include <QtTest/QtTest>
+#include "../util.h"
+
+#include <qwebenginepage.h>
+#include <qwebenginesettings.h>
+#include <qwebengineview.h>
+
+
+class tst_QWebEngineFaviconManager : public QObject {
+ Q_OBJECT
+
+public Q_SLOTS:
+ void init();
+ void initTestCase();
+ void cleanupTestCase();
+ void cleanup();
+
+private Q_SLOTS:
+ void faviconLoad();
+ void faviconLoadFromResources();
+ void faviconLoadEncodedUrl();
+ void noFavicon();
+ void aboutBlank();
+ void unavailableFavicon();
+ void errorPageEnabled();
+ void errorPageDisabled();
+ void bestFavicon();
+ void touchIcon();
+
+private:
+ QWebEngineView* m_view;
+ QWebEnginePage* m_page;
+};
+
+
+void tst_QWebEngineFaviconManager::init()
+{
+ m_view = new QWebEngineView();
+ m_page = m_view->page();
+}
+
+
+void tst_QWebEngineFaviconManager::initTestCase()
+{
+}
+
+void tst_QWebEngineFaviconManager::cleanupTestCase()
+{
+}
+
+
+void tst_QWebEngineFaviconManager::cleanup()
+{
+ delete m_view;
+}
+
+void tst_QWebEngineFaviconManager::faviconLoad()
+{
+ 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);
+
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+
+ QUrl url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/favicon-single.html"));
+ m_page->load(url);
+
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+
+ QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ QCOMPARE(iconUrl, QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/icons/qt32.ico")));
+}
+
+void tst_QWebEngineFaviconManager::faviconLoadFromResources()
+{
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+
+ QUrl url = QUrl("qrc:/resources/favicon-single.html");
+ m_page->load(url);
+
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+
+ QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ QCOMPARE(iconUrl, QUrl("qrc:/resources/icons/qt32.ico"));
+}
+
+void tst_QWebEngineFaviconManager::faviconLoadEncodedUrl()
+{
+ 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);
+
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+
+ QString urlString = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/favicon-single.html")).toString();
+ QUrl url = QUrl(urlString + QLatin1String("?favicon=load should work with#whitespace!"));
+ m_page->load(url);
+
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+
+ QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ QCOMPARE(iconUrl, QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/icons/qt32.ico")));
+}
+
+void tst_QWebEngineFaviconManager::noFavicon()
+{
+ 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);
+
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+
+ QUrl url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/test1.html"));
+ m_page->load(url);
+
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+
+ QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ QVERIFY(iconUrl.isEmpty());
+}
+
+void tst_QWebEngineFaviconManager::aboutBlank()
+{
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+
+ QUrl url = QUrl("about:blank");
+ m_page->load(url);
+
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+
+ QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ QVERIFY(iconUrl.isEmpty());
+}
+
+void tst_QWebEngineFaviconManager::unavailableFavicon()
+{
+ 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);
+
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+
+ QUrl url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/favicon-unavailable.html"));
+ m_page->load(url);
+
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+
+ QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ QCOMPARE(iconUrl, QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/icons/unavailable.ico")));
+}
+
+void tst_QWebEngineFaviconManager::errorPageEnabled()
+{
+ m_page->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true);
+
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+
+ QUrl url = QUrl(QUrl("http://non.existent/url"));
+ m_page->load(url);
+
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ // Icon is reseted at load start.
+ // Load is started twice: once for unavailale page then error page
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 2);
+
+ QUrl iconUrl;
+ iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ QVERIFY(iconUrl.isEmpty());
+ iconUrl = iconUrlChangedSpy.at(1).at(0).toString();
+ QVERIFY(iconUrl.isEmpty());
+}
+
+void tst_QWebEngineFaviconManager::errorPageDisabled()
+{
+ m_page->settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false);
+
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+
+ QUrl url = QUrl(QUrl("http://non.existent/url"));
+ m_page->load(url);
+
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+
+ QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ QVERIFY(iconUrl.isEmpty());
+}
+
+void tst_QWebEngineFaviconManager::bestFavicon()
+{
+ 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);
+
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+ QUrl url, iconUrl;
+
+ url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/favicon-misc.html"));
+ m_page->load(url);
+
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+
+ iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ // Touch icon is ignored
+ QCOMPARE(iconUrl, QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/icons/qt32.ico")));
+
+ loadFinishedSpy.clear();
+ iconUrlChangedSpy.clear();
+
+ url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/favicon-shortcut.html"));
+ m_page->load(url);
+
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+
+ iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ QCOMPARE(iconUrl, QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/icons/qt144.png")));
+}
+
+void tst_QWebEngineFaviconManager::touchIcon()
+{
+ 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);
+
+ QSignalSpy loadFinishedSpy(m_page, SIGNAL(loadFinished(bool)));
+ QSignalSpy iconUrlChangedSpy(m_page, SIGNAL(iconUrlChanged(QUrl)));
+
+ QUrl url = QUrl::fromLocalFile(TESTS_SOURCE_DIR + QLatin1String("qwebenginefaviconmanager/resources/favicon-touch.html"));
+ m_page->load(url);
+
+ QTRY_COMPARE(loadFinishedSpy.count(), 1);
+ QTRY_COMPARE(iconUrlChangedSpy.count(), 1);
+
+ QUrl iconUrl = iconUrlChangedSpy.at(0).at(0).toString();
+ QVERIFY(iconUrl.isEmpty());
+}
+
+QTEST_MAIN(tst_QWebEngineFaviconManager)
+
+#include "tst_qwebenginefaviconmanager.moc"
diff --git a/tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.qrc b/tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.qrc
new file mode 100644
index 000000000..65d8ed928
--- /dev/null
+++ b/tests/auto/widgets/qwebenginefaviconmanager/tst_qwebenginefaviconmanager.qrc
@@ -0,0 +1,12 @@
+<!DOCTYPE RCC><RCC version="1.0">
+<qresource>
+ <file>resources/favicon-misc.html</file>
+ <file>resources/favicon-shortcut.html</file>
+ <file>resources/favicon-single.html</file>
+ <file>resources/favicon-touch.html</file>
+ <file>resources/favicon-unavailable.html</file>
+ <file>resources/icons/qt144.png</file>
+ <file>resources/icons/qt32.ico</file>
+ <file>resources/test1.html</file>
+</qresource>
+</RCC>
diff --git a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
index 9195a5190..26980df7b 100644
--- a/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
+++ b/tests/auto/widgets/qwebengineprofile/tst_qwebengineprofile.cpp
@@ -1,34 +1,26 @@
/****************************************************************************
**
-** Copyright (C) 2015 The Qt Company Ltd.
-** Contact: http://www.qt.io/licensing/
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtWebEngine module of the Qt Toolkit.
**
-** $QT_BEGIN_LICENSE:LGPL$
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see http://www.qt.io/terms-conditions. For further
-** information use the contact form at http://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPLv3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl.html.
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or later as published by the Free
-** Software Foundation and appearing in the file LICENSE.GPL included in
-** the packaging of this file. Please review the following information to
-** ensure the GNU General Public License version 2.0 requirements will be
-** met: http://www.gnu.org/licenses/gpl-2.0.html.
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
@@ -40,6 +32,7 @@
#include <QtWebEngineCore/qwebengineurlrequestjob.h>
#include <QtWebEngineCore/qwebengineurlschemehandler.h>
#include <QtWebEngineWidgets/qwebengineprofile.h>
+#include <QtWebEngineWidgets/qwebenginepage.h>
#include <QtWebEngineWidgets/qwebenginesettings.h>
#include <QtWebEngineWidgets/qwebengineview.h>
@@ -50,6 +43,8 @@ class tst_QWebEngineProfile : public QObject
private Q_SLOTS:
void defaultProfile();
void profileConstructors();
+ void clearDataFromCache();
+ void disableCache();
void urlSchemeHandlers();
void urlSchemeHandlerFailRequest();
};
@@ -76,7 +71,77 @@ void tst_QWebEngineProfile::profileConstructors()
QCOMPARE(diskProfile.httpCacheType(), QWebEngineProfile::DiskHttpCache);
QCOMPARE(otrProfile.persistentCookiesPolicy(), QWebEngineProfile::NoPersistentCookies);
QCOMPARE(diskProfile.persistentCookiesPolicy(), QWebEngineProfile::AllowPersistentCookies);
+}
+
+void tst_QWebEngineProfile::clearDataFromCache()
+{
+ QWebEnginePage page;
+
+ QDir cacheDir("./tst_QWebEngineProfile_cacheDir");
+ cacheDir.makeAbsolute();
+ if (cacheDir.exists())
+ cacheDir.removeRecursively();
+ cacheDir.mkpath(cacheDir.path());
+
+ QWebEngineProfile *profile = page.profile();
+ profile->setCachePath(cacheDir.path());
+ profile->setHttpCacheType(QWebEngineProfile::DiskHttpCache);
+
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.load(QUrl("http://qt-project.org"));
+ if (!loadFinishedSpy.wait(10000) || !loadFinishedSpy.at(0).at(0).toBool())
+ QSKIP("Couldn't load page from network, skipping test.");
+
+ cacheDir.refresh();
+ QVERIFY(cacheDir.entryList().contains("Cache"));
+ cacheDir.cd("./Cache");
+ int filesBeforeClear = cacheDir.entryList().count();
+
+ QFileSystemWatcher fileSystemWatcher;
+ fileSystemWatcher.addPath(cacheDir.path());
+ QSignalSpy directoryChangedSpy(&fileSystemWatcher, SIGNAL(directoryChanged(const QString &)));
+
+ // It deletes most of the files, but not all of them.
+ profile->clearHttpCache();
+ QTest::qWait(1000);
+ QTRY_VERIFY(directoryChangedSpy.count() > 0);
+
+ cacheDir.refresh();
+ QVERIFY(filesBeforeClear > cacheDir.entryList().count());
+
+ cacheDir.removeRecursively();
+}
+
+void tst_QWebEngineProfile::disableCache()
+{
+ QWebEnginePage page;
+ QDir cacheDir("./tst_QWebEngineProfile_cacheDir");
+ if (cacheDir.exists())
+ cacheDir.removeRecursively();
+ cacheDir.mkpath(cacheDir.path());
+
+ QWebEngineProfile *profile = page.profile();
+ profile->setCachePath(cacheDir.path());
+ QVERIFY(!cacheDir.entryList().contains("Cache"));
+
+ profile->setHttpCacheType(QWebEngineProfile::NoCache);
+ QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool)));
+ page.load(QUrl("http://qt-project.org"));
+ if (!loadFinishedSpy.wait(10000) || !loadFinishedSpy.at(0).at(0).toBool())
+ QSKIP("Couldn't load page from network, skipping test.");
+
+ cacheDir.refresh();
+ QVERIFY(!cacheDir.entryList().contains("Cache"));
+
+ profile->setHttpCacheType(QWebEngineProfile::DiskHttpCache);
+ page.load(QUrl("http://qt-project.org"));
+ if (!loadFinishedSpy.wait(10000) || !loadFinishedSpy.at(1).at(0).toBool())
+ QSKIP("Couldn't load page from network, skipping test.");
+
+ cacheDir.refresh();
+ QVERIFY(cacheDir.entryList().contains("Cache"));
+ cacheDir.removeRecursively();
}
class RedirectingUrlSchemeHandler : public QWebEngineUrlSchemeHandler
diff --git a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
index 53762f54c..ad10234f4 100644
--- a/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
+++ b/tests/auto/widgets/qwebenginescript/tst_qwebenginescript.cpp
@@ -24,6 +24,7 @@
#include <qwebenginescriptcollection.h>
#include <qwebengineview.h>
#include "../util.h"
+#include <QWebChannel>
class tst_QWebEngineScript: public QObject {
Q_OBJECT
@@ -34,7 +35,8 @@ private Q_SLOTS:
void injectionPoint_data();
void scriptWorld();
void scriptModifications();
-
+ void webChannel_data();
+ void webChannel();
};
void tst_QWebEngineScript::domEditing()
@@ -115,12 +117,14 @@ void tst_QWebEngineScript::scriptWorld()
page.load(QUrl("about:blank"));
waitForSignal(&page, SIGNAL(loadFinished(bool)));
QCOMPARE(evaluateJavaScriptSync(&page, "typeof(userScriptTest) != \"undefined\" && userScriptTest == 1;"), QVariant::fromValue(true));
+ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "typeof(userScriptTest) == \"undefined\"", QWebEngineScript::ApplicationWorld), QVariant::fromValue(true));
script.setWorldId(QWebEngineScript::ApplicationWorld);
page.scripts().clear();
page.scripts().insert(script);
page.load(QUrl("about:blank"));
waitForSignal(&page, SIGNAL(loadFinished(bool)));
QCOMPARE(evaluateJavaScriptSync(&page, "typeof(userScriptTest) == \"undefined\""), QVariant::fromValue(true));
+ QCOMPARE(evaluateJavaScriptSyncInWorld(&page, "typeof(userScriptTest) != \"undefined\" && userScriptTest == 1;", QWebEngineScript::ApplicationWorld), QVariant::fromValue(true));
}
void tst_QWebEngineScript::scriptModifications()
@@ -148,6 +152,72 @@ void tst_QWebEngineScript::scriptModifications()
QVERIFY(page.scripts().count() == 0);
}
+class TestObject : public QObject
+{
+ Q_OBJECT
+ Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
+public:
+ TestObject(QObject *parent = 0) : QObject(parent) { }
+
+ void setText(const QString &text)
+ {
+ if (text == m_text)
+ return;
+ m_text = text;
+ emit textChanged(text);
+ }
+
+ QString text() const { return m_text; }
+
+signals:
+ void textChanged(const QString &text);
+
+private:
+ QString m_text;
+};
+
+
+void tst_QWebEngineScript::webChannel_data()
+{
+ QTest::addColumn<int>("worldId");
+ QTest::newRow("MainWorld") << static_cast<int>(QWebEngineScript::MainWorld);
+ QTest::newRow("ApplicationWorld") << static_cast<int>(QWebEngineScript::ApplicationWorld);
+}
+
+void tst_QWebEngineScript::webChannel()
+{
+ QFETCH(int, worldId);
+ QWebEnginePage page;
+ TestObject testObject;
+ QScopedPointer<QWebChannel> channel(new QWebChannel(this));
+ channel->registerObject(QStringLiteral("object"), &testObject);
+ page.setWebChannel(channel.data(), worldId);
+
+ QFile qwebchanneljs(":/qwebchannel.js");
+ QVERIFY(qwebchanneljs.exists());
+ qwebchanneljs.open(QFile::ReadOnly);
+ QByteArray scriptSrc = qwebchanneljs.readAll();
+ qwebchanneljs.close();
+ QWebEngineScript script;
+ script.setInjectionPoint(QWebEngineScript::DocumentCreation);
+ script.setWorldId(worldId);
+ script.setSourceCode(QString::fromLatin1(scriptSrc));
+ page.scripts().insert(script);
+ page.setHtml(QStringLiteral("<html><body></body></html>"));
+ waitForSignal(&page, SIGNAL(loadFinished(bool)));
+ page.runJavaScript(QLatin1String(
+ "new QWebChannel(qt.webChannelTransport,"
+ " function(channel) {"
+ " channel.objects.object.text = 'test';"
+ " }"
+ ");"), worldId);
+ waitForSignal(&testObject, SIGNAL(textChanged(QString)));
+ QCOMPARE(testObject.text(), QStringLiteral("test"));
+
+ if (worldId != QWebEngineScript::MainWorld)
+ QCOMPARE(evaluateJavaScriptSync(&page, "qt.webChannelTransport"), QVariant(QVariant::Invalid));
+}
+
QTEST_MAIN(tst_QWebEngineScript)
#include "tst_qwebenginescript.moc"
diff --git a/tests/auto/widgets/resources/qwebchannel.js b/tests/auto/widgets/resources/qwebchannel.js
new file mode 100644
index 000000000..1da8f5496
--- /dev/null
+++ b/tests/auto/widgets/resources/qwebchannel.js
@@ -0,0 +1,408 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2014 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Milian Wolff <milian.wolff@kdab.com>
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the QtWebChannel module of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+"use strict";
+
+var QWebChannelMessageTypes = {
+ signal: 1,
+ propertyUpdate: 2,
+ init: 3,
+ idle: 4,
+ debug: 5,
+ invokeMethod: 6,
+ connectToSignal: 7,
+ disconnectFromSignal: 8,
+ setProperty: 9,
+ response: 10,
+};
+
+var QWebChannel = function(transport, initCallback)
+{
+ if (typeof transport !== "object" || typeof transport.send !== "function") {
+ console.error("The QWebChannel expects a transport object with a send function and onmessage callback property." +
+ " Given is: transport: " + typeof(transport) + ", transport.send: " + typeof(transport.send));
+ return;
+ }
+
+ var channel = this;
+ this.transport = transport;
+
+ this.send = function(data)
+ {
+ if (typeof(data) !== "string") {
+ data = JSON.stringify(data);
+ }
+ channel.transport.send(data);
+ }
+
+ this.transport.onmessage = function(message)
+ {
+ var data = message.data;
+ if (typeof data === "string") {
+ data = JSON.parse(data);
+ }
+ switch (data.type) {
+ case QWebChannelMessageTypes.signal:
+ channel.handleSignal(data);
+ break;
+ case QWebChannelMessageTypes.response:
+ channel.handleResponse(data);
+ break;
+ case QWebChannelMessageTypes.propertyUpdate:
+ channel.handlePropertyUpdate(data);
+ break;
+ default:
+ console.error("invalid message received:", message.data);
+ break;
+ }
+ }
+
+ this.execCallbacks = {};
+ this.execId = 0;
+ this.exec = function(data, callback)
+ {
+ if (!callback) {
+ // if no callback is given, send directly
+ channel.send(data);
+ return;
+ }
+ if (channel.execId === Number.MAX_VALUE) {
+ // wrap
+ channel.execId = Number.MIN_VALUE;
+ }
+ if (data.hasOwnProperty("id")) {
+ console.error("Cannot exec message with property id: " + JSON.stringify(data));
+ return;
+ }
+ data.id = channel.execId++;
+ channel.execCallbacks[data.id] = callback;
+ channel.send(data);
+ };
+
+ this.objects = {};
+
+ this.handleSignal = function(message)
+ {
+ var object = channel.objects[message.object];
+ if (object) {
+ object.signalEmitted(message.signal, message.args);
+ } else {
+ console.warn("Unhandled signal: " + message.object + "::" + message.signal);
+ }
+ }
+
+ this.handleResponse = function(message)
+ {
+ if (!message.hasOwnProperty("id")) {
+ console.error("Invalid response message received: ", JSON.stringify(message));
+ return;
+ }
+ channel.execCallbacks[message.id](message.data);
+ delete channel.execCallbacks[message.id];
+ }
+
+ this.handlePropertyUpdate = function(message)
+ {
+ for (var i in message.data) {
+ var data = message.data[i];
+ var object = channel.objects[data.object];
+ if (object) {
+ object.propertyUpdate(data.signals, data.properties);
+ } else {
+ console.warn("Unhandled property update: " + data.object + "::" + data.signal);
+ }
+ }
+ channel.exec({type: QWebChannelMessageTypes.idle});
+ }
+
+ this.debug = function(message)
+ {
+ channel.send({type: QWebChannelMessageTypes.debug, data: message});
+ };
+
+ channel.exec({type: QWebChannelMessageTypes.init}, function(data) {
+ for (var objectName in data) {
+ var object = new QObject(objectName, data[objectName], channel);
+ }
+ // now unwrap properties, which might reference other registered objects
+ for (var objectName in channel.objects) {
+ channel.objects[objectName].unwrapProperties();
+ }
+ if (initCallback) {
+ initCallback(channel);
+ }
+ channel.exec({type: QWebChannelMessageTypes.idle});
+ });
+};
+
+function QObject(name, data, webChannel)
+{
+ this.__id__ = name;
+ webChannel.objects[name] = this;
+
+ // List of callbacks that get invoked upon signal emission
+ this.__objectSignals__ = {};
+
+ // Cache of all properties, updated when a notify signal is emitted
+ this.__propertyCache__ = {};
+
+ var object = this;
+
+ // ----------------------------------------------------------------------
+
+ this.unwrapQObject = function(response)
+ {
+ if (response instanceof Array) {
+ // support list of objects
+ var ret = new Array(response.length);
+ for (var i = 0; i < response.length; ++i) {
+ ret[i] = object.unwrapQObject(response[i]);
+ }
+ return ret;
+ }
+ if (!response
+ || !response["__QObject*__"]
+ || response.id === undefined) {
+ return response;
+ }
+
+ var objectId = response.id;
+ if (webChannel.objects[objectId])
+ return webChannel.objects[objectId];
+
+ if (!response.data) {
+ console.error("Cannot unwrap unknown QObject " + objectId + " without data.");
+ return;
+ }
+
+ var qObject = new QObject( objectId, response.data, webChannel );
+ qObject.destroyed.connect(function() {
+ if (webChannel.objects[objectId] === qObject) {
+ delete webChannel.objects[objectId];
+ // reset the now deleted QObject to an empty {} object
+ // just assigning {} though would not have the desired effect, but the
+ // below also ensures all external references will see the empty map
+ // NOTE: this detour is necessary to workaround QTBUG-40021
+ var propertyNames = [];
+ for (var propertyName in qObject) {
+ propertyNames.push(propertyName);
+ }
+ for (var idx in propertyNames) {
+ delete qObject[propertyNames[idx]];
+ }
+ }
+ });
+ // here we are already initialized, and thus must directly unwrap the properties
+ qObject.unwrapProperties();
+ return qObject;
+ }
+
+ this.unwrapProperties = function()
+ {
+ for (var propertyIdx in object.__propertyCache__) {
+ object.__propertyCache__[propertyIdx] = object.unwrapQObject(object.__propertyCache__[propertyIdx]);
+ }
+ }
+
+ function addSignal(signalData, isPropertyNotifySignal)
+ {
+ var signalName = signalData[0];
+ var signalIndex = signalData[1];
+ object[signalName] = {
+ connect: function(callback) {
+ if (typeof(callback) !== "function") {
+ console.error("Bad callback given to connect to signal " + signalName);
+ return;
+ }
+
+ object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
+ object.__objectSignals__[signalIndex].push(callback);
+
+ if (!isPropertyNotifySignal && signalName !== "destroyed") {
+ // only required for "pure" signals, handled separately for properties in propertyUpdate
+ // also note that we always get notified about the destroyed signal
+ webChannel.exec({
+ type: QWebChannelMessageTypes.connectToSignal,
+ object: object.__id__,
+ signal: signalIndex
+ });
+ }
+ },
+ disconnect: function(callback) {
+ if (typeof(callback) !== "function") {
+ console.error("Bad callback given to disconnect from signal " + signalName);
+ return;
+ }
+ object.__objectSignals__[signalIndex] = object.__objectSignals__[signalIndex] || [];
+ var idx = object.__objectSignals__[signalIndex].indexOf(callback);
+ if (idx === -1) {
+ console.error("Cannot find connection of signal " + signalName + " to " + callback.name);
+ return;
+ }
+ object.__objectSignals__[signalIndex].splice(idx, 1);
+ if (!isPropertyNotifySignal && object.__objectSignals__[signalIndex].length === 0) {
+ // only required for "pure" signals, handled separately for properties in propertyUpdate
+ webChannel.exec({
+ type: QWebChannelMessageTypes.disconnectFromSignal,
+ object: object.__id__,
+ signal: signalIndex
+ });
+ }
+ }
+ };
+ }
+
+ /**
+ * Invokes all callbacks for the given signalname. Also works for property notify callbacks.
+ */
+ function invokeSignalCallbacks(signalName, signalArgs)
+ {
+ var connections = object.__objectSignals__[signalName];
+ if (connections) {
+ connections.forEach(function(callback) {
+ callback.apply(callback, signalArgs);
+ });
+ }
+ }
+
+ this.propertyUpdate = function(signals, propertyMap)
+ {
+ // update property cache
+ for (var propertyIndex in propertyMap) {
+ var propertyValue = propertyMap[propertyIndex];
+ object.__propertyCache__[propertyIndex] = propertyValue;
+ }
+
+ for (var signalName in signals) {
+ // Invoke all callbacks, as signalEmitted() does not. This ensures the
+ // property cache is updated before the callbacks are invoked.
+ invokeSignalCallbacks(signalName, signals[signalName]);
+ }
+ }
+
+ this.signalEmitted = function(signalName, signalArgs)
+ {
+ invokeSignalCallbacks(signalName, signalArgs);
+ }
+
+ function addMethod(methodData)
+ {
+ var methodName = methodData[0];
+ var methodIdx = methodData[1];
+ object[methodName] = function() {
+ var args = [];
+ var callback;
+ for (var i = 0; i < arguments.length; ++i) {
+ if (typeof arguments[i] === "function")
+ callback = arguments[i];
+ else
+ args.push(arguments[i]);
+ }
+
+ webChannel.exec({
+ "type": QWebChannelMessageTypes.invokeMethod,
+ "object": object.__id__,
+ "method": methodIdx,
+ "args": args
+ }, function(response) {
+ if (response !== undefined) {
+ var result = object.unwrapQObject(response);
+ if (callback) {
+ (callback)(result);
+ }
+ }
+ });
+ };
+ }
+
+ function bindGetterSetter(propertyInfo)
+ {
+ var propertyIndex = propertyInfo[0];
+ var propertyName = propertyInfo[1];
+ var notifySignalData = propertyInfo[2];
+ // initialize property cache with current value
+ // NOTE: if this is an object, it is not directly unwrapped as it might
+ // reference other QObject that we do not know yet
+ object.__propertyCache__[propertyIndex] = propertyInfo[3];
+
+ if (notifySignalData) {
+ if (notifySignalData[0] === 1) {
+ // signal name is optimized away, reconstruct the actual name
+ notifySignalData[0] = propertyName + "Changed";
+ }
+ addSignal(notifySignalData, true);
+ }
+
+ Object.defineProperty(object, propertyName, {
+ configurable: true,
+ get: function () {
+ var propertyValue = object.__propertyCache__[propertyIndex];
+ if (propertyValue === undefined) {
+ // This shouldn't happen
+ console.warn("Undefined value in property cache for property \"" + propertyName + "\" in object " + object.__id__);
+ }
+
+ return propertyValue;
+ },
+ set: function(value) {
+ if (value === undefined) {
+ console.warn("Property setter for " + propertyName + " called with undefined value!");
+ return;
+ }
+ object.__propertyCache__[propertyIndex] = value;
+ webChannel.exec({
+ "type": QWebChannelMessageTypes.setProperty,
+ "object": object.__id__,
+ "property": propertyIndex,
+ "value": value
+ });
+ }
+ });
+
+ }
+
+ // ----------------------------------------------------------------------
+
+ data.methods.forEach(addMethod);
+
+ data.properties.forEach(bindGetterSetter);
+
+ data.signals.forEach(function(signal) { addSignal(signal, false); });
+
+ for (var name in data.enums) {
+ object[name] = data.enums[name];
+ }
+}
+
+//required for use with nodejs
+if (typeof module === 'object') {
+ module.exports = {
+ QWebChannel: QWebChannel
+ };
+}
diff --git a/tests/auto/widgets/resources/tests.qrc b/tests/auto/widgets/resources/tests.qrc
new file mode 100644
index 000000000..5e9df2873
--- /dev/null
+++ b/tests/auto/widgets/resources/tests.qrc
@@ -0,0 +1,5 @@
+<RCC>
+ <qresource prefix="/">
+ <file>qwebchannel.js</file>
+ </qresource>
+</RCC>
diff --git a/tests/auto/widgets/tests.pri b/tests/auto/widgets/tests.pri
index 8a62ce2a6..ca19a9496 100644
--- a/tests/auto/widgets/tests.pri
+++ b/tests/auto/widgets/tests.pri
@@ -9,6 +9,7 @@ TARGET = tst_$$TARGET
SOURCES += $${TARGET}.cpp
INCLUDEPATH += $$PWD
+RESOURCES += ../resources/tests.qrc
exists($$_PRO_FILE_PWD_/$${TARGET}.qrc): RESOURCES += $${TARGET}.qrc
QT += testlib network webenginewidgets widgets
diff --git a/tests/auto/widgets/util.h b/tests/auto/widgets/util.h
index 2b485fc0f..c2c72c8f4 100644
--- a/tests/auto/widgets/util.h
+++ b/tests/auto/widgets/util.h
@@ -156,6 +156,13 @@ static inline QVariant evaluateJavaScriptSync(QWebEnginePage *page, const QStrin
return spy.waitForResult();
}
+static inline QVariant evaluateJavaScriptSyncInWorld(QWebEnginePage *page, const QString &script, int worldId)
+{
+ CallbackSpy<QVariant> spy;
+ page->runJavaScript(script, worldId, spy.ref());
+ return spy.waitForResult();
+}
+
static inline QUrl baseUrlSync(QWebEnginePage *page)
{
CallbackSpy<QVariant> spy;
diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro
index 3220b1379..6c516b38f 100644
--- a/tests/auto/widgets/widgets.pro
+++ b/tests/auto/widgets/widgets.pro
@@ -3,6 +3,7 @@ TEMPLATE = subdirs
SUBDIRS += \
qwebengineaccessibility \
qwebenginedefaultsurfaceformat \
+ qwebenginefaviconmanager \
qwebenginepage \
qwebenginehistory \
qwebenginehistoryinterface \