diff options
Diffstat (limited to 'tests')
18 files changed, 315 insertions, 55 deletions
diff --git a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp index f762e9b5c..e45b4466c 100644 --- a/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp +++ b/tests/auto/quick/inspectorserver/tst_inspectorserver.cpp @@ -32,6 +32,7 @@ #include <QScopedPointer> #include <QtQml/QQmlEngine> #include <QtTest/QtTest> +#include <QQuickWebEngineProfile> #include <private/qquickwebengineview_p.h> #define INSPECTOR_SERVER_PORT "23654" @@ -62,6 +63,7 @@ tst_InspectorServer::tst_InspectorServer() { qputenv("QTWEBENGINE_REMOTE_DEBUGGING", INSPECTOR_SERVER_PORT); QtWebEngine::initialize(); + QQuickWebEngineProfile::defaultProfile()->setOffTheRecord(true); prepareWebViewComponent(); } diff --git a/tests/auto/quick/publicapi/tst_publicapi.cpp b/tests/auto/quick/publicapi/tst_publicapi.cpp index f9fd854cc..5cc0d18df 100644 --- a/tests/auto/quick/publicapi/tst_publicapi.cpp +++ b/tests/auto/quick/publicapi/tst_publicapi.cpp @@ -34,6 +34,7 @@ #include <QQmlListProperty> #include <QtTest/QtTest> #include <QtWebEngine/QQuickWebEngineProfile> +#include <QtWebEngine/QQuickWebEngineScript> #include <private/qquickwebengineview_p.h> #include <private/qquickwebenginecertificateerror_p.h> #include <private/qquickwebenginedialogrequests_p.h> @@ -42,7 +43,6 @@ #include <private/qquickwebengineloadrequest_p.h> #include <private/qquickwebenginenavigationrequest_p.h> #include <private/qquickwebenginenewviewrequest_p.h> -#include <private/qquickwebenginescript_p.h> #include <private/qquickwebenginesettings_p.h> #include <private/qquickwebenginesingleton_p.h> #include <private/qquickwebenginecontextmenurequest_p.h> diff --git a/tests/auto/quick/qmltests/BLACKLIST b/tests/auto/quick/qmltests/BLACKLIST index dd8258ba4..5788ce25b 100644 --- a/tests/auto/quick/qmltests/BLACKLIST +++ b/tests/auto/quick/qmltests/BLACKLIST @@ -10,3 +10,11 @@ linux [DesktopWebEngineViewLinkHovered::test_linkHoveredDoesntEmitRepeated] linux +[WebEngineViewSingleFileUpload::test_acceptDirectory] +* + +[WebEngineViewSingleFileUpload::test_acceptMultipleFilesSelection] +* + +[WebEngineViewSingleFileUpload::test_acceptSingleFileSelection] +* diff --git a/tests/auto/quick/qmltests/data/TestWebEngineView.qml b/tests/auto/quick/qmltests/data/TestWebEngineView.qml index aa1f77942..a7d890072 100644 --- a/tests/auto/quick/qmltests/data/TestWebEngineView.qml +++ b/tests/auto/quick/qmltests/data/TestWebEngineView.qml @@ -53,7 +53,7 @@ WebEngineView { return _waitFor(function() { return windowCloseRequestedSignalEmitted; }); } function _waitFor(predicate) { - var timeout = 5000 + var timeout = 12000 var i = 0 while (i < timeout && !predicate()) { testResult.wait(50) diff --git a/tests/auto/quick/qmltests/data/tst_filePicker.qml b/tests/auto/quick/qmltests/data/tst_filePicker.qml index 4e74af733..655789bb3 100644 --- a/tests/auto/quick/qmltests/data/tst_filePicker.qml +++ b/tests/auto/quick/qmltests/data/tst_filePicker.qml @@ -41,6 +41,11 @@ TestWebEngineView { target: webEngineView signalName: "titleChanged" } + SignalSpy { + id: terminationSpy + target: webEngineView + signalName: "renderProcessTerminated" + } TestCase { name: "WebEngineViewSingleFileUpload" @@ -51,11 +56,16 @@ TestWebEngineView { FilePickerParams.selectFiles = false FilePickerParams.selectedFilesUrl = [] titleSpy.clear() + terminationSpy.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() { + // Test that the render process doesn't crash, and make sure if it does it does so now. + wait(1000) + verify(terminationSpy.count == 0, "Render process didn't self terminate") + + // 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. webEngineView.url = Qt.resolvedUrl("about:blank") webEngineView.waitForLoadSucceeded() } diff --git a/tests/auto/quick/qmltests/data/tst_loadFail.qml b/tests/auto/quick/qmltests/data/tst_loadFail.qml index 9ce70fc96..47f4a2862 100644 --- a/tests/auto/quick/qmltests/data/tst_loadFail.qml +++ b/tests/auto/quick/qmltests/data/tst_loadFail.qml @@ -139,7 +139,7 @@ TestWebEngineView { verify(loadRequest.isErrorPage) compare(webEngineView.url, unavailableUrl) - compare(webEngineView.title, unavailableUrl + " failed to load") + compare(webEngineView.title, unavailableUrl) } } } diff --git a/tests/auto/quick/qmltests/data/tst_loadUrl.qml b/tests/auto/quick/qmltests/data/tst_loadUrl.qml index 2a43e1577..2cb9f6b81 100644 --- a/tests/auto/quick/qmltests/data/tst_loadUrl.qml +++ b/tests/auto/quick/qmltests/data/tst_loadUrl.qml @@ -126,7 +126,7 @@ TestWebEngineView { // Test failed load var bogusSite = "http://www.somesitethatdoesnotexist.abc/"; webEngineView.url = bogusSite; - tryCompare(loadRequestArray, "length", 2); + tryCompare(loadRequestArray, "length", 2, 12000); loadRequest = loadRequestArray[0]; compare(loadRequest.status, WebEngineView.LoadStartedStatus); @@ -217,7 +217,7 @@ TestWebEngineView { } webEngineView.loadingChanged.connect(handleLoadFailed); webEngineView.url = bogusSite - tryCompare(loadRequestArray, "length", 4); + tryCompare(loadRequestArray, "length", 4, 12000); webEngineView.loadingChanged.disconnect(handleLoadFailed); loadRequest = loadRequestArray[0]; diff --git a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml index 906dc1658..69aa76b77 100644 --- a/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml +++ b/tests/auto/quick/qmltests/data/tst_unhandledKeyEventPropagation.qml @@ -57,24 +57,40 @@ Item { } function test_keyboardModifierMapping() { - webEngineView.loadHtml("<input type='text'/>") - webEngineView.waitForLoadSucceeded() - webEngineView.runJavaScript("document.body.firstChild.focus()") + webEngineView.url = Qt.resolvedUrl("keyboardEvents.html"); + verify(webEngineView.waitForLoadSucceeded()); - keyPress(Qt.Key_A) - keyRelease(Qt.Key_A) - keyPress(Qt.Key_Left) - keyRelease(Qt.Key_Left) - keyPress(Qt.Key_Left) - keyRelease(Qt.Key_Left) + webEngineView.runJavaScript("document.getElementById('first_div').focus()"); + webEngineView.verifyElementHasFocus("first_div"); - tryCompare(parentItem.pressEvents, "length", 1) - compare(parentItem.pressEvents[0], Qt.Key_Left) + keyPress(Qt.Key_Right); + keyRelease(Qt.Key_Right); + // Right arrow key is unhandled thus focus is not changed + tryCompare(parentItem.releaseEvents, "length", 1); + webEngineView.verifyElementHasFocus("first_div"); - tryCompare(parentItem.releaseEvents, "length", 3) - compare(parentItem.releaseEvents[0], Qt.Key_A) - compare(parentItem.releaseEvents[1], Qt.Key_Left) - compare(parentItem.releaseEvents[2], Qt.Key_Left) + keyPress(Qt.Key_Tab); + keyRelease(Qt.Key_Tab); + // Tab key is handled thus focus is changed + tryCompare(parentItem.releaseEvents, "length", 2); + webEngineView.verifyElementHasFocus("second_div"); + + keyPress(Qt.Key_Left); + keyRelease(Qt.Key_Left); + // Left arrow key is unhandled thus focus is not changed + tryCompare(parentItem.releaseEvents, "length", 3); + webEngineView.verifyElementHasFocus("second_div"); + + // The page will consume the Tab key to change focus between elements while the arrow + // keys won't be used. + compare(parentItem.pressEvents.length, 2); + compare(parentItem.pressEvents[0], Qt.Key_Right); + compare(parentItem.pressEvents[1], Qt.Key_Left); + + // Key releases will all come back unconsumed. + compare(parentItem.releaseEvents[0], Qt.Key_Right); + compare(parentItem.releaseEvents[1], Qt.Key_Tab); + compare(parentItem.releaseEvents[2], Qt.Key_Left); } } } diff --git a/tests/auto/quick/qmltests/data/tst_userScripts.qml b/tests/auto/quick/qmltests/data/tst_userScripts.qml index 88fa6f6e3..e9a4eba99 100644 --- a/tests/auto/quick/qmltests/data/tst_userScripts.qml +++ b/tests/auto/quick/qmltests/data/tst_userScripts.qml @@ -61,6 +61,12 @@ Item { } TestWebEngineView { + id: webEngineView2 + width: 400 + height: 300 + } + + TestWebEngineView { id: webEngineViewWithConditionalUserScripts width: 400 height: 300 @@ -82,6 +88,7 @@ Item { function init() { webEngineView.url = ""; webEngineView.userScripts = []; + webEngineView.profile.userScripts = []; } function test_oneScript() { @@ -173,5 +180,17 @@ Item { webEngineView.waitForLoadSucceeded(); tryCompare(webEngineView, "title", "Test page with huge link area"); } + + function test_profileWideScript() { + webEngineView.profile.userScripts = [ changeDocumentTitleScript ]; + + webEngineView.url = Qt.resolvedUrl("test1.html"); + webEngineView.waitForLoadSucceeded(); + compare(webEngineView.title, "New title"); + + webEngineView2.url = Qt.resolvedUrl("test1.html"); + webEngineView2.waitForLoadSucceeded(); + compare(webEngineView2.title, "New title"); + } } } diff --git a/tests/auto/quick/qmltests/data/tst_viewSource.qml b/tests/auto/quick/qmltests/data/tst_viewSource.qml index 8076d99f8..22c3947d3 100644 --- a/tests/auto/quick/qmltests/data/tst_viewSource.qml +++ b/tests/auto/quick/qmltests/data/tst_viewSource.qml @@ -103,8 +103,8 @@ TestWebEngineView { { tag: "view-source:about:blank", userInputUrl: "view-source:about:blank", loadSucceed: true, url: "view-source:about:blank", title: "view-source:about:blank" }, { tag: testLocalUrl, userInputUrl: testLocalUrl, loadSucceed: true, url: testLocalUrl, title: "test1.html" }, { tag: testLocalUrlWithoutScheme, userInputUrl: testLocalUrlWithoutScheme, loadSucceed: true, url: testLocalUrl, title: "test1.html" }, - { tag: "view-source:http://non.existent", userInputUrl: "view-source:http://non.existent", loadSucceed: false, url: "view-source:http://non.existent/", title: "http://non.existent/ is not available" }, - { tag: "view-source:non.existent", userInputUrl: "view-source:non.existent", loadSucceed: false, url: "view-source:http://non.existent/", title: "http://non.existent/ is not available" }, + { tag: "view-source:http://non.existent", userInputUrl: "view-source:http://non.existent", loadSucceed: false, url: "view-source:http://non.existent/", title: "non.existent" }, + { tag: "view-source:non.existent", userInputUrl: "view-source:non.existent", loadSucceed: false, url: "view-source:http://non.existent/", title: "non.existent" }, ]; } diff --git a/tests/auto/quick/qmltests/tst_qmltests.cpp b/tests/auto/quick/qmltests/tst_qmltests.cpp index 6b5c4d00b..baffdbb57 100644 --- a/tests/auto/quick/qmltests/tst_qmltests.cpp +++ b/tests/auto/quick/qmltests/tst_qmltests.cpp @@ -28,6 +28,7 @@ #include <QtCore/QScopedPointer> #include <QtQuickTest/quicktest.h> +#include <QtWebEngine/QQuickWebEngineProfile> #include "qt_webengine_quicktest.h" int main(int argc, char **argv) @@ -42,6 +43,11 @@ int main(int argc, char **argv) if (!QCoreApplication::instance()) app.reset(new Application(argc, argv)); QtWebEngine::initialize(); + QQuickWebEngineProfile::defaultProfile()->setOffTheRecord(true); + + QTEST_ADD_GPU_BLACKLIST_SUPPORT_DEFS + QTEST_SET_MAIN_SOURCE_PATH + int i = quick_test_main(argc, argv, "qmltests", QUICK_TEST_SOURCE_DIR); return i; } diff --git a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp index 9f2060898..3d44efa6a 100644 --- a/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp +++ b/tests/auto/quick/qquickwebenginedefaultsurfaceformat/tst_qquickwebenginedefaultsurfaceformat.cpp @@ -44,6 +44,7 @@ #include <QtTest/QtTest> #include <QTimer> #include <private/qquickwebengineview_p.h> +#include <QQuickWebEngineProfile> class tst_QQuickWebEngineDefaultSurfaceFormat : public QObject { @@ -68,6 +69,7 @@ private: void tst_QQuickWebEngineDefaultSurfaceFormat::initEngineAndViewComponent() { m_engine = new QQmlEngine(this); + QQuickWebEngineProfile::defaultProfile()->setOffTheRecord(true); m_component.reset(new QQmlComponent(m_engine, this)); m_component->setData(QByteArrayLiteral("import QtQuick 2.0\n" "import QtWebEngine 1.2\n" diff --git a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro index 36e74a2a8..df9b3e1b7 100644 --- a/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro +++ b/tests/auto/quick/qquickwebengineview/qquickwebengineview.pro @@ -4,3 +4,8 @@ exists($${TARGET}.qrc):RESOURCES += $${TARGET}.qrc QT_PRIVATE += webengine-private gui-private HEADERS += ../shared/util.h + +use?(pdf) { + DEFINES += ENABLE_PDF +} + diff --git a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp index 2a43c9c1c..010e1c457 100644 --- a/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp +++ b/tests/auto/quick/qquickwebengineview/tst_qquickwebengineview.cpp @@ -34,6 +34,7 @@ #include <QtGui/qpa/qwindowsysteminterface.h> #include <QtQml/QQmlEngine> #include <QtTest/QtTest> +#include <QtWebEngine/QQuickWebEngineProfile> #include <private/qquickwebengineview_p.h> #include <functional> @@ -77,6 +78,7 @@ private Q_SLOTS: void inputEventForwardingDisabledWhenActiveFocusOnPressDisabled(); void changeLocale(); + void userScripts(); private: inline QQuickWebEngineView *newWebEngineView(); @@ -91,6 +93,7 @@ private: tst_QQuickWebEngineView::tst_QQuickWebEngineView() { QtWebEngine::initialize(); + QQuickWebEngineProfile::defaultProfile()->setOffTheRecord(true); m_testSourceDirPath = QString::fromLocal8Bit(TESTS_SOURCE_DIR); if (!m_testSourceDirPath.endsWith(QLatin1Char('/'))) @@ -499,15 +502,22 @@ void tst_QQuickWebEngineView::setZoomFactor() void tst_QQuickWebEngineView::printToPdf() { +#if !defined(ENABLE_PDF) + QSKIP("ENABLE_PDF"); +#else QTemporaryDir tempDir(QDir::tempPath() + "/tst_qwebengineview-XXXXXX"); QVERIFY(tempDir.isValid()); QQuickWebEngineView *view = webEngineView(); view->setUrl(urlFromTestPath("html/basic_page.html")); QVERIFY(waitForLoadSucceeded(view)); + QSignalSpy savePdfSpy(view, SIGNAL(pdfPrintingFinished(const QString&, bool))); QString path = tempDir.path() + "/print_success.pdf"; view->printToPdf(path, QQuickWebEngineView::A4, QQuickWebEngineView::Portrait); - QTRY_VERIFY(QFile::exists(path)); + QTRY_VERIFY2(savePdfSpy.count() == 1, "Printing to PDF file failed without signal"); + QList<QVariant> successArguments = savePdfSpy.takeFirst(); + QVERIFY2(successArguments.at(0).toString() == path, "File path for first saved PDF does not match arguments"); + QVERIFY2(successArguments.at(1).toBool() == true, "Printing to PDF file failed though it should succeed"); #if !defined(Q_OS_WIN) path = tempDir.path() + "/print_//fail.pdf"; @@ -515,7 +525,11 @@ void tst_QQuickWebEngineView::printToPdf() path = tempDir.path() + "/print_|fail.pdf"; #endif // #if !defined(Q_OS_WIN) view->printToPdf(path, QQuickWebEngineView::A4, QQuickWebEngineView::Portrait); - QTRY_VERIFY(!QFile::exists(path)); + QTRY_VERIFY2(savePdfSpy.count() == 1, "Printing to PDF file failed without signal"); + QList<QVariant> failedArguments = savePdfSpy.takeFirst(); + QVERIFY2(failedArguments.at(0).toString() == path, "File path for second saved PDF does not match arguments"); + QVERIFY2(failedArguments.at(1).toBool() == false, "Printing to PDF file succeeded though it should fail"); +#endif // !defined(ENABLE_PDF) } void tst_QQuickWebEngineView::stopSettingFocusWhenDisabled() @@ -671,6 +685,7 @@ void tst_QQuickWebEngineView::inputEventForwardingDisabledWhenActiveFocusOnPress void tst_QQuickWebEngineView::changeLocale() { + QSKIP("Error pages no longer have useful titles in Chromium 55"); QUrl url("http://non.existent/"); QLocale::setDefault(QLocale("de")); @@ -704,5 +719,28 @@ void tst_QQuickWebEngineView::changeLocale() delete viewEN; } +void tst_QQuickWebEngineView::userScripts() +{ + QScopedPointer<QQuickWebEngineView> webEngineView1(newWebEngineView()); + webEngineView1->setParentItem(m_window->contentItem()); + QScopedPointer<QQuickWebEngineView> webEngineView2(newWebEngineView()); + webEngineView2->setParentItem(m_window->contentItem()); + + QQmlListReference list(webEngineView1->profile(), "userScripts"); + QQuickWebEngineScript script; + script.setSourceCode("document.title = 'New title';"); + list.append(&script); + + webEngineView1->setUrl(urlFromTestPath("html/basic_page.html")); + QVERIFY(waitForLoadSucceeded(webEngineView1.data())); + QTRY_COMPARE(webEngineView1->title(), QStringLiteral("New title")); + + webEngineView2->setUrl(urlFromTestPath("html/basic_page.html")); + QVERIFY(waitForLoadSucceeded(webEngineView2.data())); + QTRY_COMPARE(webEngineView2->title(), QStringLiteral("New title")); + + list.clear(); +} + QTEST_MAIN(tst_QQuickWebEngineView) #include "tst_qquickwebengineview.moc" diff --git a/tests/auto/quick/shared/util.h b/tests/auto/quick/shared/util.h index 674c2da34..98a7c1007 100644 --- a/tests/auto/quick/shared/util.h +++ b/tests/auto/quick/shared/util.h @@ -98,7 +98,7 @@ inline bool waitForLoadSucceeded(QQuickWebEngineView *webEngineView, int timeout return spy.wait(timeout); } -inline bool waitForLoadFailed(QQuickWebEngineView *webEngineView, int timeout = 10000) +inline bool waitForLoadFailed(QQuickWebEngineView *webEngineView, int timeout = 20000) { LoadSpy loadSpy(webEngineView); QSignalSpy spy(&loadSpy, &LoadSpy::loadFailed); diff --git a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro index 6446cdd7a..e0765736e 100644 --- a/tests/auto/widgets/qwebenginepage/qwebenginepage.pro +++ b/tests/auto/widgets/qwebenginepage/qwebenginepage.pro @@ -1,4 +1,4 @@ include(../tests.pri) QT *= core-private -contains(WEBENGINE_CONFIG, enable_pdf): DEFINES+=QWEBENGINEPAGE_PDFPRINTINGENABLED +contains(WEBENGINE_CONFIG, use_pdf): DEFINES+=QWEBENGINEPAGE_PDFPRINTINGENABLED diff --git a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp index cde09f5c6..cf409654c 100644 --- a/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp +++ b/tests/auto/widgets/qwebenginepage/tst_qwebenginepage.cpp @@ -3713,8 +3713,7 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures() const QUrl first("http://abcdef.abcdef/"); page.setUrl(first); - QVERIFY(spy.wait()); - QCOMPARE(spy.count(), 1); + QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 12000); QCOMPARE(page.url(), first); QCOMPARE(page.requestedUrl(), first); QVERIFY(!spy.at(0).first().toBool()); @@ -3723,8 +3722,7 @@ void tst_QWebEnginePage::requestedUrlAfterSetAndLoadFailures() QVERIFY(first != second); page.load(second); - QVERIFY(spy.wait()); - QCOMPARE(spy.count(), 2); + QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 12000); QCOMPARE(page.url(), first); QCOMPARE(page.requestedUrl(), second); QVERIFY(!spy.at(1).first().toBool()); @@ -4494,11 +4492,11 @@ void tst_QWebEnginePage::loadFinishedAfterNotFoundError() page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, false); page.setUrl(QUrl("http://non.existent/url")); - QTRY_COMPARE(spy.count(), 1); + QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 1, 12000); page.settings()->setAttribute(QWebEngineSettings::ErrorPageEnabled, true); page.setUrl(QUrl("http://another.non.existent/url")); - QTRY_COMPARE(spy.count(), 2); + QTRY_COMPARE_WITH_TIMEOUT(spy.count(), 2, 12000); } class URLSetter : public QObject { @@ -4690,10 +4688,15 @@ void tst_QWebEnginePage::printToPdf() page.load(QUrl("qrc:///resources/basic_printing_page.html")); QTRY_VERIFY(spy.count() == 1); + QSignalSpy savePdfSpy(&page, SIGNAL(pdfPrintingFinished(const QString&, bool))); QPageLayout layout(QPageSize(QPageSize::A4), QPageLayout::Portrait, QMarginsF(0.0, 0.0, 0.0, 0.0)); QString path = tempDir.path() + "/print_1_success.pdf"; page.printToPdf(path, layout); - QTRY_VERIFY(QFile::exists(path)); + QTRY_VERIFY2(savePdfSpy.count() == 1, "Printing to PDF file failed without signal"); + + QList<QVariant> successArguments = savePdfSpy.takeFirst(); + QVERIFY2(successArguments.at(0).toString() == path, "File path for first saved PDF does not match arguments"); + QVERIFY2(successArguments.at(1).toBool() == true, "Printing to PDF file failed though it should succeed"); #if !defined(Q_OS_WIN) path = tempDir.path() + "/print_//2_failed.pdf"; @@ -4701,7 +4704,11 @@ void tst_QWebEnginePage::printToPdf() path = tempDir.path() + "/print_|2_failed.pdf"; #endif page.printToPdf(path, QPageLayout()); - QTRY_VERIFY(!QFile::exists(path)); + QTRY_VERIFY2(savePdfSpy.count() == 1, "Printing to PDF file failed without signal"); + + QList<QVariant> failedArguments = savePdfSpy.takeFirst(); + QVERIFY2(failedArguments.at(0).toString() == path, "File path for second saved PDF does not match arguments"); + QVERIFY2(failedArguments.at(1).toBool() == false, "Printing to PDF file succeeded though it should fail"); CallbackSpy<QByteArray> successfulSpy; page.printToPdf(successfulSpy.ref(), layout); @@ -4807,8 +4814,8 @@ void tst_QWebEnginePage::viewSourceURL_data() QUrl testResourceUrl = QUrl(QString("view-source:%1").arg(resourcePath)); QTest::newRow(testResourceUrl.toString().toStdString().c_str()) << testResourceUrl << true << testResourceUrl << QUrl(resourcePath) << testResourceUrl.toString(); - QTest::newRow("view-source:http://non.existent") << QUrl("view-source:non.existent") << false << QUrl("view-source:http://non.existent/") << QUrl("http://non.existent/") << QString("http://non.existent/ is not available"); - QTest::newRow("view-source:non.existent") << QUrl("view-source:non.existent") << false << QUrl("view-source:http://non.existent/") << QUrl("http://non.existent/") << QString("http://non.existent/ is not available"); + QTest::newRow("view-source:http://non.existent") << QUrl("view-source:non.existent") << false << QUrl("view-source:http://non.existent/") << QUrl("http://non.existent/") << QString("non.existent"); + QTest::newRow("view-source:non.existent") << QUrl("view-source:non.existent") << false << QUrl("view-source:http://non.existent/") << QUrl("http://non.existent/") << QString("non.existent"); } void tst_QWebEnginePage::viewSourceURL() @@ -4826,7 +4833,7 @@ void tst_QWebEnginePage::viewSourceURL() QSignalSpy loadFinishedSpy(&page, SIGNAL(loadFinished(bool))); page.load(userInputUrl); - QTRY_COMPARE(loadFinishedSpy.count(), 1); + QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpy.count(), 1, 12000); QList<QVariant> arguments = loadFinishedSpy.takeFirst(); QCOMPARE(arguments.at(0).toBool(), loadSucceed); diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 02e1d417e..3e8f1fb1e 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -38,6 +38,9 @@ #include <QHBoxLayout> #include <QQuickItem> #include <QQuickWidget> +#include <QtWebEngineCore/qwebenginehttprequest.h> +#include <QTcpServer> +#include <QTcpSocket> #include <QStyle> #define VERIFY_INPUTMETHOD_HINTS(actual, expect) \ @@ -91,6 +94,7 @@ private Q_SLOTS: void inputMethodsTextFormat(); void keyboardEvents(); void keyboardFocusAfterPopup(); + void postData(); void softwareInputPanel(); void hiddenText(); @@ -375,29 +379,40 @@ void tst_QWebEngineView::unhandledKeyEventPropagation() parentWidget.show(); QTest::qWaitForWindowExposed(&webView); - QSignalSpy loadSpy(&webView, SIGNAL(loadFinished(bool))); - webView.setHtml("<input type='text'/>"); - QTRY_COMPARE(loadSpy.count(), 1); + QSignalSpy loadFinishedSpy(&webView, SIGNAL(loadFinished(bool))); + webView.load(QUrl("qrc:///resources/keyboardEvents.html")); + QVERIFY(loadFinishedSpy.wait()); - evaluateJavaScriptSync(webView.page(), "document.body.firstChild.focus()"); + evaluateJavaScriptSync(webView.page(), "document.getElementById('first_div').focus()"); + QTRY_COMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("first_div")); + + QTest::sendKeyEvent(QTest::Press, webView.focusProxy(), Qt::Key_Right, QString(), Qt::NoModifier); + QTest::sendKeyEvent(QTest::Release, webView.focusProxy(), Qt::Key_Right, QString(), Qt::NoModifier); + // Right arrow key is unhandled thus focus is not changed + QTRY_COMPARE(parentWidget.releaseEvents.size(), 1); + QCOMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("first_div")); + + QTest::sendKeyEvent(QTest::Press, webView.focusProxy(), Qt::Key_Tab, QString(), Qt::NoModifier); + QTest::sendKeyEvent(QTest::Release, webView.focusProxy(), Qt::Key_Tab, QString(), Qt::NoModifier); + // Tab key is handled thus focus is changed + QTRY_COMPARE(parentWidget.releaseEvents.size(), 2); + QCOMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("second_div")); - 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. + // Left arrow key is unhandled thus focus is not changed QTRY_COMPARE(parentWidget.releaseEvents.size(), 3); + QCOMPARE(evaluateJavaScriptSync(webView.page(), "document.activeElement.id").toString(), QStringLiteral("second_div")); + + // The page will consume the Tab key to change focus between elements while the arrow + // keys won't be used. + QCOMPARE(parentWidget.pressEvents.size(), 2); + QCOMPARE(parentWidget.pressEvents[0].key(), (int)Qt::Key_Right); + QCOMPARE(parentWidget.pressEvents[1].key(), (int)Qt::Key_Left); - // 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[0].key(), (int)Qt::Key_A); - QCOMPARE(parentWidget.releaseEvents[1].key(), (int)Qt::Key_Left); + QCOMPARE(parentWidget.releaseEvents[0].key(), (int)Qt::Key_Right); + QCOMPARE(parentWidget.releaseEvents[1].key(), (int)Qt::Key_Tab); QCOMPARE(parentWidget.releaseEvents[2].key(), (int)Qt::Key_Left); } @@ -900,6 +915,7 @@ void tst_QWebEngineView::focusInternalRenderWidgetHostViewQuickItem() void tst_QWebEngineView::changeLocale() { + QSKIP("Error pages no longer have useful titles in Chromium 55"); QUrl url("http://non.existent/"); QLocale::setDefault(QLocale("de")); @@ -1139,6 +1155,137 @@ void tst_QWebEngineView::keyboardFocusAfterPopup() QTRY_COMPARE(evaluateJavaScriptSync(webView->page(), "document.getElementById('input1').value").toString(), QStringLiteral("x")); } +void tst_QWebEngineView::postData() +{ + QMap<QString, QString> postData; + // use reserved characters to make the test harder to pass + postData[QStringLiteral("Spä=m")] = QStringLiteral("ëgg:s"); + postData[QStringLiteral("foo\r\n")] = QStringLiteral("ba&r"); + + QEventLoop eventloop; + + // Set up dummy "HTTP" server + QTcpServer server; + connect(&server, &QTcpServer::newConnection, this, [this, &server, &eventloop, &postData](){ + QTcpSocket* socket = server.nextPendingConnection(); + + connect(socket, &QAbstractSocket::disconnected, this, [&eventloop](){ + eventloop.quit(); + }); + + connect(socket, &QIODevice::readyRead, this, [this, socket, &server, &postData](){ + QByteArray rawData = socket->readAll(); + QStringList lines = QString::fromLocal8Bit(rawData).split("\r\n"); + + // examine request + QStringList request = lines[0].split(" ", QString::SkipEmptyParts); + bool requestOk = request.length() > 2 + && request[2].toUpper().startsWith("HTTP/") + && request[0].toUpper() == "POST" + && request[1] == "/"; + if (!requestOk) // POST and HTTP/... can be switched(?) + requestOk = request.length() > 2 + && request[0].toUpper().startsWith("HTTP/") + && request[2].toUpper() == "POST" + && request[1] == "/"; + + // examine headers + int line = 1; + bool headersOk = true; + for (; headersOk && line < lines.length(); line++) { + QStringList headerParts = lines[line].split(":"); + if (headerParts.length() < 2) + break; + QString headerKey = headerParts[0].trimmed().toLower(); + QString headerValue = headerParts[1].trimmed().toLower(); + + if (headerKey == "host") + headersOk = headersOk && (headerValue == "127.0.0.1") + && (headerParts.length() == 3) + && (headerParts[2].trimmed() + == QString::number(server.serverPort())); + if (headerKey == "content-type") + headersOk = headersOk && (headerValue == "application/x-www-form-urlencoded"); + } + + // examine body + bool bodyOk = true; + if (lines.length() == line+2) { + QStringList postedFields = lines[line+1].split("&"); + QMap<QString, QString> postedData; + for (int i = 0; bodyOk && i < postedFields.length(); i++) { + QStringList postedField = postedFields[i].split("="); + if (postedField.length() == 2) + postedData[QUrl::fromPercentEncoding(postedField[0].toLocal8Bit())] + = QUrl::fromPercentEncoding(postedField[1].toLocal8Bit()); + else + bodyOk = false; + } + bodyOk = bodyOk && (postedData == postData); + } else { // no body at all or more than 1 line + bodyOk = false; + } + + // send response + socket->write("HTTP/1.1 200 OK\r\n"); + socket->write("Content-Type: text/html\r\n"); + socket->write("Content-Length: 39\r\n\r\n"); + if (requestOk && headersOk && bodyOk) + // 6 6 11 7 7 2 = 39 (Content-Length) + socket->write("<html><body>Test Passed</body></html>\r\n"); + else + socket->write("<html><body>Test Failed</body></html>\r\n"); + socket->flush(); + + if (!requestOk || !headersOk || !bodyOk) { + qDebug() << "Dummy HTTP Server: received request was not as expected"; + qDebug() << rawData; + QVERIFY(requestOk); // one of them will yield useful output and make the test fail + QVERIFY(headersOk); + QVERIFY(bodyOk); + } + + socket->close(); + }); + }); + if (!server.listen()) + QFAIL("Dummy HTTP Server: listen() failed"); + + // Manual, hard coded client (commented out, but not removed - for reference and just in case) + /* + QTcpSocket client; + connect(&client, &QIODevice::readyRead, this, [&client, &eventloop](){ + qDebug() << "Dummy HTTP client: data received"; + qDebug() << client.readAll(); + eventloop.quit(); + }); + connect(&client, &QAbstractSocket::connected, this, [&client](){ + client.write("HTTP/1.1 / GET\r\n\r\n"); + }); + client.connectToHost(QHostAddress::LocalHost, server.serverPort()); + */ + + // send the POST request + QWebEngineView view; + QString sPort = QString::number(server.serverPort()); + view.load(QWebEngineHttpRequest::postRequest(QUrl("http://127.0.0.1:"+sPort), postData)); + + // timeout after 10 seconds + QTimer timeoutGuard(this); + connect(&timeoutGuard, &QTimer::timeout, this, [&eventloop](){ + eventloop.quit(); + QFAIL("Dummy HTTP Server: waiting for data timed out"); + }); + timeoutGuard.setSingleShot(true); + timeoutGuard.start(10000); + + // start the test + eventloop.exec(); + + timeoutGuard.stop(); + server.close(); +} + class TestInputContext : public QPlatformInputContext { public: |