Merge lp:~elopio/ubuntu-ui-toolkit/device_emulation_scenarios into lp:ubuntu-ui-toolkit
- device_emulation_scenarios
- Merge into trunk
Proposed by
Leo Arias
Status: | Superseded |
---|---|
Proposed branch: | lp:~elopio/ubuntu-ui-toolkit/device_emulation_scenarios |
Merge into: | lp:ubuntu-ui-toolkit |
Diff against target: |
1862 lines (+1146/-187) 34 files modified
components.api (+48/-0) debian/ubuntu-ui-toolkit-autopilot.install (+1/-1) documentation/overview.qdoc (+7/-0) documentation/ubuntu-ui-toolkit-common.qdocconf (+2/-0) examples/ubuntu-ui-toolkit-gallery/Styles.qml (+48/-0) examples/ubuntu-ui-toolkit-gallery/Toolbar.qml (+49/-0) examples/ubuntu-ui-toolkit-gallery/WidgetsModel.qml (+10/-0) modules/Ubuntu/Components/Icon.qml (+2/-2) modules/Ubuntu/Components/Label.qml (+0/-2) modules/Ubuntu/Components/OrientationHelper.qml (+55/-21) modules/Ubuntu/Components/plugin/uctheme.cpp (+10/-0) modules/Ubuntu/Test/UbuntuTestCase.qml (+7/-6) modules/Ubuntu/Test/plugin/plugin.pro (+5/-1) modules/Ubuntu/Test/plugin/testplugin.cpp (+32/-0) modules/Ubuntu/Test/plugin/testplugin.h (+31/-0) modules/Ubuntu/Test/plugin/uctestcase.cpp (+0/-26) modules/Ubuntu/Test/plugin/uctestcase.h (+0/-67) modules/Ubuntu/Test/plugin/uctestextras.cpp (+203/-0) modules/Ubuntu/Test/plugin/uctestextras.h (+46/-0) modules/Ubuntu/Test/qmldir (+1/-0) tests/autopilot/ubuntuuitoolkit/fixture_setup.py (+36/-2) tests/autopilot/ubuntuuitoolkit/scenarios.py (+45/-0) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py (+5/-1) tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py (+23/-1) tests/autopilot/ubuntuuitoolkit/tests/test_scenarios.py (+50/-0) tests/launcher/MouseTouchAdaptor.cpp (+159/-0) tests/launcher/MouseTouchAdaptor.h (+50/-0) tests/launcher/launcher.cpp (+51/-46) tests/launcher/launcher.pro (+6/-4) tests/qmlapicheck.sh (+1/-1) tests/unit/tst_components/tst_label.qml (+5/-0) tests/unit_x11/tst_components/tst_textarea.qml (+1/-0) tests/unit_x11/tst_inversemousearea/tst_inversemouseareatest.cpp (+3/-3) tests/unit_x11/tst_test/tst_ubuntutestcase.qml (+154/-3) |
To merge this branch: | bzr merge lp:~elopio/ubuntu-ui-toolkit/device_emulation_scenarios |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu SDK team | Pending | ||
Review via email:
|
This proposal has been superseded by a proposal from 2014-06-25.
Commit message
Description of the change
To post a comment you must log in.
- 950. By Leo Arias
-
Merged with staging.
- 951. By Leo Arias
-
Merged with trunk.
- 952. By Leo Arias
-
Fixed the merge.
- 953. By Leo Arias
-
Added test scenarios for the gallery.
- 954. By Leo Arias
-
Reverted the size change.
- 955. By Leo Arias
-
Added a test for the device case.
- 956. By Leo Arias
-
Made explicit the use of scenarios.
- 957. By Leo Arias
-
Added python-gi as a dependency.
- 958. By Leo Arias
-
Fixed skip message.
- 959. By Leo Arias
-
Merged with staging.
- 960. By Leo Arias
-
Merged with staging.
- 961. By Leo Arias
-
Start the gallery tests with the toolbar closed.
- 962. By Leo Arias
-
Scroll the thumb from its bottom.
- 963. By Leo Arias
-
Fix pep8.
- 964. By Leo Arias
-
Close the toolbar only when needed.
- 965. By Leo Arias
-
Move to the thumb first.
- 966. By Leo Arias
-
Make sure that all scenarios tests will also run on the phone.
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'components.api' |
2 | --- components.api 2014-05-28 18:08:33 +0000 |
3 | +++ components.api 2014-06-25 19:24:49 +0000 |
4 | @@ -901,3 +901,51 @@ |
5 | prototype: "QQuickItem" |
6 | exports: ["TextureFromImage 0.1", "TextureFromImage 1.0"] |
7 | Property { name: "image"; type: "QImage" } |
8 | + name: "UCTestExtras" |
9 | + prototype: "QObject" |
10 | + exports: ["TestExtras 1.0"] |
11 | + Property { name: "touchPresent"; type: "bool"; isReadonly: true } |
12 | + Method { name: "registerTouchDevice" } |
13 | + Method { |
14 | + name: "touchPress" |
15 | + Parameter { name: "touchId"; type: "int" } |
16 | + Parameter { name: "item"; type: "QQuickItem"; isPointer: true } |
17 | + Parameter { name: "point"; type: "QPoint" } |
18 | + Method { |
19 | + name: "touchRelease" |
20 | + Parameter { name: "touchId"; type: "int" } |
21 | + Parameter { name: "item"; type: "QQuickItem"; isPointer: true } |
22 | + Parameter { name: "point"; type: "QPoint" } |
23 | + Method { |
24 | + name: "touchClick" |
25 | + Parameter { name: "touchId"; type: "int" } |
26 | + Parameter { name: "item"; type: "QQuickItem"; isPointer: true } |
27 | + Parameter { name: "point"; type: "QPoint" } |
28 | + Method { |
29 | + name: "touchLongPress" |
30 | + Parameter { name: "touchId"; type: "int" } |
31 | + Parameter { name: "item"; type: "QQuickItem"; isPointer: true } |
32 | + Parameter { name: "point"; type: "QPoint" } |
33 | + Method { |
34 | + name: "touchDoubleClick" |
35 | + Parameter { name: "touchId"; type: "int" } |
36 | + Parameter { name: "item"; type: "QQuickItem"; isPointer: true } |
37 | + Parameter { name: "point"; type: "QPoint" } |
38 | + Method { |
39 | + name: "touchMove" |
40 | + Parameter { name: "touchId"; type: "int" } |
41 | + Parameter { name: "item"; type: "QQuickItem"; isPointer: true } |
42 | + Parameter { name: "point"; type: "QPoint" } |
43 | + Method { |
44 | + name: "touchDrag" |
45 | + Parameter { name: "touchId"; type: "int" } |
46 | + Parameter { name: "item"; type: "QQuickItem"; isPointer: true } |
47 | + Parameter { name: "from"; type: "QPoint" } |
48 | + Parameter { name: "delta"; type: "QPoint" } |
49 | + Parameter { name: "steps"; type: "int" } |
50 | + Method { |
51 | + name: "touchDrag" |
52 | + Parameter { name: "touchId"; type: "int" } |
53 | + Parameter { name: "item"; type: "QQuickItem"; isPointer: true } |
54 | + Parameter { name: "from"; type: "QPoint" } |
55 | + Parameter { name: "delta"; type: "QPoint" } |
56 | |
57 | === modified file 'debian/ubuntu-ui-toolkit-autopilot.install' |
58 | --- debian/ubuntu-ui-toolkit-autopilot.install 2014-05-14 11:00:20 +0000 |
59 | +++ debian/ubuntu-ui-toolkit-autopilot.install 2014-06-25 19:24:49 +0000 |
60 | @@ -1,3 +1,3 @@ |
61 | usr/lib/python3 |
62 | -usr/lib/ubuntu-ui-toolkit/launcher |
63 | +usr/lib/*/ubuntu-ui-toolkit/launcher |
64 | usr/lib/python2.7 |
65 | |
66 | === modified file 'documentation/overview.qdoc' |
67 | --- documentation/overview.qdoc 2014-04-29 05:39:04 +0000 |
68 | +++ documentation/overview.qdoc 2014-06-25 19:24:49 +0000 |
69 | @@ -106,4 +106,11 @@ |
70 | import Ubuntu.PerformanceMetrics 1.0 |
71 | \endcode |
72 | \annotatedlist ubuntu-performance-metrics |
73 | + |
74 | + \part Test extensions |
75 | + Available through: |
76 | + \code |
77 | + import Ubuntu Test 1.0 |
78 | + \endcode |
79 | + \annotatedlist ubuntu-test |
80 | */ |
81 | |
82 | === modified file 'documentation/ubuntu-ui-toolkit-common.qdocconf' |
83 | --- documentation/ubuntu-ui-toolkit-common.qdocconf 2014-04-29 05:39:04 +0000 |
84 | +++ documentation/ubuntu-ui-toolkit-common.qdocconf 2014-06-25 19:24:49 +0000 |
85 | @@ -8,6 +8,8 @@ |
86 | headerdirs += ../modules/Ubuntu/Layouts/plugin |
87 | sourcedirs += ../modules/Ubuntu/PerformanceMetrics |
88 | headerdirs += ../modules/Ubuntu/PerformanceMetrics/plugin |
89 | +sourcedirs += ../modules/Ubuntu/Test |
90 | +headerdirs += ../modules/Ubuntu/Test/plugin |
91 | exampledirs += snippets |
92 | excludedirs = ../modules/Ubuntu/Components/Themes |
93 | imagedirs = images |
94 | |
95 | === added file 'examples/ubuntu-ui-toolkit-gallery/Styles.qml' |
96 | --- examples/ubuntu-ui-toolkit-gallery/Styles.qml 1970-01-01 00:00:00 +0000 |
97 | +++ examples/ubuntu-ui-toolkit-gallery/Styles.qml 2014-06-25 19:24:49 +0000 |
98 | @@ -0,0 +1,48 @@ |
99 | +/* |
100 | + * Copyright 2014 Canonical Ltd. |
101 | + * |
102 | + * This program is free software; you can redistribute it and/or modify |
103 | + * it under the terms of the GNU Lesser General Public License as published by |
104 | + * the Free Software Foundation; version 3. |
105 | + * |
106 | + * This program is distributed in the hope that it will be useful, |
107 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
108 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
109 | + * GNU Lesser General Public License for more details. |
110 | + * |
111 | + * You should have received a copy of the GNU Lesser General Public License |
112 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
113 | + */ |
114 | + |
115 | +import QtQuick 2.0 |
116 | +import Ubuntu.Components 1.1 |
117 | + |
118 | +Template { |
119 | + objectName: "stylesTemplate" |
120 | + |
121 | + Label { |
122 | + anchors.left: parent.left |
123 | + anchors.right: parent.right |
124 | + |
125 | + text: i18n.tr("Switch between old and new style header") |
126 | + } |
127 | + |
128 | + OptionSelector { |
129 | + model: [ i18n.tr('Header with Toolbar'), i18n.tr('New Style Header') ] |
130 | + expanded: true |
131 | + onSelectedIndexChanged: gallery.useDeprecatedToolbar = (selectedIndex == 0) |
132 | + } |
133 | + |
134 | + Label { |
135 | + anchors.left: parent.left |
136 | + anchors.right: parent.right |
137 | + |
138 | + text: i18n.tr("Switch between themes") |
139 | + } |
140 | + |
141 | + OptionSelector { |
142 | + model: [ 'Ambiance', 'SuruDark' ] |
143 | + expanded: true |
144 | + onSelectedIndexChanged: Theme.name = 'Ubuntu.Components.Themes.%1'.arg(model[selectedIndex]) |
145 | + } |
146 | +} |
147 | |
148 | === added file 'examples/ubuntu-ui-toolkit-gallery/Toolbar.qml' |
149 | --- examples/ubuntu-ui-toolkit-gallery/Toolbar.qml 1970-01-01 00:00:00 +0000 |
150 | +++ examples/ubuntu-ui-toolkit-gallery/Toolbar.qml 2014-06-25 19:24:49 +0000 |
151 | @@ -0,0 +1,49 @@ |
152 | +/* |
153 | + * Copyright 2014 Canonical Ltd. |
154 | + * |
155 | + * This program is free software; you can redistribute it and/or modify |
156 | + * it under the terms of the GNU Lesser General Public License as published by |
157 | + * the Free Software Foundation; version 3. |
158 | + * |
159 | + * This program is distributed in the hope that it will be useful, |
160 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
161 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
162 | + * GNU Lesser General Public License for more details. |
163 | + * |
164 | + * You should have received a copy of the GNU Lesser General Public License |
165 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
166 | + */ |
167 | + |
168 | +import QtQuick 2.0 |
169 | +import Ubuntu.Components 0.1 |
170 | +import Ubuntu.Components.Popups 0.1 |
171 | + |
172 | +Template { |
173 | + objectName: "popoversTemplate" |
174 | + |
175 | + tools: ToolbarItems { |
176 | + ToolbarButton { |
177 | + text: "Call" |
178 | + iconName: "call-start" |
179 | + } |
180 | + ToolbarButton { |
181 | + text: i18n.tr("Share") |
182 | + iconName: "share" |
183 | + } |
184 | + ToolbarButton { |
185 | + iconName: "settings" |
186 | + } |
187 | + ToolbarButton { |
188 | + iconName: "speaker" |
189 | + } |
190 | + } |
191 | + |
192 | + TemplateSection { |
193 | + className: "Toolbar" |
194 | + documentation: "qml-ubuntu-components-toolbar0-%1.html".arg(className.toLowerCase()) |
195 | + |
196 | + TemplateRow { |
197 | + title: i18n.tr("See below") |
198 | + } |
199 | + } |
200 | +} |
201 | |
202 | === modified file 'examples/ubuntu-ui-toolkit-gallery/WidgetsModel.qml' |
203 | --- examples/ubuntu-ui-toolkit-gallery/WidgetsModel.qml 2014-04-30 10:26:35 +0000 |
204 | +++ examples/ubuntu-ui-toolkit-gallery/WidgetsModel.qml 2014-06-25 19:24:49 +0000 |
205 | @@ -23,6 +23,11 @@ |
206 | label: "Navigation" |
207 | source: "Navigation.qml" |
208 | } |
209 | + ListElement { |
210 | + objectName: "stylesElement" |
211 | + label: "Styles" |
212 | + source: "Styles.qml" |
213 | + } |
214 | |
215 | ListElement { |
216 | objectName: "togglesElement" |
217 | @@ -30,6 +35,11 @@ |
218 | source: "Toggles.qml" |
219 | } |
220 | ListElement { |
221 | + objectName: "toolbarElement" |
222 | + label: "Toolbar" |
223 | + source: "Toolbar.qml" |
224 | + } |
225 | + ListElement { |
226 | objectName: "buttonsElement" |
227 | label: "Buttons" |
228 | source: "Buttons.qml" |
229 | |
230 | === modified file 'modules/Ubuntu/Components/Icon.qml' |
231 | --- modules/Ubuntu/Components/Icon.qml 2014-04-23 08:50:20 +0000 |
232 | +++ modules/Ubuntu/Components/Icon.qml 2014-06-25 19:24:49 +0000 |
233 | @@ -103,12 +103,12 @@ |
234 | id: colorizedImage |
235 | |
236 | anchors.fill: parent |
237 | - visible: active && image.status == Image.Ready |
238 | + visible: active |
239 | |
240 | // Whether or not a color has been set. |
241 | property bool active: keyColorOut != Qt.rgba(0.0, 0.0, 0.0, 0.0) |
242 | |
243 | - property Image source: visible ? image : null |
244 | + property Image source: active && image.status == Image.Ready ? image : null |
245 | property color keyColorOut: Qt.rgba(0.0, 0.0, 0.0, 0.0) |
246 | property color keyColorIn: "#808080" |
247 | property real threshold: 0.1 |
248 | |
249 | === modified file 'modules/Ubuntu/Components/Label.qml' |
250 | --- modules/Ubuntu/Components/Label.qml 2014-05-22 09:44:01 +0000 |
251 | +++ modules/Ubuntu/Components/Label.qml 2014-06-25 19:24:49 +0000 |
252 | @@ -55,8 +55,6 @@ |
253 | property string fontSize: "medium" |
254 | |
255 | font.pixelSize: FontUtils.sizeToPixels(fontSize) |
256 | - font.family: "Ubuntu" |
257 | - font.weight: Font.Light |
258 | color: Theme.palette.selected.backgroundText |
259 | |
260 | /* FIXME: workaround for QTBUG 35095 where Text's alignment is incorrect |
261 | |
262 | === modified file 'modules/Ubuntu/Components/OrientationHelper.qml' |
263 | --- modules/Ubuntu/Components/OrientationHelper.qml 2014-06-09 09:07:40 +0000 |
264 | +++ modules/Ubuntu/Components/OrientationHelper.qml 2014-06-25 19:24:49 +0000 |
265 | @@ -14,7 +14,7 @@ |
266 | * along with this program. If not, see <http://www.gnu.org/licenses/>. |
267 | */ |
268 | |
269 | -import QtQuick 2.0 |
270 | +import QtQuick 2.2 |
271 | import QtQuick.Window 2.0 |
272 | import Ubuntu.Components 1.0 |
273 | |
274 | @@ -136,6 +136,17 @@ |
275 | target: orientationHelper |
276 | rotation: 0 |
277 | } |
278 | + StateChangeScript { |
279 | + name: "anchorsScript" |
280 | + script: { |
281 | + orientationHelper.anchors.fill = null; |
282 | + orientationHelper.anchors.leftMargin = 0; |
283 | + orientationHelper.anchors.rightMargin = 0; |
284 | + orientationHelper.anchors.topMargin = 0; |
285 | + orientationHelper.anchors.bottomMargin = 0; |
286 | + orientationHelper.anchors.fill = orientationHelper.parent; |
287 | + } |
288 | + } |
289 | }, |
290 | State { |
291 | name: "180" |
292 | @@ -143,17 +154,33 @@ |
293 | target: orientationHelper |
294 | rotation: 180 |
295 | } |
296 | + StateChangeScript { |
297 | + name: "anchorsScript" |
298 | + script: { |
299 | + orientationHelper.anchors.fill = null; |
300 | + orientationHelper.anchors.leftMargin = 0; |
301 | + orientationHelper.anchors.rightMargin = 0; |
302 | + orientationHelper.anchors.topMargin = 0; |
303 | + orientationHelper.anchors.bottomMargin = 0; |
304 | + orientationHelper.anchors.fill = orientationHelper.parent; |
305 | + } |
306 | + } |
307 | }, |
308 | State { |
309 | name: "270" |
310 | PropertyChanges { |
311 | target: orientationHelper |
312 | rotation: 270 |
313 | - anchors { |
314 | - leftMargin: (parent.width - parent.height) / 2 |
315 | - rightMargin: anchors.leftMargin |
316 | - topMargin: -anchors.leftMargin |
317 | - bottomMargin: anchors.topMargin |
318 | + } |
319 | + StateChangeScript { |
320 | + name: "anchorsScript" |
321 | + script: { |
322 | + orientationHelper.anchors.fill = null; |
323 | + orientationHelper.anchors.topMargin = Qt.binding(function() {return -(parent.width - parent.height) / 2}); |
324 | + orientationHelper.anchors.bottomMargin = Qt.binding(function() {return -(parent.width - parent.height) / 2}); |
325 | + orientationHelper.anchors.leftMargin = Qt.binding(function() {return (parent.width - parent.height) / 2}); |
326 | + orientationHelper.anchors.rightMargin = Qt.binding(function() {return (parent.width - parent.height) / 2}); |
327 | + orientationHelper.anchors.fill = orientationHelper.parent; |
328 | } |
329 | } |
330 | }, |
331 | @@ -162,11 +189,16 @@ |
332 | PropertyChanges { |
333 | target: orientationHelper |
334 | rotation: 90 |
335 | - anchors { |
336 | - leftMargin: (parent.width - parent.height) / 2 |
337 | - rightMargin: anchors.leftMargin |
338 | - topMargin: -anchors.leftMargin |
339 | - bottomMargin: anchors.topMargin |
340 | + } |
341 | + StateChangeScript { |
342 | + name: "anchorsScript" |
343 | + script: { |
344 | + orientationHelper.anchors.fill = null; |
345 | + orientationHelper.anchors.topMargin = Qt.binding(function() {return -(parent.width - parent.height) / 2}); |
346 | + orientationHelper.anchors.bottomMargin = Qt.binding(function() {return -(parent.width - parent.height) / 2}); |
347 | + orientationHelper.anchors.leftMargin = Qt.binding(function() {return (parent.width - parent.height) / 2}); |
348 | + orientationHelper.anchors.rightMargin = Qt.binding(function() {return (parent.width - parent.height) / 2}); |
349 | + orientationHelper.anchors.fill = orientationHelper.parent; |
350 | } |
351 | } |
352 | } |
353 | @@ -176,18 +208,20 @@ |
354 | Transition { |
355 | id: orientationTransition |
356 | ParallelAnimation { |
357 | - SequentialAnimation { |
358 | - PauseAnimation { |
359 | - duration: 25 |
360 | - } |
361 | - PropertyAction { |
362 | - target: orientationHelper |
363 | - properties: "anchors.topMargin,anchors.bottomMargin,anchors.rightMargin,anchors.leftMargin" |
364 | - } |
365 | + /* FIXME: this is a workaround for 2 issues that trigger too many changes |
366 | + to the width and height of orientationHelper which creates intermediary |
367 | + states of the UI with unexpected sizes: |
368 | + 1) upon state change fast-forwarding is used which means that the final values are computed and applied |
369 | + then immediately reverted before the actual transition is applied |
370 | + 2) when margins are applied, width and height are updated separately |
371 | + |
372 | + Without these issues, regular PropertyChanges could be used to set the margins. |
373 | + */ |
374 | + ScriptAction { |
375 | + scriptName: "anchorsScript" |
376 | } |
377 | - RotationAnimation { |
378 | + RotationAnimator { |
379 | target: orientationHelper |
380 | - properties: "rotation" |
381 | duration: UbuntuAnimation.FastDuration |
382 | easing: UbuntuAnimation.StandardEasing |
383 | direction: RotationAnimation.Shortest |
384 | |
385 | === modified file 'modules/Ubuntu/Components/plugin/uctheme.cpp' |
386 | --- modules/Ubuntu/Components/plugin/uctheme.cpp 2014-06-09 08:43:30 +0000 |
387 | +++ modules/Ubuntu/Components/plugin/uctheme.cpp 2014-06-25 19:24:49 +0000 |
388 | @@ -21,6 +21,7 @@ |
389 | #include "listener.h" |
390 | #include "quickutils.h" |
391 | #include "i18n.h" |
392 | +#include "ucfontutils.h" |
393 | |
394 | #include <QtQml/qqml.h> |
395 | #include <QtQml/qqmlinfo.h> |
396 | @@ -32,6 +33,8 @@ |
397 | #include <QtCore/QTextStream> |
398 | #include <QtCore/QLibraryInfo> |
399 | #include <QtCore/QStandardPaths> |
400 | +#include <QtGui/QGuiApplication> |
401 | +#include <QtGui/QFont> |
402 | |
403 | /*! |
404 | \qmltype Theme |
405 | @@ -114,6 +117,13 @@ |
406 | |
407 | QObject::connect(this, SIGNAL(nameChanged()), |
408 | this, SLOT(loadPalette()), Qt::UniqueConnection); |
409 | + |
410 | + // set the default font |
411 | + QFont defaultFont; |
412 | + defaultFont.setFamily("Ubuntu"); |
413 | + defaultFont.setPixelSize(UCFontUtils::instance().sizeToPixels("medium")); |
414 | + defaultFont.setWeight(QFont::Light); |
415 | + QGuiApplication::setFont(defaultFont); |
416 | } |
417 | |
418 | void UCTheme::updateEnginePaths() |
419 | |
420 | === modified file 'modules/Ubuntu/Test/UbuntuTestCase.qml' |
421 | --- modules/Ubuntu/Test/UbuntuTestCase.qml 2014-05-02 07:22:52 +0000 |
422 | +++ modules/Ubuntu/Test/UbuntuTestCase.qml 2014-06-25 19:24:49 +0000 |
423 | @@ -19,9 +19,9 @@ |
424 | import Ubuntu.Components 1.1 |
425 | |
426 | /*! |
427 | - \qmlabstract UbuntuTestCase |
428 | - \inqmlmodule Ubuntu.Test 0.1 |
429 | - \ingroup ubuntu |
430 | + \qmltype UbuntuTestCase |
431 | + \inqmlmodule Ubuntu.Test 1.0 |
432 | + \ingroup ubuntu-test |
433 | \brief The UbuntuTestCase class expands the default TestCase class. |
434 | |
435 | \b{This component is under heavy development.} |
436 | @@ -51,6 +51,9 @@ |
437 | return null; |
438 | } |
439 | |
440 | + /*! |
441 | + Find a non-visual child such as QtObject based on objectName. |
442 | + */ |
443 | function findInvisibleChild(obj,objectName) { |
444 | var childs = new Array(0); |
445 | childs.push(obj) |
446 | @@ -113,7 +116,7 @@ |
447 | \qmlmethod UbuntuTestCase::flick(item, x, y, dx, dy, pressTimeout = -1, steps = -1, button = Qt.LeftButton, modifiers = Qt.NoModifiers, delay = -1) |
448 | |
449 | The function produces a flick event when executed on Flickables. When used |
450 | - on other components it provides the same functionality as \l mouseDrag() |
451 | + on other components it provides the same functionality as \c mouseDrag() |
452 | function. The optional \a pressTimeout parameter can be used to introduce |
453 | a small delay between the mouse press and the first mouse move. Setting a |
454 | negative or zero value will disable the timeout. |
455 | @@ -169,8 +172,6 @@ |
456 | system of \a item into window co-ordinates and then delivered. |
457 | If \a item is obscured by another item, or a child of \a item occupies |
458 | that position, then the event will be delivered to the other item instead. |
459 | - |
460 | - \sa mouseRelease(), mouseClick(), mouseDoubleClick(), mouseMove(), mouseDrag(), mouseWheel() |
461 | */ |
462 | function mouseLongPress(item, x, y, button, modifiers, delay) { |
463 | mousePress(item, x, y, button, modifiers, delay); |
464 | |
465 | === modified file 'modules/Ubuntu/Test/plugin/plugin.pro' |
466 | --- modules/Ubuntu/Test/plugin/plugin.pro 2014-06-10 09:28:21 +0000 |
467 | +++ modules/Ubuntu/Test/plugin/plugin.pro 2014-06-25 19:24:49 +0000 |
468 | @@ -1,6 +1,6 @@ |
469 | TEMPLATE = lib |
470 | TARGET = ../UbuntuTest |
471 | -QT += core-private qml qml-private quick quick-private gui-private |
472 | +QT += core-private qml qml-private quick quick-private gui-private testlib |
473 | |
474 | equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) { |
475 | QT += v8-private |
476 | @@ -15,9 +15,13 @@ |
477 | |
478 | HEADERS += \ |
479 | uctestcase.h \ |
480 | + testplugin.h \ |
481 | + uctestextras.h |
482 | |
483 | SOURCES += \ |
484 | uctestcase.cpp \ |
485 | + testplugin.cpp \ |
486 | + uctestextras.cpp |
487 | |
488 | # deployment rules for the plugin |
489 | installPath = $$[QT_INSTALL_QML]/$$replace(uri, \\., /) |
490 | |
491 | === added file 'modules/Ubuntu/Test/plugin/testplugin.cpp' |
492 | --- modules/Ubuntu/Test/plugin/testplugin.cpp 1970-01-01 00:00:00 +0000 |
493 | +++ modules/Ubuntu/Test/plugin/testplugin.cpp 2014-06-25 19:24:49 +0000 |
494 | @@ -0,0 +1,32 @@ |
495 | +/* |
496 | + * Copyright 2014 Canonical Ltd. |
497 | + * |
498 | + * This program is free software; you can redistribute it and/or modify |
499 | + * it under the terms of the GNU Lesser General Public License as published by |
500 | + * the Free Software Foundation; version 3. |
501 | + * |
502 | + * This program is distributed in the hope that it will be useful, |
503 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
504 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
505 | + * GNU Lesser General Public License for more details. |
506 | + * |
507 | + * You should have received a copy of the GNU Lesser General Public License |
508 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
509 | + */ |
510 | + |
511 | +#include "testplugin.h" |
512 | +#include <QtQml> |
513 | +#include "uctestextras.h" |
514 | + |
515 | +static QObject *registerExtras(QQmlEngine *engine, QJSEngine *scriptEngine) |
516 | +{ |
517 | + Q_UNUSED(engine) |
518 | + Q_UNUSED(scriptEngine) |
519 | + |
520 | + return new UCTestExtras; |
521 | +} |
522 | + |
523 | +void TestPlugin::registerTypes(const char *uri) |
524 | +{ |
525 | + qmlRegisterSingletonType<UCTestExtras>(uri, 1, 0, "TestExtras", registerExtras); |
526 | +} |
527 | |
528 | === added file 'modules/Ubuntu/Test/plugin/testplugin.h' |
529 | --- modules/Ubuntu/Test/plugin/testplugin.h 1970-01-01 00:00:00 +0000 |
530 | +++ modules/Ubuntu/Test/plugin/testplugin.h 2014-06-25 19:24:49 +0000 |
531 | @@ -0,0 +1,31 @@ |
532 | +/* |
533 | + * Copyright 2014 Canonical Ltd. |
534 | + * |
535 | + * This program is free software; you can redistribute it and/or modify |
536 | + * it under the terms of the GNU Lesser General Public License as published by |
537 | + * the Free Software Foundation; version 3. |
538 | + * |
539 | + * This program is distributed in the hope that it will be useful, |
540 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
541 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
542 | + * GNU Lesser General Public License for more details. |
543 | + * |
544 | + * You should have received a copy of the GNU Lesser General Public License |
545 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
546 | + */ |
547 | + |
548 | +#ifndef TESTPLUGIN_H |
549 | +#define TESTPLUGIN_H |
550 | + |
551 | +#include <QQmlExtensionPlugin> |
552 | + |
553 | +class TestPlugin : public QQmlExtensionPlugin |
554 | +{ |
555 | + Q_OBJECT |
556 | + Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QQmlExtensionInterface") |
557 | + |
558 | +public: |
559 | + void registerTypes(const char *uri); |
560 | +}; |
561 | + |
562 | +#endif // TESTPLUGIN_H |
563 | |
564 | === modified file 'modules/Ubuntu/Test/plugin/uctestcase.cpp' |
565 | --- modules/Ubuntu/Test/plugin/uctestcase.cpp 2014-06-10 11:45:11 +0000 |
566 | +++ modules/Ubuntu/Test/plugin/uctestcase.cpp 2014-06-25 19:24:49 +0000 |
567 | @@ -26,11 +26,8 @@ |
568 | #include <QtTest/QtTest> |
569 | #include <QtQuick/QQuickItem> |
570 | |
571 | -#include <qpa/qwindowsysteminterface.h> |
572 | - |
573 | Q_DECLARE_METATYPE(QList<QQmlError>) |
574 | |
575 | -QTouchDevice *UbuntuTestCase::m_touchDevice = 0; |
576 | /*! |
577 | * \ingroup ubuntu |
578 | * \brief UbuntuTestCase is the C++ pendant to the QML UbuntuTestCase. |
579 | @@ -63,26 +60,3 @@ |
580 | return m_spy->count(); |
581 | } |
582 | |
583 | -/*! |
584 | - * Registers a touch device if there's none registered. |
585 | - */ |
586 | -void UbuntuTestCase::registerTouchDevice() |
587 | -{ |
588 | - // check if there is any touch device registered in the system |
589 | - if (!m_touchDevice) { |
590 | - QList<const QTouchDevice*> touchDevices = QTouchDevice::devices(); |
591 | - Q_FOREACH(const QTouchDevice *device, touchDevices) { |
592 | - if (device->type() == QTouchDevice::TouchScreen) { |
593 | - m_touchDevice = const_cast<QTouchDevice*>(device); |
594 | - break; |
595 | - } |
596 | - } |
597 | - } |
598 | - // if none, register one |
599 | - if (!m_touchDevice) { |
600 | - m_touchDevice = new QTouchDevice; |
601 | - m_touchDevice->setType(QTouchDevice::TouchScreen); |
602 | - QWindowSystemInterface::registerTouchDevice(m_touchDevice); |
603 | - } |
604 | -} |
605 | - |
606 | |
607 | === modified file 'modules/Ubuntu/Test/plugin/uctestcase.h' |
608 | --- modules/Ubuntu/Test/plugin/uctestcase.h 2014-06-10 11:45:11 +0000 |
609 | +++ modules/Ubuntu/Test/plugin/uctestcase.h 2014-06-25 19:24:49 +0000 |
610 | @@ -24,8 +24,6 @@ |
611 | #include <QtQuick/QQuickView> |
612 | #include <QtTest/QSignalSpy> |
613 | |
614 | -#define CHECK_TOUCH_DEVICE() if (!checkTouchDevice(__FUNCTION__)) return |
615 | - |
616 | class UbuntuTestCase : public QQuickView |
617 | { |
618 | Q_OBJECT |
619 | @@ -44,73 +42,8 @@ |
620 | qFatal("No item '%s' found", qPrintable(objectName)); |
621 | } |
622 | |
623 | - static void registerTouchDevice(); |
624 | - |
625 | - inline static void touchPress(int touchId, QWindow *window, const QPoint &point) |
626 | - { |
627 | - CHECK_TOUCH_DEVICE(); |
628 | - QTest::touchEvent(window, m_touchDevice).press(touchId, point, window); |
629 | - } |
630 | - inline static void touchRelease(int touchId, QWindow *window, const QPoint &point) |
631 | - { |
632 | - CHECK_TOUCH_DEVICE(); |
633 | - QTest::touchEvent(window, m_touchDevice).release(touchId, point, window); |
634 | - } |
635 | - inline static void touchClick(int touchId, QWindow *window, const QPoint &point) |
636 | - { |
637 | - CHECK_TOUCH_DEVICE(); |
638 | - touchPress(touchId, window, point); |
639 | - QTest::qWait(10); |
640 | - touchRelease(touchId, window, point); |
641 | - } |
642 | - inline static void touchLongPress(int touchId, QWindow *window, const QPoint &point) |
643 | - { |
644 | - CHECK_TOUCH_DEVICE(); |
645 | - touchPress(touchId, window, point); |
646 | - QTest::qWait(800); |
647 | - } |
648 | - inline static void touchDoubleClick(int touchId, QWindow *window, const QPoint &point) |
649 | - { |
650 | - CHECK_TOUCH_DEVICE(); |
651 | - touchClick(touchId, window, point); |
652 | - QTest::qWait(10); |
653 | - touchClick(touchId, window, point); |
654 | - } |
655 | - inline static void touchMove(int touchId, QWindow *window, const QPoint &point) |
656 | - { |
657 | - CHECK_TOUCH_DEVICE(); |
658 | - QTest::touchEvent(window, m_touchDevice).move(touchId, point, window); |
659 | - } |
660 | - inline static void touchDrag(int touchId, QWindow *window, const QPoint &from, const QPoint &delta, int steps = 5) |
661 | - { |
662 | - touchPress(touchId, window, from); |
663 | - QTest::qWait(10); |
664 | - QTest::touchEvent(window, m_touchDevice).move(touchId, from, window); |
665 | - qreal stepDx = delta.x() / steps; |
666 | - qreal stepDy = delta.y() / steps; |
667 | - if (!delta.isNull()) { |
668 | - for (int i = 0; i < steps; i++) { |
669 | - QTest::qWait(10); |
670 | - QTest::touchEvent(window, m_touchDevice).move(touchId, from + QPoint(i * stepDx, i * stepDy), window); |
671 | - } |
672 | - } |
673 | - QTest::qWait(10); |
674 | - touchRelease(touchId, window, from + QPoint(stepDx, stepDy)); |
675 | - } |
676 | - |
677 | - |
678 | private: |
679 | QSignalSpy* m_spy; |
680 | - static QTouchDevice *m_touchDevice; |
681 | - |
682 | - static inline bool checkTouchDevice(const char *func) |
683 | - { |
684 | - if (!m_touchDevice) { |
685 | - qWarning() << QString("No touch device registered. Register one using registerTouchDevice() before using %1").arg(func); |
686 | - return false; |
687 | - } |
688 | - return true; |
689 | - } |
690 | }; |
691 | |
692 | #endif // UBUNTU_TEST_UBUNTUTESTCASE_H |
693 | |
694 | === added file 'modules/Ubuntu/Test/plugin/uctestextras.cpp' |
695 | --- modules/Ubuntu/Test/plugin/uctestextras.cpp 1970-01-01 00:00:00 +0000 |
696 | +++ modules/Ubuntu/Test/plugin/uctestextras.cpp 2014-06-25 19:24:49 +0000 |
697 | @@ -0,0 +1,203 @@ |
698 | +/* |
699 | + * Copyright 2014 Canonical Ltd. |
700 | + * |
701 | + * This program is free software; you can redistribute it and/or modify |
702 | + * it under the terms of the GNU Lesser General Public License as published by |
703 | + * the Free Software Foundation; version 3. |
704 | + * |
705 | + * This program is distributed in the hope that it will be useful, |
706 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
707 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
708 | + * GNU Lesser General Public License for more details. |
709 | + * |
710 | + * You should have received a copy of the GNU Lesser General Public License |
711 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
712 | + */ |
713 | + |
714 | +#include "uctestextras.h" |
715 | +#include "uctestcase.h" |
716 | + |
717 | +#include <qpa/qwindowsysteminterface.h> |
718 | + |
719 | +const char *DEVICE_MISSING_MSG = "No touch device registered. Register one using registerTouchDevice() before using %1"; |
720 | + |
721 | +#define CHECK_TOUCH_DEVICE(touchId, item) \ |
722 | + if (!touchDevicePresent()) { \ |
723 | + qWarning() << QString(DEVICE_MISSING_MSG).arg(__FUNCTION__); \ |
724 | + return; \ |
725 | + } \ |
726 | + if (touchId < 0) { \ |
727 | + qWarning() << "Invalid touchId specified."; \ |
728 | + return; \ |
729 | + } \ |
730 | + if (!item) { \ |
731 | + qWarning() << "Invalid item specified."; \ |
732 | + return; \ |
733 | + } |
734 | + |
735 | +QTouchDevice *UCTestExtras::m_touchDevice = 0; |
736 | + |
737 | +/*! |
738 | + * \qmltype TestExtras |
739 | + * \instantiates UCTestExtras |
740 | + * \inqmlmodule Ubuntu.Test 1.0 |
741 | + * \ingroup ubuntu-test |
742 | + * \brief Singleton type providing additional test functions. |
743 | + * |
744 | + * The component provides additional test functions like touch handling, registering |
745 | + * touch device on non-touch screen enabled environment. |
746 | + */ |
747 | + |
748 | +UCTestExtras::UCTestExtras(QObject *parent) : |
749 | + QObject(parent) |
750 | +{ |
751 | +} |
752 | + |
753 | +/*! |
754 | + * \qmlmethod TestExtras::touchDevicePresent() |
755 | + * Returns true if the system has a touch device registered. |
756 | + */ |
757 | +bool UCTestExtras::touchDevicePresent() |
758 | +{ |
759 | + QList<const QTouchDevice*> touchDevices = QTouchDevice::devices(); |
760 | + Q_FOREACH(const QTouchDevice *device, touchDevices) { |
761 | + if (device->type() == QTouchDevice::TouchScreen) { |
762 | + return true; |
763 | + } |
764 | + } |
765 | + return false; |
766 | +} |
767 | + |
768 | +/*! |
769 | + * \qmlmethod TestExtras::registerTouchDevice() |
770 | + * Registers a touch device if there's none registered. Calling the function in |
771 | + * touch enabled environment has no effect. The function must be called in initTestCase() |
772 | + * in order to perform touch related tests. |
773 | + */ |
774 | +void UCTestExtras::registerTouchDevice() |
775 | +{ |
776 | + // check if there is any touch device registered in the system |
777 | + if (!m_touchDevice) { |
778 | + QList<const QTouchDevice*> touchDevices = QTouchDevice::devices(); |
779 | + Q_FOREACH(const QTouchDevice *device, touchDevices) { |
780 | + if (device->type() == QTouchDevice::TouchScreen) { |
781 | + m_touchDevice = const_cast<QTouchDevice*>(device); |
782 | + break; |
783 | + } |
784 | + } |
785 | + } |
786 | + // if none, register one |
787 | + if (!m_touchDevice) { |
788 | + m_touchDevice = new QTouchDevice; |
789 | + m_touchDevice->setType(QTouchDevice::TouchScreen); |
790 | + QWindowSystemInterface::registerTouchDevice(m_touchDevice); |
791 | + } |
792 | +} |
793 | + |
794 | +/*! |
795 | + * \qmlmethod TestExtras::touchPress(touchId, item, point) |
796 | + * The function triggers a touch press event for a given \a touchId on a specific |
797 | + * \a item. The \a point contains the (x,y) coordinates of the event in \a item |
798 | + * coordinates. |
799 | + */ |
800 | +void UCTestExtras::touchPress(int touchId, QQuickItem *item, const QPoint &point) |
801 | +{ |
802 | + CHECK_TOUCH_DEVICE(touchId, item); |
803 | + QTest::touchEvent(item->window(), m_touchDevice).press(touchId, item->mapToScene(point).toPoint(), item->window()); |
804 | +} |
805 | +/*! |
806 | + * \qmlmethod TestExtras::touchRelease(touchId, item, point) |
807 | + * The function produces a touch release event on a given \a touchId performed on |
808 | + * \a item at a \a point. |
809 | + */ |
810 | +void UCTestExtras::touchRelease(int touchId, QQuickItem *item, const QPoint &point) |
811 | +{ |
812 | + CHECK_TOUCH_DEVICE(touchId, item); |
813 | + QTest::touchEvent(item->window(), m_touchDevice).release(touchId, item->mapToScene(point).toPoint(), item->window()); |
814 | +} |
815 | +/*! |
816 | + * \qmlmethod TestExtras::touchClick(touchId, item, point) |
817 | + * The function performs a pair of \l touchPress and \l touchRelease calls on the same |
818 | + * point resulting in a click like event. |
819 | + */ |
820 | +void UCTestExtras::touchClick(int touchId, QQuickItem *item, const QPoint &point) |
821 | +{ |
822 | + CHECK_TOUCH_DEVICE(touchId, item); |
823 | + touchPress(touchId, item, point); |
824 | + QTest::qWait(100); |
825 | + touchRelease(touchId, item, point); |
826 | +} |
827 | +/*! |
828 | + * \qmlmethod TestExtras::touchLongPress(touchId, item, point) |
829 | + * The function produces a \l touchPress event with a timeout equivalent to the |
830 | + * mouse \c pressAndHold timeout, after which the function returns. |
831 | + */ |
832 | +void UCTestExtras::touchLongPress(int touchId, QQuickItem *item, const QPoint &point) |
833 | +{ |
834 | + CHECK_TOUCH_DEVICE(touchId, item); |
835 | + touchPress(touchId, item, point); |
836 | + // 800 miliseconds + 200 to let events processed |
837 | + QTest::qWait(1000); |
838 | +} |
839 | +/*! |
840 | + * \qmlmethod TestExtras::touchDoubleClick(touchId, item, point) |
841 | + * The function performs two consecutive \l touchClick events with a slight delay |
842 | + * in between each click event. |
843 | + */ |
844 | +void UCTestExtras::touchDoubleClick(int touchId, QQuickItem *item, const QPoint &point) |
845 | +{ |
846 | + CHECK_TOUCH_DEVICE(touchId, item); |
847 | + touchClick(touchId, item, point); |
848 | + QTest::qWait(100); |
849 | + touchClick(touchId, item, point); |
850 | +} |
851 | +/*! |
852 | + * \qmlmethod TestExtras::touchMove(touchId, item, point) |
853 | + * The function moves the touch point identified by the \a touchId to the destination |
854 | + * \a point. The point is in \a item coordinates. The touch point identified by the |
855 | + * \a touchId must be pressed before calling this function in order to produce the |
856 | + * desired functionality. The event can be captured in a \c MultiPointTouchArea through |
857 | + * \c updated() signal. |
858 | + */ |
859 | +void UCTestExtras::touchMove(int touchId, QQuickItem *item, const QPoint &point) |
860 | +{ |
861 | + CHECK_TOUCH_DEVICE(touchId, item); |
862 | + QTest::touchEvent(item->window(), m_touchDevice).move(touchId, item->mapToScene(point).toPoint(), item->window()); |
863 | +} |
864 | +/*! |
865 | + * \qmlmethod TestExtras::touchDrag(touchId, item, from, delta, steps = 5) |
866 | + * The function performs a drag gesture on a touch point identified by \a touchId |
867 | + * over an \a item from the starting point \a from with a \a delta. The gesture |
868 | + * is realized with a touch press, \a step moves and a release event. |
869 | + * |
870 | + * By default the function uses 5 steps to produce the gesture. This value can be any |
871 | + * positive number, driving the gesture appliance to be faster (less than 5 moves) or |
872 | + * slower (more than 5 moves). If a negative or 0 value is given, the function will |
873 | + * use the default 5 steps to produce the gesture. |
874 | + */ |
875 | +void UCTestExtras::touchDrag(int touchId, QQuickItem *item, const QPoint &from, const QPoint &delta, int steps) |
876 | +{ |
877 | + CHECK_TOUCH_DEVICE(touchId, item); |
878 | + if (delta.isNull()) { |
879 | + qWarning() << "delta point is invalid"; |
880 | + return; |
881 | + } |
882 | + if (steps <= 0) { |
883 | + steps = 5; |
884 | + } |
885 | + touchPress(touchId, item, from); |
886 | + QTest::qWait(10); |
887 | + touchMove(touchId, item, from); |
888 | + QPoint movePoint(from); |
889 | + qreal stepDx = delta.x() / steps; |
890 | + qreal stepDy = delta.y() / steps; |
891 | + if (!delta.isNull()) { |
892 | + for (int i = 0; i < steps - 1; i++) { |
893 | + QTest::qWait(10); |
894 | + movePoint += QPoint(stepDx, stepDy); |
895 | + touchMove(touchId, item, movePoint); |
896 | + } |
897 | + } |
898 | + QTest::qWait(10); |
899 | + touchRelease(touchId, item, from + delta); |
900 | +} |
901 | |
902 | === added file 'modules/Ubuntu/Test/plugin/uctestextras.h' |
903 | --- modules/Ubuntu/Test/plugin/uctestextras.h 1970-01-01 00:00:00 +0000 |
904 | +++ modules/Ubuntu/Test/plugin/uctestextras.h 2014-06-25 19:24:49 +0000 |
905 | @@ -0,0 +1,46 @@ |
906 | +/* |
907 | + * Copyright 2014 Canonical Ltd. |
908 | + * |
909 | + * This program is free software; you can redistribute it and/or modify |
910 | + * it under the terms of the GNU Lesser General Public License as published by |
911 | + * the Free Software Foundation; version 3. |
912 | + * |
913 | + * This program is distributed in the hope that it will be useful, |
914 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
915 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
916 | + * GNU Lesser General Public License for more details. |
917 | + * |
918 | + * You should have received a copy of the GNU Lesser General Public License |
919 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
920 | + */ |
921 | + |
922 | +#ifndef TESTEXTRAS_H |
923 | +#define TESTEXTRAS_H |
924 | + |
925 | +#include <QtCore/QObject> |
926 | + |
927 | +class QQuickItem; |
928 | +class QTouchDevice; |
929 | +class UCTestExtras : public QObject |
930 | +{ |
931 | + Q_OBJECT |
932 | + Q_PROPERTY(bool touchPresent READ touchDevicePresent) |
933 | +public: |
934 | + explicit UCTestExtras(QObject *parent = 0); |
935 | + |
936 | + static bool touchDevicePresent(); |
937 | +public Q_SLOTS: |
938 | + static void registerTouchDevice(); |
939 | + static void touchPress(int touchId, QQuickItem *item, const QPoint &point); |
940 | + static void touchRelease(int touchId, QQuickItem *item, const QPoint &point); |
941 | + static void touchClick(int touchId, QQuickItem *item, const QPoint &point); |
942 | + static void touchLongPress(int touchId, QQuickItem *item, const QPoint &point); |
943 | + static void touchDoubleClick(int touchId, QQuickItem *item, const QPoint &point); |
944 | + static void touchMove(int touchId, QQuickItem *item, const QPoint &point); |
945 | + static void touchDrag(int touchId, QQuickItem *item, const QPoint &from, const QPoint &delta, int steps = 5); |
946 | + |
947 | +private: |
948 | + static QTouchDevice *m_touchDevice; |
949 | +}; |
950 | + |
951 | +#endif // TESTEXTRAS_H |
952 | |
953 | === modified file 'modules/Ubuntu/Test/qmldir' |
954 | --- modules/Ubuntu/Test/qmldir 2014-04-20 19:25:12 +0000 |
955 | +++ modules/Ubuntu/Test/qmldir 2014-06-25 19:24:49 +0000 |
956 | @@ -1,4 +1,5 @@ |
957 | module Ubuntu.Test |
958 | +plugin UbuntuTest |
959 | UbuntuTestCase 0.1 UbuntuTestCase.qml |
960 | |
961 | #version 1.0 |
962 | |
963 | === modified file 'tests/autopilot/ubuntuuitoolkit/fixture_setup.py' |
964 | --- tests/autopilot/ubuntuuitoolkit/fixture_setup.py 2014-05-26 06:40:24 +0000 |
965 | +++ tests/autopilot/ubuntuuitoolkit/fixture_setup.py 2014-06-25 19:24:49 +0000 |
966 | @@ -20,6 +20,7 @@ |
967 | import tempfile |
968 | |
969 | import fixtures |
970 | +from autopilot import display |
971 | |
972 | from ubuntuuitoolkit import base, environment |
973 | |
974 | @@ -29,7 +30,7 @@ |
975 | import Ubuntu.Components 1.1 |
976 | |
977 | MainView { |
978 | - width: units.gu(48) |
979 | + width: units.gu(80) |
980 | height: units.gu(60) |
981 | |
982 | Label { |
983 | @@ -105,7 +106,6 @@ |
984 | super(InitctlEnvironmentVariable, self).__init__() |
985 | self.variables = kwargs |
986 | |
987 | - def setUp(self): |
988 | super(InitctlEnvironmentVariable, self).setUp() |
989 | for variable, value in self.variables.items(): |
990 | self._add_variable_cleanup(variable) |
991 | @@ -163,3 +163,37 @@ |
992 | shutil.copyfile( |
993 | xauthority_file_path, |
994 | os.path.join(directory, '.Xauthority')) |
995 | + |
996 | + |
997 | +class SimulateDevice(fixtures.Fixture): |
998 | + |
999 | + def __init__(self, app_width, app_height, grid_unit_px): |
1000 | + super(SimulateDevice, self).__init__() |
1001 | + self.app_width = app_width |
1002 | + self.app_height = app_height |
1003 | + self.grid_unit_px = grid_unit_px |
1004 | + |
1005 | + def setUp(self): |
1006 | + super(SimulateDevice, self).setUp() |
1007 | + if self._is_geometry_larger_than_display( |
1008 | + self.app_width, self.app_height): |
1009 | + scale_divisor = self._get_scale_divisor() |
1010 | + grid_unit_px = self.grid_unit_px // scale_divisor |
1011 | + grid_unit_px = self.grid_unit_px |
1012 | + self.useFixture( |
1013 | + fixtures.EnvironmentVariable( |
1014 | + 'GRID_UNIT_PX', str(grid_unit_px))) |
1015 | + |
1016 | + def _is_geometry_larger_than_display(self, width, height): |
1017 | + screen = display.Display.create() |
1018 | + screen_width = screen.get_screen_width() |
1019 | + screen_height = screen.get_screen_height() |
1020 | + return (width > screen_width) or (height > screen_height) |
1021 | + |
1022 | + def _get_scale_divisor(self): |
1023 | + scale_divisor = 2 |
1024 | + while self._is_geometry_larger_than_display( |
1025 | + self.app_width // scale_divisor, |
1026 | + self.app_height // scale_divisor): |
1027 | + scale_divisor = scale_divisor * 2 |
1028 | + return scale_divisor |
1029 | |
1030 | === added file 'tests/autopilot/ubuntuuitoolkit/scenarios.py' |
1031 | --- tests/autopilot/ubuntuuitoolkit/scenarios.py 1970-01-01 00:00:00 +0000 |
1032 | +++ tests/autopilot/ubuntuuitoolkit/scenarios.py 2014-06-25 19:24:49 +0000 |
1033 | @@ -0,0 +1,45 @@ |
1034 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1035 | +# |
1036 | +# Copyright (C) 2014 Canonical Ltd. |
1037 | +# |
1038 | +# This program is free software; you can redistribute it and/or modify |
1039 | +# it under the terms of the GNU Lesser General Public License as published by |
1040 | +# the Free Software Foundation; version 3. |
1041 | +# |
1042 | +# This program is distributed in the hope that it will be useful, |
1043 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1044 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1045 | +# GNU Lesser General Public License for more details. |
1046 | +# |
1047 | +# You should have received a copy of the GNU Lesser General Public License |
1048 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1049 | + |
1050 | + |
1051 | +NEXUS4_DEVICE = 'Nexus4' |
1052 | +NEXUS10_DEVICE = 'Nexus10' |
1053 | +DEFAULT_DEVICES = (NEXUS4_DEVICE, NEXUS10_DEVICE) |
1054 | + |
1055 | + |
1056 | +def get_device_simulation_scenarios(devices=DEFAULT_DEVICES): |
1057 | + """Return a list of devices to be simulated on tests. |
1058 | + |
1059 | + :param devices: The device or devices to simulate. Default value is all the |
1060 | + officially supported devices. |
1061 | + :type devices: string or sequence of strings. |
1062 | + :return: A list of scenarios to be used with the testscenarios python |
1063 | + module, with the values of app_width, app_height and grid_unit |
1064 | + corresponding to the selected device. |
1065 | + |
1066 | + """ |
1067 | + scenarios = [] |
1068 | + if NEXUS4_DEVICE in devices: |
1069 | + scenarios.append( |
1070 | + ('Simulating Nexus 4 in desktop', |
1071 | + dict(app_width=768, app_height=1280, grid_unit_px=18)) |
1072 | + ) |
1073 | + if NEXUS10_DEVICE in devices: |
1074 | + scenarios.append( |
1075 | + ('Simulating Nexus 10 in desktop', |
1076 | + dict(app_width=2560, app_height=1600, grid_unit_px=20)) |
1077 | + ) |
1078 | + return scenarios |
1079 | |
1080 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py' |
1081 | --- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py 2014-05-30 08:21:45 +0000 |
1082 | +++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py 2014-06-25 19:24:49 +0000 |
1083 | @@ -15,6 +15,7 @@ |
1084 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
1085 | |
1086 | import os |
1087 | +import subprocess |
1088 | |
1089 | import testtools |
1090 | import ubuntuuitoolkit |
1091 | @@ -206,8 +207,11 @@ |
1092 | if os.path.exists(path_to_local_launcher): |
1093 | return path_to_local_launcher |
1094 | else: |
1095 | + arch = subprocess.check_output( |
1096 | + ["dpkg-architecture", "-qDEB_HOST_MULTIARCH"], |
1097 | + universal_newlines=True).strip() |
1098 | path_to_installed_launcher = os.path.join( |
1099 | - '/', 'usr', 'lib', 'ubuntu-ui-toolkit', 'launcher') |
1100 | + '/', 'usr', 'lib', arch, 'ubuntu-ui-toolkit', 'launcher') |
1101 | return path_to_installed_launcher |
1102 | |
1103 | def test_get_unity_top_container(self): |
1104 | |
1105 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py' |
1106 | --- tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py 2014-06-03 20:10:53 +0000 |
1107 | +++ tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py 2014-06-25 19:24:49 +0000 |
1108 | @@ -27,7 +27,7 @@ |
1109 | from autopilot import testcase as autopilot_testcase |
1110 | from testtools.matchers import Contains, FileExists, Not |
1111 | |
1112 | -from ubuntuuitoolkit import base, environment, fixture_setup |
1113 | +from ubuntuuitoolkit import base, environment, fixture_setup, scenarios |
1114 | |
1115 | |
1116 | class FakeApplicationTestCase(testtools.TestCase): |
1117 | @@ -304,3 +304,25 @@ |
1118 | self.assertTrue( |
1119 | os.path.exists( |
1120 | os.path.join(os.environ.get('HOME'), '.Xauthority'))) |
1121 | + |
1122 | + |
1123 | +class SimulateDeviceTestCase(autopilot_testcase.AutopilotTestCase): |
1124 | + |
1125 | + scenarios = scenarios.get_device_simulation_scenarios() |
1126 | + |
1127 | + def test(self): |
1128 | + self.useFixture(fixture_setup.SimulateDevice( |
1129 | + self.app_width, self.app_height, self.grid_unit_px)) |
1130 | + |
1131 | + fake_application = fixture_setup.FakeApplication() |
1132 | + self.useFixture(fake_application) |
1133 | + |
1134 | + self.application = self.launch_test_application( |
1135 | + base.get_qmlscene_launch_command(), |
1136 | + fake_application.qml_file_path, |
1137 | + '--desktop_file_hint={0}'.format( |
1138 | + fake_application.desktop_file_path), |
1139 | + app_type='qt') |
1140 | + |
1141 | + # We can select a component from the application. |
1142 | + self.application.select_single('Label', objectName='testLabel') |
1143 | |
1144 | === added file 'tests/autopilot/ubuntuuitoolkit/tests/test_scenarios.py' |
1145 | --- tests/autopilot/ubuntuuitoolkit/tests/test_scenarios.py 1970-01-01 00:00:00 +0000 |
1146 | +++ tests/autopilot/ubuntuuitoolkit/tests/test_scenarios.py 2014-06-25 19:24:49 +0000 |
1147 | @@ -0,0 +1,50 @@ |
1148 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1149 | +# |
1150 | +# Copyright (C) 2014 Canonical Ltd. |
1151 | +# |
1152 | +# This program is free software; you can redistribute it and/or modify |
1153 | +# it under the terms of the GNU Lesser General Public License as published by |
1154 | +# the Free Software Foundation; version 3. |
1155 | +# |
1156 | +# This program is distributed in the hope that it will be useful, |
1157 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1158 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1159 | +# GNU Lesser General Public License for more details. |
1160 | +# |
1161 | +# You should have received a copy of the GNU Lesser General Public License |
1162 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1163 | + |
1164 | +import testtools |
1165 | + |
1166 | +from ubuntuuitoolkit import scenarios |
1167 | + |
1168 | + |
1169 | +class ScenariosTestCase(testtools.TestCase): |
1170 | + |
1171 | + def test_get_nexus_4_scenario(self): |
1172 | + expected_scenarios = [ |
1173 | + ('Simulating Nexus 4 in desktop', |
1174 | + dict(app_width=768, app_height=1280, grid_unit_px=18)), |
1175 | + ] |
1176 | + test_scenarios = scenarios.get_device_simulation_scenarios( |
1177 | + devices=scenarios.NEXUS4_DEVICE) |
1178 | + self.assertEqual(expected_scenarios, test_scenarios) |
1179 | + |
1180 | + def test_get_nexus_10_scenario(self): |
1181 | + expected_scenarios = [ |
1182 | + ('Simulating Nexus 10 in desktop', |
1183 | + dict(app_width=2560, app_height=1600, grid_unit_px=20)) |
1184 | + ] |
1185 | + test_scenarios = scenarios.get_device_simulation_scenarios( |
1186 | + devices=scenarios.NEXUS10_DEVICE) |
1187 | + self.assertEqual(expected_scenarios, test_scenarios) |
1188 | + |
1189 | + def test_get_default_scenarios_must_return_supported_devices(self): |
1190 | + expected_scenarios = [ |
1191 | + ('Simulating Nexus 4 in desktop', |
1192 | + dict(app_width=768, app_height=1280, grid_unit_px=18)), |
1193 | + ('Simulating Nexus 10 in desktop', |
1194 | + dict(app_width=2560, app_height=1600, grid_unit_px=20)) |
1195 | + ] |
1196 | + test_scenarios = scenarios.get_device_simulation_scenarios() |
1197 | + self.assertEqual(expected_scenarios, test_scenarios) |
1198 | |
1199 | === added file 'tests/launcher/MouseTouchAdaptor.cpp' |
1200 | --- tests/launcher/MouseTouchAdaptor.cpp 1970-01-01 00:00:00 +0000 |
1201 | +++ tests/launcher/MouseTouchAdaptor.cpp 2014-06-25 19:24:49 +0000 |
1202 | @@ -0,0 +1,159 @@ |
1203 | +/* |
1204 | + * Copyright 2014 Canonical Ltd. |
1205 | + * |
1206 | + * This program is free software; you can redistribute it and/or modify |
1207 | + * it under the terms of the GNU Lesser General Public License as published by |
1208 | + * the Free Software Foundation; version 3. |
1209 | + * |
1210 | + * This program is distributed in the hope that it will be useful, |
1211 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1212 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1213 | + * GNU Lesser General Public License for more details. |
1214 | + * |
1215 | + * You should have received a copy of the GNU Lesser General Public License |
1216 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1217 | + * |
1218 | + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> |
1219 | + * |
1220 | + */ |
1221 | + |
1222 | +#include "MouseTouchAdaptor.h" |
1223 | + |
1224 | +#include <qpa/qwindowsysteminterface.h> |
1225 | + |
1226 | +#include <QtGui/QMouseEvent> |
1227 | +#include <QtTest/QTest> |
1228 | + |
1229 | +using QTest::QTouchEventSequence; |
1230 | + |
1231 | +namespace { |
1232 | +Qt::MouseButton translateMouseButton(xcb_button_t detail) |
1233 | +{ |
1234 | + switch (detail) { |
1235 | + case 1: return Qt::LeftButton; |
1236 | + case 2: return Qt::MidButton; |
1237 | + case 3: return Qt::RightButton; |
1238 | + // Button values 4-7 are Wheel events |
1239 | + default: return Qt::NoButton; |
1240 | + } |
1241 | +} |
1242 | +} // end of anonymous namespace |
1243 | + |
1244 | +MouseTouchAdaptor::MouseTouchAdaptor() |
1245 | + : m_leftButtonIsPressed(false) |
1246 | +{ |
1247 | + m_touchDevice = new QTouchDevice; |
1248 | + m_touchDevice->setType(QTouchDevice::TouchScreen); |
1249 | + QWindowSystemInterface::registerTouchDevice(m_touchDevice); |
1250 | +} |
1251 | + |
1252 | +bool MouseTouchAdaptor::nativeEventFilter(const QByteArray & eventType, |
1253 | + void * message, long * /*result*/) |
1254 | +{ |
1255 | + if (eventType != "xcb_generic_event_t") { |
1256 | + // wrong backend. |
1257 | + qWarning("MouseTouchAdaptor: XCB backend not in use. Adaptor inoperative!"); |
1258 | + return false; |
1259 | + } |
1260 | + |
1261 | + xcb_generic_event_t *xcbEvent = static_cast<xcb_generic_event_t *>(message); |
1262 | + |
1263 | + switch (xcbEvent->response_type & ~0x80) { |
1264 | + case XCB_BUTTON_PRESS: |
1265 | + return handleButtonPress(reinterpret_cast<xcb_button_press_event_t *>(xcbEvent)); |
1266 | + break; |
1267 | + case XCB_BUTTON_RELEASE: |
1268 | + return handleButtonRelease(reinterpret_cast<xcb_button_release_event_t *>(xcbEvent)); |
1269 | + break; |
1270 | + case XCB_MOTION_NOTIFY: |
1271 | + return handleMotionNotify(reinterpret_cast<xcb_motion_notify_event_t *>(xcbEvent)); |
1272 | + break; |
1273 | + default: |
1274 | + return false; |
1275 | + break; |
1276 | + }; |
1277 | +} |
1278 | + |
1279 | +bool MouseTouchAdaptor::handleButtonPress(xcb_button_press_event_t *pressEvent) |
1280 | +{ |
1281 | + Qt::MouseButton button = translateMouseButton(pressEvent->detail); |
1282 | + |
1283 | + // Skip the event if it wasn't a left mouse press |
1284 | + if (button != Qt::LeftButton) { |
1285 | + return false; |
1286 | + } |
1287 | + |
1288 | + QPoint windowPos(pressEvent->event_x, pressEvent->event_y); |
1289 | + |
1290 | + QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(pressEvent->event)); |
1291 | + |
1292 | + // no autoCommit |
1293 | + QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice, false); |
1294 | + touchEvent.press(0, windowPos); |
1295 | + // do not process events when committed, let the events be processed with next event loop |
1296 | + touchEvent.commit(false); |
1297 | + |
1298 | + m_leftButtonIsPressed = true; |
1299 | + return true; |
1300 | +} |
1301 | + |
1302 | +bool MouseTouchAdaptor::handleButtonRelease(xcb_button_release_event_t *releaseEvent) |
1303 | +{ |
1304 | + Qt::MouseButton button = translateMouseButton(releaseEvent->detail); |
1305 | + |
1306 | + // Skip the event if it wasn't a left mouse release |
1307 | + if (button != Qt::LeftButton) { |
1308 | + return false; |
1309 | + } |
1310 | + |
1311 | + QPoint windowPos(releaseEvent->event_x, releaseEvent->event_y); |
1312 | + |
1313 | + QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(releaseEvent->event)); |
1314 | + |
1315 | + // no autoCommit |
1316 | + QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice, false); |
1317 | + touchEvent.release(0, windowPos); |
1318 | + // do not process events when committed, let the events be processed with next event loop |
1319 | + touchEvent.commit(false); |
1320 | + |
1321 | + m_leftButtonIsPressed = false; |
1322 | + return true; |
1323 | +} |
1324 | + |
1325 | +bool MouseTouchAdaptor::handleMotionNotify(xcb_motion_notify_event_t *event) |
1326 | +{ |
1327 | + if (!m_leftButtonIsPressed) { |
1328 | + return false; |
1329 | + } |
1330 | + |
1331 | + QPoint windowPos(event->event_x, event->event_y); |
1332 | + |
1333 | + QWindow *targetWindow = findQWindowWithXWindowID(static_cast<WId>(event->event)); |
1334 | + |
1335 | + // no autoCommit |
1336 | + QTouchEventSequence touchEvent = QTest::touchEvent(targetWindow, m_touchDevice, false); |
1337 | + touchEvent.move(0, windowPos); |
1338 | + // do not process events when committed, let the events be processed with next event loop |
1339 | + touchEvent.commit(false); |
1340 | + |
1341 | + return true; |
1342 | +} |
1343 | + |
1344 | +QWindow *MouseTouchAdaptor::findQWindowWithXWindowID(WId windowId) |
1345 | +{ |
1346 | + QWindowList windowList = QGuiApplication::topLevelWindows(); |
1347 | + QWindow *foundWindow = 0; |
1348 | + |
1349 | + int i = 0; |
1350 | + while (!foundWindow && i < windowList.count()) { |
1351 | + QWindow *window = windowList[i]; |
1352 | + if (window->winId() == windowId) { |
1353 | + foundWindow = window; |
1354 | + } else { |
1355 | + ++i; |
1356 | + } |
1357 | + } |
1358 | + |
1359 | + Q_ASSERT(foundWindow); |
1360 | + return foundWindow; |
1361 | +} |
1362 | |
1363 | === added file 'tests/launcher/MouseTouchAdaptor.h' |
1364 | --- tests/launcher/MouseTouchAdaptor.h 1970-01-01 00:00:00 +0000 |
1365 | +++ tests/launcher/MouseTouchAdaptor.h 2014-06-25 19:24:49 +0000 |
1366 | @@ -0,0 +1,50 @@ |
1367 | +/* |
1368 | + * Copyright 2014 Canonical Ltd. |
1369 | + * |
1370 | + * This program is free software; you can redistribute it and/or modify |
1371 | + * it under the terms of the GNU Lesser General Public License as published by |
1372 | + * the Free Software Foundation; version 3. |
1373 | + * |
1374 | + * This program is distributed in the hope that it will be useful, |
1375 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1376 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1377 | + * GNU Lesser General Public License for more details. |
1378 | + * |
1379 | + * You should have received a copy of the GNU Lesser General Public License |
1380 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1381 | + * |
1382 | + * Authored by: Daniel d'Andrada <daniel.dandrada@canonical.com> |
1383 | + * |
1384 | + */ |
1385 | + |
1386 | +#ifndef MOUSE_TOUCH_ADAPTOR_H |
1387 | +#define MOUSE_TOUCH_ADAPTOR_H |
1388 | + |
1389 | +#include <QtCore/QAbstractNativeEventFilter> |
1390 | +#include <QWindow> |
1391 | +#include <xcb/xcb.h> |
1392 | + |
1393 | +class QMouseEvent; |
1394 | +class QTouchDevice; |
1395 | + |
1396 | +// Transforms QMouseEvents into single-finger QTouchEvents. |
1397 | +class MouseTouchAdaptor : public QAbstractNativeEventFilter { |
1398 | + |
1399 | +public: |
1400 | + MouseTouchAdaptor(); |
1401 | + |
1402 | + // Filters mouse events and posts the equivalent QTouchEvents. |
1403 | + virtual bool nativeEventFilter(const QByteArray & eventType, void *message, long *result); |
1404 | + |
1405 | +private: |
1406 | + |
1407 | + bool handleButtonPress(xcb_button_press_event_t *pressEvent); |
1408 | + bool handleButtonRelease(xcb_button_release_event_t *releaseEvent); |
1409 | + bool handleMotionNotify(xcb_motion_notify_event_t *event); |
1410 | + QWindow *findQWindowWithXWindowID(WId windowId); |
1411 | + |
1412 | + QTouchDevice *m_touchDevice; |
1413 | + bool m_leftButtonIsPressed; |
1414 | +}; |
1415 | + |
1416 | +#endif // MOUSE_TOUCH_ADAPTOR_H |
1417 | |
1418 | === modified file 'tests/launcher/launcher.cpp' |
1419 | --- tests/launcher/launcher.cpp 2014-06-09 08:26:24 +0000 |
1420 | +++ tests/launcher/launcher.cpp 2014-06-25 19:24:49 +0000 |
1421 | @@ -30,16 +30,18 @@ |
1422 | #include <QOpenGLContext> |
1423 | #include <QtGui/private/qopenglcontext_p.h> |
1424 | #include <QtQuick/private/qsgcontext_p.h> |
1425 | +#include <QtCore/QCommandLineParser> |
1426 | +#include <QtCore/QCommandLineOption> |
1427 | +#include "MouseTouchAdaptor.h" |
1428 | +#include <QtGui/QTouchDevice> |
1429 | |
1430 | -int usage() |
1431 | +bool touchDevicePresent() |
1432 | { |
1433 | - QString self(QGuiApplication::instance()->arguments().at(0)); |
1434 | - std::cout << "Usage\n " |
1435 | - << qPrintable(self) |
1436 | - << " -testability -frameless -engine" |
1437 | - << " --desktop_file_path=DESKTOP_FILE" |
1438 | - << " -I MODULE_PATH FILENAME\n"; |
1439 | - return 1; |
1440 | + Q_FOREACH(const QTouchDevice *device, QTouchDevice::devices()) { |
1441 | + if (device->type() == QTouchDevice::TouchScreen) |
1442 | + return true; |
1443 | + } |
1444 | + return false; |
1445 | } |
1446 | |
1447 | int main(int argc, const char *argv[]) |
1448 | @@ -58,25 +60,40 @@ |
1449 | #endif |
1450 | QGuiApplication::setApplicationName("UITK Launcher"); |
1451 | QGuiApplication application(argc, (char**)argv); |
1452 | - QStringList args (application.arguments()); |
1453 | - |
1454 | - int _testability(args.indexOf("-testability")); |
1455 | - args.removeAt(_testability); |
1456 | - int _frameless(args.indexOf("-frameless")); |
1457 | - args.removeAt(_frameless); |
1458 | - int _engine(args.indexOf("-engine")); |
1459 | - args.removeAt(_engine); |
1460 | - |
1461 | - Q_FOREACH(QString arg, args) { |
1462 | - if (arg.startsWith("--desktop_file_hint")) { |
1463 | - // This will not be used - it only needs to be ignored |
1464 | - int _desktop_file_hint(args.indexOf(arg)); |
1465 | - args.removeAt(_desktop_file_hint); |
1466 | - } |
1467 | + |
1468 | + QCommandLineParser args; |
1469 | + QCommandLineOption _import("I", "Add <path> to the list of import paths", "path"); |
1470 | + QCommandLineOption _enableTouch("touch", "Enables mouse to touch conversion on desktop"); |
1471 | + QCommandLineOption _testability("testability", "Loads the testability driver"); |
1472 | + QCommandLineOption _frameless("frameless", "Run without borders"); |
1473 | + QCommandLineOption _engine("engine", "Use quick engine from quick view"); |
1474 | + QCommandLineOption _desktop_file_hint("desktop_file_hint", "Desktop file - ignored", "desktop_file"); |
1475 | + |
1476 | + args.addOption(_import); |
1477 | + args.addOption(_enableTouch); |
1478 | + args.addOption(_testability); |
1479 | + args.addOption(_frameless); |
1480 | + args.addOption(_engine); |
1481 | + args.addOption(_desktop_file_hint); |
1482 | + args.addPositionalArgument("filename", "Document to be viewed"); |
1483 | + args.setSingleDashWordOptionMode(QCommandLineParser::ParseAsLongOptions); |
1484 | + args.addHelpOption(); |
1485 | + if (!args.parse(application.arguments())) { |
1486 | + qWarning() << args.errorText(); |
1487 | + args.showHelp(1); |
1488 | + } |
1489 | + |
1490 | + QString filename; |
1491 | + if (args.positionalArguments().count() > 0) { |
1492 | + filename = args.positionalArguments()[0]; |
1493 | + } |
1494 | + if (filename.isEmpty()) { |
1495 | + // show usage and exit |
1496 | + args.showHelp(1); |
1497 | } |
1498 | |
1499 | // Testability is only supported out of the box by QApplication not QGuiApplication |
1500 | - if (_testability > -1 || getenv("QT_LOAD_TESTABILITY")) { |
1501 | + if (args.isSet(_testability) || getenv("QT_LOAD_TESTABILITY")) { |
1502 | QLibrary testLib(QLatin1String("qttestability")); |
1503 | if (testLib.load()) { |
1504 | typedef void (*TasInitialize)(void); |
1505 | @@ -96,7 +113,7 @@ |
1506 | QQmlEngine* engine; |
1507 | // The default constructor affects the components tree (autopilot vis) |
1508 | QQuickView* view; |
1509 | - if (_engine > -1) { |
1510 | + if (args.isSet(_engine)) { |
1511 | view = new QQuickView(); |
1512 | engine = view->engine(); |
1513 | } else { |
1514 | @@ -104,43 +121,31 @@ |
1515 | view = new QQuickView(engine, NULL); |
1516 | } |
1517 | |
1518 | - int _import(args.indexOf("-I")); |
1519 | - args.removeAt(_import); |
1520 | - if (_import > -1) { |
1521 | - if (args.count() > _import) { |
1522 | - QString importPath(args.at(_import)); |
1523 | - args.removeAt(_import); |
1524 | - engine->addImportPath(importPath); |
1525 | + if (args.isSet(_import)) { |
1526 | + QStringList paths = args.values(_import); |
1527 | + Q_FOREACH(const QString &path, paths) { |
1528 | + engine->addImportPath(path); |
1529 | } |
1530 | } |
1531 | |
1532 | view->setResizeMode(QQuickView::SizeRootObjectToView); |
1533 | view->setTitle("UI Toolkit QQuickView"); |
1534 | - if (_frameless > -1) { |
1535 | + if (args.isSet(_frameless)) { |
1536 | view->setFlags(Qt::FramelessWindowHint); |
1537 | } |
1538 | |
1539 | - // The remaining unnamed argument must be a filename |
1540 | - if (args.count() == 1) { |
1541 | - qCritical() << "Missing filename"; |
1542 | - return usage(); |
1543 | + if (args.isSet(_enableTouch) && !touchDevicePresent()) { |
1544 | + // has no effect if we have touch screen |
1545 | + application.installNativeEventFilter(new MouseTouchAdaptor); |
1546 | } |
1547 | - QString filename(args.at(1)); |
1548 | - // The first argument is the launcher itself |
1549 | - args.removeAt(0); |
1550 | |
1551 | QUrl source(QUrl::fromLocalFile(filename)); |
1552 | view->setSource(source); |
1553 | if (view->errors().count() > 0) { |
1554 | - return usage(); |
1555 | + args.showHelp(3); |
1556 | } |
1557 | view->show(); |
1558 | |
1559 | - if (args.count() > 1) { |
1560 | - qCritical() << "Invalid arguments passed" << args; |
1561 | - return usage(); |
1562 | - } |
1563 | - |
1564 | return application.exec(); |
1565 | } |
1566 | |
1567 | |
1568 | === modified file 'tests/launcher/launcher.pro' |
1569 | --- tests/launcher/launcher.pro 2014-05-14 11:00:20 +0000 |
1570 | +++ tests/launcher/launcher.pro 2014-06-25 19:24:49 +0000 |
1571 | @@ -1,11 +1,13 @@ |
1572 | TEMPLATE = app |
1573 | QT += qml quick |
1574 | # For setSharedOpenGLContext |
1575 | -QT += core-private gui-private quick-private |
1576 | +QT += core-private gui-private testlib quick-private |
1577 | CONFIG += no_keywords |
1578 | -SOURCES += \ |
1579 | - launcher.cpp |
1580 | -launcher.path = /usr/lib/ubuntu-ui-toolkit |
1581 | +HEADERS += MouseTouchAdaptor.h |
1582 | +SOURCES += launcher.cpp \ |
1583 | + MouseTouchAdaptor.cpp |
1584 | +installPath = $$[QT_INSTALL_LIBS]/ubuntu-ui-toolkit |
1585 | +launcher.path = $$installPath |
1586 | launcher.files = launcher |
1587 | INSTALLS += launcher |
1588 | |
1589 | |
1590 | === modified file 'tests/qmlapicheck.sh' |
1591 | --- tests/qmlapicheck.sh 2014-04-23 13:45:41 +0000 |
1592 | +++ tests/qmlapicheck.sh 2014-06-25 19:24:49 +0000 |
1593 | @@ -16,7 +16,7 @@ |
1594 | # |
1595 | ################################################################################ |
1596 | QML="modules/Ubuntu/*/qmldir modules/Ubuntu/Components/Colors/UbuntuColors.qml modules/Ubuntu/Components/*/qmldir modules/Ubuntu/Components/Pickers/PickerPanel.qml" |
1597 | -CPP="Ubuntu.Components Ubuntu.Layouts Ubuntu.PerformanceMetrics" |
1598 | +CPP="Ubuntu.Components Ubuntu.Layouts Ubuntu.PerformanceMetrics Ubuntu.Test" |
1599 | |
1600 | echo Dumping QML API of C++ components |
1601 | echo '' > plugins.qmltypes |
1602 | |
1603 | === modified file 'tests/unit/tst_components/tst_label.qml' |
1604 | --- tests/unit/tst_components/tst_label.qml 2014-05-26 10:13:41 +0000 |
1605 | +++ tests/unit/tst_components/tst_label.qml 2014-06-25 19:24:49 +0000 |
1606 | @@ -21,6 +21,11 @@ |
1607 | TestCase { |
1608 | name: "LabelAPI" |
1609 | |
1610 | + function test_0_defaults() { |
1611 | + compare(textCustom.font.family, "Ubuntu", "Default font family"); |
1612 | + compare(textCustom.font.weight, Font.Light, "Default font weight"); |
1613 | + } |
1614 | + |
1615 | function test_fontSize() { |
1616 | compare(textCustom.fontSize,"medium","fontSize is 'medium' by default") |
1617 | |
1618 | |
1619 | === modified file 'tests/unit_x11/tst_components/tst_textarea.qml' |
1620 | --- tests/unit_x11/tst_components/tst_textarea.qml 2014-06-10 14:22:42 +0000 |
1621 | +++ tests/unit_x11/tst_components/tst_textarea.qml 2014-06-25 19:24:49 +0000 |
1622 | @@ -705,6 +705,7 @@ |
1623 | } |
1624 | |
1625 | function test_clear_selection_by_click_beside_selection() { |
1626 | + skip("The test fails and will be overruled by future UX."); |
1627 | longText.focus = true; |
1628 | var handler = findChild(longText, "input_handler"); |
1629 | var y = longText.height / 2; |
1630 | |
1631 | === modified file 'tests/unit_x11/tst_inversemousearea/tst_inversemouseareatest.cpp' |
1632 | --- tests/unit_x11/tst_inversemousearea/tst_inversemouseareatest.cpp 2014-06-11 11:24:39 +0000 |
1633 | +++ tests/unit_x11/tst_inversemousearea/tst_inversemouseareatest.cpp 2014-06-25 19:24:49 +0000 |
1634 | @@ -22,7 +22,7 @@ |
1635 | #include <QtQuick/QQuickItem> |
1636 | #include <QtCore/QEvent> |
1637 | |
1638 | -#include "uctestcase.h" |
1639 | +#include "uctestextras.h" |
1640 | #include "inversemouseareatype.h" |
1641 | #include "ucunits.h" |
1642 | #include <private/qquickevents_p_p.h> |
1643 | @@ -89,7 +89,7 @@ |
1644 | void initTestCase() |
1645 | { |
1646 | // make sure we have a touch device installed |
1647 | - UbuntuTestCase::registerTouchDevice(); |
1648 | + UCTestExtras::registerTouchDevice(); |
1649 | QString modules("../../../modules"); |
1650 | QVERIFY(QDir(modules).exists()); |
1651 | |
1652 | @@ -513,7 +513,7 @@ |
1653 | QCOMPARE(imaSpy.count(), 1); |
1654 | |
1655 | imaSpy.clear(); |
1656 | - UbuntuTestCase::touchClick(0, quickView, guPoint(20, 5)); |
1657 | + UCTestExtras::touchClick(0, quickView->rootObject(), guPoint(20, 5)); |
1658 | QCOMPARE(imaSpy.count(), 1); |
1659 | } |
1660 | |
1661 | |
1662 | === modified file 'tests/unit_x11/tst_test/tst_ubuntutestcase.qml' |
1663 | --- tests/unit_x11/tst_test/tst_ubuntutestcase.qml 2014-04-20 19:25:12 +0000 |
1664 | +++ tests/unit_x11/tst_test/tst_ubuntutestcase.qml 2014-06-25 19:24:49 +0000 |
1665 | @@ -25,11 +25,19 @@ |
1666 | |
1667 | Column { |
1668 | anchors.fill: parent |
1669 | + MultiPointTouchArea { |
1670 | + id: topTouchArea |
1671 | + width: parent.width |
1672 | + height: 100 |
1673 | + touchPoints: TouchPoint { |
1674 | +// id: point |
1675 | + } |
1676 | + } |
1677 | MouseArea { |
1678 | id: mouseArea |
1679 | objectName: "myMouseArea" |
1680 | width: parent.width |
1681 | - height: 300 |
1682 | + height: 200 |
1683 | hoverEnabled: true |
1684 | acceptedButtons: Qt.LeftButton | Qt.MiddleButton | Qt.RightButton |
1685 | property int testX : 0 |
1686 | @@ -42,6 +50,15 @@ |
1687 | steps++; |
1688 | } |
1689 | } |
1690 | + MultiPointTouchArea { |
1691 | + id: touchArea |
1692 | + width: parent.width |
1693 | + height: 100 |
1694 | + touchPoints: TouchPoint { |
1695 | + id: point |
1696 | + } |
1697 | + } |
1698 | + |
1699 | Flickable { |
1700 | id: flicker |
1701 | width: parent.width |
1702 | @@ -62,18 +79,28 @@ |
1703 | name: "TestTheUbuntuTestCase" |
1704 | when: windowShown |
1705 | |
1706 | + function initTestCase() { |
1707 | + TestExtras.registerTouchDevice(); |
1708 | + } |
1709 | + |
1710 | function init() { |
1711 | mouseArea.steps = 0; |
1712 | } |
1713 | function cleanup() { |
1714 | movementSpy.clear(); |
1715 | longPressSpy.clear(); |
1716 | + touchPressSpy.clear(); |
1717 | + touchReleaseSpy.clear(); |
1718 | + touchUpdateSpy.clear(); |
1719 | + touchPressSpy.target = null; |
1720 | + touchReleaseSpy.target = null; |
1721 | + touchUpdateSpy.target = null; |
1722 | } |
1723 | |
1724 | function test_mouseMoveSlowly() { |
1725 | - mouseMoveSlowly(root,0,0,800,300,10,100); |
1726 | + mouseMoveSlowly(mouseArea,0,0,800,200,10,100); |
1727 | compare(mouseArea.testX,800); |
1728 | - compare(mouseArea.testY,300); |
1729 | + compare(mouseArea.testY,200); |
1730 | compare(mouseArea.steps,10); |
1731 | } |
1732 | |
1733 | @@ -146,5 +173,129 @@ |
1734 | flick(flicker, flicker.width, flicker.height, -flicker.width, -flicker.height, 400, 100); |
1735 | movementSpy.wait(); |
1736 | } |
1737 | + |
1738 | + SignalSpy { |
1739 | + id: touchPressSpy |
1740 | + signalName: "onPressed" |
1741 | + target: touchArea |
1742 | + } |
1743 | + SignalSpy { |
1744 | + id: touchReleaseSpy |
1745 | + signalName: "onReleased" |
1746 | + target: touchArea |
1747 | + } |
1748 | + SignalSpy { |
1749 | + id: touchUpdateSpy |
1750 | + signalName: "onUpdated" |
1751 | + target: touchArea |
1752 | + } |
1753 | + |
1754 | + function test_has_property() { |
1755 | + verify(TestExtras.hasOwnProperty("touchPresent"), "touchPresent property missing"); |
1756 | + } |
1757 | + |
1758 | + function test_touchPress_data() { |
1759 | + return [ |
1760 | + {touch: touchArea}, |
1761 | + {touch: topTouchArea} |
1762 | + ]; |
1763 | + } |
1764 | + function test_touchPress(data) { |
1765 | + touchPressSpy.target = data.touch; |
1766 | + TestExtras.touchPress(0, data.touch, Qt.point(10, 10)); |
1767 | + touchPressSpy.wait(); |
1768 | + // cleanup |
1769 | + TestExtras.touchRelease(0, data.touch, Qt.point(10, 10)); |
1770 | + } |
1771 | + |
1772 | + function test_touchRelease_data() { |
1773 | + return [ |
1774 | + {touch: touchArea}, |
1775 | + {touch: topTouchArea} |
1776 | + ]; |
1777 | + } |
1778 | + function test_touchRelease(data) { |
1779 | + // prerequisite: do a press so we get a release |
1780 | + TestExtras.touchPress(0, data.touch, Qt.point(10, 10)); |
1781 | + |
1782 | + touchReleaseSpy.target = data.touch; |
1783 | + TestExtras.touchRelease(0, data.touch, Qt.point(10, 10)); |
1784 | + touchReleaseSpy.wait(); |
1785 | + } |
1786 | + |
1787 | + function test_touchClick_data() { |
1788 | + return [ |
1789 | + {touch: touchArea}, |
1790 | + {touch: topTouchArea} |
1791 | + ]; |
1792 | + } |
1793 | + function test_touchClick(data) { |
1794 | + touchPressSpy.target = data.touch; |
1795 | + touchReleaseSpy.target = data.touch; |
1796 | + TestExtras.touchClick(0, data.touch, Qt.point(10, 10)); |
1797 | + touchReleaseSpy.wait(); |
1798 | + compare(touchPressSpy.count, 1, "Not pressed?"); |
1799 | + compare(touchReleaseSpy.count, 1, "Not released?"); |
1800 | + } |
1801 | + |
1802 | + function test_touchDoubleClick_data() { |
1803 | + return [ |
1804 | + {touch: touchArea}, |
1805 | + {touch: topTouchArea} |
1806 | + ]; |
1807 | + } |
1808 | + function test_touchDoubleClick(data) { |
1809 | + touchPressSpy.target = data.touch; |
1810 | + touchReleaseSpy.target = data.touch; |
1811 | + TestExtras.touchDoubleClick(0, data.touch, Qt.point(10, 10)); |
1812 | + compare(touchPressSpy.count, 2, "Not pressed twice?"); |
1813 | + compare(touchReleaseSpy.count, 2, "Not released twice?"); |
1814 | + } |
1815 | + |
1816 | + function test_touchMove_data() { |
1817 | + return [ |
1818 | + {touch: touchArea}, |
1819 | + {touch: topTouchArea} |
1820 | + ]; |
1821 | + } |
1822 | + function test_touchMove(data) { |
1823 | + touchUpdateSpy.target = data.touch; |
1824 | + TestExtras.touchPress(0, data.touch, Qt.point(0, 0)); |
1825 | + TestExtras.touchMove(0, data.touch, Qt.point(10, 10)); |
1826 | + touchUpdateSpy.wait(); |
1827 | + TestExtras.touchRelease(0, data.touch, Qt.point(10, 10)); |
1828 | + } |
1829 | + |
1830 | + function test_touchDrag_default_steps_data() { |
1831 | + return [ |
1832 | + {touch: touchArea}, |
1833 | + {touch: topTouchArea} |
1834 | + ]; |
1835 | + } |
1836 | + function test_touchDrag_default_steps(data) { |
1837 | + touchPressSpy.target = data.touch; |
1838 | + touchReleaseSpy.target = data.touch; |
1839 | + touchUpdateSpy.target = data.touch; |
1840 | + TestExtras.touchDrag(0, data.touch, Qt.point(0, 0), Qt.point(10, 10)); |
1841 | + compare(touchPressSpy.count, 1, "Not pressed?"); |
1842 | + compare(touchReleaseSpy.count, 1, "Not released?"); |
1843 | + compare(touchUpdateSpy.count, 5, "Not moved?"); |
1844 | + } |
1845 | + |
1846 | + function test_touchDrag_10_steps_data() { |
1847 | + return [ |
1848 | + {touch: touchArea}, |
1849 | + {touch: topTouchArea} |
1850 | + ]; |
1851 | + } |
1852 | + function test_touchDrag_10_steps(data) { |
1853 | + touchPressSpy.target = data.touch; |
1854 | + touchReleaseSpy.target = data.touch; |
1855 | + touchUpdateSpy.target = data.touch; |
1856 | + TestExtras.touchDrag(0, data.touch, Qt.point(0, 0), Qt.point(100, 100), 10); |
1857 | + compare(touchPressSpy.count, 1, "Not pressed?"); |
1858 | + compare(touchReleaseSpy.count, 1, "Not released?"); |
1859 | + compare(touchUpdateSpy.count, 10, "Not moved?"); |
1860 | + } |
1861 | } |
1862 | } |