From 00dab06535278da1cbfb2a11e93c38258aed3655 Mon Sep 17 00:00:00 2001 From: Christian Stenger <christian.stenger@digia.com> Date: Tue, 30 Oct 2012 12:05:27 +0100 Subject: [PATCH] Squish: Added test for QML outline Change-Id: I6199cf22da0049319c2eaef6977884ed7f63a4fd Reviewed-by: Robert Loehning <robert.loehning@digia.com> --- tests/system/objects.map | 2 + tests/system/shared/editor_utils.py | 1 + tests/system/suite_qtquick/suite.conf | 2 +- .../suite_qtquick/tst_qml_outline/test.py | 114 ++++++++++++++++++ .../testdata/ListMenu.qml_outline.tsv | 85 +++++++++++++ .../testdata/focus.qml_mod1_outline.tsv | 81 +++++++++++++ .../testdata/focus.qml_mod2_outline.tsv | 81 +++++++++++++ .../testdata/focus.qml_outline.tsv | 75 ++++++++++++ 8 files changed, 440 insertions(+), 1 deletion(-) create mode 100644 tests/system/suite_qtquick/tst_qml_outline/test.py create mode 100644 tests/system/suite_qtquick/tst_qml_outline/testdata/ListMenu.qml_outline.tsv create mode 100644 tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_mod1_outline.tsv create mode 100644 tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_mod2_outline.tsv create mode 100644 tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_outline.tsv diff --git a/tests/system/objects.map b/tests/system/objects.map index cff13b8456e..2ee61a9e843 100644 --- a/tests/system/objects.map +++ b/tests/system/objects.map @@ -91,6 +91,7 @@ :Qt Creator_CompileOutput_Core::Internal::OutputPaneToggleButton {occurrence='4' type='Core::Internal::OutputPaneToggleButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Core::Internal::CommandComboBox {type='Core::Internal::CommandComboBox' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Core::Internal::MainWindow {type='Core::Internal::MainWindow' visible='1' windowTitle?='*Qt Creator'} +:Qt Creator_Core::Internal::NavComboBox {type='Core::Internal::NavComboBox' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_CppEditor::Internal::CPPEditorWidget {type='CppEditor::Internal::CPPEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_FilenameQComboBox {type='QComboBox' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_Find::Internal::SearchResultTreeView {type='Find::Internal::SearchResultTreeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} @@ -101,6 +102,7 @@ :Qt Creator_QDeclarativeView {type='QDeclarativeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_QHelpContentWidget {type='QHelpContentWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_QTableView {type='QTableView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} +:Qt Creator_QmlJSEditor::Internal::QmlJSOutlineTreeView {type='QmlJSEditor::Internal::QmlJSOutlineTreeView' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_QmlJSEditor::QmlJSTextEditorWidget {type='QmlJSEditor::QmlJSTextEditorWidget' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_SearchResult_Core::Internal::OutputPaneToggleButton {occurrence='2' type='Core::Internal::OutputPaneToggleButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} :Qt Creator_SystemSettings.Details_Utils::DetailsButton {occurrence='4' text='Details' type='Utils::DetailsButton' unnamed='1' visible='1' window=':Qt Creator_Core::Internal::MainWindow'} diff --git a/tests/system/shared/editor_utils.py b/tests/system/shared/editor_utils.py index 7200725346d..45d533420ee 100644 --- a/tests/system/shared/editor_utils.py +++ b/tests/system/shared/editor_utils.py @@ -294,6 +294,7 @@ def invokeFindUsage(editor, line, typeOperation, n=1): def openDocument(treeElement): try: + selectFromCombo(":Qt Creator_Core::Internal::NavComboBox", "Open Documents") navigator = waitForObject(":Qt Creator_Utils::NavigationTreeView") fileName = waitForObjectItem(navigator, treeElement).text doubleClickItem(navigator, treeElement, 5, 5, 0, Qt.LeftButton) diff --git a/tests/system/suite_qtquick/suite.conf b/tests/system/suite_qtquick/suite.conf index 7700a40c5aa..b7ff85fa5ae 100644 --- a/tests/system/suite_qtquick/suite.conf +++ b/tests/system/suite_qtquick/suite.conf @@ -7,6 +7,6 @@ HOOK_SUB_PROCESSES=false IMPLICITAUTSTART=0 LANGUAGE=Python OBJECTMAP=../objects.map -TEST_CASES=tst_qtquick_creation tst_qtquick_creation2 tst_qtquick_creation3 tst_qtquick_creation4 +TEST_CASES=tst_qml_outline tst_qtquick_creation tst_qtquick_creation2 tst_qtquick_creation3 tst_qtquick_creation4 VERSION=2 WRAPPERS=Qt diff --git a/tests/system/suite_qtquick/tst_qml_outline/test.py b/tests/system/suite_qtquick/tst_qml_outline/test.py new file mode 100644 index 00000000000..3a15c78183d --- /dev/null +++ b/tests/system/suite_qtquick/tst_qml_outline/test.py @@ -0,0 +1,114 @@ +source("../../shared/qtcreator.py") + +qmlEditor = ":Qt Creator_QmlJSEditor::QmlJSTextEditorWidget" +outline = ":Qt Creator_QmlJSEditor::Internal::QmlJSOutlineTreeView" + +def main(): + sourceExample = os.path.abspath(os.path.join(sdkPath, "Examples", "4.7", "declarative", + "keyinteraction", "focus")) + proFile = "focus.pro" + if not neededFilePresent(os.path.join(sourceExample, proFile)): + return + templateDir = prepareTemplate(sourceExample) + startApplication("qtcreator" + SettingsPath) + openQmakeProject(os.path.join(templateDir, proFile)) + qmlFiles = ["focus.QML.qml.focus\\.qml", "focus.QML.qml.Core.ListMenu\\.qml"] + checkOutlineFor(qmlFiles) + testModify() + invokeMenuItem("File", "Save All") + invokeMenuItem("File", "Exit") + +def checkOutlineFor(qmlFiles): + for qmlFile in qmlFiles: + if not openDocument(qmlFile): + test.fatal("Failed to open file '%s'" % simpleFileName(qmlFile)) + continue + selectFromCombo(":Qt Creator_Core::Internal::NavComboBox", "Outline") + pseudoTree = buildTreeFromOutline() + # __writeOutlineFile__(pseudoTree, simpleFileName(qmlFile)+"_outline.tsv") + verifyOutline(pseudoTree, simpleFileName(qmlFile) + "_outline.tsv") + +def buildTreeFromOutline(): + global outline + model = waitForObject(outline).model() + waitFor("model.rowCount() > 0") + return processChildren(model, QModelIndex(), 0) + +def processChildren(model, startIndex, level): + children = [] + for index in dumpIndices(model, startIndex): + annotationData = str(index.data(Qt.UserRole + 3)) # HACK - taken from source + children.append((str(index.data()), level, annotationData)) + if model.hasChildren(index): + children.extend(processChildren(model, index, level + 1)) + return children + +def testModify(): + global qmlEditor, outline + if not openDocument("focus.QML.qml.focus\\.qml"): + test.fatal("Failed to open file focus.qml") + return + test.log("Testing whether modifications show up inside outline.") + if not placeCursorToLine(qmlEditor, 'color: "#3E606F"'): + return + test.log("Modification: adding a QML element") + typeLines(qmlEditor, ['', '', 'Text {', 'id: addedText', 'text: "Squish QML outline test"', + 'color: "darkcyan"', 'font.bold: true', 'anchors.centerIn: parent']) + selectFromCombo(":Qt Creator_Core::Internal::NavComboBox", "Outline") + snooze(1) # no way to wait for a private signal + pseudoTree = buildTreeFromOutline() + # __writeOutlineFile__(pseudoTree, "focus.qml_mod1_outline.tsv") + verifyOutline(pseudoTree, "focus.qml_mod1_outline.tsv") + test.log("Modification: change existing content") + performModification('color: "#3E606F"', "<Left>", 7, "Left", "white") + performModification('color: "black"', "<Left>", 5, "Left", "#cc00bb") + performModification('rotation: 90', None, 2, "Left", "180") + snooze(1) # no way to wait for a private signal + pseudoTree = buildTreeFromOutline() + # __writeOutlineFile__(pseudoTree, "focus.qml_mod2_outline.tsv") + verifyOutline(pseudoTree, "focus.qml_mod2_outline.tsv") + +def performModification(afterLine, typing, markCount, markDirection, newText): + global qmlEditor + if not placeCursorToLine(qmlEditor, afterLine): + return + if typing: + type(qmlEditor, typing) + markText(qmlEditor, markCount, markDirection) + type(qmlEditor, newText) + +def markText(editor, charCount, direction): + for i in range(charCount): + type(editor, "<Shift+%s>" % direction) + +# used to create the tsv file(s) +def __writeOutlineFile__(outlinePseudoTree, filename): + f = open(filename, "w+") + f.write('"element"\t"nestinglevel"\t"value"\n') + for elem in outlinePseudoTree: + f.write('"%s"\t"%s"\t"%s"\n' % (elem[0], elem[1], elem[2].replace('"', '\"\"'))) + f.close() + +def retrieveData(record): + return (testData.field(record, "element"), + __builtin__.int(testData.field(record, "nestinglevel")), + testData.field(record, "value")) + +def verifyOutline(outlinePseudoTree, datasetFileName): + fileName = datasetFileName[:datasetFileName.index("_")] + expected = map(retrieveData, testData.dataset(datasetFileName)) + if len(expected) != len(outlinePseudoTree): + test.fail("Mismatch in length of expected and found elements of outline. Skipping " + "verification of nodes.", + "Found %d elements, but expected %d" % (len(outlinePseudoTree), len(expected))) + return + for counter, (expectedItem, foundItem) in enumerate(zip(expected, outlinePseudoTree)): + if expectedItem != foundItem: + test.fail("Mismatch in element number %d for '%s'" % (counter + 1, fileName), + "%s != %s" % (str(expectedItem), str(foundItem))) + return + test.passes("All nodes (%d) inside outline match expected nodes for '%s'." + % (len(expected), fileName)) + +def simpleFileName(navigatorFileName): + return ".".join(navigatorFileName.split(".")[-2:]).replace("\\", "") diff --git a/tests/system/suite_qtquick/tst_qml_outline/testdata/ListMenu.qml_outline.tsv b/tests/system/suite_qtquick/tst_qml_outline/testdata/ListMenu.qml_outline.tsv new file mode 100644 index 00000000000..3ca25e4b9c9 --- /dev/null +++ b/tests/system/suite_qtquick/tst_qml_outline/testdata/ListMenu.qml_outline.tsv @@ -0,0 +1,85 @@ +"element" "nestinglevel" "value" +"FocusScope" "0" "" +"clip" "1" "true" +"onActiveFocusChanged" "1" "" +"ListView" "1" "" +"id" "2" "list1" +"y" "2" "activeFocus ? 10 : 40" +"width" "2" "parent.width / 3" +"height" "2" "parent.height - 20" +"focus" "2" "true" +"KeyNavigation.up" "2" "gridMenu" +"KeyNavigation.left" "2" "contextMenu" +"KeyNavigation.right" "2" "list2" +"model" "2" "10" +"cacheBuffer" "2" "200" +"delegate" "2" "" +"ListViewDelegate" "3" "" +"y" "2" "" +"Behavior" "3" "" +"NumberAnimation" "4" "" +"duration" "5" "600" +"easing.type" "5" "Easing.OutQuint" +"ListView" "1" "" +"id" "2" "list2" +"y" "2" "activeFocus ? 10 : 40" +"x" "2" "parseInt(parent.width / 3)" +"width" "2" "parent.width / 3" +"height" "2" "parent.height - 20" +"KeyNavigation.up" "2" "gridMenu" +"KeyNavigation.left" "2" "list1" +"KeyNavigation.right" "2" "list3" +"model" "2" "10" +"cacheBuffer" "2" "200" +"delegate" "2" "" +"ListViewDelegate" "3" "" +"y" "2" "" +"Behavior" "3" "" +"NumberAnimation" "4" "" +"duration" "5" "600" +"easing.type" "5" "Easing.OutQuint" +"ListView" "1" "" +"id" "2" "list3" +"y" "2" "activeFocus ? 10 : 40" +"x" "2" "parseInt(2 * parent.width / 3)" +"width" "2" "parent.width / 3" +"height" "2" "parent.height - 20" +"KeyNavigation.up" "2" "gridMenu" +"KeyNavigation.left" "2" "list2" +"model" "2" "10" +"cacheBuffer" "2" "200" +"delegate" "2" "" +"ListViewDelegate" "3" "" +"y" "2" "" +"Behavior" "3" "" +"NumberAnimation" "4" "" +"duration" "5" "600" +"easing.type" "5" "Easing.OutQuint" +"Rectangle" "1" "" +"width" "2" "parent.width" +"height" "2" "1" +"color" "2" """#D1DBBD""" +"Rectangle" "1" "" +"y" "2" "1" +"width" "2" "parent.width" +"height" "2" "10" +"gradient" "2" "" +"Gradient" "3" "" +"GradientStop" "4" "" +"position" "5" "0.0" +"color" "5" """#3E606F""" +"GradientStop" "4" "" +"position" "5" "1.0" +"color" "5" """transparent""" +"Rectangle" "1" "" +"y" "2" "parent.height - 10" +"width" "2" "parent.width" +"height" "2" "10" +"gradient" "2" "" +"Gradient" "3" "" +"GradientStop" "4" "" +"position" "5" "1.0" +"color" "5" """#3E606F""" +"GradientStop" "4" "" +"position" "5" "0.0" +"color" "5" """transparent""" diff --git a/tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_mod1_outline.tsv b/tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_mod1_outline.tsv new file mode 100644 index 00000000000..d31ad3d1483 --- /dev/null +++ b/tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_mod1_outline.tsv @@ -0,0 +1,81 @@ +"element" "nestinglevel" "value" +"Rectangle" "0" "" +"id" "1" "window" +"width" "1" "800" +"height" "1" "480" +"color" "1" """#3E606F""" +"Text" "1" "" +"id" "2" "addedText" +"text" "2" """Squish QML outline test""" +"color" "2" """darkcyan""" +"font.bold" "2" "true" +"anchors.centerIn" "2" "parent" +"FocusScope" "1" "" +"id" "2" "mainView" +"width" "2" "parent.width" +"height" "2" "parent.height" +"focus" "2" "true" +"GridMenu" "2" "" +"id" "3" "gridMenu" +"width" "3" "parent.width" +"height" "3" "320" +"focus" "3" "true" +"interactive" "3" "parent.activeFocus" +"ListMenu" "2" "" +"id" "3" "listMenu" +"y" "3" "320" +"width" "3" "parent.width" +"height" "3" "320" +"Rectangle" "2" "" +"id" "3" "shade" +"anchors.fill" "3" "parent" +"color" "3" """black""" +"opacity" "3" "0" +"states" "2" "" +"State" "3" "" +"name" "4" """showListViews""" +"PropertyChanges" "4" "" +"target" "5" "gridMenu" +"y" "5" "-160" +"PropertyChanges" "4" "" +"target" "5" "listMenu" +"y" "5" "160" +"transitions" "2" "" +"Transition" "3" "" +"NumberAnimation" "4" "" +"properties" "5" """y""" +"duration" "5" "600" +"easing.type" "5" "Easing.OutQuint" +"Image" "1" "" +"source" "2" """Core/images/arrow.png""" +"rotation" "2" "90" +"anchors.verticalCenter" "2" "parent.verticalCenter" +"MouseArea" "2" "" +"anchors.fill" "3" "parent" +"anchors.margins" "3" "-10" +"onClicked" "3" "contextMenu.focus = true" +"ContextMenu" "1" "" +"id" "2" "contextMenu" +"x" "2" "-265" +"width" "2" "260" +"height" "2" "parent.height" +"states" "1" "" +"State" "2" "" +"name" "3" """contextMenuOpen""" +"when" "3" "!mainView.activeFocus" +"PropertyChanges" "3" "" +"target" "4" "contextMenu" +"x" "4" "0" +"open" "4" "true" +"PropertyChanges" "3" "" +"target" "4" "mainView" +"x" "4" "130" +"PropertyChanges" "3" "" +"target" "4" "shade" +"opacity" "4" "0.25" +"transitions" "1" "" +"Transition" "2" "" +"NumberAnimation" "3" "" +"properties" "4" """x,opacity""" +"duration" "4" "600" +"easing.type" "4" "Easing.OutQuint" diff --git a/tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_mod2_outline.tsv b/tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_mod2_outline.tsv new file mode 100644 index 00000000000..27026b87170 --- /dev/null +++ b/tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_mod2_outline.tsv @@ -0,0 +1,81 @@ +"element" "nestinglevel" "value" +"Rectangle" "0" "" +"id" "1" "window" +"width" "1" "800" +"height" "1" "480" +"color" "1" """white""" +"Text" "1" "" +"id" "2" "addedText" +"text" "2" """Squish QML outline test""" +"color" "2" """darkcyan""" +"font.bold" "2" "true" +"anchors.centerIn" "2" "parent" +"FocusScope" "1" "" +"id" "2" "mainView" +"width" "2" "parent.width" +"height" "2" "parent.height" +"focus" "2" "true" +"GridMenu" "2" "" +"id" "3" "gridMenu" +"width" "3" "parent.width" +"height" "3" "320" +"focus" "3" "true" +"interactive" "3" "parent.activeFocus" +"ListMenu" "2" "" +"id" "3" "listMenu" +"y" "3" "320" +"width" "3" "parent.width" +"height" "3" "320" +"Rectangle" "2" "" +"id" "3" "shade" +"anchors.fill" "3" "parent" +"color" "3" """#cc00bb""" +"opacity" "3" "0" +"states" "2" "" +"State" "3" "" +"name" "4" """showListViews""" +"PropertyChanges" "4" "" +"target" "5" "gridMenu" +"y" "5" "-160" +"PropertyChanges" "4" "" +"target" "5" "listMenu" +"y" "5" "160" +"transitions" "2" "" +"Transition" "3" "" +"NumberAnimation" "4" "" +"properties" "5" """y""" +"duration" "5" "600" +"easing.type" "5" "Easing.OutQuint" +"Image" "1" "" +"source" "2" """Core/images/arrow.png""" +"rotation" "2" "180" +"anchors.verticalCenter" "2" "parent.verticalCenter" +"MouseArea" "2" "" +"anchors.fill" "3" "parent" +"anchors.margins" "3" "-10" +"onClicked" "3" "contextMenu.focus = true" +"ContextMenu" "1" "" +"id" "2" "contextMenu" +"x" "2" "-265" +"width" "2" "260" +"height" "2" "parent.height" +"states" "1" "" +"State" "2" "" +"name" "3" """contextMenuOpen""" +"when" "3" "!mainView.activeFocus" +"PropertyChanges" "3" "" +"target" "4" "contextMenu" +"x" "4" "0" +"open" "4" "true" +"PropertyChanges" "3" "" +"target" "4" "mainView" +"x" "4" "130" +"PropertyChanges" "3" "" +"target" "4" "shade" +"opacity" "4" "0.25" +"transitions" "1" "" +"Transition" "2" "" +"NumberAnimation" "3" "" +"properties" "4" """x,opacity""" +"duration" "4" "600" +"easing.type" "4" "Easing.OutQuint" diff --git a/tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_outline.tsv b/tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_outline.tsv new file mode 100644 index 00000000000..0f72a543a0c --- /dev/null +++ b/tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_outline.tsv @@ -0,0 +1,75 @@ +"element" "nestinglevel" "value" +"Rectangle" "0" "" +"id" "1" "window" +"width" "1" "800" +"height" "1" "480" +"color" "1" """#3E606F""" +"FocusScope" "1" "" +"id" "2" "mainView" +"width" "2" "parent.width" +"height" "2" "parent.height" +"focus" "2" "true" +"GridMenu" "2" "" +"id" "3" "gridMenu" +"width" "3" "parent.width" +"height" "3" "320" +"focus" "3" "true" +"interactive" "3" "parent.activeFocus" +"ListMenu" "2" "" +"id" "3" "listMenu" +"y" "3" "320" +"width" "3" "parent.width" +"height" "3" "320" +"Rectangle" "2" "" +"id" "3" "shade" +"anchors.fill" "3" "parent" +"color" "3" """black""" +"opacity" "3" "0" +"states" "2" "" +"State" "3" "" +"name" "4" """showListViews""" +"PropertyChanges" "4" "" +"target" "5" "gridMenu" +"y" "5" "-160" +"PropertyChanges" "4" "" +"target" "5" "listMenu" +"y" "5" "160" +"transitions" "2" "" +"Transition" "3" "" +"NumberAnimation" "4" "" +"properties" "5" """y""" +"duration" "5" "600" +"easing.type" "5" "Easing.OutQuint" +"Image" "1" "" +"source" "2" """Core/images/arrow.png""" +"rotation" "2" "90" +"anchors.verticalCenter" "2" "parent.verticalCenter" +"MouseArea" "2" "" +"anchors.fill" "3" "parent" +"anchors.margins" "3" "-10" +"onClicked" "3" "contextMenu.focus = true" +"ContextMenu" "1" "" +"id" "2" "contextMenu" +"x" "2" "-265" +"width" "2" "260" +"height" "2" "parent.height" +"states" "1" "" +"State" "2" "" +"name" "3" """contextMenuOpen""" +"when" "3" "!mainView.activeFocus" +"PropertyChanges" "3" "" +"target" "4" "contextMenu" +"x" "4" "0" +"open" "4" "true" +"PropertyChanges" "3" "" +"target" "4" "mainView" +"x" "4" "130" +"PropertyChanges" "3" "" +"target" "4" "shade" +"opacity" "4" "0.25" +"transitions" "1" "" +"Transition" "2" "" +"NumberAnimation" "3" "" +"properties" "4" """x,opacity""" +"duration" "4" "600" +"easing.type" "4" "Easing.OutQuint" -- GitLab