summaryrefslogtreecommitdiffstats
path: root/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp')
-rw-r--r--tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp289
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"