diff options
Diffstat (limited to 'tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp')
-rw-r--r-- | tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp | 387 |
1 files changed, 167 insertions, 220 deletions
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 5e16361c5..b56053fd2 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -25,7 +25,6 @@ #include <private/qinputmethod_p.h> #include <qpainter.h> #include <qpagelayout.h> -#include <qpa/qplatforminputcontext.h> #include <qwebengineview.h> #include <qwebenginepage.h> #include <qwebenginesettings.h> @@ -39,9 +38,11 @@ #include <QLineEdit> #include <QHBoxLayout> #include <QMenu> +#include <QMimeData> #include <QQuickItem> #include <QQuickWidget> #include <QtWebEngineCore/qwebenginehttprequest.h> +#include <QScopeGuard> #include <QTcpServer> #include <QTcpSocket> #include <QStyle> @@ -60,44 +61,6 @@ do { \ QCOMPARE((__expr), __expected); \ } while (0) -static QTouchDevice* s_touchDevice = nullptr; - -static QPoint elementCenter(QWebEnginePage *page, const QString &id) -{ - const QString jsCode( - "(function(){" - " var elem = document.getElementById('" + id + "');" - " var rect = elem.getBoundingClientRect();" - " return [(rect.left + rect.right) / 2, (rect.top + rect.bottom) / 2];" - "})()"); - QVariantList rectList = evaluateJavaScriptSync(page, jsCode).toList(); - - if (rectList.count() != 2) { - qWarning("elementCenter failed."); - return QPoint(); - } - - return QPoint(rectList.at(0).toInt(), rectList.at(1).toInt()); -} - -static QRect elementGeometry(QWebEnginePage *page, const QString &id) -{ - const QString jsCode( - "(function() {" - " var elem = document.getElementById('" + id + "');" - " var rect = elem.getBoundingClientRect();" - " return [rect.left, rect.top, rect.right, rect.bottom];" - "})()"); - QVariantList coords = evaluateJavaScriptSync(page, jsCode).toList(); - - if (coords.count() != 4) { - qWarning("elementGeometry faield."); - return QRect(); - } - - return QRect(coords[0].toInt(), coords[1].toInt(), coords[2].toInt(), coords[3].toInt()); -} - QT_BEGIN_NAMESPACE namespace QTest { int Q_TESTLIB_EXPORT defaultMouseDelay(); @@ -162,14 +125,13 @@ private Q_SLOTS: void doNotBreakLayout(); void changeLocale(); + void mixLangLocale_data(); + void mixLangLocale(); void inputMethodsTextFormat_data(); void inputMethodsTextFormat(); void keyboardEvents(); void keyboardFocusAfterPopup(); void mouseClick(); - void touchTap(); - void touchTapAndHold(); - void touchTapAndHoldCancelled(); void postData(); void inputFieldOverridesShortcuts(); @@ -202,6 +164,7 @@ private Q_SLOTS: void jsKeyboardEvent_data(); void jsKeyboardEvent(); void deletePage(); + void autoDeleteOnExternalPageDelete(); void closeOpenerTab(); void switchPage(); void setPageDeletesImplicitPage(); @@ -210,13 +173,15 @@ private Q_SLOTS: void setPagePreservesExplicitPage(); void setViewPreservesExplicitPage(); void closeDiscardsPage(); + void loadAfterRendererCrashed(); + void navigateOnDrop_data(); + void navigateOnDrop(); }; // This will be called before the first test function is executed. // It is only called once. void tst_QWebEngineView::initTestCase() { - s_touchDevice = QTest::createTouchDevice(); } // This will be called after the last test function is executed. @@ -1213,7 +1178,11 @@ void tst_QWebEngineView::changeLocale() QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000); QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty()); +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts); +#else + errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts); +#endif QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar")); QLocale::setDefault(QLocale("en")); @@ -1223,7 +1192,11 @@ void tst_QWebEngineView::changeLocale() QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyEN.count(), 1, 20000); QTRY_VERIFY(!toPlainTextSync(viewEN.page()).isEmpty()); +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) errorLines = toPlainTextSync(viewEN.page()).split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts); +#else + errorLines = toPlainTextSync(viewEN.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts); +#endif QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("This site can\xE2\x80\x99t be reached")); // Reset error page @@ -1236,10 +1209,57 @@ void tst_QWebEngineView::changeLocale() QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000); QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty()); +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), Qt::SkipEmptyParts); +#else + errorLines = toPlainTextSync(viewDE.page()).split(QRegularExpression("[\r\n]"), QString::SkipEmptyParts); +#endif QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar")); } +void tst_QWebEngineView::mixLangLocale_data() +{ + QTest::addColumn<QString>("locale"); + QTest::addColumn<QByteArray>("formattedNumber"); + QTest::newRow("en_DK") << "en-DK" << QByteArray("1.234.567.890"); + QTest::newRow("de") << "de" << QByteArray("1.234.567.890"); + QTest::newRow("de_CH") << "de-CH" << QByteArray("1’234’567’890"); + QTest::newRow("eu_ES") << "eu-ES" << QByteArray("1.234.567.890"); + QTest::newRow("hu_HU") << "hu-HU" << QByteArray("1\xC2\xA0""234\xC2\xA0""567\xC2\xA0""890"); // no-break spaces +} + +void tst_QWebEngineView::mixLangLocale() +{ + QFETCH(QString, locale); + QFETCH(QByteArray, formattedNumber); + + QLocale::setDefault(locale); + + QWebEngineView view; + QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished); + + bool terminated = false; + auto sc = connect(view.page(), &QWebEnginePage::renderProcessTerminated, [&] () { terminated = true; }); + + view.load(QUrl("qrc:///resources/dummy.html")); + QTRY_VERIFY(terminated || loadSpy.count() == 1); + + QVERIFY2(!terminated, + qPrintable(QString("Locale [%1] terminated: %2, loaded: %3").arg(locale).arg(terminated).arg(loadSpy.count()))); + QVERIFY(loadSpy.first().first().toBool()); + + QString content = toPlainTextSync(view.page()); + QVERIFY2(!content.isEmpty() && content.contains("test content"), qPrintable(content)); + + QCOMPARE(evaluateJavaScriptSync(view.page(), "navigator.language").toString(), QLocale().bcp47Name()); + + if (locale == "eu-ES") + QEXPECT_FAIL("", "Basque number formatting is somehow dependent on environment", Continue); + QCOMPARE(evaluateJavaScriptSync(view.page(), "Number(1234567890).toLocaleString()").toByteArray(), formattedNumber); + + QLocale::setDefault(QLocale("en")); +} + void tst_QWebEngineView::inputMethodsTextFormat_data() { QTest::addColumn<QString>("string"); @@ -1283,6 +1303,7 @@ void tst_QWebEngineView::inputMethodsTextFormat() evaluateJavaScriptSync(view.page(), "document.getElementById('input1').focus()"); view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); QFETCH(QString, string); QFETCH(int, start); @@ -1520,172 +1541,6 @@ void tst_QWebEngineView::mouseClick() QVERIFY(view.focusProxy()->inputMethodQuery(Qt::ImCurrentSelection).toString().isEmpty()); } -void tst_QWebEngineView::touchTap() -{ -#if defined(Q_OS_MACOS) - QSKIP("Synthetic touch events are not supported on macOS"); -#endif - - QWebEngineView view; - view.show(); - view.resize(200, 200); - QVERIFY(QTest::qWaitForWindowExposed(&view)); - - QSignalSpy loadFinishedSpy(&view, &QWebEngineView::loadFinished); - - view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false); - view.setHtml("<html><body>" - "<p id='text' style='width: 150px;'>The Qt Company</p>" - "<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>" - "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>" - "</body></html>"); - QVERIFY(loadFinishedSpy.wait()); - QVERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty()); - - auto singleTap = [](QWidget* target, const QPoint& tapCoords) -> void { - QTest::touchEvent(target, s_touchDevice).press(1, tapCoords, target); - QTest::touchEvent(target, s_touchDevice).stationary(1); - QTest::touchEvent(target, s_touchDevice).release(1, tapCoords, target); - }; - - // Single tap on text doesn't trigger a selection - singleTap(view.focusProxy(), elementCenter(view.page(), "text")); - QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty()); - QTRY_VERIFY(!view.hasSelection()); - - // Single tap inside the input field focuses it without selecting the text - singleTap(view.focusProxy(), elementCenter(view.page(), "input")); - QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input")); - QTRY_VERIFY(!view.hasSelection()); - - // Single tap on the div clears the input field focus - singleTap(view.focusProxy(), elementCenter(view.page(), "notext")); - QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty()); - - // Double tap on text still doesn't trigger a selection - singleTap(view.focusProxy(), elementCenter(view.page(), "text")); - singleTap(view.focusProxy(), elementCenter(view.page(), "text")); - QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty()); - QTRY_VERIFY(!view.hasSelection()); - - // Double tap inside the input field focuses it and selects the word under it - singleTap(view.focusProxy(), elementCenter(view.page(), "input")); - singleTap(view.focusProxy(), elementCenter(view.page(), "input")); - QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input")); - QTRY_COMPARE(view.selectedText(), QStringLiteral("Company2")); - - // Double tap outside the input field behaves like a single tap: clears its focus and selection - singleTap(view.focusProxy(), elementCenter(view.page(), "notext")); - singleTap(view.focusProxy(), elementCenter(view.page(), "notext")); - QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty()); - QTRY_VERIFY(!view.hasSelection()); -} - -void tst_QWebEngineView::touchTapAndHold() -{ -#if defined(Q_OS_MACOS) - QSKIP("Synthetic touch events are not supported on macOS"); -#endif - - QWebEngineView view; - view.show(); - view.resize(200, 200); - QVERIFY(QTest::qWaitForWindowExposed(&view)); - - QSignalSpy loadFinishedSpy(&view, &QWebEngineView::loadFinished); - - view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false); - view.setHtml("<html><body>" - "<p id='text' style='width: 150px;'>The Qt Company</p>" - "<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>" - "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>" - "</body></html>"); - QVERIFY(loadFinishedSpy.wait()); - QVERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty()); - - auto tapAndHold = [](QWidget* target, const QPoint& tapCoords) -> void { - QTest::touchEvent(target, s_touchDevice).press(1, tapCoords, target); - QTest::touchEvent(target, s_touchDevice).stationary(1); - QTest::qWait(1000); - QTest::touchEvent(target, s_touchDevice).release(1, tapCoords, target); - }; - - // Tap-and-hold on text selects the word under it - tapAndHold(view.focusProxy(), elementCenter(view.page(), "text")); - QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty()); - QTRY_COMPARE(view.selectedText(), QStringLiteral("Company")); - - // Tap-and-hold inside the input field focuses it and selects the word under it - tapAndHold(view.focusProxy(), elementCenter(view.page(), "input")); - QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input")); - QTRY_COMPARE(view.selectedText(), QStringLiteral("Company2")); - - // Only test the page context menu on Windows, as Linux doesn't handle context menus consistently - // and other non-desktop platforms like Android may not even support context menus at all -#if defined(Q_OS_WIN) - // Tap-and-hold clears the text selection and shows the page's context menu - QVERIFY(QApplication::activePopupWidget() == nullptr); - tapAndHold(view.focusProxy(), elementCenter(view.page(), "notext")); - QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty()); - QTRY_VERIFY(!view.hasSelection()); - QTRY_VERIFY(QApplication::activePopupWidget() != nullptr); - - QApplication::activePopupWidget()->close(); - QVERIFY(QApplication::activePopupWidget() == nullptr); -#endif -} - -void tst_QWebEngineView::touchTapAndHoldCancelled() -{ -#if defined(Q_OS_MACOS) - QSKIP("Synthetic touch events are not supported on macOS"); -#endif - - QWebEngineView view; - view.show(); - view.resize(200, 200); - QVERIFY(QTest::qWaitForWindowExposed(&view)); - - QSignalSpy loadFinishedSpy(&view, &QWebEngineView::loadFinished); - - view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, false); - view.setHtml("<html><body>" - "<p id='text' style='width: 150px;'>The Qt Company</p>" - "<div id='notext' style='width: 150px; height: 100px; background-color: #f00;'></div>" - "<form><input id='input' width='150px' type='text' value='The Qt Company2' /></form>" - "</body></html>"); - QVERIFY(loadFinishedSpy.wait()); - QVERIFY(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty()); - - auto cancelledTapAndHold = [](QWidget* target, const QPoint& tapCoords) -> void { - QTest::touchEvent(target, s_touchDevice).press(1, tapCoords, target); - QTest::touchEvent(target, s_touchDevice).stationary(1); - QTest::qWait(1000); - QWindowSystemInterface::handleTouchCancelEvent(target->windowHandle(), s_touchDevice); - }; - - // A cancelled tap-and-hold should cancel text selection, but currently doesn't - cancelledTapAndHold(view.focusProxy(), elementCenter(view.page(), "text")); - QEXPECT_FAIL("", "Incorrect Chromium selection behavior when cancelling tap-and-hold on text", Continue); - QTRY_VERIFY_WITH_TIMEOUT(!view.hasSelection(), 100); - - // A cancelled tap-and-hold should cancel input field focusing and selection, but currently doesn't - cancelledTapAndHold(view.focusProxy(), elementCenter(view.page(), "input")); - QEXPECT_FAIL("", "Incorrect Chromium selection behavior when cancelling tap-and-hold on input field", Continue); - QTRY_VERIFY_WITH_TIMEOUT(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString().isEmpty(), 100); - QEXPECT_FAIL("", "Incorrect Chromium focus behavior when cancelling tap-and-hold on input field", Continue); - QTRY_VERIFY_WITH_TIMEOUT(!view.hasSelection(), 100); - - // Only test the page context menu on Windows, as Linux doesn't handle context menus consistently - // and other non-desktop platforms like Android may not even support context menus at all -#if defined(Q_OS_WIN) - // A cancelled tap-and-hold cancels the context menu - QVERIFY(QApplication::activePopupWidget() == nullptr); - cancelledTapAndHold(view.focusProxy(), elementCenter(view.page(), "notext")); - QVERIFY(QApplication::activePopupWidget() == nullptr); -#endif -} - void tst_QWebEngineView::postData() { QMap<QString, QString> postData; @@ -1709,7 +1564,11 @@ void tst_QWebEngineView::postData() QStringList lines = QString::fromLocal8Bit(rawData).split("\r\n"); // examine request +#if QT_VERSION >= QT_VERSION_CHECK(5, 15, 0) QStringList request = lines[0].split(" ", Qt::SkipEmptyParts); +#else + QStringList request = lines[0].split(" ", QString::SkipEmptyParts); +#endif bool requestOk = request.length() > 2 && request[2].toUpper().startsWith("HTTP/") && request[0].toUpper() == "POST" @@ -2051,6 +1910,7 @@ void tst_QWebEngineView::inputContextQueryInput() " <input type='text' id='input1' value='' size='50'/>" "</body></html>"); QTRY_COMPARE(loadFinishedSpy.count(), 1); + QVERIFY(QTest::qWaitForWindowExposed(&view)); QCOMPARE(testContext.infos.count(), 0); // Set focus on an input field. @@ -2202,6 +2062,7 @@ void tst_QWebEngineView::inputMethods() " <input type='text' id='input1' style='font-family: serif' value='' maxlength='20' size='50'/>" "</body></html>"); QTRY_COMPARE(loadFinishedSpy.size(), 1); + QVERIFY(QTest::qWaitForWindowExposed(&view)); QPoint textInputCenter = elementCenter(view.page(), "input1"); QTest::mouseClick(view.focusProxy(), Qt::LeftButton, {}, textInputCenter); @@ -2299,6 +2160,7 @@ void tst_QWebEngineView::textSelectionInInputField() " <input type='text' id='input1' value='QtWebEngine' size='50'/>" "</body></html>"); QVERIFY(loadFinishedSpy.wait()); + QVERIFY(QTest::qWaitForWindowExposed(&view)); // Tests for Selection when the Editor is NOT in Composition mode @@ -2372,6 +2234,7 @@ void tst_QWebEngineView::textSelectionInInputField() void tst_QWebEngineView::textSelectionOutOfInputField() { QWebEngineView view; + view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true); view.resize(640, 480); view.show(); @@ -2381,6 +2244,7 @@ void tst_QWebEngineView::textSelectionOutOfInputField() " This is a text" "</body></html>"); QVERIFY(loadFinishedSpy.wait()); + QVERIFY(QTest::qWaitForWindowExposed(&view)); QCOMPARE(selectionChangedSpy.count(), 0); QVERIFY(!view.hasSelection()); @@ -2429,6 +2293,7 @@ void tst_QWebEngineView::textSelectionOutOfInputField() " <input type='text' id='input1' value='QtWebEngine' size='50'/>" "</body></html>"); QVERIFY(loadFinishedSpy.wait()); + QVERIFY(QTest::qWaitForWindowExposed(&view)); QCOMPARE(selectionChangedSpy.count(), 0); QVERIFY(!view.hasSelection()); @@ -2508,6 +2373,7 @@ void tst_QWebEngineView::emptyInputMethodEvent() " <input type='text' id='input1' value='QtWebEngine'/>" "</body></html>"); QVERIFY(loadFinishedSpy.wait()); + QVERIFY(QTest::qWaitForWindowExposed(&view)); evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();"); QTRY_COMPARE(selectionChangedSpy.count(), 1); @@ -2556,6 +2422,7 @@ void tst_QWebEngineView::imeComposition() " <input type='text' id='input1' value='QtWebEngine inputMethod'/>" "</body></html>"); QVERIFY(loadFinishedSpy.wait()); + QVERIFY(QTest::qWaitForWindowExposed(&view)); evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();"); QTRY_COMPARE(selectionChangedSpy.count(), 1); @@ -2773,6 +2640,7 @@ void tst_QWebEngineView::newlineInTextarea() " <textarea rows='5' cols='1' id='input1'></textarea>" "</body></html>"); QVERIFY(loadFinishedSpy.wait()); + QVERIFY(QTest::qWaitForWindowExposed(&view)); evaluateJavaScriptSync(view.page(), "var inputEle = document.getElementById('input1'); inputEle.focus(); inputEle.select();"); QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString().isEmpty()); @@ -2897,6 +2765,7 @@ void tst_QWebEngineView::imeJSInputEvents() " <pre id='log'></pre>" "</body></html>"); QVERIFY(loadFinishedSpy.wait()); + QVERIFY(QTest::qWaitForWindowExposed(&view)); evaluateJavaScriptSync(view.page(), "document.getElementById('input').focus()"); QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input")); @@ -3019,6 +2888,7 @@ void tst_QWebEngineView::imeCompositionQueryEvent() " <input type='text' id='input1' />" "</body></html>"); QVERIFY(loadFinishedSpy.wait()); + QVERIFY(QTest::qWaitForWindowExposed(&view)); evaluateJavaScriptSync(view.page(), "document.getElementById('input1').focus()"); QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("input1")); @@ -3260,46 +3130,50 @@ void tst_QWebEngineView::webUIURLs_data() QTest::newRow("accessibility") << QUrl("chrome://accessibility") << true; QTest::newRow("appcache-internals") << QUrl("chrome://appcache-internals") << true; QTest::newRow("apps") << QUrl("chrome://apps") << false; + QTest::newRow("autofill-internals") << QUrl("chrome://autofill-internals") << false; QTest::newRow("blob-internals") << QUrl("chrome://blob-internals") << true; QTest::newRow("bluetooth-internals") << QUrl("chrome://bluetooth-internals") << false; QTest::newRow("bookmarks") << QUrl("chrome://bookmarks") << false; - QTest::newRow("cache") << QUrl("chrome://cache") << false; - QTest::newRow("chrome") << QUrl("chrome://chrome") << false; QTest::newRow("chrome-urls") << QUrl("chrome://chrome-urls") << false; QTest::newRow("components") << QUrl("chrome://components") << false; + QTest::newRow("conversion-internals") << QUrl("chrome://conversion-internals") << true; QTest::newRow("crashes") << QUrl("chrome://crashes") << false; QTest::newRow("credits") << QUrl("chrome://credits") << false; QTest::newRow("device-log") << QUrl("chrome://device-log") << false; QTest::newRow("devices") << QUrl("chrome://devices") << false; QTest::newRow("dino") << QUrl("chrome://dino") << false; // It works but this is an error page - QTest::newRow("dns") << QUrl("chrome://dns") << false; + QTest::newRow("discards") << QUrl("chrome://discards") << false; + QTest::newRow("download-internals") << QUrl("chrome://download-internals") << false; QTest::newRow("downloads") << QUrl("chrome://downloads") << false; QTest::newRow("extensions") << QUrl("chrome://extensions") << false; QTest::newRow("flags") << QUrl("chrome://flags") << false; - QTest::newRow("flash") << QUrl("chrome://flash") << false; QTest::newRow("gcm-internals") << QUrl("chrome://gcm-internals") << false; QTest::newRow("gpu") << QUrl("chrome://gpu") << true; QTest::newRow("help") << QUrl("chrome://help") << false; QTest::newRow("histograms") << QUrl("chrome://histograms") << true; + QTest::newRow("history") << QUrl("chrome://history") << false; QTest::newRow("indexeddb-internals") << QUrl("chrome://indexeddb-internals") << true; QTest::newRow("inspect") << QUrl("chrome://inspect") << false; + QTest::newRow("interstitials") << QUrl("chrome://interstitials") << false; + QTest::newRow("interventions-internals") << QUrl("chrome://interventions-internals") << false; QTest::newRow("invalidations") << QUrl("chrome://invalidations") << false; QTest::newRow("linux-proxy-config") << QUrl("chrome://linux-proxy-config") << false; QTest::newRow("local-state") << QUrl("chrome://local-state") << false; + QTest::newRow("management") << QUrl("chrome://management") << false; + QTest::newRow("media-engagement") << QUrl("chrome://media-engagement") << false; QTest::newRow("media-internals") << QUrl("chrome://media-internals") << true; QTest::newRow("net-export") << QUrl("chrome://net-export") << false; - QTest::newRow("net-internals") << QUrl("chrome://net-internals") << false; + QTest::newRow("net-internals") << QUrl("chrome://net-internals") << true; QTest::newRow("network-error") << QUrl("chrome://network-error") << false; QTest::newRow("network-errors") << QUrl("chrome://network-errors") << true; - QTest::newRow("newtab") << QUrl("chrome://newtab") << false; QTest::newRow("ntp-tiles-internals") << QUrl("chrome://ntp-tiles-internals") << false; QTest::newRow("omnibox") << QUrl("chrome://omnibox") << false; QTest::newRow("password-manager-internals") << QUrl("chrome://password-manager-internals") << false; QTest::newRow("policy") << QUrl("chrome://policy") << false; QTest::newRow("predictors") << QUrl("chrome://predictors") << false; + QTest::newRow("prefs-internals") << QUrl("chrome://prefs-internals") << false; QTest::newRow("print") << QUrl("chrome://print") << false; QTest::newRow("process-internals") << QUrl("chrome://process-internals") << true; - QTest::newRow("profiler") << QUrl("chrome://profiler") << false; QTest::newRow("quota-internals") << QUrl("chrome://quota-internals") << true; QTest::newRow("safe-browsing") << QUrl("chrome://safe-browsing") << false; #ifdef Q_OS_LINUX @@ -3316,14 +3190,14 @@ void tst_QWebEngineView::webUIURLs_data() QTest::newRow("sync-internals") << QUrl("chrome://sync-internals") << false; QTest::newRow("system") << QUrl("chrome://system") << false; QTest::newRow("terms") << QUrl("chrome://terms") << false; - QTest::newRow("thumbnails") << QUrl("chrome://thumbnails") << false; - QTest::newRow("tracing") << QUrl("chrome://tracing") << false; + QTest::newRow("tracing") << QUrl("chrome://tracing") << true; QTest::newRow("translate-internals") << QUrl("chrome://translate-internals") << false; + QTest::newRow("ukm") << QUrl("chrome://ukm") << true; QTest::newRow("usb-internals") << QUrl("chrome://usb-internals") << false; - QTest::newRow("user-actions") << QUrl("chrome://user-actions") << false; + QTest::newRow("user-actions") << QUrl("chrome://user-actions") << true; QTest::newRow("version") << QUrl("chrome://version") << false; QTest::newRow("webrtc-internals") << QUrl("chrome://webrtc-internals") << true; - QTest::newRow("webrtc-logs") << QUrl("chrome://webrtc-logs") << false; + QTest::newRow("webrtc-logs") << QUrl("chrome://webrtc-logs") << true; } void tst_QWebEngineView::webUIURLs() @@ -3440,6 +3314,26 @@ void tst_QWebEngineView::deletePage() QTRY_VERIFY(spy.count()); } +void tst_QWebEngineView::autoDeleteOnExternalPageDelete() +{ + QPointer<QWebEngineView> view = new QWebEngineView; + QPointer<QWebEnginePage> page = new QWebEnginePage; + auto sg = qScopeGuard([&] () { delete view; delete page; }); + + QSignalSpy spy(page, &QWebEnginePage::loadFinished); + view->setPage(page); + view->show(); + view->resize(320, 240); + page->load(QUrl("about:blank")); + QTRY_VERIFY(spy.count()); + QVERIFY(page->parent() != view); + + auto sc = QObject::connect(page, &QWebEnginePage::destroyed, view, &QWebEngineView::deleteLater); + QTimer::singleShot(0, page, &QObject::deleteLater); + QTRY_VERIFY(!page); + QTRY_VERIFY(!view); +} + class TestView : public QWebEngineView { Q_OBJECT public: @@ -3569,5 +3463,58 @@ void tst_QWebEngineView::closeDiscardsPage() QCOMPARE(page.lifecycleState(), QWebEnginePage::LifecycleState::Discarded); } + +void tst_QWebEngineView::loadAfterRendererCrashed() +{ + QWebEngineView view; + view.resize(640, 480); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + bool terminated = false; + connect(view.page(), &QWebEnginePage::renderProcessTerminated, [&] () { terminated = true; }); + view.load(QUrl("chrome://crash")); + QTRY_VERIFY_WITH_TIMEOUT(terminated, 30000); + + QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished); + view.load(QUrl("qrc:///resources/dummy.html")); + QTRY_COMPARE(loadSpy.count(), 1); + QVERIFY(loadSpy.first().first().toBool()); +} + +void tst_QWebEngineView::navigateOnDrop_data() +{ + QTest::addColumn<QUrl>("url"); + QTest::newRow("file") << QUrl::fromLocalFile(QDir(TESTS_SOURCE_DIR).absoluteFilePath("qwebengineview/resources/dummy.html")); + QTest::newRow("qrc") << QUrl("qrc:///resources/dummy.html"); +} + +void tst_QWebEngineView::navigateOnDrop() +{ + QFETCH(QUrl, url); + struct WebEngineView : QWebEngineView { + QWebEngineView* createWindow(QWebEnginePage::WebWindowType /* type */) override { return this; } + } view; + view.resize(640, 480); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + + QSignalSpy loadSpy(&view, &QWebEngineView::loadFinished); + QMimeData mimeData; + mimeData.setUrls({ url }); + + auto sendEvents = [&] () { + QDragEnterEvent dee(view.rect().center(), Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier); + QApplication::sendEvent(&view, &dee); + QDropEvent de(view.rect().center(), Qt::CopyAction, &mimeData, Qt::LeftButton, Qt::NoModifier); + QApplication::sendEvent(&view, &de); + }; + + sendEvents(); + QTRY_COMPARE(loadSpy.count(), 1); + QVERIFY(loadSpy.first().first().toBool()); + QCOMPARE(view.url(), url); +} + QTEST_MAIN(tst_QWebEngineView) #include "tst_qwebengineview.moc" |