diff options
Diffstat (limited to 'tests/auto')
18 files changed, 570 insertions, 95 deletions
diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp index 1937dca04..b872f6620 100644 --- a/tests/auto/quick/publicapi/tst_publicapi.cpp +++ b/tests/auto/quick/publicapi/tst_publicapi.cpp @@ -396,6 +396,12 @@ static QStringList expectedAPI = QStringList() << "QQuickWebEngineDownloadItem.MimeHtmlSaveFormat --> SavePageFormat" << "QQuickWebEngineDownloadItem.savePageFormat --> SavePageFormat" << "QQuickWebEngineDownloadItem.savePageFormatChanged() --> void" + << "QQuickWebEngineDownloadItem.Attachment --> DownloadType" + << "QQuickWebEngineDownloadItem.DownloadAttribute --> DownloadType" + << "QQuickWebEngineDownloadItem.UserRequested --> DownloadType" + << "QQuickWebEngineDownloadItem.SavePage --> DownloadType" + << "QQuickWebEngineDownloadItem.type --> DownloadType" + << "QQuickWebEngineDownloadItem.typeChanged() --> void" << "QQuickWebEngineHistory.items --> QQuickWebEngineHistoryListModel*" << "QQuickWebEngineHistory.backItems --> QQuickWebEngineHistoryListModel*" << "QQuickWebEngineHistory.forwardItems --> QQuickWebEngineHistoryListModel*" diff --git a/tests/auto/quick/qmltests/data/forms.html b/tests/auto/quick/qmltests/data/forms.html index 8dc3472f2..18133eca6 100644 --- a/tests/auto/quick/qmltests/data/forms.html +++ b/tests/auto/quick/qmltests/data/forms.html @@ -19,10 +19,6 @@ <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/> @@ -33,8 +29,12 @@ <input type="submit" name="email_invalid"/> </form> <form> - <input type="email" value="invalid" title="email_title" required/> - <input type="submit" name="email_title"/> + <input type="text" title="empty input" required/> + <input type="submit" name="input_empty"/> + </form> + <form> + <input type="text" pattern="Lorem ipsum" value="Lorem Ipsum" title="Should type 'Lorem ipsum'"/> + <input type="submit" name="lorem_ipsum"/> </form> </body> </html> diff --git a/tests/auto/quick/qmltests/data/script-with-metadata.js b/tests/auto/quick/qmltests/data/script-with-metadata.js new file mode 100644 index 000000000..4dcf50f55 --- /dev/null +++ b/tests/auto/quick/qmltests/data/script-with-metadata.js @@ -0,0 +1,10 @@ +// ==UserScript== +// @name Test script +// @homepageURL http://www.qt.io/ +// @description Test script with metadata block +// @include *test*.html +// @exclude *test2.html +// @run-at document-end +// ==/UserScript== + +document.title = "New title"; diff --git a/tests/auto/quick/qmltests/data/tst_download.qml b/tests/auto/quick/qmltests/data/tst_download.qml index 7d1e24b4d..e4e93b993 100644 --- a/tests/auto/quick/qmltests/data/tst_download.qml +++ b/tests/auto/quick/qmltests/data/tst_download.qml @@ -114,7 +114,7 @@ TestWebEngineView { compare(downloadState[1], WebEngineDownloadItem.DownloadInProgress) downloadFinishedSpy.wait() compare(totalBytes, receivedBytes) - tryCompare(downloadState, 2, WebEngineDownloadItem.DownloadCompleted) + tryCompare(downloadState, "2", WebEngineDownloadItem.DownloadCompleted) } function test_downloadCancelled() { diff --git a/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml new file mode 100644 index 000000000..ce0fa2e31 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_focusOnNavigation.qml @@ -0,0 +1,136 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.5 +import QtTest 1.0 +import QtWebEngine 1.4 + +Item { + id: container + width: 500 + height: 300 + + Row { + id: row + spacing: 1 + + Rectangle { + anchors.top: row.top + anchors.topMargin: 7 + width: input.width + height: input.height + border.color: "black" + border.width: 1 + + TextInput { + id: input + width: 80 + height: 20 + verticalAlignment: TextInput.AlignVCenter + horizontalAlignment: TextInput.AlignHCenter + text: "Text" + } + } + + TestWebEngineView { + id: webView + width: 300 + height: 300 + } + } + + TestCase { + name: "WebEngineViewFocusOnNavigation" + when: windowShown + function init() { + } + + function test_focusOnNavigation_data() { + return [ + {tag: "focusOnNavigation true", focusOnNavigation: true, + viewReceivedFocus: true }, + {tag: "focusOnNavigation false", focusOnNavigation: false, + viewReceivedFocus: false }, + ] + } + + function triggerJavascriptFocus() { + var callbackCalled = false; + webView.runJavaScript("document.getElementById(\"input\").focus()", function(result) { + callbackCalled = true; + }); + wait(100); + verify(callbackCalled); + } + + function loadAndTriggerFocusAndCompare(data) { + verify(webView.waitForLoadSucceeded()); + triggerJavascriptFocus(); + compare(webView.activeFocus, data.viewReceivedFocus); + } + + function test_focusOnNavigation(data) { + // TextInput awlays has initial focus. + input.forceActiveFocus(); + + // Set focusOnNavigation property to current testing value. + webView.settings.focusOnNavigationEnabled = data.focusOnNavigation; + + // Load the content, invoke javascript focus on the view, and check which widget has + // focus. + webView.loadHtml("<html><head><title>Title</title></head><body>Hello" + + "<input id=\"input\" type=\"text\"></body></html>"); + loadAndTriggerFocusAndCompare(data); + + // Load a different page, and check focus. + webView.loadHtml("<html><head><title>Title</title></head><body>Hello 2" + + "<input id=\"input\" type=\"text\"></body></html>"); + loadAndTriggerFocusAndCompare(data); + + // Navigate to previous page in history, check focus. + webView.triggerWebAction(WebEngineView.Back) + loadAndTriggerFocusAndCompare(data); + + // Navigate to next page in history, check focus. + webView.triggerWebAction(WebEngineView.Forward) + loadAndTriggerFocusAndCompare(data); + + // Reload page, check focus. + webView.triggerWebAction(WebEngineView.Reload) + loadAndTriggerFocusAndCompare(data); + + // Reload page bypassing cache, check focus. + webView.triggerWebAction(WebEngineView.ReloadAndBypassCache) + loadAndTriggerFocusAndCompare(data); + + // Manually forcing focus on web view should work. + webView.forceActiveFocus() + compare(webView.activeFocus, true) + } + } +} diff --git a/tests/auto/quick/qmltests/data/tst_formValidation.qml b/tests/auto/quick/qmltests/data/tst_formValidation.qml index 6da8af7ff..cae41821c 100644 --- a/tests/auto/quick/qmltests/data/tst_formValidation.qml +++ b/tests/auto/quick/qmltests/data/tst_formValidation.qml @@ -71,15 +71,6 @@ TestWebEngineView { 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() { @@ -97,15 +88,26 @@ TestWebEngineView { keyPress(Qt.Key_Enter) showSpy.wait() compare(showSpy.signalArguments[1][0], "Please include an '@' in the email address. 'invalid' is missing an '@'.") + } + + function test_textForm() { + webEngineView.url = Qt.resolvedUrl("forms.html#input_empty") + verify(webEngineView.waitForLoadSucceeded()) + keyPress(Qt.Key_Enter) + showSpy.wait() + compare(showSpy.signalArguments[0][0], "Please fill out this field.") + // Title should be shown for pattern mismatch only + compare(showSpy.signalArguments[0][1], "") webEngineView.url = Qt.resolvedUrl("about:blank") verify(webEngineView.waitForLoadSucceeded()) - webEngineView.url = Qt.resolvedUrl("forms.html#email_title") + webEngineView.url = Qt.resolvedUrl("forms.html#lorem_ipsum") verify(webEngineView.waitForLoadSucceeded()) keyPress(Qt.Key_Enter) showSpy.wait() - compare(showSpy.signalArguments[2][1], "email_title") + compare(showSpy.signalArguments[1][0], "Please match the requested format.") + compare(showSpy.signalArguments[1][1], "Should type 'Lorem ipsum'") } } } diff --git a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml index 86fb9281c..ae60e5f5e 100644 --- a/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml +++ b/tests/auto/quick/qmltests/data/tst_keyboardModifierMapping.qml @@ -53,7 +53,6 @@ TestWebEngineView { } function test_keyboardModifierMapping() { - skip("runJavaScript bug: QTBUG-51746") webEngineView.url = Qt.resolvedUrl("keyboardModifierMapping.html") waitForLoadSucceeded(); titleSpy.wait() diff --git a/tests/auto/quick/qmltests/data/tst_runJavaScript.qml b/tests/auto/quick/qmltests/data/tst_runJavaScript.qml index 2011d2a5c..beeebc049 100644 --- a/tests/auto/quick/qmltests/data/tst_runJavaScript.qml +++ b/tests/auto/quick/qmltests/data/tst_runJavaScript.qml @@ -44,7 +44,6 @@ TestWebEngineView { TestCase { name: "WebEngineViewRunJavaScript" function test_runJavaScript() { - skip("runJavaScript bug: QTBUG-51746") var testTitle = "Title to test runJavaScript"; runJavaScript("document.title = \"" + testTitle +"\""); _waitFor(function() { spy.count > 0; }); diff --git a/tests/auto/quick/qmltests/data/tst_userScripts.qml b/tests/auto/quick/qmltests/data/tst_userScripts.qml index 358e8f56d..92ae71f0b 100644 --- a/tests/auto/quick/qmltests/data/tst_userScripts.qml +++ b/tests/auto/quick/qmltests/data/tst_userScripts.qml @@ -49,6 +49,11 @@ Item { injectionPoint: WebEngineScript.DocumentReady } + WebEngineScript { + id: scriptWithMetadata + sourceUrl: Qt.resolvedUrl("script-with-metadata.js") + } + TestWebEngineView { id: webEngineView width: 400 @@ -151,5 +156,22 @@ Item { webEngineView.waitForLoadSucceeded(); compare(webEngineView.title, "Big user script changed title"); } + + function test_parseMetadataHeader() { + compare(scriptWithMetadata.name, "Test script"); + compare(scriptWithMetadata.injectionPoint, WebEngineScript.DocumentReady); + + webEngineView.userScripts = [ scriptWithMetadata ]; + + // @include *test*.html + webEngineView.url = Qt.resolvedUrl("test1.html"); + webEngineView.waitForLoadSucceeded(); + compare(webEngineView.title, "New title"); + + // @exclude *test2.html + webEngineView.url = Qt.resolvedUrl("test2.html"); + webEngineView.waitForLoadSucceeded(); + compare(webEngineView.title, "Test page with huge link area"); + } } } diff --git a/tests/auto/quick/qmltests/data/tst_viewSource.qml b/tests/auto/quick/qmltests/data/tst_viewSource.qml new file mode 100644 index 000000000..7c7dd34e0 --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_viewSource.qml @@ -0,0 +1,93 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtTest 1.0 +import QtWebEngine 1.4 + +TestWebEngineView { + id: webEngineView + width: 200 + height: 400 + + property var viewRequest: null + + SignalSpy { + id: newViewRequestedSpy + target: webEngineView + signalName: "newViewRequested" + } + + SignalSpy { + id: titleChangedSpy + target: webEngineView + signalName: "titleChanged" + } + + onNewViewRequested: { + viewRequest = { + "destination": request.destination, + "userInitiated": request.userInitiated + }; + + request.openIn(webEngineView); + } + + TestCase { + id: test + name: "WebEngineViewSource" + + function init() { + newViewRequestedSpy.clear(); + titleChangedSpy.clear(); + viewRequest = null; + } + + function test_viewSource() { + webEngineView.url = Qt.resolvedUrl("test1.html"); + verify(webEngineView.waitForLoadSucceeded()); + compare(webEngineView.title, "Test page 1"); + verify(webEngineView.canViewSource, true); + + titleChangedSpy.clear(); + webEngineView.viewSource(); + tryCompare(newViewRequestedSpy, "count", 1); + verify(webEngineView.waitForLoadSucceeded()); + // The first titleChanged signal is emitted by adoptWebContents() + tryCompare(titleChangedSpy, "count", 2); + + compare(viewRequest.destination, WebEngineView.NewViewInTab); + verify(viewRequest.userInitiated); + verify(!webEngineView.canViewSource); + + compare(webEngineView.title, "test1.html"); + compare(webEngineView.url, "view-source:" + Qt.resolvedUrl("test1.html")); + } + } +} + diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro index 0158a7268..30c3aab30 100644 --- a/tests/auto/quick/qmltests/qmltests.pro +++ b/tests/auto/quick/qmltests/qmltests.pro @@ -45,6 +45,7 @@ OTHER_FILES += \ $$PWD/data/tst_favicon.qml \ $$PWD/data/tst_faviconDownload.qml \ $$PWD/data/tst_filePicker.qml \ + $$PWD/data/tst_focusOnNavigation.qml \ $$PWD/data/tst_formValidation.qml \ $$PWD/data/tst_geopermission.qml \ $$PWD/data/tst_javaScriptDialogs.qml \ @@ -63,6 +64,7 @@ OTHER_FILES += \ $$PWD/data/tst_titleChanged.qml \ $$PWD/data/tst_unhandledKeyEventPropagation.qml \ $$PWD/data/tst_userScripts.qml \ + $$PWD/data/tst_viewSource.qml \ $$PWD/data/tst_webchannel.qml \ $$PWD/data/tst_settings.qml \ $$PWD/data/tst_keyboardModifierMapping.qml \ 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/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp index 078e70255..904dfac26 100644 --- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp +++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp @@ -76,6 +76,8 @@ private Q_SLOTS: void stopSettingFocusWhenDisabled_data(); void inputEventForwardingDisabledWhenActiveFocusOnPressDisabled(); + void changeLocale(); + private: inline QQuickWebEngineView *newWebEngineView(); inline QQuickWebEngineView *webEngineView() const; @@ -669,5 +671,40 @@ void tst_QQuickWebEngineView::inputEventForwardingDisabledWhenActiveFocusOnPress QTRY_COMPARE_WITH_TIMEOUT(view->hasActiveFocus(), true, 1000); } +void tst_QQuickWebEngineView::changeLocale() +{ + QUrl url("http://non.existent/"); + + QLocale::setDefault(QLocale("de")); + QQuickWebEngineView *viewDE = newWebEngineView(); + QSignalSpy titleSpyHU(viewDE, SIGNAL(titleChanged())); + + viewDE->setUrl(url); + QVERIFY(waitForLoadFailed(viewDE)); + QTRY_COMPARE(titleSpyHU.size(), 2); + QCOMPARE(viewDE->title(), QStringLiteral("Nicht verf\u00FCgbar: %1").arg(url.toString())); + + QLocale::setDefault(QLocale("en")); + QQuickWebEngineView *viewEN = newWebEngineView(); + QSignalSpy titleSpyEN(viewEN, SIGNAL(titleChanged())); + + viewEN->setUrl(url); + QVERIFY(waitForLoadFailed(viewEN)); + QTRY_COMPARE(titleSpyEN.size(), 2); + QCOMPARE(viewEN->title(), QStringLiteral("%1 is not available").arg(url.toString())); + + viewDE->setUrl(QUrl("about:blank")); + QVERIFY(waitForLoadSucceeded(viewDE)); + titleSpyHU.clear(); + + viewDE->setUrl(url); + QVERIFY(waitForLoadFailed(viewDE)); + QTRY_COMPARE(titleSpyHU.size(), 2); + QCOMPARE(viewDE->title(), QStringLiteral("Nicht verf\u00FCgbar: %1").arg(url.toString())); + + delete viewDE; + delete viewEN; +} + QTEST_MAIN(tst_QQuickWebEngineView) #include "tst_qquickwebengineview.moc" diff --git a/tests/auto/widgets/qwebenginepage/BLACKLIST b/tests/auto/widgets/qwebenginepage/BLACKLIST index 2b9453b0e..b1e09777c 100644 --- a/tests/auto/widgets/qwebenginepage/BLACKLIST +++ b/tests/auto/widgets/qwebenginepage/BLACKLIST @@ -1,5 +1,8 @@ [comboBoxPopupPositionAfterMove] -linux +* + +[comboBoxPopupPositionAfterChildMove] +* [macCopyUnicodeToClipboard] osx diff --git a/tests/auto/widgets/qwebenginepage/resources/test1.html b/tests/auto/widgets/qwebenginepage/resources/test1.html index b323f966e..5c09f06ed 100644 --- a/tests/auto/widgets/qwebenginepage/resources/test1.html +++ b/tests/auto/widgets/qwebenginepage/resources/test1.html @@ -1 +1,6 @@ -<html><body><p>Some text 1</p></body></html> +<html> +<head><title>Test page 1</title></head> +<body> +Hello. +</body> +</html> diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index a8730ce0d..d5f651384 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -43,6 +43,7 @@ #include <qnetworkreply.h> #include <qnetworkrequest.h> #include <qpa/qplatforminputcontext.h> +#include <qwebenginedownloaditem.h> #include <qwebenginefullscreenrequest.h> #include <qwebenginehistory.h> #include <qwebenginepage.h> @@ -156,13 +157,13 @@ private Q_SLOTS: void inputMethods(); void inputMethodsTextFormat_data(); void inputMethodsTextFormat(); - void defaultTextEncoding(); void errorPageExtension(); void errorPageExtensionLoadFinished(); void userAgentNewlineStripping(); void undoActionHaveCustomText(); void renderWidgetHostViewNotShowTopLevel(); void getUserMediaRequest(); + void savePage(); void crashTests_LazyInitializationOfMainFrame(); @@ -183,7 +184,6 @@ private Q_SLOTS: // [Qt] tst_QWebEnginePage::infiniteLoopJS() timeouts with DFG JIT // https://bugs.webkit.org/show_bug.cgi?id=79040 // void infiniteLoopJS(); - void navigatorCookieEnabled(); void deleteQWebEngineViewTwice(); void renderOnRepaintRequestedShouldNotRecurse(); void loadSignalsOrder_data(); @@ -242,6 +242,7 @@ private Q_SLOTS: void mouseButtonTranslation(); void printToPdf(); + void viewSource(); private: static QPoint elementCenter(QWebEnginePage *page, const QString &id); @@ -416,7 +417,7 @@ 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; @@ -557,10 +558,15 @@ public: virtual QWebEnginePage* createWindow(WebWindowType) { TestPage* page = new TestPage(this); createdWindows.append(page); + emit windowCreated(); return page; } QRect requestedGeometry; + +signals: + void windowCreated(); + private Q_SLOTS: void slotGeometryChangeRequested(const QRect& geom) { requestedGeometry = geom; @@ -606,6 +612,7 @@ void tst_QWebEnginePage::acceptNavigationRequestNavigationType() void tst_QWebEnginePage::popupFormSubmission() { TestPage page; + QSignalSpy windowCreatedSpy(&page, SIGNAL(windowCreated())); page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); page.setHtml("<form name=form1 method=get action='' target=myNewWin>"\ "<input type=hidden name=foo value='bar'>"\ @@ -613,7 +620,7 @@ void tst_QWebEnginePage::popupFormSubmission() page.runJavaScript("window.open('', 'myNewWin', 'width=500,height=300,toolbar=0')"); evaluateJavaScriptSync(&page, "document.form1.submit();"); - QTest::qWait(500); + QTRY_COMPARE(windowCreatedSpy.count(), 1); // The number of popup created should be one. QVERIFY(page.createdWindows.size() == 1); @@ -2614,30 +2621,6 @@ void tst_QWebEnginePage::testEnablePersistentStorage() #endif } -void tst_QWebEnginePage::defaultTextEncoding() -{ - QString defaultCharset = evaluateJavaScriptSync(m_page, "document.defaultCharset").toString(); - QVERIFY(!defaultCharset.isEmpty()); - QCOMPARE(QWebEngineSettings::globalSettings()->defaultTextEncoding(), defaultCharset); - - m_page->settings()->setDefaultTextEncoding(QString("utf-8")); - QCoreApplication::processEvents(); - QString charset = evaluateJavaScriptSync(m_page, "document.defaultCharset").toString(); - QCOMPARE(charset, QString("utf-8")); - QCOMPARE(m_page->settings()->defaultTextEncoding(), charset); - - m_page->settings()->setDefaultTextEncoding(QString()); - QCoreApplication::processEvents(); - charset = evaluateJavaScriptSync(m_page, "document.defaultCharset").toString(); - QVERIFY(!charset.isEmpty()); - QCOMPARE(charset, defaultCharset); - - QWebEngineSettings::globalSettings()->setDefaultTextEncoding(QString("utf-8")); - QCoreApplication::processEvents(); - charset = evaluateJavaScriptSync(m_page, "document.defaultCharset").toString(); - QCOMPARE(charset, QString("utf-8")); - QCOMPARE(QWebEngineSettings::globalSettings()->defaultTextEncoding(), charset); -} #if defined(QWEBENGINEPAGE_ERRORPAGEEXTENSION) class ErrorPage : public QWebEnginePage @@ -3067,22 +3050,6 @@ void tst_QWebEnginePage::supportedContentType() #endif } - -void tst_QWebEnginePage::navigatorCookieEnabled() -{ -#if !defined(QWEBENGINEPAGE_NETWORKACCESSMANAGER) - QSKIP("QWEBENGINEPAGE_NETWORKACCESSMANAGER"); -#else - m_page->networkAccessManager()->setCookieJar(0); - QVERIFY(!m_page->networkAccessManager()->cookieJar()); - QVERIFY(!evaluateJavaScriptSync(m_page, "navigator.cookieEnabled").toBool()); - - m_page->networkAccessManager()->setCookieJar(new QNetworkCookieJar()); - QVERIFY(m_page->networkAccessManager()->cookieJar()); - QVERIFY(evaluateJavaScriptSync(m_page, "navigator.cookieEnabled").toBool()); -#endif -} - void tst_QWebEnginePage::thirdPartyCookiePolicy() { #if !defined(DUMPRENDERTREESUPPORTQT) @@ -3514,9 +3481,45 @@ void tst_QWebEnginePage::getUserMediaRequest() delete page; } +void tst_QWebEnginePage::savePage() +{ + QWebEngineView view; + QWebEnginePage *page = view.page(); + + connect(page->profile(), &QWebEngineProfile::downloadRequested, + [] (QWebEngineDownloadItem *item) + { + connect(item, &QWebEngineDownloadItem::finished, + &QTestEventLoop::instance(), &QTestEventLoop::exitLoop, Qt::QueuedConnection); + }); + + const QString urlPrefix = QStringLiteral("data:text/html,<h1>"); + const QString text = QStringLiteral("There is Thingumbob shouting!"); + page->load(QUrl(urlPrefix + text)); + waitForSignal(page, SIGNAL(loadFinished(bool))); + QCOMPARE(toPlainTextSync(page), text); + + // Save the loaded page as HTML. + QTemporaryDir tempDir(QDir::tempPath() + "/tst_qwebengineview-XXXXXX"); + const QString filePath = tempDir.path() + "/thingumbob.html"; + page->save(filePath, QWebEngineDownloadItem::CompleteHtmlSaveFormat); + QTestEventLoop::instance().enterLoop(10); + + // Load something else. + page->load(QUrl(urlPrefix + QLatin1String("It's a Snark!"))); + waitForSignal(page, SIGNAL(loadFinished(bool))); + QVERIFY(toPlainTextSync(page) != text); + + // Load the saved page and compare the contents. + page->load(QUrl::fromLocalFile(filePath)); + waitForSignal(page, SIGNAL(loadFinished(bool))); + QCOMPARE(toPlainTextSync(page), text); +} + void tst_QWebEnginePage::openWindowDefaultSize() { TestPage page; + QSignalSpy windowCreatedSpy(&page, SIGNAL(windowCreated())); QWebEngineView view; page.setView(&view); view.show(); @@ -3524,11 +3527,11 @@ void tst_QWebEnginePage::openWindowDefaultSize() page.settings()->setAttribute(QWebEngineSettings::JavascriptCanOpenWindows, true); // Open a default window. page.runJavaScript("window.open()"); - QTest::qWait(200); + QTRY_COMPARE(windowCreatedSpy.count(), 1); // Open a too small window. evaluateJavaScriptSync(&page, "window.open('','about:blank','width=10,height=10')"); + QTRY_COMPARE(windowCreatedSpy.count(), 2); - QTest::qWait(200); // The number of popups created should be two. QCOMPARE(page.createdWindows.size(), 2); @@ -3770,7 +3773,7 @@ void tst_QWebEnginePage::fullScreenRequested() if (acceptRequest) request.accept(); else request.reject(); }); - QTest::keyPress(qApp->focusWindow(), Qt::Key_Space); + QTest::keyPress(view->focusProxy(), Qt::Key_Space); QTRY_VERIFY(evaluateJavaScriptSync(page, "document.webkitIsFullScreen").toBool()); page->runJavaScript("document.webkitExitFullscreen()", JavaScriptCallbackUndefined()); QVERIFY(watcher.wait()); @@ -3778,7 +3781,7 @@ void tst_QWebEnginePage::fullScreenRequested() acceptRequest = false; page->runJavaScript("document.webkitFullscreenEnabled", JavaScriptCallback(true)); - QTest::keyPress(qApp->focusWindow(), Qt::Key_Space); + QTest::keyPress(view->focusProxy(), Qt::Key_Space); QVERIFY(watcher.wait()); page->runJavaScript("document.webkitIsFullScreen", JavaScriptCallback(false)); QVERIFY(watcher.wait()); @@ -4341,23 +4344,39 @@ void tst_QWebEnginePage::horizontalScrollAfterBack() #endif } +class WebView : public QWebEngineView +{ + Q_OBJECT +signals: + void repaintRequested(); + +protected: + bool event(QEvent *event) { + if (event->type() == QEvent::UpdateRequest) + emit repaintRequested(); + + return QWebEngineView::event(event); + } +}; + void tst_QWebEnginePage::evaluateWillCauseRepaint() { -#if !defined(QWEBENGINEPAGE_EVALUATEJAVASCRIPT) - QSKIP("QWEBENGINEPAGE_EVALUATEJAVASCRIPT"); -#else - QWebEngineView view; - QString html("<html><body>top<div id=\"junk\" style=\"display: block;\">" - "junk</div>bottom</body></html>"); - view.setHtml(html); + WebView view; view.show(); - QTest::qWaitForWindowExposed(&view); - view.page()->evaluateJavaScript( - "document.getElementById('junk').style.display = 'none';"); - ::waitForSignal(view.page(), SIGNAL(repaintRequested(QRect))); -#endif + QString html("<html><body>" + " top" + " <div id=\"junk\" style=\"display: block;\">junk</div>" + " bottom" + "</body></html>"); + + QSignalSpy loadSpy(&view, SIGNAL(loadFinished(bool))); + view.setHtml(html); + QTRY_COMPARE(loadSpy.count(), 1); + + evaluateJavaScriptSync(view.page(), "document.getElementById('junk').style.display = 'none';"); + ::waitForSignal(&view, SIGNAL(repaintRequested())); } void tst_QWebEnginePage::setContent_data() @@ -5006,5 +5025,26 @@ QPoint tst_QWebEnginePage::elementCenter(QWebEnginePage *page, const QString &id return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt()); } +void tst_QWebEnginePage::viewSource() +{ + TestPage page; + QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool))); + QSignalSpy windowCreatedSpy(&page, SIGNAL(windowCreated())); + const QUrl url("qrc:/resources/test1.html"); + + page.load(url); + QTRY_COMPARE(loadFinishedSpy.count(), 1); + QCOMPARE(page.title(), QStringLiteral("Test page 1")); + QVERIFY(page.canViewSource()); + + page.viewSource(); + QTRY_COMPARE(windowCreatedSpy.count(), 1); + QCOMPARE(page.createdWindows.size(), 1); + + QTRY_COMPARE(page.createdWindows[0]->url().toString(), QStringLiteral("view-source:%1").arg(url.toString())); + QTRY_COMPARE(page.createdWindows[0]->title(), QStringLiteral("view-source:%1").arg(url.toString())); + QVERIFY(!page.createdWindows[0]->canViewSource()); +} + QTEST_MAIN(tst_QWebEnginePage) #include "tst_qwebenginepage.moc" diff --git a/tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp b/tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp index 2dfe3305d..7714f4161 100644 --- a/tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp +++ b/tests/auto/widgets/qwebenginespellcheck/tst_qwebenginespellcheck.cpp @@ -37,12 +37,13 @@ class WebView : public QWebEngineView { Q_OBJECT public: - void activateMenu(const QPoint &position) + void activateMenu(QWidget *widget, const QPoint &position) { - QTest::mouseMove(focusWidget(), position); - QTest::mousePress(focusWidget(), Qt::RightButton, 0, position); + QTest::mouseMove(widget, position); + QTest::mousePress(widget, Qt::RightButton, 0, position); QContextMenuEvent evcont(QContextMenuEvent::Mouse, position, mapToGlobal(position)); event(&evcont); + QTest::mouseRelease(widget, Qt::RightButton, 0, position); } const QWebEngineContextMenuData& data() @@ -142,6 +143,7 @@ void tst_QWebEngineSpellcheck::spellcheck() //type text, spellchecker needs time QTest::mouseMove(m_view->focusWidget(), QPoint(20,20)); QTest::mousePress(m_view->focusWidget(), Qt::LeftButton, 0, QPoint(20,20)); + QTest::mouseRelease(m_view->focusWidget(), Qt::LeftButton, 0, QPoint(20,20)); QString text("I lovee Qt ...."); for (int i = 0; i < text.length(); i++) { QTest::keyClicks(m_view->focusWidget(), text.at(i)); @@ -153,7 +155,7 @@ void tst_QWebEngineSpellcheck::spellcheck() QVERIFY(result == text); // open menu on misspelled word - m_view->activateMenu(rect.center()); + m_view->activateMenu(m_view->focusWidget(), rect.center()); waitForSignal(m_view, SIGNAL(menuReady())); // check if menu is valid diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index afb53ba20..ac142bb38 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -31,6 +31,8 @@ #include <qdiriterator.h> #include <qstackedlayout.h> #include <qtemporarydir.h> +#include <QLineEdit> +#include <QHBoxLayout> #define VERIFY_INPUTMETHOD_HINTS(actual, expect) \ QVERIFY(actual == expect); @@ -74,6 +76,10 @@ private Q_SLOTS: void doNotSendMouseKeyboardEventsWhenDisabled_data(); void stopSettingFocusWhenDisabled(); void stopSettingFocusWhenDisabled_data(); + void focusOnNavigation_data(); + void focusOnNavigation(); + + void changeLocale(); }; // This will be called before the first test function is executed. @@ -357,23 +363,21 @@ void tst_QWebEngineView::unhandledKeyEventPropagation() evaluateJavaScriptSync(webView.page(), "document.body.firstChild.focus()"); - QTest::sendKeyEvent(QTest::Press, parentWidget.windowHandle(), Qt::Key_A, 'a', Qt::NoModifier); - QTest::sendKeyEvent(QTest::Release, parentWidget.windowHandle(), Qt::Key_A, 'a', Qt::NoModifier); - QTest::sendKeyEvent(QTest::Press, parentWidget.windowHandle(), Qt::Key_Left, QString(), Qt::NoModifier); - QTest::sendKeyEvent(QTest::Release, parentWidget.windowHandle(), Qt::Key_Left, QString(), Qt::NoModifier); - QTest::sendKeyEvent(QTest::Press, parentWidget.windowHandle(), Qt::Key_Left, QString(), Qt::NoModifier); - QTest::sendKeyEvent(QTest::Release, parentWidget.windowHandle(), Qt::Key_Left, QString(), Qt::NoModifier); + QTest::sendKeyEvent(QTest::Press, webView.focusProxy(), Qt::Key_A, 'a', Qt::NoModifier); + QTest::sendKeyEvent(QTest::Release, webView.focusProxy(), Qt::Key_A, 'a', Qt::NoModifier); + QTest::sendKeyEvent(QTest::Press, webView.focusProxy(), Qt::Key_Left, QString(), Qt::NoModifier); + QTest::sendKeyEvent(QTest::Release, webView.focusProxy(), Qt::Key_Left, QString(), Qt::NoModifier); + QTest::sendKeyEvent(QTest::Press, webView.focusProxy(), Qt::Key_Left, QString(), Qt::NoModifier); + QTest::sendKeyEvent(QTest::Release, webView.focusProxy(), Qt::Key_Left, QString(), Qt::NoModifier); // All this happens asychronously, wait for the last release event to know when we're done. - for (int i = 0; i < 20 && parentWidget.releaseEvents.size() < 3; ++i) - QTest::qWait(100); + QTRY_COMPARE(parentWidget.releaseEvents.size(), 3); // The page will consume the 'a' and the first left key presses, the second left won't be // used since the cursor will already be at the left end of the text input. // Key releases will all come back unconsumed. QCOMPARE(parentWidget.pressEvents.size(), 1); QCOMPARE(parentWidget.pressEvents[0].key(), (int)Qt::Key_Left); - QCOMPARE(parentWidget.releaseEvents.size(), 3); QCOMPARE(parentWidget.releaseEvents[0].key(), (int)Qt::Key_A); QCOMPARE(parentWidget.releaseEvents[1].key(), (int)Qt::Key_Left); QCOMPARE(parentWidget.releaseEvents[2].key(), (int)Qt::Key_Left); @@ -743,5 +747,117 @@ void tst_QWebEngineView::stopSettingFocusWhenDisabled_data() QTest::newRow("disabled view does not get focus") << false << false; } +void tst_QWebEngineView::focusOnNavigation_data() +{ + QTest::addColumn<bool>("focusOnNavigation"); + QTest::addColumn<bool>("viewReceivedFocus"); + QTest::newRow("focusOnNavigation true") << true << true; + QTest::newRow("focusOnNavigation false") << false << false; +} + +void tst_QWebEngineView::focusOnNavigation() +{ + QFETCH(bool, focusOnNavigation); + QFETCH(bool, viewReceivedFocus); + +#define triggerJavascriptFocus()\ + evaluateJavaScriptSync(webView->page(), "document.getElementById(\"input\").focus()"); +#define loadAndTriggerFocusAndCompare()\ + QTRY_COMPARE(loadSpy.count(), 1);\ + triggerJavascriptFocus();\ + QTRY_COMPARE(webView->hasFocus(), viewReceivedFocus); + + // Create a container widget, that will hold a line edit that has initial focus, and a web + // engine view. + QScopedPointer<QWidget> containerWidget(new QWidget); + QLineEdit *label = new QLineEdit; + label->setText(QString::fromLatin1("Text")); + label->setFocus(); + + // Create the web view, and set its focusOnNavigation property. + QWebEngineView *webView = new QWebEngineView; + QWebEngineSettings *settings = webView->page()->settings(); + settings->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, focusOnNavigation); + webView->resize(300, 300); + + QHBoxLayout *layout = new QHBoxLayout; + layout->addWidget(label); + layout->addWidget(webView); + + containerWidget->setLayout(layout); + containerWidget->show(); + QTest::qWaitForWindowExposed(containerWidget.data()); + + // Load the content, invoke javascript focus on the view, and check which widget has focus. + QSignalSpy loadSpy(webView, SIGNAL(loadFinished(bool))); + webView->setHtml("<html><head><title>Title</title></head><body>Hello" + "<input id=\"input\" type=\"text\"></body></html>"); + loadAndTriggerFocusAndCompare(); + + // Load a different page, and check focus. + loadSpy.clear(); + webView->setHtml("<html><head><title>Title</title></head><body>Hello 2" + "<input id=\"input\" type=\"text\"></body></html>"); + loadAndTriggerFocusAndCompare(); + + // Navigate to previous page in history, check focus. + loadSpy.clear(); + webView->triggerPageAction(QWebEnginePage::Back); + loadAndTriggerFocusAndCompare(); + + // Navigate to next page in history, check focus. + loadSpy.clear(); + webView->triggerPageAction(QWebEnginePage::Forward); + loadAndTriggerFocusAndCompare(); + + // Reload page, check focus. + loadSpy.clear(); + webView->triggerPageAction(QWebEnginePage::Reload); + loadAndTriggerFocusAndCompare(); + + // Reload page bypassing cache, check focus. + loadSpy.clear(); + webView->triggerPageAction(QWebEnginePage::ReloadAndBypassCache); + loadAndTriggerFocusAndCompare(); + + // Manually forcing focus on web view should work. + webView->setFocus(); + QTRY_COMPARE(webView->hasFocus(), true); + + // Clean up. +#undef loadAndTriggerFocusAndCompare +#undef triggerJavascriptFocus +} + +void tst_QWebEngineView::changeLocale() +{ + QUrl url("http://non.existent/"); + + QLocale::setDefault(QLocale("de")); + QWebEngineView viewDE; + viewDE.setUrl(url); + + QVERIFY(waitForSignal(&viewDE, SIGNAL(titleChanged(QString)))); + QVERIFY(waitForSignal(&viewDE, SIGNAL(loadFinished(bool)))); + QCOMPARE(viewDE.title(), QStringLiteral("Nicht verf\u00FCgbar: %1").arg(url.toString())); + + QLocale::setDefault(QLocale("en")); + QWebEngineView viewEN; + viewEN.setUrl(url); + + QVERIFY(waitForSignal(&viewEN, SIGNAL(titleChanged(QString)))); + QVERIFY(waitForSignal(&viewEN, SIGNAL(loadFinished(bool)))); + QCOMPARE(viewEN.title(), QStringLiteral("%1 is not available").arg(url.toString())); + + viewDE.setUrl(QUrl("about:blank")); + QVERIFY(waitForSignal(&viewDE, SIGNAL(loadFinished(bool)))); + + viewDE.setUrl(url); + + QVERIFY(waitForSignal(&viewDE, SIGNAL(titleChanged(QString)))); + QVERIFY(waitForSignal(&viewDE, SIGNAL(loadFinished(bool)))); + QCOMPARE(viewDE.title(), QStringLiteral("Nicht verf\u00FCgbar: %1").arg(url.toString())); +} + QTEST_MAIN(tst_QWebEngineView) #include "tst_qwebengineview.moc" |