From ef767e51abc3b49b4100cb682cbf326a62def1bc Mon Sep 17 00:00:00 2001 From: Peter Varga Date: Thu, 6 Oct 2016 14:12:34 +0200 Subject: Add quick and widget auto tests for keyboard event handling Task-number: QTBUG-56242 Change-Id: Ib6689d6f183532502382c86f92fdbdf27dd6c37c Reviewed-by: Alexandru Croitor --- tests/auto/quick/qmltests/data/keyboardEvents.html | 98 ++++++++++++ .../quick/qmltests/data/tst_keyboardEvents.qml | 176 +++++++++++++++++++++ tests/auto/quick/qmltests/qmltests.pro | 2 + .../qwebengineview/resources/keyboardEvents.html | 98 ++++++++++++ .../widgets/qwebengineview/tst_qwebengineview.cpp | 90 +++++++++++ .../widgets/qwebengineview/tst_qwebengineview.qrc | 1 + 6 files changed, 465 insertions(+) create mode 100644 tests/auto/quick/qmltests/data/keyboardEvents.html create mode 100644 tests/auto/quick/qmltests/data/tst_keyboardEvents.qml create mode 100644 tests/auto/widgets/qwebengineview/resources/keyboardEvents.html diff --git a/tests/auto/quick/qmltests/data/keyboardEvents.html b/tests/auto/quick/qmltests/data/keyboardEvents.html new file mode 100644 index 000000000..d536d849f --- /dev/null +++ b/tests/auto/quick/qmltests/data/keyboardEvents.html @@ -0,0 +1,98 @@ + + + + + + +
+
First
+
Second
+
+ +
+
+ Form + + + + + + + + radio1 + radio2 + + + + checkbox1 + checkbox2 + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+ +
+ First +
+ Second +
+ + diff --git a/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml new file mode 100644 index 000000000..7007a85ac --- /dev/null +++ b/tests/auto/quick/qmltests/data/tst_keyboardEvents.qml @@ -0,0 +1,176 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the QtWebEngine module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import QtTest 1.0 +import QtWebEngine 1.4 + +TestWebEngineView { + id: webEngineView + width: 350 + height: 480 + + TestCase { + name: "WebEngineViewKeyboardEvents" + when: windowShown + + function getActiveElementId() { + var activeElementId; + runJavaScript("document.activeElement.id", function(result) { + activeElementId = result; + }); + tryVerify(function() { return activeElementId != undefined }); + return activeElementId; + } + + function verifyElementHasFocus(element) { + tryVerify(function() { return getActiveElementId() == element; }, 5000, + "Element \"" + element + "\" has focus"); + + } + + function setFocusToElement(element) { + runJavaScript("document.getElementById('" + element + "').focus()"); + verifyElementHasFocus(element); + } + + function isElementChecked(element) { + var elementChecked; + runJavaScript("document.getElementById('" + element + "').checked", function(result) { + elementChecked = result; + }); + tryVerify(function() { return elementChecked != undefined; }); + return elementChecked; + } + + function verifyElementChecked(element, expected) { + tryVerify(function() { return expected == isElementChecked(element); }, 5000, + "Element \"" + element + "\" is " + (expected ? "" : "not") + " checked"); + } + + function getElementValue(element) { + var elementValue; + runJavaScript("document.getElementById('" + element + "').value", function(result) { + elementValue = result; + }); + tryVerify(function() { return elementValue != undefined; }); + return elementValue; + } + + function compareElementValue(element, expected) { + tryVerify(function() { return expected == getElementValue(element); }, 5000, + "Value of element \"" + element + "\" is \"" + expected + "\""); + } + + function test_keyboardEvents() { + webEngineView.url = Qt.resolvedUrl("keyboardEvents.html"); + verify(webEngineView.waitForLoadSucceeded()); + + var elements = [ + "first_div", "second_div", + "text_input", "radio1", "checkbox1", "checkbox2", + "number_input", "range_input", "search_input", + "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 (var i = 0; i < elements.length; ++i) { + verifyElementHasFocus(elements[i]) + keyPress(Qt.Key_Tab); + } + + // Move back to the radio buttons with the Shift+Tab key combination + for (var i = 0; i < 10; ++i) + keyPress(Qt.Key_Tab, Qt.ShiftModifier); + verifyElementHasFocus("radio2"); + + // Test the Space key by checking a radio button + verifyElementChecked("radio2", false); + keyClick(Qt.Key_Space); + verifyElementChecked("radio2", true); + + // Test the Left key by switching the radio button + verifyElementChecked("radio1", false); + keyPress(Qt.Key_Left); + verifyElementHasFocus("radio1"); + verifyElementChecked("radio1", true); + + // Test the Space key by unchecking a checkbox + setFocusToElement("checkbox1"); + verifyElementChecked("checkbox1", true); + keyClick(Qt.Key_Space); + verifyElementChecked("checkbox1", false); + + // Test the Up and Down keys by changing the value of a spinbox + setFocusToElement("number_input"); + compareElementValue("number_input", 5); + keyPress(Qt.Key_Up); + compareElementValue("number_input", 6); + keyPress(Qt.Key_Down); + compareElementValue("number_input", 5); + + // Test the Left, Right, Home, PageUp, End and PageDown keys by changing the value of a slider + setFocusToElement("range_input"); + compareElementValue("range_input", 5); + keyPress(Qt.Key_Left); + compareElementValue("range_input", 4); + keyPress(Qt.Key_Right); + compareElementValue("range_input", 5); + keyPress(Qt.Key_Home); + compareElementValue("range_input", 0); + keyPress(Qt.Key_PageUp); + compareElementValue("range_input", 1); + keyPress(Qt.Key_End); + compareElementValue("range_input", 10); + keyPress(Qt.Key_PageDown); + compareElementValue("range_input", 9); + + // Test the Escape key by removing the content of a search field + setFocusToElement("search_input"); + compareElementValue("search_input", "test"); + keyPress(Qt.Key_Escape); + compareElementValue("search_input", ""); + + // Test the alpha keys by changing the values in a combobox + setFocusToElement("combobox"); + compareElementValue("combobox", "a"); + keyPress(Qt.Key_B); + compareElementValue("combobox", "b"); + // Must wait with the second key press to simulate selection of another element + wait(1000); + keyPress(Qt.Key_C); + compareElementValue("combobox", "c"); + + // Test the Enter key by loading a page with a hyperlink + setFocusToElement("first_hyperlink"); + keyPress(Qt.Key_Enter); + verify(webEngineView.waitForLoadSucceeded()); + } + } +} diff --git a/tests/auto/quick/qmltests/qmltests.pro b/tests/auto/quick/qmltests/qmltests.pro index 726519db2..4d4268324 100644 --- a/tests/auto/quick/qmltests/qmltests.pro +++ b/tests/auto/quick/qmltests/qmltests.pro @@ -39,6 +39,7 @@ OTHER_FILES += \ $$PWD/data/test3.html \ $$PWD/data/test4.html \ $$PWD/data/keyboardModifierMapping.html \ + $$PWD/data/keyboardEvents.html \ $$PWD/data/titleupdate.js \ $$PWD/data/tst_desktopBehaviorLoadHtml.qml \ $$PWD/data/tst_download.qml \ @@ -70,6 +71,7 @@ OTHER_FILES += \ $$PWD/data/tst_webchannel.qml \ $$PWD/data/tst_settings.qml \ $$PWD/data/tst_keyboardModifierMapping.qml \ + $$PWD/data/tst_keyboardEvents.qml \ $$PWD/data/icons/favicon.png \ $$PWD/data/icons/gray128.png \ $$PWD/data/icons/gray16.png \ diff --git a/tests/auto/widgets/qwebengineview/resources/keyboardEvents.html b/tests/auto/widgets/qwebengineview/resources/keyboardEvents.html new file mode 100644 index 000000000..d536d849f --- /dev/null +++ b/tests/auto/widgets/qwebengineview/resources/keyboardEvents.html @@ -0,0 +1,98 @@ + + + + + + +
+
First
+
Second
+
+ +
+
+ Form + + + + + + + + radio1 + radio2 + + + + checkbox1 + checkbox2 + + + + + + + + + + + + + + + + + + +
+
+ +
+ +
+ +
+ First +
+ Second +
+ + diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp index 156c56933..9966ad9ee 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.cpp @@ -82,6 +82,7 @@ private Q_SLOTS: void changeLocale(); void inputMethodsTextFormat_data(); void inputMethodsTextFormat(); + void keyboardEvents(); }; // This will be called before the first test function is executed. @@ -924,5 +925,94 @@ void tst_QWebEngineView::inputMethodsTextFormat() 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" diff --git a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc index b32b533c2..4809bbebf 100644 --- a/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc +++ b/tests/auto/widgets/qwebengineview/tst_qwebengineview.qrc @@ -5,5 +5,6 @@ resources/input_types.html resources/scrolltest_page.html resources/basic_printing_page.html + resources/keyboardEvents.html -- cgit v1.2.3