Merge lp:~zsombi/ubuntu-ui-toolkit/ubuntutestcase-extras into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Merged
Approved by: Tim Peeters
Approved revision: 1007
Merged at revision: 1002
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/ubuntutestcase-extras
Merge into: lp:ubuntu-ui-toolkit/staging
Diff against target: 275 lines (+181/-18)
5 files modified
components.api (+2/-0)
modules/Ubuntu/Test/UbuntuTestCase.qml (+69/-1)
modules/Ubuntu/Test/deployment.pri (+6/-1)
tests/unit/runtest.sh (+1/-1)
tests/unit_x11/tst_test/tst_ubuntutestcase.qml (+103/-15)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/ubuntutestcase-extras
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Tim Peeters Approve
Review via email: mp+214927@code.launchpad.net

This proposal supersedes a proposal from 2014-04-08.

Commit message

Flick and mouse long press simulation added to UbuntuTestCase.

To post a comment you must log in.
Revision history for this message
Tim Peeters (tpeeters) wrote : Posted in a previous version of this proposal

12 + The function simulates a flick event over an \item. The flick is executed
13 + between \a from and \to points (built using Qt.point()) with a given \a speed

I think \item should be \a item and \to should be \a to.

Revision history for this message
Tim Peeters (tpeeters) wrote : Posted in a previous version of this proposal

Why is poinCount = 5 needed? Does a single mouseMove not work as a flick?

Revision history for this message
Tim Peeters (tpeeters) wrote : Posted in a previous version of this proposal

This code can be written a bit nicer:
39 + for (var i = 0; i < pointCount; i++) {
40 + mouseMove(item, from.x + (i + 1) * dx / pointCount, from.y + (i + 1) * dy / pointCount, speed);
41 + }

var dx = (to.x - from.x) / pointCount;
var dy = (to.y - from.y) / pointCount;

for (var i = 1; i <= pointCount; i++) {
  mouseMove(item, from.x + i*dx, from.y + i*dy, speed);
}

Revision history for this message
Zsombor Egri (zsombi) wrote : Posted in a previous version of this proposal

> Why is poinCount = 5 needed? Does a single mouseMove not work as a flick?

No, it doesn't. I took the function btw from the tst_textarea_in_flickable.qml, and that's how we did there. One mouse move only takes a small move, and may not even be recognized.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
Zsombor Egri (zsombi) wrote : Posted in a previous version of this proposal

> This code can be written a bit nicer:
> 39 + for (var i = 0; i < pointCount; i++) {
> 40 + mouseMove(item, from.x + (i + 1) * dx / pointCount, from.y + (i + 1)
> * dy / pointCount, speed);
> 41 + }
>
>
> var dx = (to.x - from.x) / pointCount;
> var dy = (to.y - from.y) / pointCount;
>
> for (var i = 1; i <= pointCount; i++) {
> mouseMove(item, from.x + i*dx, from.y + i*dy, speed);
> }

Yep, used. I copied the code as was in the test. I modified the API and implementation to be closer to mouseXXX() functions. Please check it once more.

Revision history for this message
Zsombor Egri (zsombi) wrote : Posted in a previous version of this proposal

> > Why is poinCount = 5 needed? Does a single mouseMove not work as a flick?
>
> No, it doesn't. I took the function btw from the
> tst_textarea_in_flickable.qml, and that's how we did there. One mouse move
> only takes a small move, and may not even be recognized.

So: we need at least two mouse moves to trigger a flick on a Flickable. I defaulted the implementation to 5 points (as in mouseDrag() function) and it can be altered by the steps parameter - the bigger the steps number is the longer the flick will be.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal
review: Approve (continuous-integration)
Revision history for this message
Tim Peeters (tpeeters) wrote :

53 + var ddx = (to.x - from.x) / steps;
54 + var ddy = (to.y - from.y) / steps;

You don't need to compute "to" anymore. Just use ddx = dx / steps.

review: Needs Fixing
Revision history for this message
Tim Peeters (tpeeters) wrote :

"from" is also not needed. You can use x and y.

You only use "to" here:
64 + mouseRelease(item, to.x, to.y, button, modifiers, delay);
but there you can easily say x+dx, y+dy.

Revision history for this message
Tim Peeters (tpeeters) wrote :

