diff options
Diffstat (limited to 'tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp')
-rw-r--r-- | tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp | 289 |
1 files changed, 280 insertions, 9 deletions
diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index afb53ba20..9966ad9ee 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,13 @@ private Q_SLOTS: void doNotSendMouseKeyboardEventsWhenDisabled_data(); void stopSettingFocusWhenDisabled(); void stopSettingFocusWhenDisabled_data(); + void focusOnNavigation_data(); + void focusOnNavigation(); + + void changeLocale(); + void inputMethodsTextFormat_data(); + void inputMethodsTextFormat(); + void keyboardEvents(); }; // This will be called before the first test function is executed. @@ -357,23 +366,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 +750,269 @@ 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())); +} + +void tst_QWebEngineView::inputMethodsTextFormat_data() +{ + QTest::addColumn<QString>("string"); + QTest::addColumn<int>("start"); + QTest::addColumn<int>("length"); + QTest::addColumn<int>("underlineStyle"); + QTest::addColumn<QColor>("underlineColor"); + QTest::addColumn<QColor>("backgroundColor"); + + QTest::newRow("") << QString("") << 0 << 0 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("Q") << QString("Q") << 0 << 1 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("Qt") << QString("Qt") << 0 << 1 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("Qt") << QString("Qt") << 0 << 2 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("Qt") << QString("Qt") << 1 << 1 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("Qt ") << QString("Qt ") << 0 << 1 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("Qt ") << QString("Qt ") << 1 << 1 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("Qt ") << QString("Qt ") << 2 << 1 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("Qt ") << QString("Qt ") << 2 << -1 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("Qt ") << QString("Qt ") << -2 << 3 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("Qt ") << QString("Qt ") << -1 << -1 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("Qt ") << QString("Qt ") << 0 << 3 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("The Qt") << QString("The Qt") << 0 << 1 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("The Qt Company") << QString("The Qt Company") << 0 << 1 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("red") << QColor(); + QTest::newRow("The Qt Company") << QString("The Qt Company") << 0 << 3 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("green") << QColor(); + QTest::newRow("The Qt Company") << QString("The Qt Company") << 4 << 2 << static_cast<int>(QTextCharFormat::SingleUnderline) << QColor("green") << QColor("red"); + QTest::newRow("The Qt Company") << QString("The Qt Company") << 7 << 7 << static_cast<int>(QTextCharFormat::NoUnderline) << QColor("green") << QColor("red"); + QTest::newRow("The Qt Company") << QString("The Qt Company") << 7 << 7 << static_cast<int>(QTextCharFormat::NoUnderline) << QColor() << QColor("red"); +} + + +void tst_QWebEngineView::inputMethodsTextFormat() +{ + QWebEngineView view; + QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); + + view.setHtml("<html><body>" + " <input type='text' id='input1' style='font-family: serif' value='' maxlength='20'/>" + "</body></html>"); + QTRY_COMPARE(loadFinishedSpy.count(), 1); + + evaluateJavaScriptSync(view.page(), "document.getElementById('input1').focus()"); + view.show(); + + QFETCH(QString, string); + QFETCH(int, start); + QFETCH(int, length); + QFETCH(int, underlineStyle); + QFETCH(QColor, underlineColor); + QFETCH(QColor, backgroundColor); + + QList<QInputMethodEvent::Attribute> attrs; + QTextCharFormat format; + format.setUnderlineStyle(static_cast<QTextCharFormat::UnderlineStyle>(underlineStyle)); + format.setUnderlineColor(underlineColor); + if (backgroundColor.isValid()) + format.setBackground(QBrush(backgroundColor)); + attrs.append(QInputMethodEvent::Attribute(QInputMethodEvent::TextFormat, start, length, format)); + + QInputMethodEvent im(string, attrs); + QVERIFY(QApplication::sendEvent(view.focusProxy(), &im)); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('input1').value").toString(), string); +} + +void tst_QWebEngineView::keyboardEvents() +{ + QWebEngineView view; + view.show(); + QSignalSpy loadFinishedSpy(&view, SIGNAL(loadFinished(bool))); + view.load(QUrl("qrc:///resources/keyboardEvents.html")); + QVERIFY(loadFinishedSpy.wait()); + + QStringList elements; + elements << "first_div" << "second_div"; + elements << "text_input" << "radio1" << "checkbox1" << "checkbox2"; + elements << "number_input" << "range_input" << "search_input"; + elements << "submit_button" << "combobox" << "first_hyperlink" << "second_hyperlink"; + + // Iterate over the elements of the test page with the Tab key. This tests whether any + // element blocks the in-page navigation by Tab. + for (const QString &elementId : elements) { + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), elementId); + QTest::keyPress(view.focusProxy(), Qt::Key_Tab); + } + + // Move back to the radio buttons with the Shift+Tab key combination + for (int i = 0; i < 10; ++i) + QTest::keyPress(view.focusProxy(), Qt::Key_Tab, Qt::ShiftModifier); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("radio2")); + + // Test the Space key by checking a radio button + QVERIFY(!evaluateJavaScriptSync(view.page(), "document.getElementById('radio2').checked").toBool()); + QTest::keyClick(view.focusProxy(), Qt::Key_Space); + QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('radio2').checked").toBool()); + + // Test the Left key by switching the radio button + QVERIFY(!evaluateJavaScriptSync(view.page(), "document.getElementById('radio1').checked").toBool()); + QTest::keyPress(view.focusProxy(), Qt::Key_Left); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.activeElement.id").toString(), QStringLiteral("radio1")); + QVERIFY(!evaluateJavaScriptSync(view.page(), "document.getElementById('radio2').checked").toBool()); + QVERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('radio1').checked").toBool()); + + // Test the Space key by unchecking a checkbox + evaluateJavaScriptSync(view.page(), "document.getElementById('checkbox1').focus()"); + QVERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('checkbox1').checked").toBool()); + QTest::keyClick(view.focusProxy(), Qt::Key_Space); + QTRY_VERIFY(!evaluateJavaScriptSync(view.page(), "document.getElementById('checkbox1').checked").toBool()); + + // Test the Up and Down keys by changing the value of a spinbox + evaluateJavaScriptSync(view.page(), "document.getElementById('number_input').focus()"); + QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('number_input').value").toInt(), 5); + QTest::keyPress(view.focusProxy(), Qt::Key_Up); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('number_input').value").toInt(), 6); + QTest::keyPress(view.focusProxy(), Qt::Key_Down); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('number_input').value").toInt(), 5); + + // Test the Left, Right, Home, PageUp, End and PageDown keys by changing the value of a slider + evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').focus()"); + QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("5")); + QTest::keyPress(view.focusProxy(), Qt::Key_Left); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("4")); + QTest::keyPress(view.focusProxy(), Qt::Key_Right); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("5")); + QTest::keyPress(view.focusProxy(), Qt::Key_Home); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("0")); + QTest::keyPress(view.focusProxy(), Qt::Key_PageUp); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("1")); + QTest::keyPress(view.focusProxy(), Qt::Key_End); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("10")); + QTest::keyPress(view.focusProxy(), Qt::Key_PageDown); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('range_input').value").toString(), QStringLiteral("9")); + + // Test the Escape key by removing the content of a search field + evaluateJavaScriptSync(view.page(), "document.getElementById('search_input').focus()"); + QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('search_input').value").toString(), QStringLiteral("test")); + QTest::keyPress(view.focusProxy(), Qt::Key_Escape); + QTRY_VERIFY(evaluateJavaScriptSync(view.page(), "document.getElementById('search_input').value").toString().isEmpty()); + + // Test the alpha keys by changing the values in a combobox + evaluateJavaScriptSync(view.page(), "document.getElementById('combobox').focus()"); + QCOMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('combobox').value").toString(), QStringLiteral("a")); + QTest::keyPress(view.focusProxy(), Qt::Key_B); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('combobox').value").toString(), QStringLiteral("b")); + // Must wait with the second key press to simulate selection of another element + QTest::keyPress(view.focusProxy(), Qt::Key_C, Qt::NoModifier, 1000); + QTRY_COMPARE(evaluateJavaScriptSync(view.page(), "document.getElementById('combobox').value").toString(), QStringLiteral("c")); + + // Test the Enter key by loading a page with a hyperlink + evaluateJavaScriptSync(view.page(), "document.getElementById('first_hyperlink').focus()"); + QTest::keyPress(view.focusProxy(), Qt::Key_Enter); + QVERIFY(loadFinishedSpy.wait()); +} + QTEST_MAIN(tst_QWebEngineView) #include "tst_qwebengineview.moc" |