diff options
author | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-06-13 10:16:32 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@theqtcompany.com> | 2016-06-14 10:43:10 +0200 |
commit | 939d104cc5a8208a0bef94ca14889ccd584a3526 (patch) | |
tree | 4d89c122ad5014a32cd8d4fbad6b7418944d2fb6 /tests | |
parent | 5a7063154520544fe19bb57af3609afef898bffb (diff) | |
parent | 6c2a111f8c82b56388abf409a61a3e0d56a52156 (diff) |
Merge branch '5.7' into dev
Change-Id: I1ecb615b8df1303c27b6609970502920123b3610
Diffstat (limited to 'tests')
-rw-r--r-- | tests/auto/quick/publicapi/tst_publicapi.cpp | 3 | ||||
-rw-r--r-- | tests/auto/quick/qquickwebengineview/BLACKLIST | 3 | ||||
-rw-r--r-- | tests/auto/quick/qquickwebengineview/qquickwebengineview.pro | 2 | ||||
-rw-r--r-- | tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp | 138 | ||||
-rw-r--r-- | tests/auto/widgets/positionplugin/plugin.cpp | 107 | ||||
-rw-r--r-- | tests/auto/widgets/positionplugin/plugin.json | 9 | ||||
-rw-r--r-- | tests/auto/widgets/positionplugin/positionplugin.pro | 13 | ||||
-rw-r--r-- | tests/auto/widgets/qwebenginepage/BLACKLIST | 9 | ||||
-rw-r--r-- | tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp | 238 | ||||
-rw-r--r-- | tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp | 152 | ||||
-rw-r--r-- | tests/auto/widgets/widgets.pro | 5 |
11 files changed, 324 insertions, 355 deletions
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp index 34170da8a..1937dca04 100644 --- a/tests/auto/quick/publicapi/tst_publicapi.cpp +++ b/tests/auto/quick/publicapi/tst_publicapi.cpp @@ -364,6 +364,7 @@ static QStringList expectedAPI = QStringList() << "QQuickWebEngineCertificateError.CertificateNonUniqueName --> Error" << "QQuickWebEngineCertificateError.CertificateWeakKey --> Error" << "QQuickWebEngineCertificateError.CertificateNameConstraintViolation --> Error" + << "QQuickWebEngineCertificateError.CertificateValidityTooLong --> Error" << "QQuickWebEngineCertificateError.url --> QUrl" << "QQuickWebEngineCertificateError.error --> Error" << "QQuickWebEngineCertificateError.description --> QString" @@ -492,13 +493,11 @@ static QStringList expectedAPI = QStringList() << "QQuickWebEngineSettings.defaultTextEncodingChanged() --> void" << "QQuickWebEngineSettings.screenCaptureEnabled --> bool" << "QQuickWebEngineSettings.webGLEnabled --> bool" - << "QQuickWebEngineSettings.webAudioEnabled --> bool" << "QQuickWebEngineSettings.accelerated2dCanvasEnabled --> bool" << "QQuickWebEngineSettings.autoLoadIconsForPage --> bool" << "QQuickWebEngineSettings.touchIconsEnabled --> bool" << "QQuickWebEngineSettings.screenCaptureEnabledChanged() --> void" << "QQuickWebEngineSettings.webGLEnabledChanged() --> void" - << "QQuickWebEngineSettings.webAudioEnabledChanged() --> void" << "QQuickWebEngineSettings.accelerated2dCanvasEnabledChanged() --> void" << "QQuickWebEngineSettings.autoLoadIconsForPageChanged() --> void" << "QQuickWebEngineSettings.touchIconsEnabledChanged() --> void" diff --git a/tests/auto/quick/qquickwebengineview/BLACKLIST b/tests/auto/quick/qquickwebengineview/BLACKLIST index d4d5c9844..2cde59454 100644 --- a/tests/auto/quick/qquickwebengineview/BLACKLIST +++ b/tests/auto/quick/qquickwebengineview/BLACKLIST @@ -1,2 +1,5 @@ [transparentWebEngineViews] windows + +[inputEventForwardingDisabledWhenActiveFocusOnPressDisabled] +* diff --git a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro index 826b47de7..36e74a2a8 100644 --- a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro +++ b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro @@ -1,6 +1,6 @@ include(../tests.pri) exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc -QT_PRIVATE += webengine-private +QT_PRIVATE += webengine-private gui-private HEADERS += ../shared/util.h diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp index 0def76d6f..1c5461fa7 100644 --- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp +++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp @@ -31,6 +31,7 @@ #include <QScopedPointer> #include <QtCore/qelapsedtimer.h> +#include <QtGui/qpa/qwindowsysteminterface.h> #include <QtQml/QQmlEngine> #include <QtTest/QtTest> #include <private/qquickwebengineview_p.h> @@ -71,6 +72,9 @@ private Q_SLOTS: void basicRenderingSanity(); void setZoomFactor(); void printToPdf(); + void stopSettingFocusWhenDisabled(); + void stopSettingFocusWhenDisabled_data(); + void inputEventForwardingDisabledWhenActiveFocusOnPressDisabled(); private: inline QQuickWebEngineView *newWebEngineView(); @@ -514,5 +518,139 @@ void tst_QQuickWebEngineView::printToPdf() QVERIFY(!QFile::exists(path)); } +void tst_QQuickWebEngineView::stopSettingFocusWhenDisabled() +{ + QFETCH(bool, viewEnabled); + QFETCH(bool, activeFocusResult); + + QQuickWebEngineView *view = webEngineView(); + m_window->show(); + view->setSize(QSizeF(640, 480)); + view->setEnabled(viewEnabled); + view->loadHtml("<html><head><title>Title</title></head><body>Hello" + "<input id=\"input\" type=\"text\"></body></html>"); + QVERIFY(waitForLoadSucceeded(view)); + + // When enabled, the view should get active focus after the page is loaded. + QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), activeFocusResult, 1000); + view->runJavaScript("document.getElementById(\"input\").focus()"); + QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), activeFocusResult, 1000); +} + +void tst_QQuickWebEngineView::stopSettingFocusWhenDisabled_data() +{ + QTest::addColumn<bool>("viewEnabled"); + QTest::addColumn<bool>("activeFocusResult"); + + QTest::newRow("enabled view gets active focus") << true << true; + QTest::newRow("disabled view does not get active focus") << false << false; +} + +class MouseTouchEventRecordingItem : public QQuickItem { +public: + explicit MouseTouchEventRecordingItem(QQuickItem *parent = 0) : + QQuickItem(parent), m_eventCounter(0) { + setFlag(ItemHasContents); + setAcceptedMouseButtons(Qt::AllButtons); + setAcceptHoverEvents(true); + } + + bool event(QEvent *event) Q_DECL_OVERRIDE + { + switch (event->type()) { + case QEvent::TabletPress: + case QEvent::TabletRelease: + case QEvent::TabletMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + case QEvent::TouchCancel: + case QEvent::HoverEnter: + case QEvent::HoverMove: + case QEvent::HoverLeave: + ++m_eventCounter; + event->accept(); + return true; + default: + break; + } + return QQuickItem::event(event); + } + + void clearEventCount() + { + m_eventCounter = 0; + } + + int eventCount() + { + return m_eventCounter; + } + +private: + int m_eventCounter; +}; + +void tst_QQuickWebEngineView::inputEventForwardingDisabledWhenActiveFocusOnPressDisabled() +{ + QQuickWebEngineView *view = webEngineView(); + MouseTouchEventRecordingItem item; + item.setParentItem(m_window->contentItem()); + item.setSize(QSizeF(640, 480)); + view->setParentItem(&item); + view->setSize(QSizeF(640, 480)); + m_window->show(); + + // Simulate click and move of mouse, so that last known position in the application + // is updated, thus a mouse move event is not generated when we don't expect it. + QTest::mouseClick(view->window(), Qt::LeftButton); + item.clearEventCount(); + + // First disable view, so it does not receive focus on page load. + view->setEnabled(false); + view->setActiveFocusOnPress(false); + view->loadHtml("<html><head>" + "<script>" + "window.onload = function() { document.getElementById(\"input\").focus(); }" + "</script>" + "<title>Title</title></head><body>Hello" + "<input id=\"input\" type=\"text\"></body></html>"); + QVERIFY(waitForLoadSucceeded(view)); + QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), false, 1000); + + // Enable the view back so we can try to interact with it. + view->setEnabled(true); + + // Click on the view, to try and set focus. + QTest::mouseClick(view->window(), Qt::LeftButton); + + // View should not have focus after click, because setActiveFocusOnPress is false. + QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), false, 1000); + + // Now test sending various input events, to check that indeed all the input events are not + // forwarded to Chromium, but rather processed and accepted by the view's parent item. + QTest::mousePress(view->window(), Qt::LeftButton); + QTest::mouseRelease(view->window(), Qt::LeftButton); + + QTouchDevice *device = new QTouchDevice; + device->setType(QTouchDevice::TouchScreen); + QWindowSystemInterface::registerTouchDevice(device); + + QTest::touchEvent(view->window(), device).press(0, QPoint(0,0), view->window()); + QTest::touchEvent(view->window(), device).move(0, QPoint(1, 1), view->window()); + QTest::touchEvent(view->window(), device).release(0, QPoint(1, 1), view->window()); + + // We expect to catch 7 events - click = 2, press + release = 2, touches = 3. + QCOMPARE(item.eventCount(), 7); + + // Manually forcing focus should still be possible. + view->forceActiveFocus(); + QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), true, 1000); +} + QTEST_MAIN(tst_QQuickWebEngineView) #include "tst_qquickwebengineview.moc" diff --git a/tests/auto/widgets/positionplugin/plugin.cpp b/tests/auto/widgets/positionplugin/plugin.cpp deleted file mode 100644 index ca2e7eb45..000000000 --- a/tests/auto/widgets/positionplugin/plugin.cpp +++ /dev/null @@ -1,107 +0,0 @@ -/**************************************************************************** -** -** 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: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 <QtPositioning/qgeopositioninfosource.h> -#include <QtPositioning/qgeopositioninfosourcefactory.h> -#include <QObject> -#include <QtPlugin> - -class DummySource : public QGeoPositionInfoSource -{ - Q_OBJECT - -public: - DummySource(QObject *parent=0); - - void startUpdates() {} - void stopUpdates() {} - void requestUpdate(int) {} - - QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const; - PositioningMethods supportedPositioningMethods() const; - - int minimumUpdateInterval() const; - Error error() const; -}; - -DummySource::DummySource(QObject *parent) : - QGeoPositionInfoSource(parent) -{ -} - -QGeoPositionInfoSource::Error DummySource::error() const -{ - return QGeoPositionInfoSource::NoError; -} - -int DummySource::minimumUpdateInterval() const -{ - return 1000; -} - -QGeoPositionInfo DummySource::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const -{ - Q_UNUSED(fromSatellitePositioningMethodsOnly); - return QGeoPositionInfo(QGeoCoordinate(54.186824, 12.087262), QDateTime::currentDateTime()); -} - -QGeoPositionInfoSource::PositioningMethods DummySource::supportedPositioningMethods() const -{ - return QGeoPositionInfoSource::AllPositioningMethods; -} - - -class QGeoPositionInfoSourceFactoryTest : public QObject, public QGeoPositionInfoSourceFactory -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/5.0" - FILE "plugin.json") - Q_INTERFACES(QGeoPositionInfoSourceFactory) - -public: - QGeoPositionInfoSource *positionInfoSource(QObject *parent); - QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent); - QGeoAreaMonitorSource *areaMonitor(QObject *parent); -}; - -QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryTest::positionInfoSource(QObject *parent) -{ - return new DummySource(parent); -} - -QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryTest::satelliteInfoSource(QObject *) -{ - return 0; -} - -QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryTest::areaMonitor(QObject* ) -{ - return 0; -} - -#include "plugin.moc" diff --git a/tests/auto/widgets/positionplugin/plugin.json b/tests/auto/widgets/positionplugin/plugin.json deleted file mode 100644 index 68acaded3..000000000 --- a/tests/auto/widgets/positionplugin/plugin.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Keys": ["test.source"], - "Provider": "test.source", - "Position": true, - "Satellite": false, - "Monitor": false, - "Priority": 0, - "Testable": true -} diff --git a/tests/auto/widgets/positionplugin/positionplugin.pro b/tests/auto/widgets/positionplugin/positionplugin.pro deleted file mode 100644 index 6f2e736c6..000000000 --- a/tests/auto/widgets/positionplugin/positionplugin.pro +++ /dev/null @@ -1,13 +0,0 @@ -TARGET = qtwebengine_positioning_testplugin - -QT += positioning - -SOURCES += plugin.cpp - -OTHER_FILES += \ - plugin.json - -PLUGIN_TYPE = position -PLUGIN_CLASS_NAME = TestPositionPlugin -PLUGIN_EXTENDS = - -load(qt_plugin) diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST index 30b43d6b7..fcd36ba83 100644 --- a/tests/auto/widgets/qwebenginepage/BLACKLIST +++ b/tests/auto/widgets/qwebenginepage/BLACKLIST @@ -1,11 +1,2 @@ -[geolocationRequestJS] -* - [macCopyUnicodeToClipboard] osx - -[getUserMediaRequest] -windows - -[setHtmlWithImageResource] -* diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index 3e0a5abae..e50692226 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -201,9 +201,6 @@ private Q_SLOTS: void progressSignal(); void urlChange(); void requestedUrlAfterSetAndLoadFailures(); - void javaScriptWindowObjectCleared_data(); - void javaScriptWindowObjectCleared(); - void javaScriptWindowObjectClearedOnEvaluate(); void asyncAndDelete(); void earlyToHtml(); void setHtml(); @@ -215,7 +212,6 @@ private Q_SLOTS: void hitTestContent(); void baseUrl_data(); void baseUrl(); - void renderHints(); void scrollPosition(); void scrollToAnchor(); void scrollbarsOff(); @@ -412,16 +408,21 @@ void tst_QWebEnginePage::geolocationRequestJS() newPage, SLOT(requestPermission(const QUrl&, QWebEnginePage::Feature))); QSignalSpy spyLoadFinished(newPage, SIGNAL(loadFinished(bool))); - newPage->setHtml(QString("<html><body>test</body></html>"), QUrl()); + newPage->setHtml(QString("<html><body>test</body></html>"), QUrl("qrc://secure/origin")); QTRY_COMPARE(spyLoadFinished.count(), 1); if (evaluateJavaScriptSync(newPage, QLatin1String("!navigator.geolocation")).toBool()) { delete view; W_QSKIP("Geolocation is not supported.", SkipSingle); } - evaluateJavaScriptSync(newPage, "var errorCode = 0; function error(err) { errorCode = err.code; } function success(pos) { } navigator.geolocation.getCurrentPosition(success, error)"); + evaluateJavaScriptSync(newPage, "var errorCode = 0; var done = false; function error(err) { errorCode = err.code; done = true; } function success(pos) { done = true; } navigator.geolocation.getCurrentPosition(success, error)"); + + QTRY_VERIFY(evaluateJavaScriptSync(newPage, "done").toBool()); + int result = evaluateJavaScriptSync(newPage, "errorCode").toInt(); + if (result == 2) + QEXPECT_FAIL("", "No location service available.", Continue); + QCOMPARE(result, errorCode); - QTRY_COMPARE(evaluateJavaScriptSync(newPage, "errorCode").toInt(), errorCode); delete view; } @@ -3879,48 +3880,6 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures() QVERIFY(!spy.at(1).first().toBool()); } -void tst_QWebEnginePage::javaScriptWindowObjectCleared_data() -{ - QTest::addColumn<QString>("html"); - QTest::addColumn<int>("signalCount"); - QTest::newRow("with <script>") << "<html><body><script>i=0</script><p>hello world</p></body></html>" << 1; - // NOTE: Empty scripts no longer cause this signal to be emitted. - QTest::newRow("with empty <script>") << "<html><body><script></script><p>hello world</p></body></html>" << 0; - QTest::newRow("without <script>") << "<html><body><p>hello world</p></body></html>" << 0; -} - -void tst_QWebEnginePage::javaScriptWindowObjectCleared() -{ -#if !defined(QWEBENGINEPAGE_JAVASCRIPTWINDOWOBJECTCLEARED) - QSKIP("QWEBENGINEPAGE_JAVASCRIPTWINDOWOBJECTCLEARED"); -#else - QWebEnginePage page; - QSignalSpy spy(&page, SIGNAL(javaScriptWindowObjectCleared())); - QFETCH(QString, html); - page.setHtml(html); - - QFETCH(int, signalCount); - QCOMPARE(spy.count(), signalCount); -#endif -} - -void tst_QWebEnginePage::javaScriptWindowObjectClearedOnEvaluate() -{ -#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT) - QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT"); -#else - QWebEnginePage page; - QSignalSpy spy(&page, SIGNAL(javaScriptWindowObjectCleared())); - page.setHtml("<html></html>"); - QCOMPARE(spy.count(), 0); - page.evaluateJavaScript("var a = 'a';"); - QCOMPARE(spy.count(), 1); - // no new clear for a new script: - page.evaluateJavaScript("var a = 1;"); - QCOMPARE(spy.count(), 1); -#endif -} - void tst_QWebEnginePage::asyncAndDelete() { QWebEnginePage *page = new QWebEnginePage; @@ -3954,28 +3913,26 @@ void tst_QWebEnginePage::setHtml() void tst_QWebEnginePage::setHtmlWithImageResource() { - // By default, only security origins of local files can load local resources. - // So we should specify baseUrl to be a local file in order to get a proper origin and load the local image. + // We allow access to qrc resources from any security origin, including local and anonymous QLatin1String html("<html><body><p>hello world</p><img src='qrc:/resources/image.png'/></body></html>"); QWebEnginePage page; - page.setHtml(html, QUrl(QLatin1String("file:///path/to/file"))); - waitForSignal(&page, SIGNAL(loadFinished(bool))); + QSignalSpy spy(&page, SIGNAL(loadFinished(bool))); + page.setHtml(html, QUrl("file:///path/to/file")); + QTRY_COMPARE(spy.count(), 1); QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1); QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128); QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128); - // Now we test the opposite: without a baseUrl as a local file, we cannot request local resources. + // Now we test the opposite: without a baseUrl as a local file, we can still request qrc resources. page.setHtml(html); - waitForSignal(&page, SIGNAL(loadFinished(bool))); + QTRY_COMPARE(spy.count(), 2); QCOMPARE(evaluateJavaScriptSync(&page, "document.images.length").toInt(), 1); - QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue); - QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 0); - QEXPECT_FAIL("", "https://bugs.webkit.org/show_bug.cgi?id=118659", Continue); - QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 0); + QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].width").toInt(), 128); + QCOMPARE(evaluateJavaScriptSync(&page, "document.images[0].height").toInt(), 128); } void tst_QWebEnginePage::setHtmlWithStylesheetResource() @@ -4154,167 +4111,30 @@ void tst_QWebEnginePage::baseUrl() QCOMPARE(baseUrlSync(m_page), baseUrl); } -class DummyPaintEngine: public QPaintEngine { -public: - - DummyPaintEngine() - : QPaintEngine(QPaintEngine::AllFeatures) - , renderHints(0) - { - } - - bool begin(QPaintDevice*) - { - setActive(true); - return true; - } - - bool end() - { - setActive(false); - return false; - } - - void updateState(const QPaintEngineState& state) - { - renderHints = state.renderHints(); - } - - void drawPath(const QPainterPath&) { } - void drawPixmap(const QRectF&, const QPixmap&, const QRectF&) { } - - QPaintEngine::Type type() const - { - return static_cast<QPaintEngine::Type>(QPaintEngine::User + 2); - } - - QPainter::RenderHints renderHints; -}; - -class DummyPaintDevice: public QPaintDevice { -public: - DummyPaintDevice() - : QPaintDevice() - , m_engine(new DummyPaintEngine) - { - } - - ~DummyPaintDevice() - { - delete m_engine; - } - - QPaintEngine* paintEngine() const - { - return m_engine; - } - - QPainter::RenderHints renderHints() const - { - return m_engine->renderHints; - } - -protected: - int metric(PaintDeviceMetric metric) const; - -private: - DummyPaintEngine* m_engine; - friend class DummyPaintEngine; -}; - - -int DummyPaintDevice::metric(PaintDeviceMetric metric) const -{ - switch (metric) { - case PdmWidth: - return 400; - break; - - case PdmHeight: - return 200; - break; - - case PdmNumColors: - return INT_MAX; - break; - - case PdmDepth: - return 32; - break; - - default: - break; - } - return 0; -} - -void tst_QWebEnginePage::renderHints() -{ -#if !defined(QWEBENGINEPAGE_RENDER) - QSKIP("QWEBENGINEPAGE_RENDER"); -#else - QString html("<html><body><p>Hello, world!</p></body></html>"); - - QWebEnginePage page; - page.setHtml(html); - page.setViewportSize(page.contentsSize()); - - // We will call frame->render and trap the paint engine state changes - // to ensure that GraphicsContext does not clobber the render hints. - DummyPaintDevice buffer; - QPainter painter(&buffer); - - painter.setRenderHint(QPainter::TextAntialiasing, false); - page.render(&painter); - QVERIFY(!(buffer.renderHints() & QPainter::TextAntialiasing)); - QVERIFY(!(buffer.renderHints() & QPainter::SmoothPixmapTransform)); - QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing)); - - painter.setRenderHint(QPainter::TextAntialiasing, true); - page.render(&painter); - QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing); - QVERIFY(!(buffer.renderHints() & QPainter::SmoothPixmapTransform)); - QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing)); - - painter.setRenderHint(QPainter::SmoothPixmapTransform, true); - page.render(&painter); - QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing); - QVERIFY(buffer.renderHints() & QPainter::SmoothPixmapTransform); - QVERIFY(!(buffer.renderHints() & QPainter::HighQualityAntialiasing)); - - painter.setRenderHint(QPainter::HighQualityAntialiasing, true); - page.render(&painter); - QVERIFY(buffer.renderHints() & QPainter::TextAntialiasing); - QVERIFY(buffer.renderHints() & QPainter::SmoothPixmapTransform); - QVERIFY(buffer.renderHints() & QPainter::HighQualityAntialiasing); -#endif -} - void tst_QWebEnginePage::scrollPosition() { -#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT) - QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT"); -#else // enlarged image in a small viewport, to provoke the scrollbars to appear QString html("<html><body><img src='qrc:/image.png' height=500 width=500/></body></html>"); - QWebEnginePage page; - page.setViewportSize(QSize(200, 200)); + QWebEngineView view; + view.setFixedSize(200,200); + view.show(); - page.setHtml(html); - page.setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff); - page.setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff); + QTest::qWaitForWindowExposed(&view); + + QSignalSpy loadSpy(view.page(), SIGNAL(loadFinished(bool))); + view.setHtml(html); + QTRY_COMPARE(loadSpy.count(), 1); // try to set the scroll offset programmatically - page.setScrollPosition(QPoint(23, 29)); - QCOMPARE(page.scrollPosition().x(), 23); - QCOMPARE(page.scrollPosition().y(), 29); + view.page()->runJavaScript("window.scrollTo(23, 29);"); + QTRY_COMPARE(view.page()->scrollPosition().x(), qreal(23)); + QCOMPARE(view.page()->scrollPosition().y(), qreal(29)); - int x = page.evaluateJavaScript("window.scrollX").toInt(); - int y = page.evaluateJavaScript("window.scrollY").toInt(); + int x = evaluateJavaScriptSync(view.page(), "window.scrollX").toInt(); + int y = evaluateJavaScriptSync(view.page(), "window.scrollY").toInt(); QCOMPARE(x, 23); QCOMPARE(y, 29); -#endif } void tst_QWebEnginePage::scrollToAnchor() diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 8aaf9ccc3..afb53ba20 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -29,11 +29,20 @@ #include <qwebenginesettings.h> #include <qnetworkrequest.h> #include <qdiriterator.h> +#include <qstackedlayout.h> #include <qtemporarydir.h> #define VERIFY_INPUTMETHOD_HINTS(actual, expect) \ QVERIFY(actual == expect); +#define QTRY_COMPARE_WITH_TIMEOUT_FAIL_BLOCK(__expr, __expected, __timeout, __fail_block) \ +do { \ + QTRY_IMPL(((__expr) == (__expected)), __timeout);\ + if (__expr != __expected)\ + __fail_block\ + QCOMPARE((__expr), __expected); \ +} while (0) + class tst_QWebEngineView : public QObject { Q_OBJECT @@ -61,6 +70,10 @@ private Q_SLOTS: void setPalette_data(); void setPalette(); #endif + void doNotSendMouseKeyboardEventsWhenDisabled(); + void doNotSendMouseKeyboardEventsWhenDisabled_data(); + void stopSettingFocusWhenDisabled(); + void stopSettingFocusWhenDisabled_data(); }; // This will be called before the first test function is executed. @@ -591,5 +604,144 @@ void tst_QWebEngineView::renderingAfterMaxAndBack() #endif } +class KeyboardAndMouseEventRecordingWidget : public QWidget { +public: + explicit KeyboardAndMouseEventRecordingWidget(QWidget *parent = 0) : + QWidget(parent), m_eventCounter(0) {} + + bool event(QEvent *event) Q_DECL_OVERRIDE + { + QString eventString; + switch (event->type()) { + case QEvent::TabletPress: + case QEvent::TabletRelease: + case QEvent::TabletMove: + case QEvent::MouseButtonPress: + case QEvent::MouseButtonRelease: + case QEvent::MouseButtonDblClick: + case QEvent::MouseMove: + case QEvent::TouchBegin: + case QEvent::TouchUpdate: + case QEvent::TouchEnd: + case QEvent::TouchCancel: + case QEvent::ContextMenu: + case QEvent::KeyPress: + case QEvent::KeyRelease: +#ifndef QT_NO_WHEELEVENT + case QEvent::Wheel: +#endif + ++m_eventCounter; + event->setAccepted(true); + QDebug(&eventString) << event; + m_eventHistory.append(eventString); + return true; + default: + break; + } + return QWidget::event(event); + } + + void clearEventCount() + { + m_eventCounter = 0; + } + + int eventCount() + { + return m_eventCounter; + } + + void printEventHistory() + { + qDebug() << "Received events are:"; + for (int i = 0; i < m_eventHistory.size(); ++i) { + qDebug() << m_eventHistory[i]; + } + } + +private: + int m_eventCounter; + QVector<QString> m_eventHistory; +}; + +void tst_QWebEngineView::doNotSendMouseKeyboardEventsWhenDisabled() +{ + QFETCH(bool, viewEnabled); + QFETCH(int, resultEventCount); + + KeyboardAndMouseEventRecordingWidget parentWidget; + QWebEngineView webView(&parentWidget); + webView.setEnabled(viewEnabled); + parentWidget.setLayout(new QStackedLayout); + parentWidget.layout()->addWidget(&webView); + webView.resize(640, 480); + parentWidget.show(); + QTest::qWaitForWindowExposed(&webView); + + QSignalSpy loadSpy(&webView, SIGNAL(loadFinished(bool))); + webView.setHtml("<html><head><title>Title</title></head><body>Hello" + "<input id=\"input\" type=\"text\"></body></html>"); + QTRY_COMPARE(loadSpy.count(), 1); + + // When the webView is enabled, the events are swallowed by it, and the parent widget + // does not receive any events, otherwise all events are processed by the parent widget. + parentWidget.clearEventCount(); + QTest::mousePress(parentWidget.windowHandle(), Qt::LeftButton); + QTest::mouseMove(parentWidget.windowHandle(), QPoint(100, 100)); + QTest::mouseRelease(parentWidget.windowHandle(), Qt::LeftButton, + Qt::KeyboardModifiers(), QPoint(100, 100)); + + // Wait a bit for the mouse events to be processed, so they don't interfere with the js focus + // below. + QTest::qWait(100); + evaluateJavaScriptSync(webView.page(), "document.getElementById(\"input\").focus()"); + QTest::keyPress(parentWidget.windowHandle(), Qt::Key_H); + + // Wait a bit for the key press to be handled. We have to do it, because the compare + // below could immediately finish successfully, without alloing for the events to be handled. + QTest::qWait(100); + QTRY_COMPARE_WITH_TIMEOUT_FAIL_BLOCK(parentWidget.eventCount(), resultEventCount, + 1000, parentWidget.printEventHistory();); +} + +void tst_QWebEngineView::doNotSendMouseKeyboardEventsWhenDisabled_data() +{ + QTest::addColumn<bool>("viewEnabled"); + QTest::addColumn<int>("resultEventCount"); + + QTest::newRow("enabled view receives events") << true << 0; + QTest::newRow("disabled view does not receive events") << false << 4; +} + +void tst_QWebEngineView::stopSettingFocusWhenDisabled() +{ + QFETCH(bool, viewEnabled); + QFETCH(bool, focusResult); + + QWebEngineView webView; + webView.resize(640, 480); + webView.show(); + webView.setEnabled(viewEnabled); + QTest::qWaitForWindowExposed(&webView); + + QSignalSpy loadSpy(&webView, SIGNAL(loadFinished(bool))); + webView.setHtml("<html><head><title>Title</title></head><body>Hello" + "<input id=\"input\" type=\"text\"></body></html>"); + QTRY_COMPARE(loadSpy.count(), 1); + + QTRY_COMPARE_WITH_TIMEOUT(webView.hasFocus(), focusResult, 1000); + evaluateJavaScriptSync(webView.page(), "document.getElementById(\"input\").focus()"); + QTRY_COMPARE_WITH_TIMEOUT(webView.hasFocus(), focusResult, 1000); +} + +void tst_QWebEngineView::stopSettingFocusWhenDisabled_data() +{ + QTest::addColumn<bool>("viewEnabled"); + QTest::addColumn<bool>("focusResult"); + + QTest::newRow("enabled view gets focus") << true << true; + QTest::newRow("disabled view does not get focus") << false << false; +} + QTEST_MAIN(tst_QWebEngineView) #include "tst_qwebengineview.moc" diff --git a/tests/auto/widgets/widgets.pro b/tests/auto/widgets/widgets.pro index 7543a4382..2f5416701 100644 --- a/tests/auto/widgets/widgets.pro +++ b/tests/auto/widgets/widgets.pro @@ -17,8 +17,3 @@ SUBDIRS += \ !contains(WEBENGINE_CONFIG, no_spellcheck):!osx:!cross_compile { SUBDIRS += qwebenginespellcheck } - -qtHaveModule(positioning) { - SUBDIRS += positionplugin - qwebenginepage.depends = positionplugin -} |