30 + The default flick velocity is built up using 5 move points. This can be altered
31 + by setting a positive value to \a steps parameter. The bigger the number the
32 + longer the flick will be.

Can you add something like this?
"When a negative value is given, the default of 5 move points will be used."

Revision history for this message
Tim Peeters (tpeeters) wrote :

also for the pressTimeout. "Setting a negative value will disable the press timeout."

Revision history for this message
Tim Peeters (tpeeters) wrote :

First MR ready to go in staging :)

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'components.api'
--- components.api 2014-03-14 16:11:00 +0000
+++ components.api 2014-04-09 12:37:48 +0000
@@ -592,6 +592,8 @@
592 function findChild(obj,objectName)592 function findChild(obj,objectName)
593 function findInvisibleChild(obj,objectName)593 function findInvisibleChild(obj,objectName)
594 function mouseMoveSlowly(item,x,y,dx,dy,steps,stepdelay)594 function mouseMoveSlowly(item,x,y,dx,dy,steps,stepdelay)
595 function flick(item, x, y, dx, dy, pressTimeout, steps, button, modifiers, delay)
596 function mouseLongPress(item, x, y, button, modifiers, delay)
595 function tryCompareFunction(func, expectedResult, timeout)597 function tryCompareFunction(func, expectedResult, timeout)
596plugins.qmltypes598plugins.qmltypes
597 name: "InverseMouseAreaType"599 name: "InverseMouseAreaType"
598600
=== modified file 'modules/Ubuntu/Test/UbuntuTestCase.qml'
--- modules/Ubuntu/Test/UbuntuTestCase.qml 2014-02-25 12:36:27 +0000
+++ modules/Ubuntu/Test/UbuntuTestCase.qml 2014-04-09 12:37:48 +0000
@@ -87,7 +87,75 @@
87 }87 }
88 }88 }
8989
90 /*!90 /*!
91 \qmlmethod UbuntuTestCase::flick(item, x, y, dx, dy, pressTimeout = -1, steps = -1, button = Qt.LeftButton, modifiers = Qt.NoModifiers, delay = -1)
92
93 The function produces a flick event when executed on Flickables. When used
94 on other components it provides the same functionality as \l mouseDrag()
95 function. The optional \a pressTimeout parameter can be used to introduce
96 a small delay between the mouse press and the first mouse move. Setting a
97 negative or zero value will disable the timeout.
98
99 The default flick velocity is built up using 5 move points. This can be altered
100 by setting a positive value to \a steps parameter. The bigger the number the
101 longer the flick will be. When a negative or zero value is given, the default
102 of 5 move points will be used.
103
104 \note The function can be used to select a text in a TextField or TextArea by
105 specifying at least 400 millisecods to \a pressTimeout.
106 */
107 function flick(item, x, y, dx, dy, pressTimeout, steps, button, modifiers, delay) {
108 if (item === undefined || item.x === undefined || item.y === undefined)
109 return
110 if (button === undefined)
111 button = Qt.LeftButton
112 if (modifiers === undefined)
113 modifiers = Qt.NoModifier
114 if (steps === undefined || steps <= 0)
115 steps = 4;
116 // make sure we have at least two move steps so the flick will be sensed
117 steps += 1;
118 if (delay === undefined)
119 delay = -1;
120
121 var ddx = dx / steps;
122 var ddy = dy / steps;
123
124 mousePress(item, x, y, button, modifiers, delay);
125 if (pressTimeout !== undefined && pressTimeout > 0) {
126 wait(pressTimeout);
127 }
128 for (var i = 1; i <= steps; i++) {
129 // mouse moves are all processed immediately, without delay in between events
130 mouseMove(item, x + i * ddx, y + i * ddy, -1, button);
131 }
132 mouseRelease(item, x + dx, y + dy, button, modifiers, delay);
133 // empty event buffer
134 wait(200);
135 }
136
137 /*!
138 \qmlmethod UbuntuTestCase::mouseLongPress(item, x, y, button = Qt.LeftButton, modifiers = Qt.NoModifiers, delay = -1)
139
140 Simulates a long press on a mouse \a button with an optional \a modifier
141 on an \a item. The position is defined by \a x and \a y. If \a delay is
142 specified, the test will wait the specified amount of milliseconds before
143 the press.
144
145 The position given by \a x and \a y is transformed from the co-ordinate
146 system of \a item into window co-ordinates and then delivered.
147 If \a item is obscured by another item, or a child of \a item occupies
148 that position, then the event will be delivered to the other item instead.
149
150 \sa mouseRelease(), mouseClick(), mouseDoubleClick(), mouseMove(), mouseDrag(), mouseWheel()
151 */
152 function mouseLongPress(item, x, y, button, modifiers, delay) {
153 mousePress(item, x, y, button, modifiers, delay);
154 // the delay is taken from QQuickMouseArea
155 wait(800);
156 }
157
158 /*!
91 Keeps executing a given parameter-less function until it returns the given159 Keeps executing a given parameter-less function until it returns the given
92 expected result or the timemout is reached (in which case a test failure160 expected result or the timemout is reached (in which case a test failure
93 is generated)161 is generated)
94162
=== modified file 'modules/Ubuntu/Test/deployment.pri'
--- modules/Ubuntu/Test/deployment.pri 2014-01-17 12:30:05 +0000
+++ modules/Ubuntu/Test/deployment.pri 2014-04-09 12:37:48 +0000
@@ -7,9 +7,14 @@
7# make found deployables visible in Qt Creator7# make found deployables visible in Qt Creator
8OTHER_FILES += $$QMLDIR_FILE8OTHER_FILES += $$QMLDIR_FILE
99
10QML_FILES = $$system(ls *.qml)
11JS_FILES = $$system(ls *.js)
12
10# define deployment for found deployables13# define deployment for found deployables
11qmldir_file.path = $$installPath14qmldir_file.path = $$installPath
12qmldir_file.files = $$QMLDIR_FILE15qmldir_file.files = $$QMLDIR_FILE
16qml_files.path = $$installPath
17qml_files.files = $$QML_FILES
13js_files.path = $$installPath18js_files.path = $$installPath
14js_files.files = $$JS_FILES19js_files.files = $$JS_FILES
1520
@@ -20,4 +25,4 @@
20# https://bugreports.qt-project.org/browse/QTBUG-3624325# https://bugreports.qt-project.org/browse/QTBUG-36243
21plugins_qmltypes.extra = $$[QT_INSTALL_BINS]/qmlplugindump -notrelocatable Ubuntu.Test 0.1 ../../ 2>/dev/null > $(INSTALL_ROOT)/$$installPath/plugins.qmltypes26plugins_qmltypes.extra = $$[QT_INSTALL_BINS]/qmlplugindump -notrelocatable Ubuntu.Test 0.1 ../../ 2>/dev/null > $(INSTALL_ROOT)/$$installPath/plugins.qmltypes
2227
23INSTALLS += qmldir_file plugins_qmltypes28INSTALLS += qmldir_file plugins_qmltypes qml_files js_files
2429
=== modified file 'tests/unit/runtest.sh'
--- tests/unit/runtest.sh 2014-03-31 18:26:46 +0000
+++ tests/unit/runtest.sh 2014-04-09 12:37:48 +0000
@@ -33,7 +33,7 @@
33 if [ $_TARGET != $_TESTFILE ]; then33 if [ $_TARGET != $_TESTFILE ]; then
34 _CMD="$_CMD -input $_TESTFILE"34 _CMD="$_CMD -input $_TESTFILE"
35 fi35 fi
36 _CMD="$_CMD -maxwarnings 4"36 _CMD="$_CMD -maxwarnings 40"
37}37}
3838
39function execute_test_cmd {39function execute_test_cmd {
4040
=== modified file 'tests/unit_x11/tst_test/tst_ubuntutestcase.qml'
--- tests/unit_x11/tst_test/tst_ubuntutestcase.qml 2014-02-13 10:27:14 +0000
+++ tests/unit_x11/tst_test/tst_ubuntutestcase.qml 2014-04-09 12:37:48 +0000
@@ -23,30 +23,57 @@
23 width: 80023 width: 800
24 height: 60024 height: 600
2525
26 MouseArea {26 Column {
27 id: mouseArea27 anchors.fill: parent
28 objectName: "myMouseArea"28 MouseArea {
29 anchors.fill: parent29 id: mouseArea
30 hoverEnabled: true30 objectName: "myMouseArea"
31 property int testX : 031 width: parent.width
32 property int testY : 032 height: 300
33 property int steps : 033 hoverEnabled: true
34 acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton
35 property int testX : 0
36 property int testY : 0
37 property int steps : 0
3438
35 onPositionChanged: {39 onPositionChanged: {
36 testX = mouseX;40 testX = mouseX;
37 testY = mouseY;41 testY = mouseY;
38 steps++;42 steps++;
39 }43 }
44 }
45 Flickable {
46 id: flicker
47 width: parent.width
48 height: 400
49 contentWidth: rect.width
50 contentHeight: rect.height
51 clip: true
52 Rectangle {
53 id: rect
54 color: "blue"
55 width: 1000
56 height: 1000
57 }
58 }
40 }59 }
41 60
42 UbuntuTestCase {61 UbuntuTestCase {
43 name: "TestTheUbuntuTestCase"62 name: "TestTheUbuntuTestCase"
44 when: windowShown63 when: windowShown
4564
65 function init() {
66 mouseArea.steps = 0;
67 }
68 function cleanup() {
69 movementSpy.clear();
70 longPressSpy.clear();
71 }
72
46 function test_mouseMoveSlowly() {73 function test_mouseMoveSlowly() {
47 mouseMoveSlowly(root,0,0,800,600,10,100);74 mouseMoveSlowly(root,0,0,800,300,10,100);
48 compare(mouseArea.testX,800);75 compare(mouseArea.testX,800);
49 compare(mouseArea.testY,600);76 compare(mouseArea.testY,300);
50 compare(mouseArea.steps,10);77 compare(mouseArea.steps,10);
51 }78 }
5279
@@ -58,5 +85,66 @@
58 child = findChild(root,"NoSuchChildHere");85 child = findChild(root,"NoSuchChildHere");
59 compare(child===null,true,"When there is no child, function should return null");86 compare(child===null,true,"When there is no child, function should return null");
60 }87 }
88
89 SignalSpy {
90 id: longPressSpy
91 target: mouseArea
92 signalName: "onPressAndHold"
93 }
94
95 function test_longPress_left() {
96 longPressSpy.clear();
97 mouseLongPress(mouseArea, mouseArea.width / 2, mouseArea.height / 2);
98 longPressSpy.wait();
99 // cleanup
100 mouseRelease(mouseArea, mouseArea.width / 2, mouseArea.height / 2);
101 }
102
103 function test_longPress_right() {
104 longPressSpy.clear();
105 mouseLongPress(mouseArea, mouseArea.width / 2, mouseArea.height / 2, Qt.RightButton);
106 longPressSpy.wait();
107 // cleanup
108 mouseRelease(mouseArea, mouseArea.width / 2, mouseArea.height / 2, Qt.RightButton);
109 }
110
111 function test_longPress_middle() {
112 longPressSpy.clear();
113 mouseLongPress(mouseArea, mouseArea.width / 2, mouseArea.height / 2, Qt.MiddleButton);
114 longPressSpy.wait();
115 // cleanup
116 mouseRelease(mouseArea, mouseArea.width / 2, mouseArea.height / 2, Qt.MiddleButton);
117 }
118
119 SignalSpy {
120 id: movementSpy
121 target: flicker
122 signalName: "onMovementEnded"
123 }
124
125 function test_flick_default() {
126 flick(flicker, 0, 0, flicker.width, flicker.height);
127 movementSpy.wait();
128 }
129 function test_flick_long() {
130 flick(flicker, 0, 0, flicker.width, flicker.height, -1, 10);
131 movementSpy.wait();
132 }
133 function test_flick_short() {
134 flick(flicker, 0, 0, flicker.width, flicker.height, -1, 1);
135 movementSpy.wait();
136 }
137 function test_flick_pressTimeout() {
138 flick(flicker, 0, 0, flicker.width, flicker.height, 400);
139 movementSpy.wait();
140 }
141 function test_flick_pressTimeout_short() {
142 flick(flicker, flicker.width, flicker.height, -flicker.width, -flicker.height, 400, 1);
143 movementSpy.wait();
144 }
145 function test_flick_pressTimeout_long() {
146 flick(flicker, flicker.width, flicker.height, -flicker.width, -flicker.height, 400, 100);
147 movementSpy.wait();
148 }
61 }149 }
62}150}

Subscribers

People subscribed via source and target branches