diff options
Diffstat (limited to 'tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp')
-rw-r--r-- | tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp | 276 |
1 files changed, 217 insertions, 59 deletions
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index b9a8b6a09..92e281873 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -134,6 +134,8 @@ private Q_SLOTS: void renderHints(); void getWebKitVersion(); + void changePage_data(); + void changePage(); void reusePage_data(); void reusePage(); void microFocusCoordinates(); @@ -186,6 +188,9 @@ private Q_SLOTS: void contextMenu(); void webUIURLs_data(); void webUIURLs(); + void visibilityState(); + void jsKeyboardEvent(); + void deletePage(); }; // This will be called before the first test function is executed. @@ -257,6 +262,100 @@ void tst_QWebEngineView::getWebKitVersion() #endif } +void tst_QWebEngineView::changePage_data() +{ + QString html = "<html><head><title>%1</title>" + "<link rel='icon' href='file://" TESTS_SOURCE_DIR "/resources/image2.png'></head></html>"; + QUrl urlFrom("data:text/html," + html.arg("TitleFrom")); + QUrl urlTo("data:text/html," + html.arg("TitleTo")); + QUrl nullPage("data:text/html,<html/>"); + QTest::addColumn<QUrl>("urlFrom"); + QTest::addColumn<QUrl>("urlTo"); + QTest::addColumn<bool>("fromIsNullPage"); + QTest::addColumn<bool>("toIsNullPage"); + QTest::newRow("From empty page to url") << nullPage << urlTo << true << false; + QTest::newRow("From url to empty content page") << urlFrom << nullPage << false << true; + QTest::newRow("From one content to another") << urlFrom << urlTo << false << false; +} + +void tst_QWebEngineView::changePage() +{ + QScopedPointer<QWebEngineView> view(new QWebEngineView); view->resize(640, 480); view->show(); + + QFETCH(QUrl, urlFrom); + QFETCH(QUrl, urlTo); + QFETCH(bool, fromIsNullPage); + QFETCH(bool, toIsNullPage); + + QSignalSpy spyUrl(view.get(), &QWebEngineView::urlChanged); + QSignalSpy spyTitle(view.get(), &QWebEngineView::titleChanged); + QSignalSpy spyIconUrl(view.get(), &QWebEngineView::iconUrlChanged); + QSignalSpy spyIcon(view.get(), &QWebEngineView::iconChanged); + + QScopedPointer<QWebEnginePage> pageFrom(new QWebEnginePage); + QSignalSpy pageFromLoadSpy(pageFrom.get(), &QWebEnginePage::loadFinished); + QSignalSpy pageFromIconLoadSpy(pageFrom.get(), &QWebEnginePage::iconChanged); + pageFrom->load(urlFrom); + QTRY_COMPARE(pageFromLoadSpy.count(), 1); + QCOMPARE(pageFromLoadSpy.last().value(0).toBool(), true); + if (!fromIsNullPage) { + QTRY_COMPARE(pageFromIconLoadSpy.count(), 1); + QVERIFY(!pageFromIconLoadSpy.last().value(0).isNull()); + } + + view->setPage(pageFrom.get()); + + QTRY_COMPARE(spyUrl.count(), 1); + QCOMPARE(spyUrl.last().value(0).toUrl(), pageFrom->url()); + QTRY_COMPARE(spyTitle.count(), 1); + QCOMPARE(spyTitle.last().value(0).toString(), pageFrom->title()); + + QTRY_COMPARE(spyIconUrl.count(), fromIsNullPage ? 0 : 1); + QTRY_COMPARE(spyIcon.count(), fromIsNullPage ? 0 : 1); + if (!fromIsNullPage) { + QVERIFY(!pageFrom->iconUrl().isEmpty()); + QCOMPARE(spyIconUrl.last().value(0).toUrl(), pageFrom->iconUrl()); + QCOMPARE(spyIcon.last().value(0), QVariant::fromValue(pageFrom->icon())); + } + + QScopedPointer<QWebEnginePage> pageTo(new QWebEnginePage); + QSignalSpy pageToLoadSpy(pageTo.get(), &QWebEnginePage::loadFinished); + QSignalSpy pageToIconLoadSpy(pageTo.get(), &QWebEnginePage::iconChanged); + pageTo->load(urlTo); + QTRY_COMPARE(pageToLoadSpy.count(), 1); + QCOMPARE(pageToLoadSpy.last().value(0).toBool(), true); + if (!toIsNullPage) { + QTRY_COMPARE(pageToIconLoadSpy.count(), 1); + QVERIFY(!pageToIconLoadSpy.last().value(0).isNull()); + } + + view->setPage(pageTo.get()); + + QTRY_COMPARE(spyUrl.count(), 2); + QCOMPARE(spyUrl.last().value(0).toUrl(), pageTo->url()); + QTRY_COMPARE(spyTitle.count(), 2); + QCOMPARE(spyTitle.last().value(0).toString(), pageTo->title()); + + bool iconIsSame = fromIsNullPage == toIsNullPage; + int iconChangeNotifyCount = fromIsNullPage ? (iconIsSame ? 0 : 1) : (iconIsSame ? 1 : 2); + + QTRY_COMPARE(spyIconUrl.count(), iconChangeNotifyCount); + QTRY_COMPARE(spyIcon.count(), iconChangeNotifyCount); + QCOMPARE(pageFrom->iconUrl() == pageTo->iconUrl(), iconIsSame); + if (!iconIsSame) { + QCOMPARE(spyIconUrl.last().value(0).toUrl(), pageTo->iconUrl()); + QCOMPARE(spyIcon.last().value(0), QVariant::fromValue(pageTo->icon())); + } + + // verify no emits on destroy with the same number of signals in spy + view.reset(); + qApp->processEvents(); + QTRY_COMPARE(spyUrl.count(), 2); + QTRY_COMPARE(spyTitle.count(), 2); + QTRY_COMPARE(spyIconUrl.count(), iconChangeNotifyCount); + QTRY_COMPARE(spyIcon.count(), iconChangeNotifyCount); +} + void tst_QWebEngineView::reusePage_data() { QTest::addColumn<QString>("html"); @@ -306,11 +405,13 @@ class WebViewCrashTest : public QObject { QWebEngineView* m_view; public: bool m_invokedStop; + bool m_stopBypassed; WebViewCrashTest(QWebEngineView* view) : m_view(view) , m_invokedStop(false) + , m_stopBypassed(false) { view->connect(view, SIGNAL(loadProgress(int)), this, SLOT(loading(int))); } @@ -323,6 +424,8 @@ private Q_SLOTS: QVERIFY(!m_invokedStop); m_view->stop(); m_invokedStop = true; + } else if (!m_invokedStop && progress == 100) { + m_stopBypassed = true; } } }; @@ -340,7 +443,10 @@ void tst_QWebEngineView::crashTests() // If the verification fails, it means that either stopping doesn't work, or the hardware is // too slow to load the page and thus to slow to issue the first loadProgress > 0 signal. - QTRY_VERIFY_WITH_TIMEOUT(tester.m_invokedStop, 10000); + QTRY_VERIFY_WITH_TIMEOUT(tester.m_invokedStop || tester.m_stopBypassed, 10000); + if (tester.m_stopBypassed) + QEXPECT_FAIL("", "Loading was too fast to stop", Continue); + QVERIFY(tester.m_invokedStop); } void tst_QWebEngineView::microFocusCoordinates() @@ -1069,17 +1175,17 @@ void tst_QWebEngineView::changeLocale() QWebEngineView viewDE; QSignalSpy loadFinishedSpyDE(&viewDE, SIGNAL(loadFinished(bool))); viewDE.load(url); - QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 12000); + QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000); QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty()); errorLines = toPlainTextSync(viewDE.page()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts); - QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Diese Website ist nicht erreichbar")); + QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar")); QLocale::setDefault(QLocale("en")); QWebEngineView viewEN; QSignalSpy loadFinishedSpyEN(&viewEN, SIGNAL(loadFinished(bool))); viewEN.load(url); - QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyEN.count(), 1, 12000); + QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyEN.count(), 1, 20000); QTRY_VERIFY(!toPlainTextSync(viewEN.page()).isEmpty()); errorLines = toPlainTextSync(viewEN.page()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts); @@ -1092,11 +1198,11 @@ void tst_QWebEngineView::changeLocale() // Check whether an existing QWebEngineView keeps the language settings after changing the default locale viewDE.load(url); - QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 12000); + QTRY_COMPARE_WITH_TIMEOUT(loadFinishedSpyDE.count(), 1, 20000); QTRY_VERIFY(!toPlainTextSync(viewDE.page()).isEmpty()); errorLines = toPlainTextSync(viewDE.page()).split(QRegExp("[\r\n]"), QString::SkipEmptyParts); - QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Diese Website ist nicht erreichbar")); + QCOMPARE(errorLines.first().toUtf8(), QByteArrayLiteral("Die Website ist nicht erreichbar")); } void tst_QWebEngineView::inputMethodsTextFormat_data() @@ -1258,60 +1364,55 @@ void tst_QWebEngineView::keyboardEvents() QVERIFY(loadFinishedSpy.wait()); } -void tst_QWebEngineView::keyboardFocusAfterPopup() -{ - QScopedPointer<QWidget> containerWidget(new QWidget); - - QLineEdit *urlLine = new QLineEdit(containerWidget.data()); - QStringList urlList; - urlList << "test"; - QCompleter *completer = new QCompleter(urlList, urlLine); - completer->setCompletionMode(QCompleter::PopupCompletion); - urlLine->setCompleter(completer); - urlLine->setFocus(); - - QWebEngineView *webView = new QWebEngineView(containerWidget.data()); - webView->settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true); - QSignalSpy loadFinishedSpy(webView, SIGNAL(loadFinished(bool))); - - connect(urlLine, &QLineEdit::editingFinished, [=] { - webView->setHtml("<html><body onload=\"document.getElementById('input1').focus()\">" - " <input type='text' id='input1' />" - "</body></html>"); - - // Check whether the RenderWidgetHostView has the keyboard focus - QQuickWidget *rwhv = qobject_cast<QQuickWidget *>(webView->focusProxy()); - QVERIFY(rwhv); - QVERIFY(rwhv->hasFocus()); - QVERIFY(rwhv->rootObject()->hasFocus()); - QVERIFY(rwhv->window()->windowHandle()->isActive()); - QVERIFY(rwhv->rootObject()->hasActiveFocus()); - }); - +class WebViewWithUrlBar : public QWidget { +public: + QLineEdit *lineEdit = new QLineEdit; + QCompleter *urlCompleter = new QCompleter({ QStringLiteral("test") }, lineEdit); + QWebEngineView *webView = new QWebEngineView; QVBoxLayout *layout = new QVBoxLayout; - layout->addWidget(urlLine); - layout->addWidget(webView); - - containerWidget->setLayout(layout); - containerWidget->show(); - QVERIFY(QTest::qWaitForWindowExposed(containerWidget.data())); - // Trigger completer's popup and select the first suggestion - QTest::keyClick(urlLine, Qt::Key_T); - qApp->processEvents(); - QTRY_VERIFY(qApp->activePopupWidget()); - QTest::keyClick(qApp->activePopupWidget(), Qt::Key_Down); - qApp->processEvents(); - QTest::keyClick(qApp->activePopupWidget(), Qt::Key_Enter); - qApp->processEvents(); + WebViewWithUrlBar() + { + resize(500, 500); + setLayout(layout); + layout->addWidget(lineEdit); + layout->addWidget(webView); + lineEdit->setCompleter(urlCompleter); + lineEdit->setFocus(); + } +}; - // After the load the focused window should forward the keyboard events to the webView - QVERIFY(loadFinishedSpy.wait()); - // Wait for active focus on the input field - QTRY_COMPARE(evaluateJavaScriptSync(webView->page(), "document.activeElement.id").toString(), QStringLiteral("input1")); - QTest::keyClick(qApp->focusWindow(), Qt::Key_X); - qApp->processEvents(); - QTRY_COMPARE(evaluateJavaScriptSync(webView->page(), "document.getElementById('input1').value").toString(), QStringLiteral("x")); +void tst_QWebEngineView::keyboardFocusAfterPopup() +{ + const QString html = QStringLiteral( + "<html>" + " <body onload=\"document.getElementById('input1').focus()\">" + " <input id=input1 type=text/>" + " </body>" + "</html>"); + WebViewWithUrlBar window; + QSignalSpy loadFinishedSpy(window.webView, &QWebEngineView::loadFinished); + connect(window.lineEdit, &QLineEdit::editingFinished, [&] { window.webView->setHtml(html); }); + window.webView->settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true); + window.show(); + + // Focus will initially go to the QLineEdit. + QTRY_COMPARE(QApplication::focusWidget(), window.lineEdit); + + // Trigger QCompleter's popup and select the first suggestion. + QTest::keyClick(QApplication::focusWindow(), Qt::Key_T); + QTRY_VERIFY(QApplication::activePopupWidget()); + QTest::keyClick(QApplication::focusWindow(), Qt::Key_Down); + QTest::keyClick(QApplication::focusWindow(), Qt::Key_Enter); + + // Due to FocusOnNavigationEnabled, focus should now move to the webView. + QTRY_COMPARE(QApplication::focusWidget(), window.webView->focusProxy()); + + // Keyboard events sent to the window should go to the <input> element. + QVERIFY(loadFinishedSpy.count() || loadFinishedSpy.wait()); + QTest::keyClick(QApplication::focusWindow(), Qt::Key_X); + QTRY_COMPARE(evaluateJavaScriptSync(window.webView->page(), "document.getElementById('input1').value").toString(), + QStringLiteral("x")); } void tst_QWebEngineView::mouseClick() @@ -1680,6 +1781,7 @@ void tst_QWebEngineView::softwareInputPanel() void tst_QWebEngineView::inputMethods() { QWebEngineView view; + view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true); view.resize(640, 480); view.show(); @@ -1777,6 +1879,7 @@ void tst_QWebEngineView::inputMethods() void tst_QWebEngineView::textSelectionInInputField() { QWebEngineView view; + view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true); view.resize(640, 480); view.show(); @@ -1969,6 +2072,7 @@ void tst_QWebEngineView::hiddenText() void tst_QWebEngineView::emptyInputMethodEvent() { QWebEngineView view; + view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true); view.resize(640, 480); view.show(); @@ -2016,6 +2120,7 @@ void tst_QWebEngineView::emptyInputMethodEvent() void tst_QWebEngineView::imeComposition() { QWebEngineView view; + view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true); view.resize(640, 480); view.show(); @@ -2191,6 +2296,7 @@ void tst_QWebEngineView::imeComposition() void tst_QWebEngineView::newlineInTextarea() { QWebEngineView view; + view.settings()->setAttribute(QWebEngineSettings::FocusOnNavigationEnabled, true); view.resize(640, 480); view.show(); @@ -2664,7 +2770,7 @@ void tst_QWebEngineView::webUIURLs_data() QTest::addColumn<QUrl>("url"); QTest::addColumn<bool>("supported"); QTest::newRow("about") << QUrl("chrome://about") << false; - QTest::newRow("accessibility") << QUrl("chrome://accessibility") << false; + 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("blob-internals") << QUrl("chrome://blob-internals") << true; @@ -2705,6 +2811,7 @@ void tst_QWebEngineView::webUIURLs_data() QTest::newRow("policy") << QUrl("chrome://policy") << false; QTest::newRow("predictors") << QUrl("chrome://predictors") << 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; @@ -2729,7 +2836,6 @@ void tst_QWebEngineView::webUIURLs_data() QTest::newRow("usb-internals") << QUrl("chrome://usb-internals") << false; QTest::newRow("user-actions") << QUrl("chrome://user-actions") << false; QTest::newRow("version") << QUrl("chrome://version") << false; - QTest::newRow("view-http-cache") << QUrl("chrome://view-http-cache") << true; QTest::newRow("webrtc-internals") << QUrl("chrome://webrtc-internals") << true; QTest::newRow("webrtc-logs") << QUrl("chrome://webrtc-logs") << false; } @@ -2747,5 +2853,57 @@ void tst_QWebEngineView::webUIURLs() QCOMPARE(loadFinishedSpy.takeFirst().at(0).toBool(), supported); } +void tst_QWebEngineView::visibilityState() +{ + QWebEngineView view; + QSignalSpy spy(&view, &QWebEngineView::loadFinished); + view.load(QStringLiteral("about:blank")); + QVERIFY(spy.count() || spy.wait()); + QVERIFY(spy.takeFirst().takeFirst().toBool()); + QCOMPARE(evaluateJavaScriptSync(view.page(), "document.visibilityState").toString(), QStringLiteral("hidden")); + view.show(); + QVERIFY(QTest::qWaitForWindowExposed(&view)); + QCOMPARE(evaluateJavaScriptSync(view.page(), "document.visibilityState").toString(), QStringLiteral("visible")); +} + +void tst_QWebEngineView::jsKeyboardEvent() +{ + QWebEngineView view; + evaluateJavaScriptSync( + view.page(), + "var log = '';" + "addEventListener('keydown', (ev) => {" + " log += [ev.keyCode, ev.code, ev.key, ev.ctrlKey, ev.shiftKey, ev.altKey].join(',') + ';';" + "});"); + // Note that this only tests the fallback code path where native scan codes are not used. +#if defined(Q_OS_MACOS) + // See Qt::AA_MacDontSwapCtrlAndMeta + QTest::keyClick(view.focusProxy(), 'A', Qt::MetaModifier | Qt::ShiftModifier); +#else + QTest::keyClick(view.focusProxy(), 'A', Qt::ControlModifier | Qt::ShiftModifier); +#endif + QString expected = QStringLiteral( + "16,ShiftLeft,Shift,false,true,false;" + "17,ControlLeft,Control,true,true,false;" + "65,KeyA,A,true,true,false;" + ); + QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "log") != QVariant(QString())); + QCOMPARE(evaluateJavaScriptSync(view.page(), "log"), expected); +} + +void tst_QWebEngineView::deletePage() +{ + QWebEngineView view; + QWebEnginePage *page = view.page(); + QVERIFY(page); + QCOMPARE(page->parent(), &view); + delete page; + // Test that a new page is created and that it is useful: + QVERIFY(view.page()); + QSignalSpy spy(view.page(), &QWebEnginePage::loadFinished); + view.page()->load(QStringLiteral("about:blank")); + QTRY_VERIFY(spy.count()); +} + QTEST_MAIN(tst_QWebEngineView) #include "tst_qwebengineview.moc" |