diff options
Diffstat (limited to 'tests')
67 files changed, 1371 insertions, 65 deletions
diff --git a/tests/auto/auto.pro b/tests/auto/auto.pro index f14305f72..06430cf8e 100644 --- a/tests/auto/auto.pro +++ b/tests/auto/auto.pro @@ -4,4 +4,6 @@ SUBDIRS = quick qtHaveModule(webenginewidgets) { SUBDIRS += widgets +# core tests depend on widgets for now + SUBDIRS += core } diff --git a/tests/auto/core/core.pro b/tests/auto/core/core.pro new file mode 100644 index 000000000..ed0a61532 --- /dev/null +++ b/tests/auto/core/core.pro @@ -0,0 +1,7 @@ +TEMPLATE = subdirs + +CONFIG += ordered + +SUBDIRS += \ + qwebenginecookiestoreclient \ + qwebengineurlrequestinterceptor \ diff --git a/tests/auto/core/qwebenginecookiestoreclient/qwebenginecookiestoreclient.pro b/tests/auto/core/qwebenginecookiestoreclient/qwebenginecookiestoreclient.pro new file mode 100644 index 000000000..e99c7f493 --- /dev/null +++ b/tests/auto/core/qwebenginecookiestoreclient/qwebenginecookiestoreclient.pro @@ -0,0 +1 @@ +include(../tests.pri) diff --git a/tests/auto/core/qwebenginecookiestoreclient/resources/content.html b/tests/auto/core/qwebenginecookiestoreclient/resources/content.html new file mode 100644 index 000000000..360ad65ef --- /dev/null +++ b/tests/auto/core/qwebenginecookiestoreclient/resources/content.html @@ -0,0 +1,5 @@ +<html> +<body> +<a>This is test content</a> +</body> +</html> diff --git a/tests/auto/core/qwebenginecookiestoreclient/resources/index.html b/tests/auto/core/qwebenginecookiestoreclient/resources/index.html new file mode 100644 index 000000000..d41866712 --- /dev/null +++ b/tests/auto/core/qwebenginecookiestoreclient/resources/index.html @@ -0,0 +1,38 @@ +<html> + <head> + <script type="text/javascript"> + function generateCookieString(key, value, options) { + key = key.replace(/[^#$&+\^`|]/g, encodeURIComponent); + key = key.replace(/\(/g, '%28').replace(/\)/g, '%29'); + value = (value + '').replace(/[^!#$&-+\--:<-\[\]-~]/g, encodeURIComponent); + options = options || {}; + + var cookieString = key + '=' + value; + cookieString += options.path ? '; Path=' + options.path : ''; + cookieString += options.domain ? '; Domain=' + options.domain : ''; + cookieString += options.expires ? '; Expires=' + options.expires.toUTCString() : ''; + cookieString += options.secure ? '; Secure' : ''; + + console.log(cookieString) + return cookieString; +}; +function setCookie() { + var name = "SessionCookie" + var value = "QtWebEngineCookieTest" + document.cookie = generateCookieString(name, value, {}) + + name = "CookieWithExpiresField" + value = "QtWebEngineCookieTest" + var daysValid = 10; + var date = new Date(); + date.setTime(date.getTime() + (daysValid*24*60*60*1000)); + var expires = date; + var options = {}; + options.expires = expires; + document.cookie = generateCookieString(name, value, options) +} +</script> + </head> + <body onload="setCookie()"> + </body> +</html> diff --git a/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp new file mode 100644 index 000000000..0f007d643 --- /dev/null +++ b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.cpp @@ -0,0 +1,212 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: 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.0 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 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../widgets/util.h" +#include <QtTest/QtTest> +#include <QtWebEngineCore/qwebenginecallback.h> +#include <QtWebEngineCore/qwebenginecookiestoreclient.h> +#include <QtWebEngineWidgets/qwebenginepage.h> +#include <QtWebEngineWidgets/qwebengineprofile.h> +#include <QtWebEngineWidgets/qwebengineview.h> + +class tst_QWebEngineCookieStoreClient : public QObject +{ + Q_OBJECT + +public: + tst_QWebEngineCookieStoreClient(); + ~tst_QWebEngineCookieStoreClient(); + +public Q_SLOTS: + void init(); + void cleanup(); + +private Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + void cookieSignals(); + void setAndDeleteCookie(); + void batchCookieTasks(); +}; + +tst_QWebEngineCookieStoreClient::tst_QWebEngineCookieStoreClient() +{ +} + +tst_QWebEngineCookieStoreClient::~tst_QWebEngineCookieStoreClient() +{ +} + +void tst_QWebEngineCookieStoreClient::init() +{ +} + +void tst_QWebEngineCookieStoreClient::cleanup() +{ +} + +void tst_QWebEngineCookieStoreClient::initTestCase() +{ +} + +void tst_QWebEngineCookieStoreClient::cleanupTestCase() +{ +} + +void tst_QWebEngineCookieStoreClient::cookieSignals() +{ + QWebEngineView view; + QWebEngineCookieStoreClient client; + + QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool))); + QSignalSpy cookieAddedSpy(&client, SIGNAL(cookieAdded(const QNetworkCookie &))); + QSignalSpy cookieRemovedSpy(&client, SIGNAL(cookieRemoved(const QNetworkCookie &))); + + view.page()->profile()->setCookieStoreClient(&client); + + view.load(QUrl("qrc:///resources/index.html")); + + QTRY_COMPARE(loadSpy.count(), 1); + QVariant success = loadSpy.takeFirst().takeFirst(); + QVERIFY(success.toBool()); + QTRY_COMPARE(cookieAddedSpy.count(), 2); + + // try whether updating a cookie to be expired results in that cookie being removed. + QNetworkCookie expiredCookie(QNetworkCookie::parseCookies(QByteArrayLiteral("SessionCookie=delete; expires=Thu, 01-Jan-1970 00:00:00 GMT; path=///resources")).first()); + client.setCookie(expiredCookie, QUrl("qrc:///resources/index.html")); + QTRY_COMPARE(cookieRemovedSpy.count(), 1); + cookieRemovedSpy.clear(); + + // try removing the other cookie. + QNetworkCookie nonSessionCookie(QNetworkCookie::parseCookies(QByteArrayLiteral("CookieWithExpiresField=QtWebEngineCookieTest; path=///resources")).first()); + client.deleteCookie(nonSessionCookie, QUrl("qrc:///resources/index.html")); + QTRY_COMPARE(cookieRemovedSpy.count(), 1); +} + +void tst_QWebEngineCookieStoreClient::setAndDeleteCookie() +{ + QWebEngineView view; + QWebEngineCookieStoreClient client; + + QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool))); + QSignalSpy cookieAddedSpy(&client, SIGNAL(cookieAdded(const QNetworkCookie &))); + QSignalSpy cookieRemovedSpy(&client, SIGNAL(cookieRemoved(const QNetworkCookie &))); + + QNetworkCookie cookie1(QNetworkCookie::parseCookies(QByteArrayLiteral("khaos=I9GX8CWI; Domain=.example.com; Path=/docs")).first()); + QNetworkCookie cookie2(QNetworkCookie::parseCookies(QByteArrayLiteral("Test%20Cookie=foobar; domain=example.com; Path=/")).first()); + QNetworkCookie cookie3(QNetworkCookie::parseCookies(QByteArrayLiteral("SessionCookie=QtWebEngineCookieTest; Path=///resources")).first()); + QNetworkCookie expiredCookie3(QNetworkCookie::parseCookies(QByteArrayLiteral("SessionCookie=delete; expires=Thu, 01-Jan-1970 00:00:00 GMT; path=///resources")).first()); + + // check if pending cookies are set and removed + client.setCookieWithCallback(cookie1, [](bool success) { QVERIFY(success); }); + client.setCookieWithCallback(cookie2, [](bool success) { QVERIFY(success); }); + client.deleteCookie(cookie1); + + view.page()->profile()->setCookieStoreClient(&client); + view.load(QUrl("qrc:///resources/content.html")); + + QTRY_COMPARE(loadSpy.count(), 1); + QVariant success = loadSpy.takeFirst().takeFirst(); + QVERIFY(success.toBool()); + QTRY_COMPARE(cookieAddedSpy.count(), 2); + QTRY_COMPARE(cookieRemovedSpy.count(), 1); + cookieAddedSpy.clear(); + cookieRemovedSpy.clear(); + + client.setCookieWithCallback(cookie3, [](bool success) { QVERIFY(success); }); + // updating a cookie with an expired 'expires' field should remove the cookie with the same name + client.setCookieWithCallback(expiredCookie3, [](bool success) { QVERIFY(success); }); + client.deleteCookie(cookie2); + QTRY_COMPARE(cookieAddedSpy.count(), 1); + QTRY_COMPARE(cookieRemovedSpy.count(), 2); +} + +void tst_QWebEngineCookieStoreClient::batchCookieTasks() +{ + QWebEngineView view; + QWebEngineCookieStoreClient client; + + QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool))); + QSignalSpy cookieAddedSpy(&client, SIGNAL(cookieAdded(const QNetworkCookie &))); + QSignalSpy cookieRemovedSpy(&client, SIGNAL(cookieRemoved(const QNetworkCookie &))); + + QNetworkCookie cookie1(QNetworkCookie::parseCookies(QByteArrayLiteral("khaos=I9GX8CWI; Domain=.example.com; Path=/docs")).first()); + QNetworkCookie cookie2(QNetworkCookie::parseCookies(QByteArrayLiteral("Test%20Cookie=foobar; domain=example.com; Path=/")).first()); + + int capture = 0; + + client.setCookieWithCallback(cookie1, [&capture](bool success) { QVERIFY(success); ++capture; }); + client.setCookieWithCallback(cookie2, [&capture](bool success) { QVERIFY(success); ++capture; }); + + view.page()->profile()->setCookieStoreClient(&client); + view.load(QUrl("qrc:///resources/index.html")); + + QTRY_COMPARE(loadSpy.count(), 1); + QVariant success = loadSpy.takeFirst().takeFirst(); + QVERIFY(success.toBool()); + QTRY_COMPARE(cookieAddedSpy.count(), 4); + QTRY_COMPARE(cookieRemovedSpy.count(), 0); + QTRY_COMPARE(capture, 2); + capture = 0; + + cookieAddedSpy.clear(); + cookieRemovedSpy.clear(); + + client.getAllCookies([&capture](const QByteArray& cookieLine) { + ++capture; + QCOMPARE(QNetworkCookie::parseCookies(cookieLine).count(), 4); + }); + + client.deleteSessionCookiesWithCallback([&capture](int numDeleted) { + ++capture; + QCOMPARE(numDeleted, 3); + }); + + client.deleteAllCookiesWithCallback([&capture](int numDeleted) { + ++capture; + QCOMPARE(numDeleted, 1); + }); + + QTRY_COMPARE(capture, 3); +} + +QTEST_MAIN(tst_QWebEngineCookieStoreClient) +#include "tst_qwebenginecookiestoreclient.moc" diff --git a/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.qrc b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.qrc new file mode 100644 index 000000000..afeae268b --- /dev/null +++ b/tests/auto/core/qwebenginecookiestoreclient/tst_qwebenginecookiestoreclient.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>resources/index.html</file> + <file>resources/content.html</file> +</qresource> +</RCC> diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro b/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro new file mode 100644 index 000000000..e99c7f493 --- /dev/null +++ b/tests/auto/core/qwebengineurlrequestinterceptor/qwebengineurlrequestinterceptor.pro @@ -0,0 +1 @@ +include(../tests.pri) diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/content.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content.html new file mode 100644 index 000000000..360ad65ef --- /dev/null +++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/content.html @@ -0,0 +1,5 @@ +<html> +<body> +<a>This is test content</a> +</body> +</html> diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/resources/index.html b/tests/auto/core/qwebengineurlrequestinterceptor/resources/index.html new file mode 100644 index 000000000..a744dbd99 --- /dev/null +++ b/tests/auto/core/qwebengineurlrequestinterceptor/resources/index.html @@ -0,0 +1,16 @@ +<html> + <head> + <script type="text/javascript"> + function post() { + var form = document.createElement("form"); + form.setAttribute("method", "POST"); + document.body.appendChild(form); + form.submit(); + return true; + } +</script> + </head> + <body> + <h1>Test page</h1> + </body> +</html> diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp new file mode 100644 index 000000000..ed7d7ad09 --- /dev/null +++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.cpp @@ -0,0 +1,155 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: 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.0 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 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "../../widgets/util.h" +#include <QtTest/QtTest> +#include <QtWebEngineCore/qwebengineurlrequestinterceptor.h> +#include <QtWebEngineWidgets/qwebenginepage.h> +#include <QtWebEngineWidgets/qwebengineprofile.h> +#include <QtWebEngineWidgets/qwebengineview.h> + +class tst_QWebEngineUrlRequestInterceptor : public QObject +{ + Q_OBJECT + +public: + tst_QWebEngineUrlRequestInterceptor(); + ~tst_QWebEngineUrlRequestInterceptor(); + +public Q_SLOTS: + void init(); + void cleanup(); + +private Q_SLOTS: + void initTestCase(); + void cleanupTestCase(); + void interceptRequest(); +}; + +tst_QWebEngineUrlRequestInterceptor::tst_QWebEngineUrlRequestInterceptor() +{ +} + +tst_QWebEngineUrlRequestInterceptor::~tst_QWebEngineUrlRequestInterceptor() +{ +} + +void tst_QWebEngineUrlRequestInterceptor::init() +{ +} + +void tst_QWebEngineUrlRequestInterceptor::cleanup() +{ +} + +void tst_QWebEngineUrlRequestInterceptor::initTestCase() +{ +} + +void tst_QWebEngineUrlRequestInterceptor::cleanupTestCase() +{ +} + +class TestRequestInterceptor: public QWebEngineUrlRequestInterceptor +{ +public: + QList<QUrl> observedUrls; + bool shouldIntercept; + + bool interceptRequest(QWebEngineUrlRequestInfo &info) override + { + info.block(info.requestMethod() != QByteArrayLiteral("GET")); + if (info.requestUrl().toString().endsWith(QLatin1String("__placeholder__"))) + info.redirect(QUrl("qrc:///resources/content.html")); + + observedUrls.append(info.requestUrl()); + return shouldIntercept; + } + TestRequestInterceptor(bool intercept) + : shouldIntercept(intercept) + { + } +}; + +void tst_QWebEngineUrlRequestInterceptor::interceptRequest() +{ + QWebEngineView view; + TestRequestInterceptor interceptor(/* intercept */ true); + + QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool))); + view.page()->profile()->setRequestInterceptor(&interceptor); + view.load(QUrl("qrc:///resources/index.html")); + QTRY_COMPARE(loadSpy.count(), 1); + QVariant success = loadSpy.takeFirst().takeFirst(); + QVERIFY(success.toBool()); + loadSpy.clear(); + QVariant ok; + + view.page()->runJavaScript("post();", [&ok](const QVariant result){ ok = result; }); + QTRY_VERIFY(ok.toBool()); + QTRY_COMPARE(loadSpy.count(), 1); + success = loadSpy.takeFirst().takeFirst(); + // We block non-GET requests, so this should not succeed. + QVERIFY(!success.toBool()); + loadSpy.clear(); + + view.load(QUrl("qrc:///resources/__placeholder__")); + QTRY_COMPARE(loadSpy.count(), 1); + success = loadSpy.takeFirst().takeFirst(); + // The redirection for __placeholder__ should succeed. + QVERIFY(success.toBool()); + loadSpy.clear(); + QCOMPARE(interceptor.observedUrls.count(), 4); + + + // Make sure that registering an observer does not modify the request. + TestRequestInterceptor observer(/* intercept */ false); + view.page()->profile()->setRequestInterceptor(&observer); + view.load(QUrl("qrc:///resources/__placeholder__")); + QTRY_COMPARE(loadSpy.count(), 1); + success = loadSpy.takeFirst().takeFirst(); + // Since we do not intercept, loading an invalid path should not succeed. + QVERIFY(!success.toBool()); + QCOMPARE(observer.observedUrls.count(), 1); +} + +QTEST_MAIN(tst_QWebEngineUrlRequestInterceptor) +#include "tst_qwebengineurlrequestinterceptor.moc" diff --git a/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc new file mode 100644 index 000000000..afeae268b --- /dev/null +++ b/tests/auto/core/qwebengineurlrequestinterceptor/tst_qwebengineurlrequestinterceptor.qrc @@ -0,0 +1,6 @@ +<!DOCTYPE RCC><RCC version="1.0"> +<qresource> + <file>resources/index.html</file> + <file>resources/content.html</file> +</qresource> +</RCC> diff --git a/tests/auto/core/tests.pri b/tests/auto/core/tests.pri new file mode 100644 index 000000000..cd6ef8615 --- /dev/null +++ b/tests/auto/core/tests.pri @@ -0,0 +1,17 @@ +TEMPLATE = app + +# FIXME: Re-enable once we want to run tests on the CI +# CONFIG += testcase + +CONFIG += c++11 + +VPATH += $$_PRO_FILE_PWD_ +TARGET = tst_$$TARGET + +SOURCES += $${TARGET}.cpp +INCLUDEPATH += $$PWD + +exists($$_PRO_FILE_PWD_/$${TARGET}.qrc): RESOURCES += $${TARGET}.qrc + +QT += testlib network webenginewidgets widgets +osx: CONFIG -= app_bundle diff --git a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp index 28a77d8cd..b5894a248 100644 --- a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp +++ b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp @@ -86,7 +86,7 @@ void tst_InspectorServer::prepareWebViewComponent() m_component.reset(new QQmlComponent(engine, this)); m_component->setData(QByteArrayLiteral("import QtQuick 2.0\n" - "import QtWebEngine 1.1\n" + "import QtWebEngine 1.2\n" "WebEngineView { }") , QUrl()); } diff --git a/tests/auto/quick/qmltests/data/TestWebEngineView.qml b/tests/auto/quick/qmltests/data/TestWebEngineView.qml index a97739404..8a01dfa09 100644 --- a/tests/auto/quick/qmltests/data/TestWebEngineView.qml +++ b/tests/auto/quick/qmltests/data/TestWebEngineView.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 import QtWebEngine.experimental 1.0 WebEngineView { diff --git a/tests/auto/quick/qmltests/data/directoryupload.html b/tests/auto/quick/qmltests/data/directoryupload.html new file mode 100644 index 000000000..6a6e4580c --- /dev/null +++ b/tests/auto/quick/qmltests/data/directoryupload.html @@ -0,0 +1,16 @@ +<html> +<head> +<meta name="viewport" initial-scale=1"> +<title> Directory Upload </title> +<script src = "./titleupdate.js"> +</script> + +<body> +<input type="file" id="upfile" webkitdirectory="" directory="" onchange="updateTitle()"> +<script> +window.onload = function() { +document.getElementById("upfile").focus() +} +</script> +</body> +</html> diff --git a/tests/auto/quick/qmltests/data/forms.html b/tests/auto/quick/qmltests/data/forms.html new file mode 100644 index 000000000..8dc3472f2 --- /dev/null +++ b/tests/auto/quick/qmltests/data/forms.html @@ -0,0 +1,40 @@ +<html> +<head> + <title>Forms</title> + <script type="text/javascript"> + function updateFocus() { + var name = window.location.hash.substring(1); + var element = document.getElementsByName(name)[0]; + + element.focus(); + } + </script> +</head> +<body onload="updateFocus();"> + <form> + <input type="url" required/> + <input type="submit" name="url_empty"/> + </form> + <form> + <input type="url" value="invalid" required/> + <input type="submit" name="url_invalid"/> + </form> + <form> + <input type="url" value="invalid" title="url_title" required/> + <input type="submit" name="url_title"/> + </form> + + <form> + <input type="email" required/> + <input type="submit" name="email_empty"/> + </form> + <form> + <input type="email" value="invalid" required/> + <input type="submit" name="email_invalid"/> + </form> + <form> + <input type="email" value="invalid" title="email_title" required/> + <input type="submit" name="email_title"/> + </form> +</body> +</html> diff --git a/tests/auto/quick/qmltests/data/multifileupload.html b/tests/auto/quick/qmltests/data/multifileupload.html new file mode 100644 index 000000000..cc87d8f41 --- /dev/null +++ b/tests/auto/quick/qmltests/data/multifileupload.html @@ -0,0 +1,17 @@ +<html> +<head> +<meta name="viewport" initial-scale=1"> +<title> Mutli-file Upload </title> +<script src = "./titleupdate.js"> +</script> + +<body> +<input type="file" name="file" id="upfile" onchange="updateTitle()" multiple/> + +<script> +window.onload = function() { +document.getElementById("upfile").focus() +} +</script> +</body> +</html> diff --git a/tests/auto/quick/qmltests/data/singlefileupload.html b/tests/auto/quick/qmltests/data/singlefileupload.html new file mode 100644 index 000000000..8469aa128 --- /dev/null +++ b/tests/auto/quick/qmltests/data/singlefileupload.html @@ -0,0 +1,17 @@ +<html> +<head> +<meta name="viewport" initial-scale=1"> +<title> Single File Upload </title> +<script src = "./titleupdate.js"> +</script> + +<body> +<input type="file" name="file" id="upfile" onchange="updateTitle()"/> + +<script> +window.onload = function() { +document.getElementById("upfile").focus() +} +</script> +</body> +</html> diff --git a/tests/auto/quick/qmltests/data/titleupdate.js b/tests/auto/quick/qmltests/data/titleupdate.js new file mode 100644 index 000000000..cfcc52c60 --- /dev/null +++ b/tests/auto/quick/qmltests/data/titleupdate.js @@ -0,0 +1,55 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: 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.0 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 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +function updateTitle() +{ + var inp = document.getElementById("upfile"); + var allfiles = new String(""); + var name = new String(""); + for (var i = 0; i < inp.files.length; ++i) { + name = inp.files.item(i).name; + if (allfiles.length == 0) + allfiles = name; + else + allfiles = allfiles + "," + name; + } + document.title = allfiles; +} diff --git a/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml new file mode 100644 index 000000000..eaca8822b --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_activeFocusOnPress.qml @@ -0,0 +1,82 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: 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.0 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 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 +import QtTest 1.0 + +Item { + id: root + width: 300 + height: 400 + TextInput { + id: textInput + anchors { + top: parent.top + left: parent.left + right: parent.right + } + focus: true + text: "foo" + } + + TestWebEngineView { + id: webEngineView + activeFocusOnPress: false + anchors { + top: textInput.bottom + left: parent.left + right: parent.right + bottom: parent.bottom + } + + TestCase { + name: "ActiveFocusOnPress" + when:windowShown + + function test_activeFocusOnPress() { + textInput.forceActiveFocus() + verify(textInput.activeFocus) + mouseClick(root, 150, 300, Qt.LeftButton) + verify(textInput.activeFocus) + } + } + } +} diff --git a/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml b/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml index dfb983c43..51c1d5580 100644 --- a/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml +++ b/tests/auto/quick/qmltests/data/tst_desktopBehaviorLoadHtml.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView diff --git a/tests/auto/quick/qmltests/data/tst_favIconLoad.qml b/tests/auto/quick/qmltests/data/tst_favIconLoad.qml index 73190f1bd..df5479eec 100644 --- a/tests/auto/quick/qmltests/data/tst_favIconLoad.qml +++ b/tests/auto/quick/qmltests/data/tst_favIconLoad.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView diff --git a/tests/auto/quick/qmltests/data/tst_filePicker.qml b/tests/auto/quick/qmltests/data/tst_filePicker.qml new file mode 100644 index 000000000..02b2dd024 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_filePicker.qml @@ -0,0 +1,129 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: 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.0 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 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtTest 1.0 +import QtWebEngine 1.2 +import "../mock-delegates/TestParams" 1.0 + +TestWebEngineView { + id: webEngineView + width: 400 + height: 300 + + SignalSpy { + id: titleSpy + target: webEngineView + signalName: "titleChanged" + } + + TestCase { + name: "WebEngineViewSingleFileUpload" + when: windowShown + + function init() { + FilePickerParams.filePickerOpened = false + FilePickerParams.selectFiles = false + FilePickerParams.selectedFilesUrl = [] + titleSpy.clear() + } + + // FIXME: Almost every second url loading progress does get stuck at about 90 percent, so the loadFinished signal won't arrive. + // This cleanup function is a workaround for this problem. + function cleanup() { + webEngineView.url = Qt.resolvedUrl("about:blank") + webEngineView.waitForLoadSucceeded() + } + + function test_acceptSingleFileSelection() { + webEngineView.url = Qt.resolvedUrl("singlefileupload.html") + verify(webEngineView.waitForLoadSucceeded()) + + FilePickerParams.selectFiles = true + FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("test1.html")) + + keyPress(Qt.Key_Enter) // Focus is on the button. Open FileDialog. + wait(100) // The ui delegate is invoked asynchronously + verify(FilePickerParams.filePickerOpened) + titleSpy.wait() + compare(webEngineView.title, "test1.html") + } + + function test_acceptMultipleFilesSelection() { + webEngineView.url = Qt.resolvedUrl("multifileupload.html") + verify(webEngineView.waitForLoadSucceeded()) + + FilePickerParams.selectFiles = true + FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("test1.html")) + FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("test2.html")) + + keyPress(Qt.Key_Enter) // Focus is on the button. Open FileDialog. + wait(100) + verify(FilePickerParams.filePickerOpened) + titleSpy.wait() + compare(webEngineView.title, "test1.html,test2.html") + } + + function test_acceptDirectory() { + webEngineView.url = Qt.resolvedUrl("directoryupload.html") + verify(webEngineView.waitForLoadSucceeded()) + + FilePickerParams.selectFiles = true + FilePickerParams.selectedFilesUrl.push(Qt.resolvedUrl("../data")) + + keyPress(Qt.Key_Enter) // Focus is on the button. Open FileDialog. + wait(100) // The ui delegate is invoked asynchronously + verify(FilePickerParams.filePickerOpened) + titleSpy.wait() + compare(webEngineView.title, "data") + } + + function test_reject() { + webEngineView.url = Qt.resolvedUrl("singlefileupload.html") + verify(webEngineView.waitForLoadSucceeded()) + + titleSpy.clear() + keyPress(Qt.Key_Enter) // Focus is on the button. Open FileDialog. + wait(100) + compare(titleSpy.count, 0) + } + } +} diff --git a/tests/auto/quick/qmltests/data/tst_findText.qml b/tests/auto/quick/qmltests/data/tst_findText.qml index b51da0b2e..9c4aa48c1 100644 --- a/tests/auto/quick/qmltests/data/tst_findText.qml +++ b/tests/auto/quick/qmltests/data/tst_findText.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView diff --git a/tests/auto/quick/qmltests/data/tst_formValidation.qml b/tests/auto/quick/qmltests/data/tst_formValidation.qml new file mode 100644 index 000000000..4acb7ce63 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_formValidation.qml @@ -0,0 +1,124 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: 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.0 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 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtTest 1.0 +import QtWebEngine 1.2 +import QtWebEngine.testsupport 1.0 + +TestWebEngineView { + id: webEngineView + width: 400 + height: 300 + + testSupport: WebEngineTestSupport { + id: testSupportAPI + } + + SignalSpy { + id: showSpy + target: testSupportAPI + signalName: "validationMessageShown" + } + + TestCase { + name: "WebEngineViewFormValidation" + when: windowShown + + function init() { + webEngineView.url = Qt.resolvedUrl("about:blank") + verify(webEngineView.waitForLoadSucceeded()) + showSpy.clear() + } + + function test_urlForm() { + webEngineView.url = Qt.resolvedUrl("forms.html#url_empty") + verify(webEngineView.waitForLoadSucceeded()) + keyPress(Qt.Key_Enter) + showSpy.wait() + compare(showSpy.signalArguments[0][0], "Please fill out this field.") + + webEngineView.url = Qt.resolvedUrl("about:blank") + verify(webEngineView.waitForLoadSucceeded()) + + webEngineView.url = Qt.resolvedUrl("forms.html#url_invalid") + verify(webEngineView.waitForLoadSucceeded()) + keyPress(Qt.Key_Enter) + showSpy.wait() + compare(showSpy.signalArguments[1][0], "Please enter a URL.") + + webEngineView.url = Qt.resolvedUrl("about:blank") + verify(webEngineView.waitForLoadSucceeded()) + + webEngineView.url = Qt.resolvedUrl("forms.html#url_title") + verify(webEngineView.waitForLoadSucceeded()) + keyPress(Qt.Key_Enter) + showSpy.wait() + compare(showSpy.signalArguments[2][1], "url_title") + } + + function test_emailForm() { + webEngineView.url = Qt.resolvedUrl("forms.html#email_empty") + verify(webEngineView.waitForLoadSucceeded()) + keyPress(Qt.Key_Enter) + showSpy.wait() + compare(showSpy.signalArguments[0][0], "Please fill out this field.") + + webEngineView.url = Qt.resolvedUrl("about:blank") + verify(webEngineView.waitForLoadSucceeded()) + + webEngineView.url = Qt.resolvedUrl("forms.html#email_invalid") + verify(webEngineView.waitForLoadSucceeded()) + keyPress(Qt.Key_Enter) + showSpy.wait() + compare(showSpy.signalArguments[1][0], "Please include an '@' in the email address. 'invalid' is missing an '@'.") + + webEngineView.url = Qt.resolvedUrl("about:blank") + verify(webEngineView.waitForLoadSucceeded()) + + webEngineView.url = Qt.resolvedUrl("forms.html#email_title") + verify(webEngineView.waitForLoadSucceeded()) + keyPress(Qt.Key_Enter) + showSpy.wait() + compare(showSpy.signalArguments[2][1], "email_title") + } + } +} diff --git a/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml index 58a49da5a..75b45bfac 100644 --- a/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml +++ b/tests/auto/quick/qmltests/data/tst_javaScriptDialogs.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.0 +import QtWebEngine 1.2 import "../mock-delegates/TestParams" 1.0 TestWebEngineView { diff --git a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml index 230ee9635..c127d7391 100644 --- a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml +++ b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView diff --git a/tests/auto/quick/qmltests/data/tst_linkHovered.qml b/tests/auto/quick/qmltests/data/tst_linkHovered.qml index c9fbd5520..31d90615b 100644 --- a/tests/auto/quick/qmltests/data/tst_linkHovered.qml +++ b/tests/auto/quick/qmltests/data/tst_linkHovered.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView diff --git a/tests/auto/quick/qmltests/data/tst_loadFail.qml b/tests/auto/quick/qmltests/data/tst_loadFail.qml index 0885fc193..c2a4b6e13 100644 --- a/tests/auto/quick/qmltests/data/tst_loadFail.qml +++ b/tests/auto/quick/qmltests/data/tst_loadFail.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 import QtWebEngine.experimental 1.0 import QtWebEngine.testsupport 1.0 diff --git a/tests/auto/quick/qmltests/data/tst_loadHtml.qml b/tests/auto/quick/qmltests/data/tst_loadHtml.qml index b8acd0dd7..ee1149b16 100644 --- a/tests/auto/quick/qmltests/data/tst_loadHtml.qml +++ b/tests/auto/quick/qmltests/data/tst_loadHtml.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView diff --git a/tests/auto/quick/qmltests/data/tst_loadProgress.qml b/tests/auto/quick/qmltests/data/tst_loadProgress.qml index 9f8b6f6f7..096861c4d 100644 --- a/tests/auto/quick/qmltests/data/tst_loadProgress.qml +++ b/tests/auto/quick/qmltests/data/tst_loadProgress.qml @@ -41,22 +41,39 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView width: 400 height: 300 + property var loadProgressArray: [] + + onLoadProgressChanged: { + loadProgressArray.push(webEngineView.loadProgress) + } + TestCase { name: "WebEngineViewLoadProgress" function test_loadProgress() { compare(webEngineView.loadProgress, 0) + loadProgressArray = [] + webEngineView.url = Qt.resolvedUrl("test1.html") - compare(webEngineView.loadProgress, 0) verify(webEngineView.waitForLoadSucceeded()) - compare(webEngineView.loadProgress, 100) + + // Test whether the chromium emits progress numbers in ascending order + var loadProgressMin = 0 + for (var i in loadProgressArray) { + var loadProgress = loadProgressArray[i] + verify(loadProgressMin <= loadProgress) + loadProgressMin = loadProgress + } + + // The progress must be 100% at the end + compare(loadProgressArray[loadProgressArray.length - 1], 100) } } } diff --git a/tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml b/tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml index 8e2e99b64..7b0bac61b 100644 --- a/tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml +++ b/tests/auto/quick/qmltests/data/tst_loadProgressSignal.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView diff --git a/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml b/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml index 2400a5ed6..fb692c472 100644 --- a/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml +++ b/tests/auto/quick/qmltests/data/tst_loadRecursionCrash.qml @@ -41,7 +41,7 @@ import QtQuick 2.3 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 Item { width: 300 diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml index 922925b48..c8abf2bb0 100644 --- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml +++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 import QtWebEngine.experimental 1.0 TestWebEngineView { diff --git a/tests/auto/quick/qmltests/data/tst_navigationHistory.qml b/tests/auto/quick/qmltests/data/tst_navigationHistory.qml index 3acde3abc..f7875bb78 100644 --- a/tests/auto/quick/qmltests/data/tst_navigationHistory.qml +++ b/tests/auto/quick/qmltests/data/tst_navigationHistory.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView diff --git a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml index 72eb0aac9..7d49cda90 100644 --- a/tests/auto/quick/qmltests/data/tst_navigationRequested.qml +++ b/tests/auto/quick/qmltests/data/tst_navigationRequested.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView diff --git a/tests/auto/quick/qmltests/data/tst_properties.qml b/tests/auto/quick/qmltests/data/tst_properties.qml index 738ef532d..9418252cb 100644 --- a/tests/auto/quick/qmltests/data/tst_properties.qml +++ b/tests/auto/quick/qmltests/data/tst_properties.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView diff --git a/tests/auto/quick/qmltests/data/tst_runJavaScript.qml b/tests/auto/quick/qmltests/data/tst_runJavaScript.qml index 6cf3a71fb..07e7130c6 100644 --- a/tests/auto/quick/qmltests/data/tst_runJavaScript.qml +++ b/tests/auto/quick/qmltests/data/tst_runJavaScript.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView diff --git a/tests/auto/quick/qmltests/data/tst_titleChanged.qml b/tests/auto/quick/qmltests/data/tst_titleChanged.qml index adc8564c0..8d9dae0a4 100644 --- a/tests/auto/quick/qmltests/data/tst_titleChanged.qml +++ b/tests/auto/quick/qmltests/data/tst_titleChanged.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 TestWebEngineView { id: webEngineView diff --git a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml index 1c32c73a9..5fefd0fe5 100644 --- a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml +++ b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 Item { id: parentItem diff --git a/tests/auto/quick/qmltests/data/tst_userScripts.qml b/tests/auto/quick/qmltests/data/tst_userScripts.qml index a9ed933d9..8a3b8207f 100644 --- a/tests/auto/quick/qmltests/data/tst_userScripts.qml +++ b/tests/auto/quick/qmltests/data/tst_userScripts.qml @@ -41,7 +41,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 Item { WebEngineScript { diff --git a/tests/auto/quick/qmltests/data/tst_webchannel.qml b/tests/auto/quick/qmltests/data/tst_webchannel.qml index dce585b67..51e37d50e 100644 --- a/tests/auto/quick/qmltests/data/tst_webchannel.qml +++ b/tests/auto/quick/qmltests/data/tst_webchannel.qml @@ -40,7 +40,7 @@ import QtQuick 2.0 import QtTest 1.0 -import QtWebEngine 1.1 +import QtWebEngine 1.2 import QtWebEngine.experimental 1.0 import QtWebChannel 1.0 diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/FilePicker.qml b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/FilePicker.qml new file mode 100644 index 000000000..5ee231c19 --- /dev/null +++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/FilePicker.qml @@ -0,0 +1,60 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: 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.0 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 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.2 +import "../../TestParams" 1.0 + +QtObject { + property bool selectMultiple: false; + property bool selectExisting: false; + property bool selectFolder: false; + + signal filesSelected(var fileList); + signal rejected(); + + function open() { + FilePickerParams.filePickerOpened = true; + if (FilePickerParams.selectFiles) + filesSelected(FilePickerParams.selectedFilesUrl) + else + rejected() + } +} diff --git a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/qmldir b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/qmldir index 1ebabd335..cf8ac0512 100644 --- a/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/qmldir +++ b/tests/auto/quick/qmltests/mock-delegates/QtWebEngine/UIDelegates/qmldir @@ -1,4 +1,5 @@ module QtWebEngine.UIDelegates AlertDialog 1.0 AlertDialog.qml ConfirmDialog 1.0 ConfirmDialog.qml +FilePicker 1.0 FilePicker.qml PromptDialog 1.0 PromptDialog.qml diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml b/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml new file mode 100644 index 000000000..f0f2d9368 --- /dev/null +++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/FilePickerParams.qml @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** 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 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: 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.0 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 3.0 requirements will be +** met: http://www.gnu.org/copyleft/gpl.html. +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +pragma Singleton +import QtQuick 2.0 + +QtObject { + property var selectedFilesUrl: []; + property bool selectFiles: false; + property bool filePickerOpened: false; +} diff --git a/tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir b/tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir index f2ed87a75..a21dd8236 100644 --- a/tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir +++ b/tests/auto/quick/qmltests/mock-delegates/TestParams/qmldir @@ -1,4 +1,5 @@ # QML module so that the autotests can set testing parameters module TestParams +singleton FilePickerParams 1.0 FilePickerParams.qml singleton JSDialogParams 1.0 JSDialogParams.qml diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro index 9f6f55275..01517af47 100644 --- a/tests/auto/quick/qmltests/qmltests.pro +++ b/tests/auto/quick/qmltests/qmltests.pro @@ -12,23 +12,30 @@ OTHER_FILES += \ $$PWD/data/change-document-title.js \ $$PWD/data/download.zip \ $$PWD/data/confirm.html \ + $$PWD/data/directoryupload.html \ $$PWD/data/favicon.html \ $$PWD/data/favicon.png \ $$PWD/data/favicon2.html \ + $$PWD/data/forms.html \ $$PWD/data/geolocation.html \ $$PWD/data/javascript.html \ $$PWD/data/link.html \ $$PWD/data/prompt.html \ + $$PWD/data/multifileupload.html \ $$PWD/data/redirect.html \ + $$PWD/data/singlefileupload.html \ $$PWD/data/small-favicon.png \ $$PWD/data/test1.html \ $$PWD/data/test2.html \ $$PWD/data/test3.html \ $$PWD/data/test4.html \ $$PWD/data/keyboardModifierMapping.html \ + $$PWD/data/titleupdate.js \ $$PWD/data/tst_desktopBehaviorLoadHtml.qml \ $$PWD/data/tst_download.qml \ $$PWD/data/tst_favIconLoad.qml \ + $$PWD/data/tst_filePicker.qml \ + $$PWD/data/tst_formValidation.qml \ $$PWD/data/tst_geopermission.qml \ $$PWD/data/tst_javaScriptDialogs.qml \ $$PWD/data/tst_linkHovered.qml \ @@ -49,12 +56,13 @@ OTHER_FILES += \ $$PWD/data/tst_keyboardModifierMapping.qml \ $$PWD/mock-delegates/QtWebEngine/UIDelegates/AlertDialog.qml \ $$PWD/mock-delegates/QtWebEngine/UIDelegates/ConfirmDialog.qml \ + $$PWD/mock-delegates/QtWebEngine/UIDelegates/FilePicker.qml \ $$PWD/mock-delegates/QtWebEngine/UIDelegates/PromptDialog.qml \ $$PWD/mock-delegates/QtWebEngine/UIDelegates/qmldir \ + $$PWD/mock-delegates/TestParams/FilePickerParams.qml \ $$PWD/mock-delegates/TestParams/JSDialogParams.qml \ $$PWD/mock-delegates/TestParams/qmldir \ - load(qt_build_paths) DEFINES += QUICK_TEST_SOURCE_DIR=\\\"$$re_escape($$PWD$${QMAKE_DIR_SEP}data)\\\" diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp index 2cbcf0979..40dc3cb61 100644 --- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp +++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp @@ -73,7 +73,7 @@ tst_QQuickWebEngineView::tst_QQuickWebEngineView() static QQmlEngine *engine = new QQmlEngine(this); m_component.reset(new QQmlComponent(engine, this)); m_component->setData(QByteArrayLiteral("import QtQuick 2.0\n" - "import QtWebEngine 1.1\n" + "import QtWebEngine 1.2\n" "WebEngineView {}") , QUrl()); } @@ -335,12 +335,10 @@ void tst_QQuickWebEngineView::titleUpdate() webEngineView()->setUrl(QUrl::fromLocalFile(QLatin1String(TESTS_SOURCE_DIR "html/file_that_does_not_exist.html"))); QVERIFY(waitForLoadFailed(webEngineView())); QCOMPARE(titleSpy.size(), 0); - } void tst_QQuickWebEngineView::transparentWebEngineViews() { - showWebEngineView(); // This should not crash. @@ -348,13 +346,10 @@ void tst_QQuickWebEngineView::transparentWebEngineViews() webEngineView1->setParentItem(m_window->contentItem()); QScopedPointer<QQuickWebEngineView> webEngineView2(newWebEngineView()); webEngineView2->setParentItem(m_window->contentItem()); -#if !defined(QQUICKWEBENGINEVIEW_EXPERIMENTAL_TRANSPARENTBACKGROUND) - QWARN("QQUICKWEBENGINEVIEW_EXPERIMENTAL_TRANSPARENTBACKGROUND"); -#else - QVERIFY(!webEngineView1->experimental()->transparentBackground()); - webEngineView2->experimental()->setTransparentBackground(true); - QVERIFY(webEngineView2->experimental()->transparentBackground()); -#endif + + QVERIFY(webEngineView1->backgroundColor() != Qt::transparent); + webEngineView2->setBackgroundColor(Qt::transparent); + QVERIFY(webEngineView2->backgroundColor() == Qt::transparent); webEngineView1->setSize(QSizeF(300, 400)); webEngineView1->loadHtml("<html><body bgcolor=\"red\"></body></html>"); @@ -367,7 +362,24 @@ void tst_QQuickWebEngineView::transparentWebEngineViews() webEngineView2->setVisible(true); QTest::qWait(200); - // FIXME: test actual rendering results; https://bugs.webkit.org/show_bug.cgi?id=80609. + + // Result image: black text on red background. + QImage grabbedWindow = m_window->grabWindow(); + + QSet<int> redComponents; + for (int i = 0, width = grabbedWindow.width(); i < width; i++) { + for (int j = 0, height = grabbedWindow.height(); j < height; j++) { + QColor color(grabbedWindow.pixel(i, j)); + redComponents.insert(color.red()); + // There are no green or blue components between red and black. + QVERIFY(color.green() == 0); + QVERIFY(color.blue() == 0); + } + } + + QVERIFY(redComponents.count() > 1); + QVERIFY(redComponents.contains(0)); // black + QVERIFY(redComponents.contains(255)); // red } void tst_QQuickWebEngineView::inputMethod() diff --git a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp index 5d15537b3..e0e876fc8 100644 --- a/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp +++ b/tests/auto/quick/qquickwebengineviewgraphics/tst_qquickwebengineviewgraphics.cpp @@ -184,7 +184,7 @@ void tst_QQuickWebEngineViewGraphics::reparentToOtherWindow() void tst_QQuickWebEngineViewGraphics::setHtml(const QString &html) { QString htmlData = QUrl::toPercentEncoding(html); - QString qmlData = QUrl::toPercentEncoding(QStringLiteral("import QtQuick 2.0; import QtWebEngine 1.1; WebEngineView { width: 150; height: 150; url: loadUrl }")); + QString qmlData = QUrl::toPercentEncoding(QStringLiteral("import QtQuick 2.0; import QtWebEngine 1.2; WebEngineView { width: 150; height: 150; url: loadUrl }")); m_view->rootContext()->setContextProperty("loadUrl", QUrl(QStringLiteral("data:text/html,%1").arg(htmlData))); m_view->setSource(QUrl(QStringLiteral("data:text/plain,%1").arg(qmlData))); m_view->create(); diff --git a/tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro b/tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro index ff6c49628..e99c7f493 100644 --- a/tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro +++ b/tests/auto/widgets/qwebengineaccessibility/qwebengineaccessibility.pro @@ -1,2 +1 @@ include(../tests.pri) -exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc diff --git a/tests/auto/widgets/qwebengineframe/qwebengineframe.pro b/tests/auto/widgets/qwebengineframe/qwebengineframe.pro index ff6c49628..e99c7f493 100644 --- a/tests/auto/widgets/qwebengineframe/qwebengineframe.pro +++ b/tests/auto/widgets/qwebengineframe/qwebengineframe.pro @@ -1,2 +1 @@ include(../tests.pri) -exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc diff --git a/tests/auto/widgets/qwebenginehistory/qwebenginehistory.pro b/tests/auto/widgets/qwebenginehistory/qwebenginehistory.pro index ff6c49628..e99c7f493 100644 --- a/tests/auto/widgets/qwebenginehistory/qwebenginehistory.pro +++ b/tests/auto/widgets/qwebenginehistory/qwebenginehistory.pro @@ -1,2 +1 @@ include(../tests.pri) -exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc diff --git a/tests/auto/widgets/qwebenginehistoryinterface/qwebenginehistoryinterface.pro b/tests/auto/widgets/qwebenginehistoryinterface/qwebenginehistoryinterface.pro index ff6c49628..e99c7f493 100644 --- a/tests/auto/widgets/qwebenginehistoryinterface/qwebenginehistoryinterface.pro +++ b/tests/auto/widgets/qwebenginehistoryinterface/qwebenginehistoryinterface.pro @@ -1,2 +1 @@ include(../tests.pri) -exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc diff --git a/tests/auto/widgets/qwebengineinspector/qwebengineinspector.pro b/tests/auto/widgets/qwebengineinspector/qwebengineinspector.pro index ff6c49628..e99c7f493 100644 --- a/tests/auto/widgets/qwebengineinspector/qwebengineinspector.pro +++ b/tests/auto/widgets/qwebengineinspector/qwebengineinspector.pro @@ -1,2 +1 @@ include(../tests.pri) -exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc diff --git a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro index e56bbe8f7..70786e70f 100644 --- a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro +++ b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro @@ -1,3 +1,2 @@ include(../tests.pri) -exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc QT *= core-private gui-private diff --git a/tests/auto/widgets/qwebenginepage/resources/fullscreen.html b/tests/auto/widgets/qwebenginepage/resources/fullscreen.html new file mode 100644 index 000000000..84771ca85 --- /dev/null +++ b/tests/auto/widgets/qwebenginepage/resources/fullscreen.html @@ -0,0 +1,10 @@ +<html> +<body onkeypress='onKeyPress()'> +<a>This is test content</a> +<script> +function onKeyPress() { + document.documentElement.webkitRequestFullScreen(); +} +</script> +</body> +</html> diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 9562871b3..ba5366460 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -192,6 +192,7 @@ private Q_SLOTS: #endif void runJavaScript(); + void fullScreenRequested(); private: QWebEngineView* m_view; @@ -1176,6 +1177,10 @@ public: int isSelectionCollapsed() { return evaluateJavaScriptSync(this, "window.getSelection().getRangeAt(0).collapsed").toBool(); } + bool hasSelection() + { + return !selectedText().isEmpty(); + } }; void tst_QWebEnginePage::cursorMovements() @@ -1380,17 +1385,19 @@ void tst_QWebEnginePage::cursorMovements() void tst_QWebEnginePage::textSelection() { -#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT) - QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT"); -#else - CursorTrackedPage* page = new CursorTrackedPage; + QWebEngineView *view = new QWebEngineView; + CursorTrackedPage *page = new CursorTrackedPage; QString content("<html><body><p id=one>The quick brown fox</p>" \ "<p id=two>jumps over the lazy dog</p>" \ "<p>May the source<br/>be with you!</p></body></html>"); + page->setView(view); + QSignalSpy loadSpy(view, SIGNAL(loadFinished(bool))); page->setHtml(content); + QTRY_COMPARE(loadSpy.count(), 1); // these actions must exist QVERIFY(page->action(QWebEnginePage::SelectAll) != 0); +#if defined(QWEBENGINEPAGE_SELECTACTIONS) QVERIFY(page->action(QWebEnginePage::SelectNextChar) != 0); QVERIFY(page->action(QWebEnginePage::SelectPreviousChar) != 0); QVERIFY(page->action(QWebEnginePage::SelectNextWord) != 0); @@ -1418,6 +1425,7 @@ void tst_QWebEnginePage::textSelection() QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), false); QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), false); QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), false); +#endif // ..but SelectAll is awalys enabled QCOMPARE(page->action(QWebEnginePage::SelectAll)->isEnabled(), true); @@ -1432,13 +1440,15 @@ void tst_QWebEnginePage::textSelection() "getSelection().addRange(range);"; evaluateJavaScriptSync(page, selectScript); QCOMPARE(page->selectedText().trimmed(), QString::fromLatin1("The quick brown fox")); +#if defined(QWEBENGINEPAGE_SELECTEDHTML) QRegExp regExp(" style=\".*\""); regExp.setMinimal(true); QCOMPARE(page->selectedHtml().trimmed().replace(regExp, ""), QString::fromLatin1("<p id=\"one\">The quick brown fox</p>")); - +#endif // Make sure hasSelection returns true, since there is selected text now... QCOMPARE(page->hasSelection(), true); +#if defined(QWEBENGINEPAGE_SELECTACTIONS) // here the actions are enabled after a selection has been created QCOMPARE(page->action(QWebEnginePage::SelectNextChar)->isEnabled(), true); QCOMPARE(page->action(QWebEnginePage::SelectPreviousChar)->isEnabled(), true); @@ -1474,9 +1484,10 @@ void tst_QWebEnginePage::textSelection() QCOMPARE(page->action(QWebEnginePage::SelectEndOfBlock)->isEnabled(), true); QCOMPARE(page->action(QWebEnginePage::SelectStartOfDocument)->isEnabled(), true); QCOMPARE(page->action(QWebEnginePage::SelectEndOfDocument)->isEnabled(), true); +#endif delete page; -#endif + delete view; } void tst_QWebEnginePage::textEditing() @@ -3109,13 +3120,16 @@ void tst_QWebEnginePage::testStopScheduledPageRefresh() void tst_QWebEnginePage::findText() { - m_view->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>")); -#if defined(QWEBENGINEPAGE_TRIGGERACTION_SELECTALL) + QSignalSpy loadSpy(m_page, SIGNAL(loadFinished(bool))); + m_page->setHtml(QString("<html><head></head><body><div>foo bar</div></body></html>")); + QTRY_COMPARE(loadSpy.count(), 1); m_page->triggerAction(QWebEnginePage::SelectAll); - QVERIFY(!m_page->selectedText().isEmpty()); + QTRY_COMPARE(m_page->hasSelection(), true); +#if defined(QWEBENGINEPAGE_SELECTEDHTML) QVERIFY(!m_page->selectedHtml().isEmpty()); #endif m_page->findText(""); + QEXPECT_FAIL("", "Unsupported: findText only highlights and doesn't update the selection.", Continue); QVERIFY(m_page->selectedText().isEmpty()); #if defined(QWEBENGINEPAGE_SELECTEDHTML) QVERIFY(m_page->selectedHtml().isEmpty()); @@ -3129,6 +3143,7 @@ void tst_QWebEnginePage::findText() QVERIFY(m_page->selectedHtml().contains(subString)); #endif m_page->findText(""); + QEXPECT_FAIL("", "Unsupported: findText only highlights and doesn't update the selection.", Continue); QVERIFY(m_page->selectedText().isEmpty()); #if defined(QWEBENGINEPAGE_SELECTEDHTML) QVERIFY(m_page->selectedHtml().isEmpty()); @@ -3674,41 +3689,115 @@ void tst_QWebEnginePage::cssMediaTypePageSetting() #endif } -class JavaScriptCallback +class JavaScriptCallbackBase +{ +public: + JavaScriptCallbackBase() + { + if (watcher) + QMetaObject::invokeMethod(watcher, "add"); + } + + void operator() (const QVariant &result) + { + check(result); + if (watcher) + QMetaObject::invokeMethod(watcher, "notify"); + } + +protected: + virtual void check(const QVariant &result) = 0; + +private: + friend class JavaScriptCallbackWatcher; + static QPointer<QObject> watcher; +}; + +QPointer<QObject> JavaScriptCallbackBase::watcher = 0; + +class JavaScriptCallback : public JavaScriptCallbackBase { public: JavaScriptCallback() { } JavaScriptCallback(const QVariant& _expected) : expected(_expected) { } - virtual void operator() (const QVariant& result) { + + void check(const QVariant& result) Q_DECL_OVERRIDE + { QVERIFY(result.isValid()); QCOMPARE(result, expected); } + private: QVariant expected; }; -class JavaScriptCallbackNull +class JavaScriptCallbackNull : public JavaScriptCallbackBase { public: - virtual void operator() (const QVariant& result) { + void check(const QVariant& result) Q_DECL_OVERRIDE + { QVERIFY(result.isNull()); // FIXME: Returned null values are currently invalid QVariants. // QVERIFY(result.isValid()); } }; -class JavaScriptCallbackUndefined +class JavaScriptCallbackUndefined : public JavaScriptCallbackBase { public: - virtual void operator() (const QVariant& result) { + void check(const QVariant& result) Q_DECL_OVERRIDE + { QVERIFY(result.isNull()); QVERIFY(!result.isValid()); } }; +class JavaScriptCallbackWatcher : public QObject +{ + Q_OBJECT +public: + JavaScriptCallbackWatcher() + { + Q_ASSERT(!JavaScriptCallbackBase::watcher); + JavaScriptCallbackBase::watcher = this; + } + + Q_INVOKABLE void add() + { + available++; + } + + Q_INVOKABLE void notify() + { + called++; + if (called == available) + emit allCalled(); + } + + bool wait(int maxSeconds = 30) + { + if (called == available) + return true; + + QTestEventLoop loop; + connect(this, SIGNAL(allCalled()), &loop, SLOT(exitLoop())); + loop.enterLoop(maxSeconds); + return !loop.timeout(); + } + +signals: + void allCalled(); + +private: + int available = 0; + int called = 0; +}; + + void tst_QWebEnginePage::runJavaScript() { TestPage page; + JavaScriptCallbackWatcher watcher; JavaScriptCallback callbackBool(QVariant(false)); page.runJavaScript("false", QWebEngineCallback<const QVariant&>(callbackBool)); @@ -3734,10 +3823,63 @@ void tst_QWebEnginePage::runJavaScript() JavaScriptCallbackNull callbackNull; page.runJavaScript("null", QWebEngineCallback<const QVariant&>(callbackNull)); - JavaScriptCallbackNull callbackUndefined; + JavaScriptCallbackUndefined callbackUndefined; page.runJavaScript("undefined", QWebEngineCallback<const QVariant&>(callbackUndefined)); + QVERIFY(watcher.wait()); +} + +class FullScreenPage : public QWebEnginePage { + Q_OBJECT +public: + FullScreenPage(QObject* parent = 0) + : QWebEnginePage(parent) + , m_isFullScreen(true) + { } + + void setIsFullScreen(bool b) { m_isFullScreen = b; } + +protected: + bool isFullScreen() override + { + return m_isFullScreen; + } + bool m_isFullScreen; +}; + +void tst_QWebEnginePage::fullScreenRequested() +{ + JavaScriptCallbackWatcher watcher; + FullScreenPage* page = new FullScreenPage; + QWebEngineView* view = new QWebEngineView; + view->setPage(page); + view->show(); + + page->settings()->setAttribute(QWebEngineSettings::FullScreenSupportEnabled, true); + + QSignalSpy loadSpy(view, SIGNAL(loadFinished(bool))); + page->load(QUrl("qrc:///resources/fullscreen.html")); + QTRY_COMPARE(loadSpy.count(), 1); + + page->runJavaScript("document.webkitFullscreenEnabled", JavaScriptCallback(true)); + page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(false)); + QVERIFY(watcher.wait()); + + // FullscreenRequest must be a user gesture + QTest::keyPress(qApp->focusWindow(), Qt::Key_Space); QTest::qWait(100); + page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(true)); + page->runJavaScript("document.webkitExitFullscreen()", JavaScriptCallbackUndefined()); + QVERIFY(watcher.wait()); + page->setIsFullScreen(false); + page->runJavaScript("document.webkitFullscreenEnabled", JavaScriptCallback(true)); + QTest::keyPress(qApp->focusWindow(), Qt::Key_Space); + QVERIFY(watcher.wait()); + page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(false)); + QVERIFY(watcher.wait()); + + delete view; + delete page; } QTEST_MAIN(tst_QWebEnginePage) diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc index 994d71b43..0a8995090 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.qrc @@ -1,5 +1,6 @@ <!DOCTYPE RCC><RCC version="1.0"> <qresource> + <file>resources/content.html</file> <file>resources/index.html</file> <file>resources/frame_a.html</file> <file>resources/frame_c.html</file> @@ -7,7 +8,7 @@ <file>resources/iframe2.html</file> <file>resources/iframe3.html</file> <file>resources/framedindex.html</file> - <file>resources/content.html</file> + <file>resources/fullscreen.html</file> <file>resources/script.html</file> <file>resources/user.css</file> </qresource> diff --git a/tests/auto/widgets/qwebenginescript/qwebenginescript.pro b/tests/auto/widgets/qwebenginescript/qwebenginescript.pro index ff6c49628..e99c7f493 100644 --- a/tests/auto/widgets/qwebenginescript/qwebenginescript.pro +++ b/tests/auto/widgets/qwebenginescript/qwebenginescript.pro @@ -1,2 +1 @@ include(../tests.pri) -exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc diff --git a/tests/auto/widgets/qwebengineview/qwebengineview.pro b/tests/auto/widgets/qwebengineview/qwebengineview.pro index ff6c49628..e99c7f493 100644 --- a/tests/auto/widgets/qwebengineview/qwebengineview.pro +++ b/tests/auto/widgets/qwebengineview/qwebengineview.pro @@ -1,2 +1 @@ include(../tests.pri) -exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc diff --git a/tests/auto/widgets/tests.pri b/tests/auto/widgets/tests.pri index 8d86ac93e..afdf46f42 100644 --- a/tests/auto/widgets/tests.pri +++ b/tests/auto/widgets/tests.pri @@ -11,6 +11,8 @@ TARGET = tst_$$TARGET SOURCES += $${TARGET}.cpp INCLUDEPATH += $$PWD +exists($$_PRO_FILE_PWD_/$${TARGET}.qrc): RESOURCES += $${TARGET}.qrc + QT += testlib network webenginewidgets widgets macx: CONFIG -= app_bundle diff --git a/tests/auto/widgets/util.h b/tests/auto/widgets/util.h index 83067fe8d..2b485fc0f 100644 --- a/tests/auto/widgets/util.h +++ b/tests/auto/widgets/util.h @@ -166,6 +166,9 @@ static inline QUrl baseUrlSync(QWebEnginePage *page) #define W_QSKIP(a, b) QSKIP(a) #define W_QTEST_MAIN(TestObject, params) \ +QT_BEGIN_NAMESPACE \ +QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS \ +QT_END_NAMESPACE \ int main(int argc, char *argv[]) \ { \ QVector<const char *> w_argv(argc); \ @@ -178,6 +181,8 @@ int main(int argc, char *argv[]) \ QApplication app(w_argc, const_cast<char **>(w_argv.data())); \ app.setAttribute(Qt::AA_Use96Dpi, true); \ QTEST_DISABLE_KEYPAD_NAVIGATION \ + QTEST_ADD_GPU_BLACKLIST_SUPPORT \ TestObject tc; \ + QTEST_SET_MAIN_SOURCE_PATH \ return QTest::qExec(&tc, argc, argv); \ } diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro index 2dbb498d1..b2df0880d 100644 --- a/tests/auto/widgets/widgets.pro +++ b/tests/auto/widgets/widgets.pro @@ -4,7 +4,6 @@ CONFIG += ordered SUBDIRS += \ qwebengineaccessibility \ - qwebengineframe \ qwebenginepage \ qwebenginehistoryinterface \ qwebengineview \ diff --git a/tests/quicktestbrowser/ApplicationRoot.qml b/tests/quicktestbrowser/ApplicationRoot.qml index 71737694d..5641b89a3 100644 --- a/tests/quicktestbrowser/ApplicationRoot.qml +++ b/tests/quicktestbrowser/ApplicationRoot.qml @@ -44,6 +44,8 @@ import QtWebEngine 1.1 QtObject { id: root + property bool thirdPartyCookiesEnabled: true + property QtObject testProfile: WebEngineProfile { storageName: "Test" } diff --git a/tests/quicktestbrowser/BrowserWindow.qml b/tests/quicktestbrowser/BrowserWindow.qml index f93a6ccd1..ca0b6499b 100644 --- a/tests/quicktestbrowser/BrowserWindow.qml +++ b/tests/quicktestbrowser/BrowserWindow.qml @@ -39,7 +39,7 @@ ****************************************************************************/ import QtQuick 2.1 -import QtWebEngine 1.1 +import QtWebEngine 1.2 import QtWebEngine.experimental 1.0 import QtQuick.Controls 1.0 @@ -76,6 +76,8 @@ ApplicationWindow { property alias autoLoadImages: loadImages.checked; property alias javaScriptEnabled: javaScriptEnabled.checked; property alias errorPageEnabled: errorPageEnabled.checked; + property alias pluginsEnabled: pluginsEnabled.checked; + property alias thirdPartyCookiesEnabled: thirdPartyCookiesEnabled.checked; } // Make sure the Qt.WindowFullscreenButtonHint is set on OS X. @@ -245,6 +247,19 @@ ApplicationWindow { checked: true } MenuItem { + id: pluginsEnabled + text: "Plugins On" + checkable: true + checked: true + } + MenuItem { + id: thirdPartyCookiesEnabled + text: "Third party cookies enabled" + checkable: true + checked: true + onToggled: applicationRoot.thirdPartyCookiesEnabled = checked + } + MenuItem { id: offTheRecordEnabled text: "Off The Record" checkable: true @@ -347,6 +362,7 @@ ApplicationWindow { settings.autoLoadImages: appSettings.autoLoadImages settings.javascriptEnabled: appSettings.javaScriptEnabled settings.errorPageEnabled: appSettings.errorPageEnabled + settings.pluginsEnabled: appSettings.pluginsEnabled onCertificateError: { if (!acceptedCertificates.shouldAutoAccept(error)){ diff --git a/tests/quicktestbrowser/main.cpp b/tests/quicktestbrowser/main.cpp index 7171baf77..166da4d5b 100644 --- a/tests/quicktestbrowser/main.cpp +++ b/tests/quicktestbrowser/main.cpp @@ -50,7 +50,9 @@ typedef QGuiApplication Application; #endif #include <QtQml/QQmlApplicationEngine> #include <QtQml/QQmlContext> +#include <QtQml/QQmlComponent> #include <QtWebEngine/qtwebengineglobal.h> +#include <QtWebEngineCore/qwebenginecookiestoreclient.h> static QUrl startupUrl() { @@ -67,6 +69,24 @@ static QUrl startupUrl() return QUrl(QStringLiteral("http://qt.io/")); } +class CookieClient: public QWebEngineCookieStoreClient +{ + QMetaProperty m_settingProperty; + const QObject *m_object; +public: + CookieClient(const QObject *object) + : m_object(object) + { + const QMetaObject *rootMeta = object->metaObject(); + int index = rootMeta->indexOfProperty("thirdPartyCookiesEnabled"); + Q_ASSERT(index != -1); + m_settingProperty = rootMeta->property(index); + } + virtual bool acceptCookieFromUrl(const QByteArray &, const QUrl &) { + return m_settingProperty.read(m_object).toBool(); + } +}; + int main(int argc, char **argv) { Application app(argc, argv); @@ -80,7 +100,25 @@ int main(int argc, char **argv) Utils utils; appEngine.rootContext()->setContextProperty("utils", &utils); appEngine.load(QUrl("qrc:/ApplicationRoot.qml")); - QMetaObject::invokeMethod(appEngine.rootObjects().first(), "load", Q_ARG(QVariant, startupUrl())); + QObject *rootObject = appEngine.rootObjects().first(); + + QQmlComponent component(&appEngine); + component.setData(QByteArrayLiteral("import QtQuick 2.0\n" + "import QtWebEngine 1.1\n" + "WebEngineProfile {\n" + "storageName: \"Test\"\n" + "}") + , QUrl()); + QObject *profile = component.create(); + CookieClient client(rootObject); + QMetaObject::invokeMethod(profile, "setCookieStoreClient", Q_ARG(QWebEngineCookieStoreClient*, &client)); + const QMetaObject *rootMeta = rootObject->metaObject(); + int index = rootMeta->indexOfProperty("testProfile"); + Q_ASSERT(index != -1); + QMetaProperty profileProperty = rootMeta->property(index); + profileProperty.write(rootObject, qVariantFromValue(profile)); + + QMetaObject::invokeMethod(rootObject, "load", Q_ARG(QVariant, startupUrl())); return app.exec(); } |