Merge lp:~bzoltan/ubuntu-ui-toolkit/landing_04-06 into lp:ubuntu-ui-toolkit
- landing_04-06
- Merge into trunk
Status: | Merged |
---|---|
Merged at revision: | 1032 |
Proposed branch: | lp:~bzoltan/ubuntu-ui-toolkit/landing_04-06 |
Merge into: | lp:ubuntu-ui-toolkit |
Diff against target: |
1860 lines (+730/-327) 47 files modified
debian/changelog (+46/-0) debian/ubuntu-ui-toolkit-autopilot.install (+1/-0) examples/ubuntu-ui-toolkit-gallery/Template.qml (+4/-0) modules/Ubuntu/Components/ListItems/Empty.qml (+3/-23) modules/Ubuntu/Components/OrientationHelper.qml (+1/-1) modules/Ubuntu/Components/Popups/ComposerSheet.qml (+3/-0) modules/Ubuntu/Components/Popups/DefaultSheet.qml (+4/-0) modules/Ubuntu/Components/Popups/SheetBase.qml (+7/-1) modules/Ubuntu/Components/Scrollbar.qml (+1/-1) modules/Ubuntu/Components/Themes/Ambiance/NewHeaderStyle.qml (+13/-1) modules/Ubuntu/Components/Themes/Ambiance/ScrollbarStyle.qml (+5/-1) modules/Ubuntu/Components/plugin/filterbehavior.cpp (+8/-0) modules/Ubuntu/Components/plugin/filterbehavior.h (+2/-0) modules/Ubuntu/Components/plugin/inversemouseareatype.cpp (+9/-5) modules/Ubuntu/Components/plugin/inversemouseareatype.h (+1/-0) modules/Ubuntu/Components/plugin/sortbehavior.cpp (+8/-0) modules/Ubuntu/Components/plugin/sortbehavior.h (+2/-0) modules/Ubuntu/Components/plugin/uctheme.cpp (+6/-1) modules/Ubuntu/Test/plugin/plugin.pro (+1/-1) modules/Ubuntu/Test/plugin/uctestcase.cpp (+26/-0) modules/Ubuntu/Test/plugin/uctestcase.h (+69/-0) push_to_phone.sh (+41/-0) tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_flickable.py (+10/-0) tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/listitems.py (+13/-5) tests/autopilot/ubuntuuitoolkit/tests/__init__.py (+1/-112) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py (+62/-39) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_header.py (+89/-60) tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitems.py (+2/-0) tests/autopilot/ubuntuuitoolkit/tests/gallery/__init__.py (+21/-7) tests/autopilot/ubuntuuitoolkit/tests/gallery/test_buttons.py (+1/-3) tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.py (+10/-30) tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.py (+1/-3) tests/autopilot/ubuntuuitoolkit/tests/gallery/test_scrollbar.py (+63/-0) tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.py (+2/-6) tests/autopilot/ubuntuuitoolkit/tests/gallery/test_toggles.py (+2/-8) tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py (+1/-1) tests/launcher/launcher.cpp (+146/-0) tests/launcher/launcher.pro (+11/-0) tests/tests.pro (+2/-0) tests/unit/runtest.sh (+4/-1) tests/unit/unit.pro (+0/-2) tests/unit_x11/tst_components/tst_hide_chrome.qml (+5/-0) tests/unit_x11/tst_components/tst_popover.qml (+1/-0) tests/unit_x11/tst_components/tst_textarea.qml (+2/-0) tests/unit_x11/tst_inversemousearea/InverseMouseAreaInWindow.qml (+3/-0) tests/unit_x11/tst_inversemousearea/tst_inversemouseareatest.cpp (+8/-14) tests/unit_x11/unit_x11.pro (+9/-1) |
To merge this branch: | bzr merge lp:~bzoltan/ubuntu-ui-toolkit/landing_04-06 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Zsombor Egri | Pending | ||
Review via email: mp+221987@code.launchpad.net |
Commit message
[Leo Arias ]
* On the autopilot helper for the header, fix the swipe to show
when hidden.
* Added a fixture for autopilot tests to use a fake home directory.
Fixes: https:/
* Cleaned the containers in unity test using the alternate
launcher.
[ Christian Dywan ]
* Add a launcher with a switch for the QQMLEngine.
[ Tim Peeters ]
* Anchor the internal PageTreeNode of PageStack to fill its parent.
Fixes: https:/
Description of the change
[Leo Arias ]
* On the autopilot helper for the header, fix the swipe to show
when hidden.
* Added a fixture for autopilot tests to use a fake home directory.
Fixes: https:/
* Cleaned the containers in unity test using the alternate
launcher.
[ Christian Dywan ]
* Add a launcher with a switch for the QQMLEngine.
[ Tim Peeters ]
* Anchor the internal PageTreeNode of PageStack to fill its parent.
Fixes: https:/
PS Jenkins bot (ps-jenkins) wrote : | # |
- 1095. By Zoltan Balogh
-
Updated from the staging branch
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1095
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:1097
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
- 1096. By Zoltan Balogh
-
updated from staging branch
- 1097. By Zoltan Balogh
-
Reverting InverseMouseAre
aType updateArea() method to update(). Calling shadowed superclass update() method.
Preview Diff
1 | === modified file 'debian/changelog' |
2 | --- debian/changelog 2014-06-04 07:26:07 +0000 |
3 | +++ debian/changelog 2014-06-18 17:07:12 +0000 |
4 | @@ -1,3 +1,49 @@ |
5 | +ubuntu-ui-toolkit (0.1.46+14.10.20140602-0ubuntu2) UNRELEASED; urgency=medium |
6 | + |
7 | + [Leo Arias ] |
8 | + * On the autopilot helper for the header, fix the swipe to show |
9 | + when hidden. |
10 | + * Added a fixture for autopilot tests to use a fake home directory. |
11 | + Fixes: https://bugs.launchpad.net/bugs/1317639 |
12 | + * Cleaned the containers in unity test using the alternate |
13 | + launcher. |
14 | + * Fixed the creation of the fake Xauthority file on mako for the |
15 | + fixture tests. Fixes: https://bugs.launchpad.net/bugs/1326072 |
16 | + * Fixed the swipe to delete on the list item autopilot helper. |
17 | + Fixes: https://bugs.launchpad.net/bugs/1311392. |
18 | + * clean ups to the autopilot tests for the widget gallery. |
19 | + |
20 | + [ Christian Dywan ] |
21 | + * Add a launcher with a switch for the QQMLEngine. |
22 | + * The presence of a mouse enables the interactive thumb. |
23 | + Fixes: https://bugs.launchpad.net/bugs/1165173 |
24 | + * Initialize sort.order explicitly. |
25 | + Fixes: https://bugs.launchpad.net/bugs/1324087 |
26 | + * Swiping from Left to Right to Delete only. |
27 | + * Show explicit failure when test wasn't built yet. |
28 | + * Add push_to_phone script to push QML/ Python/ artwork. |
29 | + |
30 | + |
31 | + [ Tim Peeters ] |
32 | + * Anchor the internal PageTreeNode of PageStack to fill its parent. |
33 | + Fixes: https://bugs.launchpad.net/bugs/1322527 |
34 | + * Deprecate sheets. Fixes: https://bugs.launchpad.net/bugs/1304541 |
35 | + * Fix bug where header overflow action popover does not close when |
36 | + the associated action pushes a new page on the pagestack. |
37 | + Fixes: https://bugs.launchpad.net/bugs/1326963. |
38 | + |
39 | + [ Zsombor Egri] |
40 | + * Adding touch functions to UbuntuTestCase. |
41 | + * Qt5.3 related fixes. Fixes: |
42 | + https://bugs.launchpad.net/bugs/1324070, |
43 | + https://bugs.launchpad.net/bugs/1324088, |
44 | + https://bugs.launchpad.net/bugs/1324089. |
45 | + * Reverting InverseMouseAreaType updateArea() method to update(). |
46 | + Calling shadowed superclass' update() method. |
47 | + |
48 | + |
49 | + -- Zoltán Balogh <zoltan@bakter.hu> Wed, 04 Jun 2014 09:40:11 +0200 |
50 | + |
51 | ubuntu-ui-toolkit (0.1.46+14.10.20140602-0ubuntu1) utopic; urgency=low |
52 | |
53 | [ Christian Dywan ] |
54 | |
55 | === modified file 'debian/ubuntu-ui-toolkit-autopilot.install' |
56 | --- debian/ubuntu-ui-toolkit-autopilot.install 2014-02-21 23:39:43 +0000 |
57 | +++ debian/ubuntu-ui-toolkit-autopilot.install 2014-06-18 17:07:12 +0000 |
58 | @@ -1,2 +1,3 @@ |
59 | usr/lib/python3 |
60 | +usr/lib/ubuntu-ui-toolkit/launcher |
61 | usr/lib/python2.7 |
62 | |
63 | === modified file 'examples/ubuntu-ui-toolkit-gallery/Template.qml' |
64 | --- examples/ubuntu-ui-toolkit-gallery/Template.qml 2014-04-23 09:39:11 +0000 |
65 | +++ examples/ubuntu-ui-toolkit-gallery/Template.qml 2014-06-18 17:07:12 +0000 |
66 | @@ -30,6 +30,7 @@ |
67 | |
68 | Flickable { |
69 | id: flickable |
70 | + objectName: "TemplateFlickable" |
71 | anchors.fill: parent |
72 | anchors.topMargin: units.gu(2) |
73 | anchors.bottomMargin: units.gu(2) |
74 | @@ -46,6 +47,9 @@ |
75 | } |
76 | |
77 | Scrollbar { |
78 | + id: sb |
79 | + objectName: "TemplateScrollbar" |
80 | flickableItem: flickable |
81 | + property alias interactive: sb.__interactive |
82 | } |
83 | } |
84 | |
85 | === modified file 'modules/Ubuntu/Components/ListItems/Empty.qml' |
86 | --- modules/Ubuntu/Components/ListItems/Empty.qml 2014-05-12 16:40:44 +0000 |
87 | +++ modules/Ubuntu/Components/ListItems/Empty.qml 2014-06-18 17:07:12 +0000 |
88 | @@ -105,7 +105,7 @@ |
89 | /*! |
90 | \preliminary |
91 | \qmlproperty string swipingState |
92 | - The current swiping state ("SwipingLeft", "SwipingRight", "") |
93 | + The current swiping state ("SwipingRight" or "") |
94 | */ |
95 | readonly property alias swipingState: backgroundIndicator.state |
96 | |
97 | @@ -228,7 +228,7 @@ |
98 | __mouseArea.drag.target = body |
99 | held = true |
100 | __mouseArea.drag.maximumX = parent.width |
101 | - __mouseArea.drag.minimumX = (parent.width * -1) |
102 | + __mouseArea.drag.minimumX = 0 |
103 | backgroundIndicator.visible = true |
104 | } |
105 | |
106 | @@ -334,10 +334,8 @@ |
107 | onXChanged: { |
108 | if (x > 0) { |
109 | backgroundIndicator.state = "SwipingRight" |
110 | - } else if (x === 0) { |
111 | + } else { |
112 | backgroundIndicator.state = "" |
113 | - } else { |
114 | - backgroundIndicator.state = "SwipingLeft" |
115 | } |
116 | } |
117 | } |
118 | @@ -427,24 +425,6 @@ |
119 | target: confirmRemovalDialog |
120 | x: body.x - confirmRemovalDialog.width - units.gu(2) |
121 | } |
122 | - }, |
123 | - State { |
124 | - name: "SwipingLeft" |
125 | - AnchorChanges { |
126 | - target: backgroundIndicator |
127 | - anchors.left: body.right |
128 | - anchors.right: parent.right |
129 | - } |
130 | - |
131 | - PropertyChanges { |
132 | - target: backgroundIndicator |
133 | - opacity: 1.0 |
134 | - } |
135 | - |
136 | - PropertyChanges { |
137 | - target: confirmRemovalDialog |
138 | - x: units.gu(2) |
139 | - } |
140 | } |
141 | ] |
142 | } |
143 | |
144 | === modified file 'modules/Ubuntu/Components/OrientationHelper.qml' |
145 | --- modules/Ubuntu/Components/OrientationHelper.qml 2014-04-23 09:39:11 +0000 |
146 | +++ modules/Ubuntu/Components/OrientationHelper.qml 2014-06-18 17:07:12 +0000 |
147 | @@ -121,7 +121,7 @@ |
148 | http://qt-project.org/doc/qt-5.0/qtgui/qwindow.html#contentOrientation-prop |
149 | */ |
150 | function applyOrientation() { |
151 | - if (windowActive) |
152 | + if (windowActive && window) |
153 | window.contentOrientation = Screen.orientation |
154 | } |
155 | |
156 | |
157 | === modified file 'modules/Ubuntu/Components/Popups/ComposerSheet.qml' |
158 | --- modules/Ubuntu/Components/Popups/ComposerSheet.qml 2014-04-23 08:50:20 +0000 |
159 | +++ modules/Ubuntu/Components/Popups/ComposerSheet.qml 2014-06-18 17:07:12 +0000 |
160 | @@ -20,6 +20,7 @@ |
161 | \qmltype ComposerSheet |
162 | \inherits SheetBase |
163 | \inqmlmodule Ubuntu.Components.Popups 1.0 |
164 | + \deprecated |
165 | \ingroup ubuntu-popups |
166 | \brief Much like the \l DefaultSheet the Composer Sheet allows an application to insert a content |
167 | view over the focused view without disrupting the navigation pattern. However the Composer Sheet |
168 | @@ -56,6 +57,8 @@ |
169 | } |
170 | } |
171 | \endqml |
172 | + |
173 | + \b{Sheets are deprecated. Consider using \l Dialog, \l Popover or \l PageStack instead.} |
174 | */ |
175 | |
176 | SheetBase { |
177 | |
178 | === modified file 'modules/Ubuntu/Components/Popups/DefaultSheet.qml' |
179 | --- modules/Ubuntu/Components/Popups/DefaultSheet.qml 2014-04-23 08:50:20 +0000 |
180 | +++ modules/Ubuntu/Components/Popups/DefaultSheet.qml 2014-06-18 17:07:12 +0000 |
181 | @@ -19,6 +19,7 @@ |
182 | |
183 | /*! |
184 | \qmltype DefaultSheet |
185 | + \deprecated |
186 | \inherits SheetBase |
187 | \inqmlmodule Ubuntu.Components.Popups 1.0 |
188 | \ingroup ubuntu-popups |
189 | @@ -58,6 +59,9 @@ |
190 | } |
191 | } |
192 | \endqml |
193 | + |
194 | + \b{Sheets are deprecated. Consider using \l Dialog, \l Popover or \l PageStack instead.} |
195 | + |
196 | */ |
197 | SheetBase { |
198 | id: sheet |
199 | |
200 | === modified file 'modules/Ubuntu/Components/Popups/SheetBase.qml' |
201 | --- modules/Ubuntu/Components/Popups/SheetBase.qml 2014-04-23 08:50:20 +0000 |
202 | +++ modules/Ubuntu/Components/Popups/SheetBase.qml 2014-06-18 17:07:12 +0000 |
203 | @@ -19,16 +19,22 @@ |
204 | |
205 | /*! |
206 | \qmltype SheetBase |
207 | + \deprecated |
208 | \inqmlmodule Ubuntu.Components.Popups 1.0 |
209 | \ingroup ubuntu-popups |
210 | \brief Parent class of different types of sheets. Not to be used directly. |
211 | |
212 | Examples: See subclasses. |
213 | - \b{This component is under heavy development.} |
214 | + \b{Sheets are deprecated. Consider using \l Dialog, \l Popover or \l PageStack instead.} |
215 | */ |
216 | PopupBase { |
217 | id: sheet |
218 | |
219 | + Component.onCompleted: { |
220 | + print("WARNING: Sheets are deprecated. " + |
221 | + "Consider using Dialog, Popover or PageStack instead.") |
222 | + } |
223 | + |
224 | /*! |
225 | \preliminary |
226 | \qmlproperty list<Object> container |
227 | |
228 | === modified file 'modules/Ubuntu/Components/Scrollbar.qml' |
229 | --- modules/Ubuntu/Components/Scrollbar.qml 2014-04-23 08:50:20 +0000 |
230 | +++ modules/Ubuntu/Components/Scrollbar.qml 2014-06-18 17:07:12 +0000 |
231 | @@ -87,7 +87,7 @@ |
232 | This property holds whether the scrollbar is active or passive. It is present |
233 | for testing purposes. |
234 | */ |
235 | - property bool __interactive: false |
236 | + property bool __interactive: __styleInstance !== null && __styleInstance.interactive |
237 | |
238 | implicitWidth: internals.vertical ? units.gu(4) : flickableItem.width |
239 | implicitHeight: !internals.vertical ? units.gu(4) : flickableItem.height |
240 | |
241 | === modified file 'modules/Ubuntu/Components/Themes/Ambiance/NewHeaderStyle.qml' |
242 | --- modules/Ubuntu/Components/Themes/Ambiance/NewHeaderStyle.qml 2014-05-14 13:21:10 +0000 |
243 | +++ modules/Ubuntu/Components/Themes/Ambiance/NewHeaderStyle.qml 2014-06-18 17:07:12 +0000 |
244 | @@ -259,9 +259,21 @@ |
245 | |
246 | Popover { |
247 | id: actionsOverflowPopover |
248 | - objectName: "actionsOverflowPopover" |
249 | + objectName: "actions_overflow_popover" |
250 | parent: QuickUtils.rootItem(actionsOverflowPopover) |
251 | caller: actionsOverflowButton |
252 | + |
253 | + Connections { |
254 | + target: styledItem |
255 | + onActionsChanged: { |
256 | + // Ensure the popover closes when actions change and |
257 | + // the list item below may be destroyed before its |
258 | + // onClicked is executed. See bug |
259 | + // https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1326963 |
260 | + actionsOverflowPopover.hide(); |
261 | + } |
262 | + } |
263 | + |
264 | Column { |
265 | anchors { |
266 | left: parent.left |
267 | |
268 | === modified file 'modules/Ubuntu/Components/Themes/Ambiance/ScrollbarStyle.qml' |
269 | --- modules/Ubuntu/Components/Themes/Ambiance/ScrollbarStyle.qml 2014-04-23 08:50:20 +0000 |
270 | +++ modules/Ubuntu/Components/Themes/Ambiance/ScrollbarStyle.qml 2014-06-18 17:07:12 +0000 |
271 | @@ -59,7 +59,7 @@ |
272 | property bool interactive: false |
273 | property real minimumSliderSize: units.gu(2) |
274 | |
275 | - property bool overlay: true |
276 | + property bool overlay: !interactive |
277 | property real overlayOpacityWhenShown: 0.6 |
278 | property real overlayOpacityWhenHidden: 0.0 |
279 | |
280 | @@ -222,6 +222,9 @@ |
281 | onReleased: mouse.accepted = false |
282 | } |
283 | |
284 | + // The presence of a mouse enables the interactive thumb |
285 | + // FIXME: Should use form factor hints |
286 | + InverseMouse.onEntered: interactive = true |
287 | |
288 | // The slider's position represents which part of the flickable is visible. |
289 | // The slider's size represents the size the visible part relative to the |
290 | @@ -401,6 +404,7 @@ |
291 | |
292 | Item { |
293 | id: thumb |
294 | + objectName: "interactiveScrollbarThumb" |
295 | |
296 | enabled: interactive |
297 | |
298 | |
299 | === modified file 'modules/Ubuntu/Components/plugin/filterbehavior.cpp' |
300 | --- modules/Ubuntu/Components/plugin/filterbehavior.cpp 2014-05-15 09:35:22 +0000 |
301 | +++ modules/Ubuntu/Components/plugin/filterbehavior.cpp 2014-06-18 17:07:12 +0000 |
302 | @@ -19,6 +19,14 @@ |
303 | |
304 | #include "filterbehavior.h" |
305 | |
306 | +FilterBehavior::FilterBehavior(QObject *parent) |
307 | + : QObject(parent) |
308 | + , m_property(QString()) |
309 | + , m_pattern(QRegExp()) |
310 | +{ |
311 | + |
312 | +} |
313 | + |
314 | QString |
315 | FilterBehavior::property() const |
316 | { |
317 | |
318 | === modified file 'modules/Ubuntu/Components/plugin/filterbehavior.h' |
319 | --- modules/Ubuntu/Components/plugin/filterbehavior.h 2014-05-15 09:35:22 +0000 |
320 | +++ modules/Ubuntu/Components/plugin/filterbehavior.h 2014-06-18 17:07:12 +0000 |
321 | @@ -29,6 +29,8 @@ |
322 | Q_PROPERTY(QRegExp pattern READ pattern WRITE setPattern NOTIFY patternChanged) |
323 | |
324 | public: |
325 | + explicit FilterBehavior(QObject *parent = 0); |
326 | + |
327 | QString property() const; |
328 | void setProperty(const QString& property); |
329 | QRegExp pattern() const; |
330 | |
331 | === modified file 'modules/Ubuntu/Components/plugin/inversemouseareatype.cpp' |
332 | --- modules/Ubuntu/Components/plugin/inversemouseareatype.cpp 2014-04-25 12:53:58 +0000 |
333 | +++ modules/Ubuntu/Components/plugin/inversemouseareatype.cpp 2014-06-18 17:07:12 +0000 |
334 | @@ -244,11 +244,6 @@ |
335 | */ |
336 | QObject::connect(this, &QQuickMouseArea::windowChanged, |
337 | this, &InverseMouseAreaType::resetFilterOnWindowUpdate); |
338 | - |
339 | - if (!m_sensingArea) { |
340 | - // get sensing area upon parent change |
341 | - QObject::connect(this, SIGNAL(parentChanged(QQuickItem*)), this, SLOT(update())); |
342 | - } |
343 | } |
344 | |
345 | InverseMouseAreaType::~InverseMouseAreaType() |
346 | @@ -291,6 +286,7 @@ |
347 | m_sensingArea = QuickUtils::instance().rootItem(this); |
348 | } |
349 | updateEventFilter(isEnabled() && isVisible() && m_topmostItem); |
350 | + QQuickMouseArea::update(); |
351 | } |
352 | /*! |
353 | \internal |
354 | @@ -302,6 +298,14 @@ |
355 | updateEventFilter(m_topmostItem); |
356 | } |
357 | |
358 | +void InverseMouseAreaType::itemChange(ItemChange change, const ItemChangeData &data) |
359 | +{ |
360 | + if (change == ItemParentHasChanged && data.item) { |
361 | + update(); |
362 | + } |
363 | + QQuickMouseArea::itemChange(change, data); |
364 | +} |
365 | + |
366 | void InverseMouseAreaType::componentComplete() |
367 | { |
368 | QQuickMouseArea::componentComplete(); |
369 | |
370 | === modified file 'modules/Ubuntu/Components/plugin/inversemouseareatype.h' |
371 | --- modules/Ubuntu/Components/plugin/inversemouseareatype.h 2014-03-20 10:01:21 +0000 |
372 | +++ modules/Ubuntu/Components/plugin/inversemouseareatype.h 2014-06-18 17:07:12 +0000 |
373 | @@ -32,6 +32,7 @@ |
374 | Q_INVOKABLE virtual bool contains(const QPointF &point) const; |
375 | |
376 | protected: |
377 | + void itemChange(ItemChange, const ItemChangeData &); |
378 | void componentComplete(); |
379 | bool eventFilter(QObject *, QEvent *); |
380 | |
381 | |
382 | === modified file 'modules/Ubuntu/Components/plugin/sortbehavior.cpp' |
383 | --- modules/Ubuntu/Components/plugin/sortbehavior.cpp 2014-05-15 09:35:22 +0000 |
384 | +++ modules/Ubuntu/Components/plugin/sortbehavior.cpp 2014-06-18 17:07:12 +0000 |
385 | @@ -19,6 +19,14 @@ |
386 | |
387 | #include "sortbehavior.h" |
388 | |
389 | +SortBehavior::SortBehavior(QObject *parent) |
390 | + : QObject(parent) |
391 | + , m_property(QString()) |
392 | + , m_order(Qt::AscendingOrder) |
393 | +{ |
394 | + |
395 | +} |
396 | + |
397 | QString |
398 | SortBehavior::property() const |
399 | { |
400 | |
401 | === modified file 'modules/Ubuntu/Components/plugin/sortbehavior.h' |
402 | --- modules/Ubuntu/Components/plugin/sortbehavior.h 2014-05-15 09:35:22 +0000 |
403 | +++ modules/Ubuntu/Components/plugin/sortbehavior.h 2014-06-18 17:07:12 +0000 |
404 | @@ -29,6 +29,8 @@ |
405 | Q_PROPERTY(Qt::SortOrder order READ order WRITE setOrder NOTIFY orderChanged) |
406 | |
407 | public: |
408 | + explicit SortBehavior(QObject *parent = 0); |
409 | + |
410 | QString property() const; |
411 | void setProperty(const QString& property); |
412 | Qt::SortOrder order() const; |
413 | |
414 | === modified file 'modules/Ubuntu/Components/plugin/uctheme.cpp' |
415 | --- modules/Ubuntu/Components/plugin/uctheme.cpp 2014-04-23 08:50:20 +0000 |
416 | +++ modules/Ubuntu/Components/plugin/uctheme.cpp 2014-06-18 17:07:12 +0000 |
417 | @@ -81,7 +81,12 @@ |
418 | QStringList pathList = envPath.split(':', QString::SkipEmptyParts); |
419 | if (pathList.isEmpty()) { |
420 | // get the default path list from generic data location, which contains |
421 | - // ~/.local/share and XDG_DATA_DIRS |
422 | + // XDG_DATA_DIRS |
423 | + QString xdgDirs = QLatin1String(getenv("XDG_DATA_DIRS")); |
424 | + if (!xdgDirs.isEmpty()) { |
425 | + pathList << xdgDirs.split(':', QString::SkipEmptyParts); |
426 | + } |
427 | + // ~/.local/share |
428 | pathList << QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); |
429 | } |
430 | // fix folders |
431 | |
432 | === modified file 'modules/Ubuntu/Test/plugin/plugin.pro' |
433 | --- modules/Ubuntu/Test/plugin/plugin.pro 2013-12-16 17:37:48 +0000 |
434 | +++ modules/Ubuntu/Test/plugin/plugin.pro 2014-06-18 17:07:12 +0000 |
435 | @@ -1,6 +1,6 @@ |
436 | TEMPLATE = lib |
437 | TARGET = ../UbuntuTest |
438 | -QT += core-private qml qml-private quick quick-private |
439 | +QT += core-private qml qml-private quick quick-private gui-private |
440 | |
441 | equals(QT_MAJOR_VERSION, 5):lessThan(QT_MINOR_VERSION, 2) { |
442 | QT += v8-private |
443 | |
444 | === modified file 'modules/Ubuntu/Test/plugin/uctestcase.cpp' |
445 | --- modules/Ubuntu/Test/plugin/uctestcase.cpp 2014-03-28 17:02:52 +0000 |
446 | +++ modules/Ubuntu/Test/plugin/uctestcase.cpp 2014-06-18 17:07:12 +0000 |
447 | @@ -26,8 +26,11 @@ |
448 | #include <QtTest/QtTest> |
449 | #include <QtQuick/QQuickItem> |
450 | |
451 | +#include <qpa/qwindowsysteminterface.h> |
452 | + |
453 | Q_DECLARE_METATYPE(QList<QQmlError>) |
454 | |
455 | +QTouchDevice *UbuntuTestCase::m_touchDevice = 0; |
456 | /*! |
457 | * \ingroup ubuntu |
458 | * \brief UbuntuTestCase is the C++ pendant to the QML UbuntuTestCase. |
459 | @@ -60,3 +63,26 @@ |
460 | return m_spy->count(); |
461 | } |
462 | |
463 | +/*! |
464 | + * Registers a touch device if there's none registered. |
465 | + */ |
466 | +void UbuntuTestCase::registerTouchDevice() |
467 | +{ |
468 | + // check if there is any touch device registered in the system |
469 | + if (!m_touchDevice) { |
470 | + QList<const QTouchDevice*> touchDevices = QTouchDevice::devices(); |
471 | + Q_FOREACH(const QTouchDevice *device, touchDevices) { |
472 | + if (device->type() == QTouchDevice::TouchScreen) { |
473 | + m_touchDevice = const_cast<QTouchDevice*>(device); |
474 | + break; |
475 | + } |
476 | + } |
477 | + } |
478 | + // if none, register one |
479 | + if (!m_touchDevice) { |
480 | + m_touchDevice = new QTouchDevice; |
481 | + m_touchDevice->setType(QTouchDevice::TouchScreen); |
482 | + QWindowSystemInterface::registerTouchDevice(m_touchDevice); |
483 | + } |
484 | +} |
485 | + |
486 | |
487 | === modified file 'modules/Ubuntu/Test/plugin/uctestcase.h' |
488 | --- modules/Ubuntu/Test/plugin/uctestcase.h 2014-03-28 17:02:52 +0000 |
489 | +++ modules/Ubuntu/Test/plugin/uctestcase.h 2014-06-18 17:07:12 +0000 |
490 | @@ -19,10 +19,13 @@ |
491 | #ifndef UBUNTU_TEST_UBUNTUTESTCASE_H |
492 | #define UBUNTU_TEST_UBUNTUTESTCASE_H |
493 | |
494 | +#include <QtTest/QtTest> |
495 | #include <QtQuick/QQuickItem> |
496 | #include <QtQuick/QQuickView> |
497 | #include <QtTest/QSignalSpy> |
498 | |
499 | +#define CHECK_TOUCH_DEVICE() if (!checkTouchDevice(__FUNCTION__)) return |
500 | + |
501 | class UbuntuTestCase : public QQuickView |
502 | { |
503 | Q_OBJECT |
504 | @@ -40,8 +43,74 @@ |
505 | qFatal("Item '%s' found with unexpected type", qPrintable(objectName)); |
506 | qFatal("No item '%s' found", qPrintable(objectName)); |
507 | } |
508 | + |
509 | + static void registerTouchDevice(); |
510 | + |
511 | + inline static void touchPress(int touchId, QWindow *window, const QPoint &point) |
512 | + { |
513 | + CHECK_TOUCH_DEVICE(); |
514 | + QTest::touchEvent(window, m_touchDevice).press(touchId, point, window); |
515 | + } |
516 | + inline static void touchRelease(int touchId, QWindow *window, const QPoint &point) |
517 | + { |
518 | + CHECK_TOUCH_DEVICE(); |
519 | + QTest::touchEvent(window, m_touchDevice).release(touchId, point, window); |
520 | + } |
521 | + inline static void touchClick(int touchId, QWindow *window, const QPoint &point) |
522 | + { |
523 | + CHECK_TOUCH_DEVICE(); |
524 | + touchPress(touchId, window, point); |
525 | + QTest::qWait(10); |
526 | + touchRelease(touchId, window, point); |
527 | + } |
528 | + inline static void touchLongPress(int touchId, QWindow *window, const QPoint &point) |
529 | + { |
530 | + CHECK_TOUCH_DEVICE(); |
531 | + touchPress(touchId, window, point); |
532 | + QTest::qWait(800); |
533 | + } |
534 | + inline static void touchDoubleClick(int touchId, QWindow *window, const QPoint &point) |
535 | + { |
536 | + CHECK_TOUCH_DEVICE(); |
537 | + touchClick(touchId, window, point); |
538 | + QTest::qWait(10); |
539 | + touchClick(touchId, window, point); |
540 | + } |
541 | + inline static void touchMove(int touchId, QWindow *window, const QPoint &point) |
542 | + { |
543 | + CHECK_TOUCH_DEVICE(); |
544 | + QTest::touchEvent(window, m_touchDevice).move(touchId, point, window); |
545 | + } |
546 | + inline static void touchDrag(int touchId, QWindow *window, const QPoint &from, const QPoint &delta, int steps = 5) |
547 | + { |
548 | + touchPress(touchId, window, from); |
549 | + QTest::qWait(10); |
550 | + QTest::touchEvent(window, m_touchDevice).move(touchId, from, window); |
551 | + qreal stepDx = delta.x() / steps; |
552 | + qreal stepDy = delta.y() / steps; |
553 | + if (!delta.isNull()) { |
554 | + for (int i = 0; i < steps; i++) { |
555 | + QTest::qWait(10); |
556 | + QTest::touchEvent(window, m_touchDevice).move(touchId, from + QPoint(i * stepDx, i * stepDy), window); |
557 | + } |
558 | + } |
559 | + QTest::qWait(10); |
560 | + touchRelease(touchId, window, from + QPoint(stepDx, stepDy)); |
561 | + } |
562 | + |
563 | + |
564 | private: |
565 | QSignalSpy* m_spy; |
566 | + static QTouchDevice *m_touchDevice; |
567 | + |
568 | + static inline bool checkTouchDevice(const char *func) |
569 | + { |
570 | + if (!m_touchDevice) { |
571 | + qWarning() << QString("No touch device registered. Register one using registerTouchDevice() before using %1").arg(func); |
572 | + return false; |
573 | + } |
574 | + return true; |
575 | + } |
576 | }; |
577 | |
578 | #endif // UBUNTU_TEST_UBUNTUTESTCASE_H |
579 | |
580 | === added file 'push_to_phone.sh' |
581 | --- push_to_phone.sh 1970-01-01 00:00:00 +0000 |
582 | +++ push_to_phone.sh 2014-06-18 17:07:12 +0000 |
583 | @@ -0,0 +1,41 @@ |
584 | +#!/bin/sh |
585 | +# |
586 | +# Copyright 2014 Canonical Ltd. |
587 | +# |
588 | +# This program is free software; you can redistribute it and/or modify |
589 | +# it under the terms of the GNU Lesser General Public License as published by |
590 | +# the Free Software Foundation; version 3. |
591 | +# |
592 | +# This program is distributed in the hope that it will be useful, |
593 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
594 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
595 | +# GNU Lesser General Public License for more details. |
596 | +# |
597 | +# You should have received a copy of the GNU Lesser General Public License |
598 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
599 | +# |
600 | +# Author: Christian Dywan <christian.dywan@canonical.com> |
601 | + |
602 | +ARCH=arm-linux-gnueabihf |
603 | + |
604 | +# Make the image writable |
605 | +phablet-config writable-image || exit 1 |
606 | +# Copy selectively to avoid pushing binaries (arch conflict) and sources (unneeded) |
607 | +cd modules || exit 1 |
608 | +for i in $(ls Ubuntu/Components/*.qml 2>/dev/null); do |
609 | + echo modules/$i '->' /usr/lib/$ARCH/qt5/qml/Ubuntu/Components/ |
610 | + adb push $i /usr/lib/$ARCH/qt5/qml/Ubuntu/Components/ |
611 | +done |
612 | +for i in $(ls Ubuntu/Components/*.js 2>/dev/null); do |
613 | + echo modules/$i '->' /usr/lib/$ARCH/qt5/qml/Ubuntu/Components/ |
614 | + adb push $i /usr/lib/$ARCH/qt5/qml/Ubuntu/Components/ |
615 | +done |
616 | +cd .. |
617 | +for i in ListItems Pickers Popups Colors Styles Themes artwork; do |
618 | + adb push modules/Ubuntu/Components/$i/ /usr/lib/$ARCH/qt5/qml/Ubuntu/Components/$i || exit 1 |
619 | +done |
620 | +# Autopilot tests should always match the Toolkit |
621 | +adb push tests/autopilot/ubuntuuitoolkit/ /usr/lib/python2.7/dist-packages/ubuntuuitoolkit || exit 1 |
622 | +adb push examples/ubuntu-ui-toolkit-gallery/ /usr/lib/ubuntu-ui-toolkit/examples/ubuntu-ui-toolkit-gallery || exit 1 |
623 | +# For launching the gallery easily |
624 | +adb push examples/ubuntu-ui-toolkit-gallery/*.desktop /usr/share/applications/ || exit 1 |
625 | |
626 | === modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_flickable.py' |
627 | --- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_flickable.py 2014-05-29 16:14:55 +0000 |
628 | +++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_flickable.py 2014-06-18 17:07:12 +0000 |
629 | @@ -40,6 +40,16 @@ |
630 | |
631 | class Scrollable(_common.UbuntuUIToolkitCustomProxyObjectBase): |
632 | |
633 | + @autopilot_logging.log_action(logger.info) |
634 | + def is_child_visible(self, child): |
635 | + """Determine if the child is visible. |
636 | + |
637 | + A child is visible if no scrolling is needed to reveal it. |
638 | + |
639 | + """ |
640 | + containers = self._get_containers() |
641 | + return self._is_child_visible(child, containers) |
642 | + |
643 | def _get_containers(self): |
644 | """Return a list with the containers to take into account when swiping. |
645 | |
646 | |
647 | === modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/listitems.py' |
648 | --- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/listitems.py 2014-04-25 18:39:51 +0000 |
649 | +++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/listitems.py 2014-06-18 17:07:12 +0000 |
650 | @@ -42,6 +42,9 @@ |
651 | def swipe_to_delete(self, direction='right'): |
652 | """Swipe the item in a specific direction.""" |
653 | if self.removable: |
654 | + # Swipe to delete is always right to left |
655 | + if direction == 'left': |
656 | + direction = 'right' |
657 | self._drag_pointing_device_to_delete(direction) |
658 | if self.confirmRemoval: |
659 | self.waitingConfirmationForRemoval.wait_for(True) |
660 | @@ -52,14 +55,19 @@ |
661 | 'The item "{0}" is not removable'.format(self.objectName)) |
662 | |
663 | def _drag_pointing_device_to_delete(self, direction): |
664 | - x, y, w, h = self.globalRect |
665 | - tx = x + (w // 8) |
666 | - ty = y + (h // 2) |
667 | + x, y, width, height = self.globalRect |
668 | + left_x = x + (width * 0.2) |
669 | + right_x = x + (width * 0.8) |
670 | + start_y = stop_y = y + (height // 2) |
671 | |
672 | if direction == 'right': |
673 | - self.pointing_device.drag(tx, ty, w, ty) |
674 | + start_x = left_x |
675 | + stop_x = right_x |
676 | + self.pointing_device.drag(start_x, start_y, stop_x, stop_y) |
677 | elif direction == 'left': |
678 | - self.pointing_device.drag(w - (w*0.1), ty, x, ty) |
679 | + start_x = right_x |
680 | + stop_x = left_x |
681 | + self.pointing_device.drag(start_x, start_y, stop_x, stop_y) |
682 | else: |
683 | raise _common.ToolkitException( |
684 | 'Invalid direction "{0}" used on swipe to delete function' |
685 | |
686 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/__init__.py' |
687 | --- tests/autopilot/ubuntuuitoolkit/tests/__init__.py 2014-05-29 16:17:56 +0000 |
688 | +++ tests/autopilot/ubuntuuitoolkit/tests/__init__.py 2014-06-18 17:07:12 +0000 |
689 | @@ -1,6 +1,6 @@ |
690 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
691 | # |
692 | -# Copyright (C) 2012, 2013 Canonical Ltd. |
693 | +# Copyright (C) 2012, 2013, 2014 Canonical Ltd. |
694 | # |
695 | # This program is free software; you can redistribute it and/or modify |
696 | # it under the terms of the GNU Lesser General Public License as published by |
697 | @@ -142,91 +142,6 @@ |
698 | def main_view(self): |
699 | return self.app.select_single(emulators.MainView) |
700 | |
701 | - def checkListItem(self, itemText): |
702 | - item = self.getListItem(itemText) |
703 | - self.assertThat(item, Not(Is(None))) |
704 | - |
705 | - def getListItem(self, itemText): |
706 | - # XXX We shouldn't access the elements by text, because that's likely |
707 | - # to change often and might be translated. We should always use the |
708 | - # objectName instead. --elopio - 2013-06-26216 |
709 | - return self.main_view.select_single("Standard", text=itemText) |
710 | - |
711 | - def getWidgetLoaderAndListView(self): |
712 | - contentLoader = self.main_view.select_single( |
713 | - "QQuickLoader", objectName="contentLoader") |
714 | - listView = self.main_view.select_single( |
715 | - "QQuickListView", objectName="widgetList") |
716 | - self.assertThat(listView, Not(Is(None))) |
717 | - self.assertThat(listView.visible, Eventually(Equals(True))) |
718 | - return (contentLoader, listView) |
719 | - |
720 | - def loadItem(self, item): |
721 | - self.selectItem(item) |
722 | - contentLoader = self.main_view.select_single( |
723 | - "QQuickLoader", objectName="contentLoader") |
724 | - self.assertThat(contentLoader.progress, Eventually(Equals(1.0))) |
725 | - loadedPage = self.getListItem(item) |
726 | - self.assertThat(loadedPage, Not(Is(None))) |
727 | - #loadedPage is not a page, it is the list item which goes in |
728 | - #background when the item is selected, which changes the visible |
729 | - #property of item in list itself to False. So followin check |
730 | - #fails on Nexus 4. Commenting it for now. |
731 | - #self.assertThat(loadedPage.visible, Eventually(Equals(True))) |
732 | - |
733 | - def drag(self, itemText, itemTextTo): |
734 | - item = self.getListItem(itemText) |
735 | - itemTo = self.getListItem(itemTextTo) |
736 | - |
737 | - self.pointing_device.move_to_object(item) |
738 | - self.pointing_device.press() |
739 | - self.pointing_device.move_to_object(itemTo) |
740 | - self.pointing_device.release() |
741 | - |
742 | - def reveal_item_by_flick(self, item, flickable, direction): |
743 | - x1, y1, w1, h1 = item.globalRect |
744 | - x2, y2, w2, h2 = flickable.globalRect |
745 | - if direction is FlickDirection.UP: |
746 | - while y1 + h1 > y2 + h2: |
747 | - self.flick(flickable, direction) |
748 | - x1, y1, w1, h1 = item.globalRect |
749 | - elif direction is FlickDirection.DOWN: |
750 | - while y1 < y2: |
751 | - self.flick(flickable, direction) |
752 | - x1, y1, w1, h1 = item.globalRect |
753 | - |
754 | - def flick(self, flickable, direction, delta=40): |
755 | - """This funcito flicks the page from middle to the given direction.""" |
756 | - x, y, w, h = flickable.globalRect |
757 | - if direction == FlickDirection.UP: |
758 | - self.pointing_device.drag(x + w / 2, y + h / 2, x + w / 2, |
759 | - y + h / 2 - delta) |
760 | - flickable.flicking.wait_for(False) |
761 | - elif direction == FlickDirection.DOWN: |
762 | - self.pointing_device.drag(x + w / 2, y + h / 2, x + w / 2, |
763 | - y + h / 2 + delta) |
764 | - flickable.flicking.wait_for(False) |
765 | - else: |
766 | - raise ValueError("Invalid direction or not implementd yet") |
767 | - |
768 | - def selectItem(self, itemText): |
769 | - item = self.getListItem(itemText) |
770 | - x1, y1, w1, h1 = item.globalRect |
771 | - x2, y2, w2, h2 = self.main_view.globalRect |
772 | - |
773 | - orientationHelper = self.getOrientationHelper() |
774 | - rot = orientationHelper.rotation |
775 | - scrollTo = h2 / 2 - (y1 - h2 - h1) |
776 | - if rot == 0.0 and y1 > h2: |
777 | - self.pointing_device.drag(w2 / 2, h2 / 2, w2 / 2, scrollTo) |
778 | - |
779 | - self.assertThat(item.selected, Eventually(Equals(False))) |
780 | - |
781 | - self.pointing_device.move_to_object(item) |
782 | - self.pointing_device.click() |
783 | - |
784 | - self.assertThat(item.selected, Eventually(Equals(True))) |
785 | - |
786 | def getOrientationHelper(self): |
787 | orientationHelper = self.main_view.select_many( |
788 | "OrientationHelper")[0] |
789 | @@ -249,29 +164,3 @@ |
790 | obj = self.getObject(objectName) |
791 | self.pointing_device.move_to_object(obj) |
792 | self.pointing_device.click() |
793 | - |
794 | - def mousePress(self, objectName): |
795 | - obj = self.getObject(objectName) |
796 | - self.pointing_device.move_to_object(obj) |
797 | - self.pointing_device.press() |
798 | - |
799 | - def mouseRelease(self): |
800 | - self.pointing_device.release() |
801 | - |
802 | - def type_string(self, string): |
803 | - self.keyboard.type(string) |
804 | - |
805 | - def type_key(self, key): |
806 | - self.keyboard.key(key) |
807 | - |
808 | - def tap_clearButton(self, objectName): |
809 | - textField = self.getObject(objectName) |
810 | - self.assertIsNotNone(textField) |
811 | - self.pointing_device.click_object(textField) |
812 | - self.assertThat(textField.focus, Eventually(Equals(True))) |
813 | - self.assertThat(textField.hasClearButton, Eventually(Equals(True))) |
814 | - btn = textField.select_single("AbstractButton") |
815 | - self.assertIsNotNone(btn) |
816 | - self.assertThat(btn.visible, Eventually(Equals(True))) |
817 | - self.pointing_device.click_object(btn) |
818 | - self.assertThat(btn.pressed, Eventually(Equals(False))) |
819 | |
820 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py' |
821 | --- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py 2014-05-19 09:46:05 +0000 |
822 | +++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_flickable.py 2014-06-18 17:07:12 +0000 |
823 | @@ -14,53 +14,16 @@ |
824 | # You should have received a copy of the GNU Lesser General Public License |
825 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
826 | |
827 | +import os |
828 | |
829 | import testtools |
830 | - |
831 | import ubuntuuitoolkit |
832 | -from ubuntuuitoolkit import tests |
833 | +from ubuntuuitoolkit import fixture_setup, tests |
834 | from ubuntuuitoolkit._custom_proxy_objects import _common |
835 | |
836 | |
837 | class FlickableTestCase(testtools.TestCase): |
838 | |
839 | - def test_get_unity_top_container(self): |
840 | - """Test that we can get the top cointainer in Unity.""" |
841 | - # This tests bug http://pad.lv/1314390 |
842 | - # On Unity, the top container is not the first child as it is in all |
843 | - # the apps that have a MainView. This makes the first implementation of |
844 | - # _get_top_container fail. Instead of going from the top looking for |
845 | - # a container, we should start from the flickable until we find the |
846 | - # top-most container. |
847 | - # FIXME we are faking the QML tree because we have no way to launch |
848 | - # the app with a tree like the one in Unity8. kalikiana has a branch |
849 | - # with an alternate launcher that will let us clean this test. |
850 | - # --elopio - 2014-05-15. |
851 | - RootClass = type('obj', (object,), {'id': 'root'}) |
852 | - mock_root_instance = RootClass() |
853 | - # We consider a container is an object with a globalRect. |
854 | - MockNonContainerClass = type('obj', (object,), {}) |
855 | - mock_non_container = MockNonContainerClass() |
856 | - MockContainerClass = type( |
857 | - 'obj', (object,), {'id': 'container', 'globalRect': 'dummy'}) |
858 | - mock_container = MockContainerClass() |
859 | - mock_container.get_parent = lambda: mock_root_instance |
860 | - |
861 | - # The root instance has two children. This exposes the bug. |
862 | - mock_root_instance.get_children = lambda: [ |
863 | - mock_non_container, mock_container] |
864 | - |
865 | - dummy_state = {'id': '10'} |
866 | - flickable = ubuntuuitoolkit.QQuickFlickable( |
867 | - dummy_state, '/dummy'.encode(), 'dummy') |
868 | - |
869 | - flickable.get_root_instance = lambda: mock_root_instance |
870 | - # The top container of the flickable is its immediate parent. |
871 | - flickable.get_parent = lambda: mock_container |
872 | - |
873 | - top_container = flickable._get_top_container() |
874 | - self.assertEqual(top_container, mock_container) |
875 | - |
876 | def test_is_flickable_with_flicking_property_must_return_true(self): |
877 | """is_flickable returns True if flickable property exists.""" |
878 | dummy_id = (0, 0) |
879 | @@ -68,6 +31,7 @@ |
880 | state_with_flicking = {'id': dummy_id, 'flicking': dummy_flicking} |
881 | element = _common.UbuntuUIToolkitCustomProxyObjectBase( |
882 | state_with_flicking, '/dummy'.encode(), 'dummy') |
883 | + |
884 | with element.no_automatic_refreshing(): |
885 | self.assertTrue(element.is_flickable()) |
886 | |
887 | @@ -77,6 +41,7 @@ |
888 | state_without_flicking = {'id': dummy_id} |
889 | element = _common.UbuntuUIToolkitCustomProxyObjectBase( |
890 | state_without_flicking, '/dummy'.encode(), 'dummy') |
891 | + |
892 | with element.no_automatic_refreshing(): |
893 | self.assertFalse(element.is_flickable()) |
894 | |
895 | @@ -199,3 +164,61 @@ |
896 | |
897 | self.pointing_device.click_object(topButton) |
898 | self.assertEqual(self.label.text, 'topButton') |
899 | + |
900 | + |
901 | +class UnityFlickableTestCase(tests.QMLStringAppTestCase): |
902 | + |
903 | + test_qml = (""" |
904 | +import QtQuick 2.0 |
905 | +import Ubuntu.Components 0.1 |
906 | + |
907 | +MainView { |
908 | + width: units.gu(48) |
909 | + height: units.gu(60) |
910 | + |
911 | + Flickable { |
912 | + objectName: 'testFlickable' |
913 | + width: 200; height: 200 |
914 | + contentWidth: image.width; contentHeight: image.height |
915 | + } |
916 | +} |
917 | +""") |
918 | + |
919 | + def launch_application(self): |
920 | + fake_application = fixture_setup.FakeApplication( |
921 | + qml_file_contents=self.test_qml) |
922 | + self.useFixture(fake_application) |
923 | + |
924 | + self.app = self.launch_test_application( |
925 | + self.get_alternate_launch_command(), |
926 | + '-engine', |
927 | + '-I', tests._get_module_include_path(), |
928 | + fake_application.qml_file_path, |
929 | + '--desktop_file_hint={0}'.format( |
930 | + fake_application.desktop_file_path), |
931 | + emulator_base=ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase, |
932 | + app_type='qt') |
933 | + |
934 | + def get_alternate_launch_command(self): |
935 | + root = tests.get_path_to_source_root() |
936 | + path_to_local_launcher = os.path.join( |
937 | + root, 'tests', 'launcher', 'launcher') |
938 | + if os.path.exists(path_to_local_launcher): |
939 | + return path_to_local_launcher |
940 | + else: |
941 | + path_to_installed_launcher = os.path.join( |
942 | + '/', 'usr', 'lib', 'ubuntu-ui-toolkit', 'launcher') |
943 | + return path_to_installed_launcher |
944 | + |
945 | + def test_get_unity_top_container(self): |
946 | + """Test that we can get the top cointainer in Unity.""" |
947 | + # This tests bug http://pad.lv/1314390 |
948 | + # On Unity, the top container is not the first child as it is in all |
949 | + # the apps that have a MainView. This makes the first implementation of |
950 | + # _get_top_container fail. Instead of going from the top looking for |
951 | + # a container, we should start from the flickable until we find the |
952 | + # top-most container. |
953 | + test_flickable = self.app.select_single( |
954 | + ubuntuuitoolkit.QQuickFlickable, objectName='testFlickable') |
955 | + top_container = test_flickable._get_top_container() |
956 | + self.assertIsInstance(top_container, ubuntuuitoolkit.MainView) |
957 | |
958 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_header.py' |
959 | --- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_header.py 2014-05-29 18:18:43 +0000 |
960 | +++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_header.py 2014-06-18 17:07:12 +0000 |
961 | @@ -18,6 +18,8 @@ |
962 | |
963 | import ubuntuuitoolkit |
964 | from ubuntuuitoolkit import tests |
965 | +from testtools.matchers import Equals |
966 | +from autopilot.matchers import Eventually |
967 | |
968 | |
969 | class HeaderTestCase(tests.QMLStringAppTestCase): |
970 | @@ -32,73 +34,93 @@ |
971 | |
972 | useDeprecatedToolbar: false |
973 | |
974 | - Page { |
975 | - title: "Test title" |
976 | - |
977 | - Flickable { |
978 | - anchors.fill: parent |
979 | - contentHeight: units.gu(120) |
980 | - objectName: "header_test_flickable" |
981 | - |
982 | - Label { |
983 | - id: label |
984 | - objectName: "clicked_label" |
985 | - anchors { |
986 | - top: parent.top |
987 | - horizontalCenter: parent.horizontalCenter |
988 | - } |
989 | - text: "No button clicked." |
990 | - } |
991 | - |
992 | - Button { |
993 | - objectName: "hide_actions_button" |
994 | - anchors { |
995 | - top: label.bottom |
996 | - topMargin: units.gu(5) |
997 | - horizontalCenter: parent.horizontalCenter |
998 | - } |
999 | - text: "Hide some actions" |
1000 | - onClicked: { |
1001 | - cancelAction.visible = false; |
1002 | - for (var i=0; i < 3; i++) { |
1003 | - buttonRepeater.itemAt(i).action.visible = false; |
1004 | - } |
1005 | - // only three of five visible actions left |
1006 | - } |
1007 | - } |
1008 | - Label { |
1009 | - id: endLabel |
1010 | - objectName: "end_label" |
1011 | - anchors { |
1012 | - bottom: parent.bottom |
1013 | - horizontalCenter: parent.horizontalCenter |
1014 | - } |
1015 | - text: "The end." |
1016 | - } |
1017 | - } |
1018 | - |
1019 | - tools: ToolbarItems { |
1020 | - back: ToolbarButton { |
1021 | - action: Action { |
1022 | - id: cancelAction |
1023 | - iconName: "cancel" |
1024 | - text: "cancel" |
1025 | - onTriggered: label.text = "Cancel button clicked." |
1026 | - } |
1027 | - } |
1028 | - Repeater { |
1029 | - id: buttonRepeater |
1030 | - model: 5 |
1031 | + PageStack { |
1032 | + id: stack |
1033 | + Component.onCompleted: stack.push(page) |
1034 | + |
1035 | + Page { |
1036 | + title: "Test title" |
1037 | + id: page |
1038 | + |
1039 | + Flickable { |
1040 | + anchors.fill: parent |
1041 | + contentHeight: units.gu(120) |
1042 | + objectName: "header_test_flickable" |
1043 | + |
1044 | + Label { |
1045 | + id: label |
1046 | + objectName: "clicked_label" |
1047 | + anchors { |
1048 | + top: parent.top |
1049 | + horizontalCenter: parent.horizontalCenter |
1050 | + } |
1051 | + text: "No button clicked." |
1052 | + } |
1053 | + |
1054 | + Button { |
1055 | + objectName: "hide_actions_button" |
1056 | + anchors { |
1057 | + top: label.bottom |
1058 | + topMargin: units.gu(5) |
1059 | + horizontalCenter: parent.horizontalCenter |
1060 | + } |
1061 | + text: "Hide some actions" |
1062 | + onClicked: { |
1063 | + cancelAction.visible = false; |
1064 | + for (var i=0; i < 3; i++) { |
1065 | + buttonRepeater.itemAt(i).action.visible = false; |
1066 | + } |
1067 | + // only three of five visible actions left |
1068 | + } |
1069 | + } |
1070 | + Label { |
1071 | + id: endLabel |
1072 | + objectName: "end_label" |
1073 | + anchors { |
1074 | + bottom: parent.bottom |
1075 | + horizontalCenter: parent.horizontalCenter |
1076 | + } |
1077 | + text: "The end." |
1078 | + } |
1079 | + } |
1080 | + |
1081 | + tools: ToolbarItems { |
1082 | + back: ToolbarButton { |
1083 | + action: Action { |
1084 | + id: cancelAction |
1085 | + iconName: "cancel" |
1086 | + text: "cancel" |
1087 | + onTriggered: label.text = "Cancel button clicked." |
1088 | + } |
1089 | + } |
1090 | + Repeater { |
1091 | + id: buttonRepeater |
1092 | + model: 5 |
1093 | + ToolbarButton { |
1094 | + action: Action { |
1095 | + objectName: "action" + index |
1096 | + text: "text " + index |
1097 | + iconName: "add" |
1098 | + onTriggered: { |
1099 | + label.text = "Button "+index+" clicked."; |
1100 | + } |
1101 | + } |
1102 | + } |
1103 | + } |
1104 | ToolbarButton { |
1105 | action: Action { |
1106 | - objectName: "action" + index |
1107 | - text: "text " + index |
1108 | + objectName: "pushStackAction" |
1109 | + text: "Push page" |
1110 | iconName: "add" |
1111 | - onTriggered: label.text = "Button "+index+" clicked." |
1112 | + onTriggered: stack.push(pushMe) |
1113 | } |
1114 | } |
1115 | } |
1116 | } |
1117 | + Page { |
1118 | + title: "Pushed page" |
1119 | + id: pushMe |
1120 | + } |
1121 | } |
1122 | } |
1123 | """) |
1124 | @@ -125,6 +147,13 @@ |
1125 | self.header.click_action_button('action3') |
1126 | self.assertEqual(self.label.text, 'Button 3 clicked.') |
1127 | |
1128 | + def test_click_header_overflow_action_closes_popover_bug1326963(self): |
1129 | + overflow_popover = self.main_view.select_single( |
1130 | + 'Popover', |
1131 | + objectName='actions_overflow_popover') |
1132 | + self.header.click_action_button('pushStackAction') |
1133 | + self.assertThat(overflow_popover.visible, Eventually(Equals(False))) |
1134 | + |
1135 | def test_click_unexisting_header_action_button(self): |
1136 | error = self.assertRaises( |
1137 | ubuntuuitoolkit.ToolkitException, self.header.click_action_button, |
1138 | |
1139 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitems.py' |
1140 | --- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitems.py 2014-04-25 18:39:51 +0000 |
1141 | +++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitems.py 2014-06-18 17:07:12 +0000 |
1142 | @@ -120,6 +120,7 @@ |
1143 | self.assertTrue(self._item.waitingConfirmationForRemoval) |
1144 | |
1145 | def test_swipe_item_to_left(self): |
1146 | + # This will do a right to left swipe behind the scenes |
1147 | self._item.swipe_to_delete('left') |
1148 | self.assertTrue(self._item.waitingConfirmationForRemoval) |
1149 | |
1150 | @@ -134,6 +135,7 @@ |
1151 | self.assertFalse(self._item.exists()) |
1152 | |
1153 | def test_delete_item_moving_left(self): |
1154 | + # This will do a right to left swipe behind the scenes |
1155 | self._item.swipe_to_delete('left') |
1156 | self._item.confirm_removal() |
1157 | self.assertFalse(self._item.exists()) |
1158 | |
1159 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/__init__.py' |
1160 | --- tests/autopilot/ubuntuuitoolkit/tests/gallery/__init__.py 2013-10-24 11:01:03 +0000 |
1161 | +++ tests/autopilot/ubuntuuitoolkit/tests/gallery/__init__.py 2014-06-18 17:07:12 +0000 |
1162 | @@ -1,6 +1,6 @@ |
1163 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1164 | # |
1165 | -# Copyright (C) 2012, 2013 Canonical Ltd. |
1166 | +# Copyright (C) 2012, 2013, 2014 Canonical Ltd. |
1167 | # |
1168 | # This program is free software; you can redistribute it and/or modify |
1169 | # it under the terms of the GNU Lesser General Public License as published by |
1170 | @@ -19,10 +19,10 @@ |
1171 | import os |
1172 | import shutil |
1173 | |
1174 | -from ubuntuuitoolkit import tests |
1175 | - |
1176 | - |
1177 | -class GalleryTestCase(tests.QMLFileAppTestCase): |
1178 | +import ubuntuuitoolkit |
1179 | + |
1180 | + |
1181 | +class GalleryTestCase(ubuntuuitoolkit.tests.QMLFileAppTestCase): |
1182 | """Base class for gallery test cases.""" |
1183 | |
1184 | local_desktop_file_path = None |
1185 | @@ -39,7 +39,7 @@ |
1186 | |
1187 | def _get_path_to_gallery_source(self): |
1188 | return os.path.join( |
1189 | - tests.get_path_to_source_root(), 'examples', |
1190 | + ubuntuuitoolkit.tests.get_path_to_source_root(), 'examples', |
1191 | 'ubuntu-ui-toolkit-gallery') |
1192 | |
1193 | def _application_source_exists(self): |
1194 | @@ -58,7 +58,8 @@ |
1195 | self.test_source_path, |
1196 | 'ubuntu-ui-toolkit-gallery.desktop') |
1197 | if self._application_source_exists(): |
1198 | - local_desktop_file_dir = tests.get_local_desktop_file_directory() |
1199 | + local_desktop_file_dir = ( |
1200 | + ubuntuuitoolkit.tests.get_local_desktop_file_directory()) |
1201 | if not os.path.exists(local_desktop_file_dir): |
1202 | os.makedirs(local_desktop_file_dir) |
1203 | local_desktop_file_path = os.path.join( |
1204 | @@ -71,6 +72,19 @@ |
1205 | else: |
1206 | return desktop_file_path |
1207 | |
1208 | + def open_page(self, page): |
1209 | + """Open a page of the widget gallery. |
1210 | + |
1211 | + :param page: The objectName of the element in the index list that opens |
1212 | + the page. |
1213 | + |
1214 | + """ |
1215 | + list_view = self.main_view.select_single( |
1216 | + ubuntuuitoolkit.QQuickListView, objectName="widgetList") |
1217 | + list_view.click_element(page) |
1218 | + element = self.main_view.select_single('Standard', objectName=page) |
1219 | + element.selected.wait_for(True) |
1220 | + |
1221 | def tearDown(self): |
1222 | super(GalleryTestCase, self).tearDown() |
1223 | # We can't delete the desktop file before we close the application, |
1224 | |
1225 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_buttons.py' |
1226 | --- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_buttons.py 2014-02-11 01:55:49 +0000 |
1227 | +++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_buttons.py 2014-06-18 17:07:12 +0000 |
1228 | @@ -45,9 +45,7 @@ |
1229 | ] |
1230 | |
1231 | def test_buttons(self): |
1232 | - item = "Buttons" |
1233 | - self.loadItem(item) |
1234 | - self.checkPageHeader(item) |
1235 | + self.open_page('buttonsElement') |
1236 | |
1237 | button = self.app.select_single(objectName=self.button_name) |
1238 | self.assertIsNot(button, None) |
1239 | |
1240 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.py' |
1241 | --- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.py 2014-05-26 12:37:32 +0000 |
1242 | +++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_gallery.py 2014-06-18 17:07:12 +0000 |
1243 | @@ -1,6 +1,6 @@ |
1244 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1245 | # |
1246 | -# Copyright (C) 2012, 2013 Canonical Ltd. |
1247 | +# Copyright (C) 2012, 2013, 2014 Canonical Ltd. |
1248 | # |
1249 | # This program is free software; you can redistribute it and/or modify |
1250 | # it under the terms of the GNU Lesser General Public License as published by |
1251 | @@ -16,32 +16,19 @@ |
1252 | |
1253 | """Tests for the Ubuntu UI Toolkit Gallery""" |
1254 | |
1255 | -from autopilot.matchers import Eventually |
1256 | -from testtools.matchers import Is, Not, Equals |
1257 | - |
1258 | -from ubuntuuitoolkit import emulators |
1259 | +import ubuntuuitoolkit |
1260 | from ubuntuuitoolkit.tests import gallery |
1261 | |
1262 | |
1263 | -class GenericTests(gallery.GalleryTestCase): |
1264 | +class GalleryAppTestCase(gallery.GalleryTestCase): |
1265 | """Generic tests for the Gallery""" |
1266 | |
1267 | - def test_0_can_select_mainwindow(self): |
1268 | - """Must be able to select the main window.""" |
1269 | - |
1270 | - rootItem = self.main_view |
1271 | - self.assertThat(rootItem, Not(Is(None))) |
1272 | - self.assertThat(rootItem.visible, Eventually(Equals(True))) |
1273 | - |
1274 | - def test_navigation(self): |
1275 | - item = "Navigation" |
1276 | - self.loadItem(item) |
1277 | - self.checkPageHeader(item) |
1278 | + def test_select_main_view_must_return_main_window_emulator(self): |
1279 | + main_view = self.main_view |
1280 | + self.assertIsInstance(main_view, ubuntuuitoolkit.MainView) |
1281 | |
1282 | def test_slider(self): |
1283 | - item = "Slider" |
1284 | - self.loadItem(item) |
1285 | - self.checkPageHeader(item) |
1286 | + self.open_page('slidersElement') |
1287 | |
1288 | item_data = [ |
1289 | ["slider_standard"], |
1290 | @@ -57,9 +44,7 @@ |
1291 | # TODO: move slider value |
1292 | |
1293 | def test_progress_and_activity(self): |
1294 | - item = "Progress and activity" |
1295 | - self.loadItem(item) |
1296 | - self.checkPageHeader(item) |
1297 | + self.open_page('progressBarsElement') |
1298 | |
1299 | item_data = [ |
1300 | ["progressbar_standard"], |
1301 | @@ -79,9 +64,7 @@ |
1302 | # FIXME: https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1308979 |
1303 | return |
1304 | |
1305 | - item = "Ubuntu Shape" |
1306 | - self.loadItem(item) |
1307 | - self.checkPageHeader(item) |
1308 | + self.open_page('ubuntuShapesElement') |
1309 | |
1310 | item_data = [ |
1311 | ["ubuntushape_color_hex"], |
1312 | @@ -115,12 +98,9 @@ |
1313 | ] |
1314 | |
1315 | def test_open_page(self): |
1316 | - list_view = self.main_view.select_single( |
1317 | - emulators.QQuickListView, objectName="widgetList") |
1318 | - list_view.click_element(self.element_name) |
1319 | + self.open_page(self.element_name) |
1320 | element = self.main_view.select_single( |
1321 | 'Standard', objectName=self.element_name) |
1322 | - element.selected.wait_for(True) |
1323 | self.checkPageHeader(element.text) |
1324 | if self.template_name == 'textinputsTemplate': |
1325 | page_type = 'TextInputs' |
1326 | |
1327 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.py' |
1328 | --- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.py 2014-05-23 09:50:42 +0000 |
1329 | +++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_optionselector.py 2014-06-18 17:07:12 +0000 |
1330 | @@ -24,9 +24,7 @@ |
1331 | |
1332 | def setUp(self): |
1333 | super(OptionSelectorTestCase, self).setUp() |
1334 | - item = "Option Selector" |
1335 | - self.loadItem(item) |
1336 | - self.checkPageHeader(item) |
1337 | + self.open_page('optionSelectorsElement') |
1338 | |
1339 | def test_select_option_from_collapsed_optionselector(self): |
1340 | collapsed_option_selector = self.main_view.select_single( |
1341 | |
1342 | === added file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_scrollbar.py' |
1343 | --- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_scrollbar.py 1970-01-01 00:00:00 +0000 |
1344 | +++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_scrollbar.py 2014-06-18 17:07:12 +0000 |
1345 | @@ -0,0 +1,63 @@ |
1346 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1347 | +# |
1348 | +# Copyright (C) 2014 Canonical Ltd. |
1349 | +# |
1350 | +# This program is free software; you can redistribute it and/or modify |
1351 | +# it under the terms of the GNU Lesser General Public License as published by |
1352 | +# the Free Software Foundation; version 3. |
1353 | +# |
1354 | +# This program is distributed in the hope that it will be useful, |
1355 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1356 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1357 | +# GNU Lesser General Public License for more details. |
1358 | +# |
1359 | +# You should have received a copy of the GNU Lesser General Public License |
1360 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1361 | + |
1362 | +from autopilot import platform |
1363 | + |
1364 | +from ubuntuuitoolkit.tests import gallery |
1365 | + |
1366 | + |
1367 | +class ScrollBarTestCase(gallery.GalleryTestCase): |
1368 | + |
1369 | + def setUp(self): |
1370 | + super(ScrollBarTestCase, self).setUp() |
1371 | + self.open_page('navigationElement') |
1372 | + self.scrollbar = self.main_view.wait_select_single( |
1373 | + 'Scrollbar', objectName="TemplateScrollbar") |
1374 | + |
1375 | + def move_mouse_to_thumb(self): |
1376 | + # TODO we need a helper to move the interactive thumb. |
1377 | + # --elopio 2014-05-06 |
1378 | + thumb = self.scrollbar.select_single( |
1379 | + objectName='interactiveScrollbarThumb') |
1380 | + self.pointing_device.move_to_object(thumb) |
1381 | + |
1382 | + def test_scrollbar_must_start_without_interactive_thumb(self): |
1383 | + self.assertEqual(self.scrollbar.interactive, False) |
1384 | + |
1385 | + def test_move_mouse_to_thumb_must_make_scrollbar_interactive(self): |
1386 | + if platform.model() != 'Desktop': |
1387 | + self.skipTest( |
1388 | + 'The interactive thumb is activated by the move of a mouse') |
1389 | + |
1390 | + self.move_mouse_to_thumb() |
1391 | + |
1392 | + self.assertEqual(self.scrollbar.interactive, True) |
1393 | + |
1394 | + def test_drag_thumb_down_must_make_bottom_visible(self): |
1395 | + if platform.model() != 'Desktop': |
1396 | + self.skipTest( |
1397 | + 'The interactive thumb is activated by the move of a mouse') |
1398 | + |
1399 | + bottom_section = self.main_view.select_single(className='PageStack') |
1400 | + flickable = self.main_view.select_single( |
1401 | + 'QQuickFlickable', objectName='TemplateFlickable') |
1402 | + self.assertEqual(flickable.is_child_visible(bottom_section), False) |
1403 | + |
1404 | + self.move_mouse_to_thumb() |
1405 | + x, y = self.pointing_device.position() |
1406 | + self.pointing_device.drag(x, y, x, self.main_view.height) |
1407 | + |
1408 | + self.assertEqual(flickable.is_child_visible(bottom_section), True) |
1409 | |
1410 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.py' |
1411 | --- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.py 2014-04-30 09:40:17 +0000 |
1412 | +++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_textinput.py 2014-06-18 17:07:12 +0000 |
1413 | @@ -54,9 +54,7 @@ |
1414 | # Apply the user locale from the environment |
1415 | # The UITK does the same, so the test must be localized |
1416 | locale.setlocale(locale.LC_ALL, "") |
1417 | - item = 'Text Field' |
1418 | - self.loadItem(item) |
1419 | - self.checkPageHeader(item) |
1420 | + self.open_page('textinputsElement') |
1421 | |
1422 | def test_write_on_textfield_must_update_text(self): |
1423 | textfield = self.main_view.select_single( |
1424 | @@ -78,9 +76,7 @@ |
1425 | |
1426 | def setUp(self): |
1427 | super(DisabledTextInputTestCase, self).setUp() |
1428 | - item = 'Text Field' |
1429 | - self.loadItem(item) |
1430 | - self.checkPageHeader(item) |
1431 | + self.open_page('textinputsElement') |
1432 | |
1433 | def test_textfield_disabled(self): |
1434 | textfield_disabled = self.main_view.select_single( |
1435 | |
1436 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/gallery/test_toggles.py' |
1437 | --- tests/autopilot/ubuntuuitoolkit/tests/gallery/test_toggles.py 2013-11-01 15:15:30 +0000 |
1438 | +++ tests/autopilot/ubuntuuitoolkit/tests/gallery/test_toggles.py 2014-06-18 17:07:12 +0000 |
1439 | @@ -35,10 +35,7 @@ |
1440 | |
1441 | def setUp(self): |
1442 | super(EnabledTogglesTestCase, self).setUp() |
1443 | - item = "Toggles" |
1444 | - self.checkListItem(item) |
1445 | - self.loadItem(item) |
1446 | - self.checkPageHeader(item) |
1447 | + self.open_page('togglesElement') |
1448 | |
1449 | def test_change_toggles_state(self): |
1450 | toggle = self.main_view.select_single( |
1451 | @@ -65,10 +62,7 @@ |
1452 | |
1453 | def setUp(self): |
1454 | super(DisabledTogglesTestCase, self).setUp() |
1455 | - item = "Toggles" |
1456 | - self.checkListItem(item) |
1457 | - self.loadItem(item) |
1458 | - self.checkPageHeader(item) |
1459 | + self.open_page('togglesElement') |
1460 | |
1461 | def test_change_toggles_state(self): |
1462 | toggle = self.main_view.select_single( |
1463 | |
1464 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py' |
1465 | --- tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py 2014-05-28 09:42:30 +0000 |
1466 | +++ tests/autopilot/ubuntuuitoolkit/tests/test_fixture_setup.py 2014-06-18 17:07:12 +0000 |
1467 | @@ -298,7 +298,7 @@ |
1468 | # home. |
1469 | self.useFixture(fixture_setup.FakeHome()) |
1470 | |
1471 | - open(os.path.join(os.environ.get('HOME'), '.Xauthority')).close() |
1472 | + open(os.path.join(os.environ.get('HOME'), '.Xauthority'), 'w').close() |
1473 | |
1474 | self.useFixture(fixture_setup.FakeHome()) |
1475 | self.assertTrue( |
1476 | |
1477 | === added directory 'tests/launcher' |
1478 | === added file 'tests/launcher/launcher.cpp' |
1479 | --- tests/launcher/launcher.cpp 1970-01-01 00:00:00 +0000 |
1480 | +++ tests/launcher/launcher.cpp 2014-06-18 17:07:12 +0000 |
1481 | @@ -0,0 +1,146 @@ |
1482 | +/* |
1483 | + * Copyright 2014 Canonical Ltd. |
1484 | + * |
1485 | + * This program is free software; you can redistribute it and/or modify |
1486 | + * it under the terms of the GNU Lesser General Public License as published by |
1487 | + * the Free Software Foundation; version 3. |
1488 | + * |
1489 | + * This program is distributed in the hope that it will be useful, |
1490 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
1491 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1492 | + * GNU Lesser General Public License for more details. |
1493 | + * |
1494 | + * You should have received a copy of the GNU Lesser General Public License |
1495 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
1496 | + * |
1497 | + * QML launcher with the ability to setup the QQuickView/ QQmlEngine differently |
1498 | + * |
1499 | + * Rationale: Different variants of qmlscene exist as well as C++ and Go apps |
1500 | + * This is to write Autopilot test cases that exhibit specific behavior |
1501 | + */ |
1502 | + |
1503 | +#include <iostream> |
1504 | +#include <QtCore/qdebug.h> |
1505 | +#include <QtQuick/QQuickView> |
1506 | +#include <QtGui/QGuiApplication> |
1507 | +#include <QtQml/QQmlEngine> |
1508 | +#include <QtQml/QQmlContext> |
1509 | +#include <QtCore/QFileInfo> |
1510 | +#include <QLibrary> |
1511 | +#include <QOpenGLContext> |
1512 | +#include <QtGui/private/qopenglcontext_p.h> |
1513 | +#include <QtQuick/private/qsgcontext_p.h> |
1514 | + |
1515 | +int usage() |
1516 | +{ |
1517 | + QString self(QGuiApplication::instance()->arguments().at(0)); |
1518 | + std::cout << "Usage\n " |
1519 | + << qPrintable(self) |
1520 | + << " -testability -frameless -engine" |
1521 | + << " --desktop_file_path=DESKTOP_FILE" |
1522 | + << " -I MODULE_PATH FILENAME\n"; |
1523 | + return 1; |
1524 | +} |
1525 | + |
1526 | +int main(int argc, const char *argv[]) |
1527 | +{ |
1528 | + // QPlatformIntegration::ThreadedOpenGL |
1529 | + setenv("QML_FORCE_THREADED_RENDERER", "1", 1); |
1530 | + // QPlatformIntegration::BufferQueueingOpenGL |
1531 | + setenv("QML_FIXED_ANIMATION_STEP", "1", 1); |
1532 | + // Oxide and QWebEngine need a shared context |
1533 | + QScopedPointer<QOpenGLContext> shareContext; |
1534 | + shareContext.reset(new QOpenGLContext); |
1535 | +#if QT_VERSION < QT_VERSION_CHECK(5, 3, 0) |
1536 | + QSGContext::setSharedOpenGLContext(shareContext.data()); |
1537 | +#else |
1538 | + QOpenGLContextPrivate::setGlobalShareContext(shareContext.data()); |
1539 | +#endif |
1540 | + QGuiApplication::setApplicationName("UITK Launcher"); |
1541 | + QGuiApplication application(argc, (char**)argv); |
1542 | + QStringList args (application.arguments()); |
1543 | + |
1544 | + int _testability(args.indexOf("-testability")); |
1545 | + args.removeAt(_testability); |
1546 | + int _frameless(args.indexOf("-frameless")); |
1547 | + args.removeAt(_frameless); |
1548 | + int _engine(args.indexOf("-engine")); |
1549 | + args.removeAt(_engine); |
1550 | + |
1551 | + Q_FOREACH(QString arg, args) { |
1552 | + if (arg.startsWith("--desktop_file_hint")) { |
1553 | + // This will not be used - it only needs to be ignored |
1554 | + int _desktop_file_hint(args.indexOf(arg)); |
1555 | + args.removeAt(_desktop_file_hint); |
1556 | + } |
1557 | + } |
1558 | + |
1559 | + // Testability is only supported out of the box by QApplication not QGuiApplication |
1560 | + if (_testability > -1 || getenv("QT_LOAD_TESTABILITY")) { |
1561 | + QLibrary testLib(QLatin1String("qttestability")); |
1562 | + if (testLib.load()) { |
1563 | + typedef void (*TasInitialize)(void); |
1564 | + TasInitialize initFunction = (TasInitialize)testLib.resolve("qt_testability_init"); |
1565 | + if (initFunction) { |
1566 | + initFunction(); |
1567 | + } else { |
1568 | + qCritical("Library qttestability resolve failed!"); |
1569 | + return 1; |
1570 | + } |
1571 | + } else { |
1572 | + qCritical("Library qttestability load failed!"); |
1573 | + return 1; |
1574 | + } |
1575 | + } |
1576 | + |
1577 | + QQmlEngine* engine; |
1578 | + // The default constructor affects the components tree (autopilot vis) |
1579 | + QQuickView* view; |
1580 | + if (_engine > -1) { |
1581 | + view = new QQuickView(); |
1582 | + engine = view->engine(); |
1583 | + } else { |
1584 | + engine = new QQmlEngine(); |
1585 | + view = new QQuickView(engine, NULL); |
1586 | + } |
1587 | + |
1588 | + int _import(args.indexOf("-I")); |
1589 | + args.removeAt(_import); |
1590 | + if (_import > -1) { |
1591 | + if (args.count() > _import) { |
1592 | + QString importPath(args.at(_import)); |
1593 | + args.removeAt(_import); |
1594 | + engine->addImportPath(importPath); |
1595 | + } |
1596 | + } |
1597 | + |
1598 | + view->setResizeMode(QQuickView::SizeRootObjectToView); |
1599 | + view->setTitle("UI Toolkit QQuickView"); |
1600 | + if (_frameless > -1) { |
1601 | + view->setFlags(Qt::FramelessWindowHint); |
1602 | + } |
1603 | + |
1604 | + // The remaining unnamed argument must be a filename |
1605 | + if (args.count() == 1) { |
1606 | + qCritical() << "Missing filename"; |
1607 | + return usage(); |
1608 | + } |
1609 | + QString filename(args.at(1)); |
1610 | + // The first argument is the launcher itself |
1611 | + args.removeAt(0); |
1612 | + |
1613 | + QUrl source(QUrl::fromLocalFile(filename)); |
1614 | + view->setSource(source); |
1615 | + if (view->errors().count() > 0) { |
1616 | + return usage(); |
1617 | + } |
1618 | + view->show(); |
1619 | + |
1620 | + if (args.count() > 1) { |
1621 | + qCritical() << "Invalid arguments passed" << args; |
1622 | + return usage(); |
1623 | + } |
1624 | + |
1625 | + return application.exec(); |
1626 | +} |
1627 | + |
1628 | |
1629 | === added file 'tests/launcher/launcher.pro' |
1630 | --- tests/launcher/launcher.pro 1970-01-01 00:00:00 +0000 |
1631 | +++ tests/launcher/launcher.pro 2014-06-18 17:07:12 +0000 |
1632 | @@ -0,0 +1,11 @@ |
1633 | +TEMPLATE = app |
1634 | +QT += qml quick |
1635 | +# For setSharedOpenGLContext |
1636 | +QT += core-private gui-private quick-private |
1637 | +CONFIG += no_keywords |
1638 | +SOURCES += \ |
1639 | + launcher.cpp |
1640 | +launcher.path = /usr/lib/ubuntu-ui-toolkit |
1641 | +launcher.files = launcher |
1642 | +INSTALLS += launcher |
1643 | + |
1644 | |
1645 | === modified file 'tests/tests.pro' |
1646 | --- tests/tests.pro 2014-02-21 23:39:43 +0000 |
1647 | +++ tests/tests.pro 2014-06-18 17:07:12 +0000 |
1648 | @@ -7,4 +7,6 @@ |
1649 | autopilot2_module.path = /usr/lib/python2.7/dist-packages/ubuntuuitoolkit |
1650 | autopilot2_module.files = autopilot/ubuntuuitoolkit/* |
1651 | |
1652 | +SUBDIRS += launcher |
1653 | + |
1654 | INSTALLS += autopilot_module autopilot2_module |
1655 | |
1656 | === modified file 'tests/unit/runtest.sh' |
1657 | --- tests/unit/runtest.sh 2014-04-15 14:26:35 +0000 |
1658 | +++ tests/unit/runtest.sh 2014-06-18 17:07:12 +0000 |
1659 | @@ -38,7 +38,10 @@ |
1660 | |
1661 | function execute_test_cmd { |
1662 | echo "Executing $_CMD $_ARGS" |
1663 | - if [ $DISPLAY ]; then |
1664 | + if [ ! -x $_TARGET ]; then |
1665 | + echo "Error: $_TARGET wasn't built!" |
1666 | + RESULT=2 |
1667 | + elif [ $DISPLAY ]; then |
1668 | # https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1256999 |
1669 | # https://bugreports.qt-project.org/browse/QTBUG-36243 |
1670 | QML2_IMPORT_PATH=../../../modules:$QML2_IMPORT_PATH UBUNTU_UI_TOOLKIT_THEMES_PATH=../../../modules \ |
1671 | |
1672 | === modified file 'tests/unit/unit.pro' |
1673 | --- tests/unit/unit.pro 2013-12-03 10:36:54 +0000 |
1674 | +++ tests/unit/unit.pro 2014-06-18 17:07:12 +0000 |
1675 | @@ -18,9 +18,7 @@ |
1676 | tst_scaling_image_provider \ |
1677 | tst_qquick_image_extension \ |
1678 | tst_performance \ |
1679 | - tst_ubuntu_shape \ |
1680 | tst_mainview \ |
1681 | - tst_page \ |
1682 | tst_i18n \ |
1683 | tst_arguments \ |
1684 | tst_argument \ |
1685 | |
1686 | === modified file 'tests/unit_x11/tst_components/tst_hide_chrome.qml' |
1687 | --- tests/unit_x11/tst_components/tst_hide_chrome.qml 2014-04-25 05:28:37 +0000 |
1688 | +++ tests/unit_x11/tst_components/tst_hide_chrome.qml 2014-06-18 17:07:12 +0000 |
1689 | @@ -61,6 +61,11 @@ |
1690 | when: windowShown |
1691 | id: testCase |
1692 | |
1693 | + function cleanup() { |
1694 | + // clean buffers |
1695 | + waitForRendering(mainView, 500); |
1696 | + } |
1697 | + |
1698 | function openToolbar() { |
1699 | var toolbar = mainView.__propagated.toolbar; |
1700 | toolbar.open(); |
1701 | |
1702 | === renamed file 'tests/unit/tst_components/tst_page.qml' => 'tests/unit_x11/tst_components/tst_page.qml' |
1703 | === modified file 'tests/unit_x11/tst_components/tst_popover.qml' |
1704 | --- tests/unit_x11/tst_components/tst_popover.qml 2014-04-17 14:14:43 +0000 |
1705 | +++ tests/unit_x11/tst_components/tst_popover.qml 2014-06-18 17:07:12 +0000 |
1706 | @@ -61,6 +61,7 @@ |
1707 | function cleanup() { |
1708 | popoverSpy.target = null; |
1709 | popoverSpy.clear(); |
1710 | + waitForRendering(main, 500); |
1711 | } |
1712 | |
1713 | function test_dismiss_on_click_data() { |
1714 | |
1715 | === renamed file 'tests/unit/tst_components/tst_quickutils.qml' => 'tests/unit_x11/tst_components/tst_quickutils.qml' |
1716 | === modified file 'tests/unit_x11/tst_components/tst_textarea.qml' |
1717 | --- tests/unit_x11/tst_components/tst_textarea.qml 2014-04-30 07:10:06 +0000 |
1718 | +++ tests/unit_x11/tst_components/tst_textarea.qml 2014-06-18 17:07:12 +0000 |
1719 | @@ -555,6 +555,7 @@ |
1720 | } |
1721 | |
1722 | function test_scroll_with_selected_text() { |
1723 | + skip("Flaky test, feature needs rewrite"); |
1724 | longText.focus = true; |
1725 | var handler = findChild(longText, "input_handler"); |
1726 | verify(handler); |
1727 | @@ -629,6 +630,7 @@ |
1728 | } |
1729 | |
1730 | function test_press_and_hold_over_selected_text() { |
1731 | + skip("Flaky test, feature will be rewritten"); |
1732 | longText.focus = true; |
1733 | var handler = findChild(longText, "input_handler"); |
1734 | var y = longText.height / 2; |
1735 | |
1736 | === renamed file 'tests/unit/tst_components/tst_toolbaritems.qml' => 'tests/unit_x11/tst_components/tst_toolbaritems.qml' |
1737 | === modified file 'tests/unit_x11/tst_inversemousearea/InverseMouseAreaInWindow.qml' |
1738 | --- tests/unit_x11/tst_inversemousearea/InverseMouseAreaInWindow.qml 2014-04-23 08:50:20 +0000 |
1739 | +++ tests/unit_x11/tst_inversemousearea/InverseMouseAreaInWindow.qml 2014-06-18 17:07:12 +0000 |
1740 | @@ -21,6 +21,7 @@ |
1741 | Item{ |
1742 | id: root |
1743 | property string log: "" |
1744 | +// onLogChanged: print("LOG", log) |
1745 | width: units.gu(100) |
1746 | height: units.gu(100) |
1747 | |
1748 | @@ -28,9 +29,11 @@ |
1749 | objectName: "isawindow" |
1750 | width: units.gu(50) |
1751 | height: units.gu(50) |
1752 | + visible: true |
1753 | |
1754 | Item { |
1755 | id: clickArea |
1756 | + objectName: "clickArea" |
1757 | anchors { |
1758 | left: parent.left |
1759 | right: parent.right |
1760 | |
1761 | === modified file 'tests/unit_x11/tst_inversemousearea/tst_inversemouseareatest.cpp' |
1762 | --- tests/unit_x11/tst_inversemousearea/tst_inversemouseareatest.cpp 2014-04-15 21:37:57 +0000 |
1763 | +++ tests/unit_x11/tst_inversemousearea/tst_inversemouseareatest.cpp 2014-06-18 17:07:12 +0000 |
1764 | @@ -22,10 +22,10 @@ |
1765 | #include <QtQuick/QQuickItem> |
1766 | #include <QtCore/QEvent> |
1767 | |
1768 | +#include "uctestcase.h" |
1769 | #include "inversemouseareatype.h" |
1770 | #include "ucunits.h" |
1771 | #include <private/qquickevents_p_p.h> |
1772 | -#include <qpa/qwindowsysteminterface.h> |
1773 | |
1774 | #define DOUBLECLICK_TIMEOUT 400 |
1775 | |
1776 | @@ -78,13 +78,6 @@ |
1777 | return QPointF(UCUnits::instance().gu(guX), UCUnits::instance().gu(guY)).toPoint(); |
1778 | } |
1779 | |
1780 | - void touchClick(QWindow *window, const QPoint &point) |
1781 | - { |
1782 | - QTest::touchEvent(window, device).press(0, point, window); |
1783 | - QTest::qWait(10); |
1784 | - QTest::touchEvent(window, device).release(0, point, window); |
1785 | - } |
1786 | - |
1787 | protected Q_SLOTS: |
1788 | void capturePressed(QQuickMouseEvent *event) |
1789 | { |
1790 | @@ -95,16 +88,14 @@ |
1791 | |
1792 | void initTestCase() |
1793 | { |
1794 | + // make sure we have a touch device installed |
1795 | + UbuntuTestCase::registerTouchDevice(); |
1796 | QString modules("../../../modules"); |
1797 | QVERIFY(QDir(modules).exists()); |
1798 | |
1799 | quickView = new QQuickView(0); |
1800 | quickEngine = quickView->engine(); |
1801 | |
1802 | - device = new QTouchDevice; |
1803 | - device->setType(QTouchDevice::TouchScreen); |
1804 | - QWindowSystemInterface::registerTouchDevice(device); |
1805 | - |
1806 | quickView->setGeometry(0,0, 240, 320); |
1807 | //add modules folder so we have access to the plugin from QML |
1808 | QStringList imports = quickEngine->importPathList(); |
1809 | @@ -139,7 +130,6 @@ |
1810 | QVERIFY(eventCleanup.isEmpty()); |
1811 | } |
1812 | |
1813 | - |
1814 | void testCase_PropagateEvents() |
1815 | { |
1816 | eventCleanup.clear(); |
1817 | @@ -167,10 +157,14 @@ |
1818 | InverseMouseAreaType *area = testArea("InverseMouseAreaInWindow.qml"); |
1819 | QVERIFY(area); |
1820 | quickView->show(); |
1821 | + QTest::qWaitForWindowExposed(quickView); |
1822 | |
1823 | QList<QQuickWindow *> l = quickView->rootObject()->findChildren<QQuickWindow*>("isawindow"); |
1824 | QVERIFY(l.count()); |
1825 | |
1826 | + QQuickItem *clickArea = quickView->rootObject()->findChild<QQuickItem*>("clickArea"); |
1827 | + QVERIFY(clickArea); |
1828 | + |
1829 | QTest::mouseClick(l[0], Qt::LeftButton, 0, QPoint(20, 10)); |
1830 | QTest::waitForEvents(); |
1831 | QCOMPARE(quickView->rootObject()->property("log").toString(), QString("IMA")); |
1832 | @@ -519,7 +513,7 @@ |
1833 | QCOMPARE(imaSpy.count(), 1); |
1834 | |
1835 | imaSpy.clear(); |
1836 | - touchClick(quickView, guPoint(20, 5)); |
1837 | + UbuntuTestCase::touchClick(0, quickView, guPoint(20, 5)); |
1838 | QCOMPARE(imaSpy.count(), 1); |
1839 | } |
1840 | |
1841 | |
1842 | === renamed directory 'tests/unit/tst_page' => 'tests/unit_x11/tst_page' |
1843 | === renamed directory 'tests/unit/tst_ubuntu_shape' => 'tests/unit_x11/tst_ubuntu_shape' |
1844 | === modified file 'tests/unit_x11/unit_x11.pro' |
1845 | --- tests/unit_x11/unit_x11.pro 2013-12-29 19:15:15 +0000 |
1846 | +++ tests/unit_x11/unit_x11.pro 2014-06-18 17:07:12 +0000 |
1847 | @@ -1,4 +1,12 @@ |
1848 | TEMPLATE = subdirs |
1849 | |
1850 | -SUBDIRS += tst_components tst_test tst_inversemousearea tst_recreateview tst_statesaver tst_theme_engine tst_orientation tst_layouts \ |
1851 | +SUBDIRS += tst_components \ |
1852 | + tst_ubuntu_shape \ |
1853 | + tst_page \ |
1854 | + tst_test \ |
1855 | + tst_inversemousearea \ |
1856 | + tst_recreateview \ |
1857 | + tst_statesaver \ |
1858 | + tst_theme_engine \ |
1859 | + tst_orientation tst_layouts \ |
1860 | tst_mousefilters |
FAILED: Continuous integration, rev:1094 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- ci/2086/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/651 jenkins. qa.ubuntu. com/job/ generic- mediumtests- utopic/ 596 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- utopic- amd64-ci/ 32 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- utopic- armhf-ci/ 32 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- utopic- armhf-ci/ 32/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- mako/1084 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/1247 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/1247/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 8057 jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-utopic/ 528 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/735 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/735/ artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- ui-toolkit- ci/2086/ rebuild
http://