aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Stenger <christian.stenger@digia.com>2012-10-30 12:05:27 +0100
committerChristian Stenger <christian.stenger@digia.com>2013-01-18 13:58:33 +0100
commit00dab06535278da1cbfb2a11e93c38258aed3655 (patch)
treefcb6a68c356d846632538a85a324d508f64d7b7d
parentfbb197655bcb4b0289da00af987ccdb58928cdfd (diff)
Squish: Added test for QML outline
Change-Id: I6199cf22da0049319c2eaef6977884ed7f63a4fd Reviewed-by: Robert Loehning <robert.loehning@digia.com>
-rw-r--r--tests/system/objects.map2
-rw-r--r--tests/system/shared/editor_utils.py1
-rw-r--r--tests/system/suite_qtquick/suite.conf2
-rw-r--r--tests/system/suite_qtquick/tst_qml_outline/test.py114
-rw-r--r--tests/system/suite_qtquick/tst_qml_outline/testdata/ListMenu.qml_outline.tsv85
-rw-r--r--tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_mod1_outline.tsv81
-rw-r--r--tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_mod2_outline.tsv81
-rw-r--r--tests/system/suite_qtquick/tst_qml_outline/testdata/focus.qml_outline.tsv75
8 files changed, 440 insertions, 1 deletions
diff --git a/tests/system/objects.map b/tests/system/objects.map
index cff13b8456..2ee61a9e84 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 7200725346..45d533420e 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 7700a40c5a..b7ff85fa5a 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 0000000000..3a15c78183
--- /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 0000000000..3ca25e4b9c
--- /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 0000000000..d31ad3d148
--- /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 0000000000..27026b8717
--- /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 0000000000..0f72a543a0
--- /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"