aboutsummaryrefslogtreecommitdiffstats
path: root/tests/auto/controls/data
diff options
context:
space:
mode:
Diffstat (limited to 'tests/auto/controls/data')
-rw-r--r--tests/auto/controls/data/tst_abstractbutton.qml23
-rw-r--r--tests/auto/controls/data/tst_button.qml3
-rw-r--r--tests/auto/controls/data/tst_combobox.qml68
-rw-r--r--tests/auto/controls/data/tst_delaybutton.qml3
-rw-r--r--tests/auto/controls/data/tst_dial.qml22
-rw-r--r--tests/auto/controls/data/tst_spinbox.qml16
-rw-r--r--tests/auto/controls/data/tst_splitview.qml51
-rw-r--r--tests/auto/controls/data/tst_stackview.qml159
-rw-r--r--tests/auto/controls/data/tst_swipedelegate.qml3
-rw-r--r--tests/auto/controls/data/tst_tooltip.qml33
10 files changed, 366 insertions, 15 deletions
diff --git a/tests/auto/controls/data/tst_abstractbutton.qml b/tests/auto/controls/data/tst_abstractbutton.qml
index ee26a6d6..da5642cc 100644
--- a/tests/auto/controls/data/tst_abstractbutton.qml
+++ b/tests/auto/controls/data/tst_abstractbutton.qml
@@ -887,4 +887,27 @@ TestCase {
mouseRelease(control)
compare(clickedSpy.count, 1)
}
+
+ function test_doubleClick() {
+ let control = createTemporaryObject(button, testCase, { text: "Hello" })
+ verify(control)
+
+ let pressedSpy = signalSpy.createObject(control, { target: control, signalName: "pressed" })
+ verify(pressedSpy.valid)
+
+ let releasedSpy = signalSpy.createObject(control, { target: control, signalName: "released" })
+ verify(releasedSpy.valid)
+
+ let clickedSpy = signalSpy.createObject(control, { target: control, signalName: "clicked" })
+ verify(clickedSpy.valid)
+
+ let doubleClickedSpy = signalSpy.createObject(control, { target: control, signalName: "doubleClicked" })
+ verify(doubleClickedSpy.valid)
+
+ mouseDoubleClickSequence(control)
+ compare(pressedSpy.count, 2)
+ compare(releasedSpy.count, 2)
+ compare(clickedSpy.count, 1)
+ compare(doubleClickedSpy.count, 1)
+ }
}
diff --git a/tests/auto/controls/data/tst_button.qml b/tests/auto/controls/data/tst_button.qml
index bd4fe80e..83a6ea61 100644
--- a/tests/auto/controls/data/tst_button.qml
+++ b/tests/auto/controls/data/tst_button.qml
@@ -152,8 +152,7 @@ TestCase {
"doubleClicked",
["pressedChanged", { "pressed": false }],
["downChanged", { "down": false }],
- "released",
- "clicked"]
+ "released"]
mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton)
verify(sequenceSpy.success)
}
diff --git a/tests/auto/controls/data/tst_combobox.qml b/tests/auto/controls/data/tst_combobox.qml
index 2cf71f73..2d5069b3 100644
--- a/tests/auto/controls/data/tst_combobox.qml
+++ b/tests/auto/controls/data/tst_combobox.qml
@@ -1853,4 +1853,72 @@ TestCase {
closedSpy.wait()
compare(closedSpy.count, 1)
}
+
+ function test_comboBoxSelectTextByMouse() {
+ let control = createTemporaryObject(comboBox, testCase,
+ { editable: true, selectTextByMouse: true, model: [ "Some text" ], width: parent.width })
+ verify(control)
+ waitForRendering(control)
+ control.forceActiveFocus()
+
+ // Position the text cursor at the beginning of the text.
+ mouseClick(control, control.leftPadding, control.height / 2)
+ // Select all of the text.
+ mousePress(control, control.leftPadding, control.height / 2)
+ mouseMove(control, control.leftPadding + control.contentItem.width, control.height / 2)
+ mouseRelease(control, control.leftPadding + control.contentItem.width, control.height / 2)
+ compare(control.contentItem.selectedText, "Some text")
+ }
+
+ // QTBUG-78885: When the edit text is changed on an editable ComboBox,
+ // and then that ComboBox loses focus, its currentIndex should change
+ // to the index of the edit text (assuming a match is found).
+ function test_currentIndexChangeOnLostFocus() {
+ if (Qt.styleHints.tabFocusBehavior !== Qt.TabFocusAllControls)
+ skip("This platform only allows tab focus for text controls")
+
+ let theModel = []
+ for (let i = 0; i < 10; ++i)
+ theModel.push("Item " + (i + 1))
+
+ let comboBox1 = createTemporaryObject(comboBox, testCase,
+ { objectName: "comboBox1", editable: true, model: theModel })
+ verify(comboBox1)
+ compare(comboBox1.currentIndex, 0)
+
+ let comboBox2 = createTemporaryObject(comboBox, testCase, { objectName: "comboBox2" })
+ verify(comboBox2)
+
+ // Give the first ComboBox focus and type in 0 to select "Item 10" (default is "Item 1").
+ waitForRendering(comboBox1)
+ comboBox1.forceActiveFocus()
+ verify(comboBox1.activeFocus)
+ keyClick(Qt.Key_0)
+ compare(comboBox1.editText, "Item 10")
+
+ let currentIndexSpy = signalSpy.createObject(comboBox1,
+ { target: comboBox1, signalName: "currentIndexChanged" })
+ verify(currentIndexSpy.valid)
+
+ // Give focus to the other ComboBox so that the first one loses it.
+ // The first ComboBox's currentIndex should change to that of "Item 10".
+ keyClick(Qt.Key_Tab)
+ verify(comboBox2.activeFocus)
+ compare(comboBox1.currentIndex, 9)
+ compare(currentIndexSpy.count, 1)
+
+ // Give focus back to the first ComboBox, and try the same thing except
+ // with non-existing text; the currentIndex should not change.
+ comboBox1.forceActiveFocus()
+ verify(comboBox1.activeFocus)
+ keySequence(StandardKey.SelectAll)
+ compare(comboBox1.contentItem.selectedText, "Item 10")
+ keyClick(Qt.Key_N)
+ keyClick(Qt.Key_O)
+ keyClick(Qt.Key_P)
+ keyClick(Qt.Key_E)
+ compare(comboBox1.editText, "nope")
+ compare(comboBox1.currentIndex, 9)
+ compare(currentIndexSpy.count, 1)
+ }
}
diff --git a/tests/auto/controls/data/tst_delaybutton.qml b/tests/auto/controls/data/tst_delaybutton.qml
index 2560177d..e965b5ef 100644
--- a/tests/auto/controls/data/tst_delaybutton.qml
+++ b/tests/auto/controls/data/tst_delaybutton.qml
@@ -173,8 +173,7 @@ TestCase {
"doubleClicked",
["pressedChanged", { "pressed": false }],
["downChanged", { "down": false }],
- "released",
- "clicked"]
+ "released"]
mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton)
verify(sequenceSpy.success)
}
diff --git a/tests/auto/controls/data/tst_dial.qml b/tests/auto/controls/data/tst_dial.qml
index 86999594..26f30c33 100644
--- a/tests/auto/controls/data/tst_dial.qml
+++ b/tests/auto/controls/data/tst_dial.qml
@@ -223,33 +223,39 @@ TestCase {
var minimumExpectedValueCount = data.live ? 2 : 1;
// drag to the left
- mouseDrag(dial, dial.width / 2, dial.height / 2, -dial.width / 2, 0, Qt.LeftButton);
+ // we always add or subtract 1 to ensure we start the drag from the opposite side
+ // of where we're dragging to, for more reliable tests
+ mouseDrag(dial, dial.width / 2 + 1, dial.height / 2, -dial.width / 2, 0, Qt.LeftButton);
fuzzyCompare(dial.value, data.leftValue, 0.1);
- verify(valueSpy.count >= minimumExpectedValueCount);
+ verify(valueSpy.count >= minimumExpectedValueCount, "expected valueChanged to be emitted at least "
+ + minimumExpectedValueCount + " time(s), but it was only emitted " + valueSpy.count + " time(s)");
valueSpy.clear();
verify(moveSpy.count > 0);
moveSpy.clear();
// drag to the top
- mouseDrag(dial, dial.width / 2, dial.height / 2, 0, -dial.height / 2, Qt.LeftButton);
+ mouseDrag(dial, dial.width / 2, dial.height / 2 + 1, 0, -dial.height / 2, Qt.LeftButton);
fuzzyCompare(dial.value, data.topValue, 0.1);
- verify(valueSpy.count >= minimumExpectedValueCount);
+ verify(valueSpy.count >= minimumExpectedValueCount, "expected valueChanged to be emitted at least "
+ + minimumExpectedValueCount + " time(s), but it was only emitted " + valueSpy.count + " time(s)");
valueSpy.clear();
verify(moveSpy.count > 0);
moveSpy.clear();
// drag to the right
- mouseDrag(dial, dial.width / 2, dial.height / 2, dial.width / 2, 0, Qt.LeftButton);
+ mouseDrag(dial, dial.width / 2 - 1, dial.height / 2, dial.width / 2, 0, Qt.LeftButton);
fuzzyCompare(dial.value, data.rightValue, 0.1);
- verify(valueSpy.count >= minimumExpectedValueCount);
+ verify(valueSpy.count >= minimumExpectedValueCount, "expected valueChanged to be emitted at least "
+ + minimumExpectedValueCount + " time(s), but it was only emitted " + valueSpy.count + " time(s)");
valueSpy.clear();
verify(moveSpy.count > 0);
moveSpy.clear();
// drag to the bottom (* 0.6 to ensure we don't go over to the minimum position)
- mouseDrag(dial, dial.width / 2, dial.height / 2, 10, dial.height / 2, Qt.LeftButton);
+ mouseDrag(dial, dial.width / 2, dial.height / 2 - 1, 10, dial.height / 2, Qt.LeftButton);
fuzzyCompare(dial.value, data.bottomValue, 0.1);
- verify(valueSpy.count >= minimumExpectedValueCount);
+ verify(valueSpy.count >= minimumExpectedValueCount, "expected valueChanged to be emitted at least "
+ + minimumExpectedValueCount + " time(s), but it was only emitted " + valueSpy.count + " time(s)");
valueSpy.clear();
verify(moveSpy.count > 0);
moveSpy.clear();
diff --git a/tests/auto/controls/data/tst_spinbox.qml b/tests/auto/controls/data/tst_spinbox.qml
index d3a0d8bb..22dbb352 100644
--- a/tests/auto/controls/data/tst_spinbox.qml
+++ b/tests/auto/controls/data/tst_spinbox.qml
@@ -658,4 +658,20 @@ TestCase {
compare(control.displayText, data.displayTexts[i])
}
}
+
+ Component {
+ id: overriddenSpinBox
+ SpinBox {
+ value: 50
+ up.indicator: Rectangle {
+ property string s: "this is the one"
+ }
+ }
+ }
+
+ function test_indicatorOverridden() {
+ var control = createTemporaryObject(overriddenSpinBox, testCase)
+ verify(control)
+ compare(control.up.indicator.s, "this is the one");
+ }
}
diff --git a/tests/auto/controls/data/tst_splitview.qml b/tests/auto/controls/data/tst_splitview.qml
index c125b99e..74e4c68e 100644
--- a/tests/auto/controls/data/tst_splitview.qml
+++ b/tests/auto/controls/data/tst_splitview.qml
@@ -2026,4 +2026,55 @@ TestCase {
compare(control.repeater.count, 3)
compare(control.contentChildren.length, 3)
}
+
+ Component {
+ id: hoverableChildrenSplitViewComponent
+
+ SplitView {
+ handle: handleComponent
+ anchors.fill: parent
+
+ MouseArea {
+ objectName: "mouseArea1"
+ hoverEnabled: true
+
+ SplitView.preferredWidth: 200
+ }
+ MouseArea {
+ objectName: "mouseArea2"
+ hoverEnabled: true
+ }
+ }
+ }
+
+ function test_hoverableChilden() {
+ if (Qt.platform.pluginName === "offscreen" || Qt.platform.pluginName === "minimal")
+ skip("Mouse hovering not functional on offscreen/minimal platforms")
+
+ var control = createTemporaryObject(hoverableChildrenSplitViewComponent, testCase)
+ verify(control)
+
+ verify(isPolishScheduled(control))
+ verify(waitForItemPolished(control))
+
+ // Move the mouse over the handle.
+ var handles = findHandles(control)
+ var targetHandle = handles[0]
+ // Test fails if we don't do two moves for some reason...
+ mouseMove(targetHandle, targetHandle.width / 2, targetHandle.height / 2)
+ mouseMove(targetHandle, targetHandle.width / 2, targetHandle.height / 2)
+ verify(targetHandle.SplitHandle.hovered)
+
+ // Move the mouse to the MouseArea on the left. The handle should no longer be hovered.
+ mouseMove(control, 100, control.height / 2)
+ verify(!targetHandle.SplitHandle.hovered)
+
+ // Move the mouse back over the handle.
+ mouseMove(targetHandle, targetHandle.width / 2, targetHandle.height / 2)
+ verify(targetHandle.SplitHandle.hovered)
+
+ // Move the mouse to the MouseArea on the right. The handle should no longer be hovered.
+ mouseMove(control, control.width - 100, control.height / 2)
+ verify(!targetHandle.SplitHandle.hovered)
+ }
}
diff --git a/tests/auto/controls/data/tst_stackview.qml b/tests/auto/controls/data/tst_stackview.qml
index a9fbf874..c15ce8ea 100644
--- a/tests/auto/controls/data/tst_stackview.qml
+++ b/tests/auto/controls/data/tst_stackview.qml
@@ -1245,4 +1245,163 @@ TestCase {
gc()
verify(control.initialItem)
}
+
+ // Need to use this specific structure in order to reproduce the crash.
+ Component {
+ id: clearUponDestructionContainerComponent
+
+ Item {
+ id: container
+ objectName: "container"
+
+ property alias control: stackView
+ property var onDestructionCallback
+
+ property Component clearUponDestructionComponent: Component {
+ id: clearUponDestructionComponent
+
+ Item {
+ objectName: "clearUponDestructionItem"
+ Component.onDestruction: container.onDestructionCallback(stackView)
+ }
+ }
+
+ StackView {
+ id: stackView
+ initialItem: Item {
+ objectName: "initialItem"
+ }
+ }
+ }
+ }
+
+ // QTBUG-80353
+ // Tests that calling clear() in Component.onDestruction in response to that
+ // item being removed (e.g. via an earlier call to clear()) results in a warning and not a crash.
+ function test_recursiveClearClear() {
+ let container = createTemporaryObject(clearUponDestructionContainerComponent, testCase,
+ { onDestructionCallback: function(stackView) { stackView.clear(StackView.Immediate) }})
+ verify(container)
+
+ let control = container.control
+ control.push(container.clearUponDestructionComponent, StackView.Immediate)
+
+ // Shouldn't crash.
+ ignoreWarning(new RegExp(".*cannot clear while already in the process of removing elements"))
+ control.clear(StackView.Immediate)
+ }
+
+ function test_recursivePopClear() {
+ let container = createTemporaryObject(clearUponDestructionContainerComponent, testCase,
+ { onDestructionCallback: function(stackView) { stackView.clear(StackView.Immediate) }})
+ verify(container)
+
+ let control = container.control
+ control.push(container.clearUponDestructionComponent, StackView.Immediate)
+
+ // Pop all items except the first, removing the second item we pushed in the process.
+ // Shouldn't crash.
+ ignoreWarning(new RegExp(".*cannot clear while already in the process of removing elements"))
+ control.pop(null, StackView.Immediate)
+ }
+
+ function test_recursivePopPop() {
+ let container = createTemporaryObject(clearUponDestructionContainerComponent, testCase,
+ { onDestructionCallback: function(stackView) { stackView.pop(null, StackView.Immediate) }})
+ verify(container)
+
+ let control = container.control
+ // Push an extra item so that we can call pop(null) and reproduce the conditions for the crash.
+ control.push(component, StackView.Immediate)
+ control.push(container.clearUponDestructionComponent, StackView.Immediate)
+
+ // Pop the top item, then pop down to the first item in response.
+ ignoreWarning(new RegExp(".*cannot pop while already in the process of removing elements"))
+ control.pop(StackView.Immediate)
+ }
+
+ function test_recursiveReplaceClear() {
+ let container = createTemporaryObject(clearUponDestructionContainerComponent, testCase,
+ { onDestructionCallback: function(stackView) { stackView.clear(StackView.Immediate) }})
+ verify(container)
+
+ let control = container.control
+ control.push(container.clearUponDestructionComponent, StackView.Immediate)
+
+ // Replace the top item, then clear in response.
+ ignoreWarning(new RegExp(".*cannot clear while already in the process of removing elements"))
+ control.replace(component, StackView.Immediate)
+ }
+
+ function test_recursiveClearReplace() {
+ let container = createTemporaryObject(clearUponDestructionContainerComponent, testCase,
+ { onDestructionCallback: function(stackView) { stackView.replace(component, StackView.Immediate) }})
+ verify(container)
+
+ let control = container.control
+ control.push(container.clearUponDestructionComponent, StackView.Immediate)
+
+ // Replace the top item, then clear in response.
+ ignoreWarning(new RegExp(".*cannot replace while already in the process of removing elements"))
+ control.clear(StackView.Immediate)
+ }
+
+ Component {
+ id: rectangleComponent
+ Rectangle {}
+ }
+
+ Component {
+ id: qtbug57267_StackViewComponent
+
+ StackView {
+ id: stackView
+
+ popEnter: Transition {
+ XAnimator { from: (stackView.mirrored ? -1 : 1) * -stackView.width; to: 0; duration: 400; easing.type: Easing.Linear }
+ }
+ popExit: Transition {
+ XAnimator { from: 0; to: (stackView.mirrored ? -1 : 1) * stackView.width; duration: 400; easing.type: Easing.Linear }
+ }
+ pushEnter: Transition {
+ XAnimator { from: (stackView.mirrored ? -1 : 1) * stackView.width; to: 0; duration: 400; easing.type: Easing.Linear }
+ }
+ pushExit: Transition {
+ XAnimator { from: 0; to: (stackView.mirrored ? -1 : 1) * -stackView.width; duration: 400; easing.type: Easing.Linear }
+ }
+ replaceEnter: Transition {
+ XAnimator { from: (stackView.mirrored ? -1 : 1) * stackView.width; to: 0; duration: 400; easing.type: Easing.Linear }
+ }
+ replaceExit: Transition {
+ XAnimator { from: 0; to: (stackView.mirrored ? -1 : 1) * -stackView.width; duration: 400; easing.type: Easing.Linear }
+ }
+ }
+ }
+
+ function test_qtbug57267() {
+ let redRect = createTemporaryObject(rectangleComponent, testCase, { color: "red" })
+ verify(redRect)
+ let blueRect = createTemporaryObject(rectangleComponent, testCase, { color: "blue" })
+ verify(blueRect)
+ let control = createTemporaryObject(qtbug57267_StackViewComponent, testCase,
+ { "anchors.fill": testCase, initialItem: redRect })
+ verify(control)
+
+ control.replace(blueRect)
+ compare(control.currentItem, blueRect)
+ compare(control.depth, 1)
+
+ // Wait until the animation has started and then interrupt it by pushing the redRect.
+ tryCompare(control, "busy", true)
+ control.replace(redRect)
+ // The blue rect shouldn't be visible since we replaced it and therefore interrupted its animation.
+ tryCompare(blueRect, "visible", false)
+ // We did the replace very early on, so the transition for the redRect should still be happening.
+ compare(control.busy, true)
+ compare(redRect.visible, true)
+
+ // After finishing the transition, the red rect should still be visible.
+ tryCompare(control, "busy", false)
+ compare(redRect.visible, true)
+ }
}
diff --git a/tests/auto/controls/data/tst_swipedelegate.qml b/tests/auto/controls/data/tst_swipedelegate.qml
index 3e2ff460..71eb0b99 100644
--- a/tests/auto/controls/data/tst_swipedelegate.qml
+++ b/tests/auto/controls/data/tst_swipedelegate.qml
@@ -654,8 +654,7 @@ TestCase {
"pressed",
"doubleClicked",
["pressedChanged", { "pressed": false }],
- "released",
- "clicked"
+ "released"
];
mouseDoubleClickSequence(control, control.width / 2, control.height / 2, Qt.LeftButton);
verify(mouseSignalSequenceSpy.success);
diff --git a/tests/auto/controls/data/tst_tooltip.qml b/tests/auto/controls/data/tst_tooltip.qml
index d98a7cc8..6d45b09d 100644
--- a/tests/auto/controls/data/tst_tooltip.qml
+++ b/tests/auto/controls/data/tst_tooltip.qml
@@ -227,15 +227,46 @@ TestCase {
id: toolTipWithExitTransition
ToolTip {
+ Component.onCompleted: contentItem.objectName = "contentItem"
+
enter: Transition {
NumberAnimation { property: "opacity"; from: 0.0; to: 1.0; duration: 100 }
}
exit: Transition {
- NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 1000 }
+ NumberAnimation { property: "opacity"; from: 1.0; to: 0.0; duration: 500 }
}
}
}
+ function test_openDuringExitTransitionWithTimeout() {
+ let control = createTemporaryObject(toolTipWithExitTransition, testCase, { timeout: 250 })
+ verify(control)
+
+ let openedSpy = signalSpy.createObject(control, { target: control, signalName: "opened" })
+ verify(openedSpy.valid)
+
+ control.open()
+ verify(control.visible)
+ // Can't be fully open yet because the enter transition has only just started.
+ compare(control.opened, false)
+ compare(control.enter.running, true)
+ // Wait for it to have opened. We don't check that the opened property is still true
+ // because it can result in hard-to-reproduce flakiness. Instead we just check that
+ // it was opened at some point.
+ tryCompare(openedSpy, "count", 1)
+
+ // Let it timeout and begin the exit transition.
+ tryCompare(control, "opened", false)
+ verify(control.visible)
+ tryCompare(control.exit, "running", true)
+ verify(control.visible)
+
+ // Quickly open it again; it should still timeout eventually.
+ control.open()
+ tryCompare(openedSpy, "count", 2)
+ tryCompare(control.exit, "running", true)
+ }
+
function test_makeVisibleWhileExitTransitionRunning_data() {
return [
{ tag: "imperative", imperative: true },