Merge lp:~tpeeters/ubuntu-ui-toolkit/panel-hideTimer into lp:ubuntu-ui-toolkit
- panel-hideTimer
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Cris Dywan |
Approved revision: | 892 |
Merged at revision: | 879 |
Proposed branch: | lp:~tpeeters/ubuntu-ui-toolkit/panel-hideTimer |
Merge into: | lp:ubuntu-ui-toolkit |
Diff against target: |
305 lines (+104/-36) 6 files modified
CHANGES (+1/-0) components.api (+1/-0) modules/Ubuntu/Components/Panel.qml (+54/-6) modules/Ubuntu/Components/Toolbar.qml (+1/-22) tests/unit_x11/tst_components/tst_panel.qml (+33/-7) tests/unit_x11/tst_components/tst_toolbar.qml (+14/-1) |
To merge this branch: | bzr merge lp:~tpeeters/ubuntu-ui-toolkit/panel-hideTimer |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Approve | |
Cris Dywan | Approve | ||
Review via email: mp+197442@code.launchpad.net |
Commit message
Reset hide timer when user interacts with toolbar or toolbar buttons.
Description of the change
Move the hide timer from Toolbar to Panel, trigger it when open() is called, and restart it on user interaction.
The timer was moved because open() is defined in Panel, and user interaction (pressing and releasing on top of the panel) are dealt with in Panel, not Toolbar, and open() and user interactions need to reset the timer. To keep backwards UX compatibility for Panel, the default hideTimeout was set to -1 ==> no timer.
- 887. By Tim Peeters
-
fix conditional restart
- 888. By Tim Peeters
-
clean
- 889. By Tim Peeters
-
update panel unit tests
PS Jenkins bot (ps-jenkins) wrote : | # |
Tim Peeters (tpeeters) wrote : | # |
Tested gallery-app and webbrowser-app on maguro, and executed ubuntuuitoolkit AP tests on same device. All good.
Tim Peeters (tpeeters) wrote : | # |
Webbrowser AP tests also pass on device
Cris Dywan (kalikiana) wrote : | # |
What's the motivation behind these numbers? "wait(3*
- 890. By Tim Peeters
-
improved test and explained it better
- 891. By Tim Peeters
-
improve toolbar tests
Tim Peeters (tpeeters) wrote : | # |
> What's the motivation behind these numbers? "wait(3*
I simplified it to *0.6, and added explanation in the code.
Basically, in total you want to wait > 1.0*hideTimeout, but with user interaction inbetween, so you wait twice < hideTimeout, and you check that because of the user interaction the toolbar/panel is not closed.
Cris Dywan (kalikiana) wrote : | # |
That makes sense. I guessed it would be something like that but it's good to be clear so everyone doesn't have to ponder what it does. Thanks for adding the explanations.
> + compare(
s/Toolbar/Panel
> + the panel frmo detecting interaction and the timer will not be reset.
s/frmo/from
- 892. By Tim Peeters
-
fix typos
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:891
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) : | # |
Preview Diff
1 | === modified file 'CHANGES' | |||
2 | --- CHANGES 2013-11-28 15:07:31 +0000 | |||
3 | +++ CHANGES 2013-12-03 18:38:40 +0000 | |||
4 | @@ -79,6 +79,7 @@ | |||
5 | 79 | * CHANGED IN Header: property Component contents TO property Item contents | 79 | * CHANGED IN Header: property Component contents TO property Item contents |
6 | 80 | * ADDED IN Panel: function open() | 80 | * ADDED IN Panel: function open() |
7 | 81 | * ADDED IN Panel: function close() | 81 | * ADDED IN Panel: function close() |
8 | 82 | * ADDED IN Panel: property int hideTimeout | ||
9 | 82 | * DEPRECATED IN Panel: writable property opened. Will be made read-only. | 83 | * DEPRECATED IN Panel: writable property opened. Will be made read-only. |
10 | 83 | * ADDED IN: Empty: property bool waitingConfirmationForRemoval | 84 | * ADDED IN: Empty: property bool waitingConfirmationForRemoval |
11 | 84 | * ADDED IN: Empty: function cancelItemRemoval() | 85 | * ADDED IN: Empty: function cancelItemRemoval() |
12 | 85 | 86 | ||
13 | === modified file 'components.api' | |||
14 | --- components.api 2013-12-02 19:14:03 +0000 | |||
15 | +++ components.api 2013-12-03 18:38:40 +0000 | |||
16 | @@ -234,6 +234,7 @@ | |||
17 | 234 | property bool opened | 234 | property bool opened |
18 | 235 | function open() | 235 | function open() |
19 | 236 | function close() | 236 | function close() |
20 | 237 | property int hideTimeout | ||
21 | 237 | property bool locked | 238 | property bool locked |
22 | 238 | property real hintSize | 239 | property real hintSize |
23 | 239 | property real triggerSize | 240 | property real triggerSize |
24 | 240 | 241 | ||
25 | === modified file 'modules/Ubuntu/Components/Panel.qml' | |||
26 | --- modules/Ubuntu/Components/Panel.qml 2013-11-27 14:54:05 +0000 | |||
27 | +++ modules/Ubuntu/Components/Panel.qml 2013-12-03 18:38:40 +0000 | |||
28 | @@ -103,8 +103,7 @@ | |||
29 | 103 | Any Items can be placed inside the Panel, but MouseAreas can block mouse events from reaching | 103 | Any Items can be placed inside the Panel, but MouseAreas can block mouse events from reaching |
30 | 104 | the panel and thus obstruct the swiping behavior for hiding the panel. As a result, the user cannot | 104 | the panel and thus obstruct the swiping behavior for hiding the panel. As a result, the user cannot |
31 | 105 | start swiping on the buttons in the examples above in order to hide the panel. To remedy this, clicked() | 105 | start swiping on the buttons in the examples above in order to hide the panel. To remedy this, clicked() |
34 | 106 | signals are forwarded from the panel to its children. The children's clicked() signal does not have | 106 | signals are forwarded from the panel by calling the child's trigger() function. Example: |
33 | 107 | a mouse parameter. Example: | ||
35 | 108 | \qml | 107 | \qml |
36 | 109 | import QtQuick 2.0 | 108 | import QtQuick 2.0 |
37 | 110 | import Ubuntu.Components 0.1 | 109 | import Ubuntu.Components 0.1 |
38 | @@ -130,15 +129,17 @@ | |||
39 | 130 | width: units.gu(8) | 129 | width: units.gu(8) |
40 | 131 | height: units.gu(4) | 130 | height: units.gu(4) |
41 | 132 | anchors.centerIn: parent | 131 | anchors.centerIn: parent |
45 | 133 | color: Theme.palette.normal.foreground | 132 | color: "red" |
46 | 134 | signal clicked() | 133 | function trigger() { |
47 | 135 | onClicked: print("The red rectangle was clicked"); | 134 | print("The red rectangle was clicked"); |
48 | 135 | } | ||
49 | 136 | } | 136 | } |
50 | 137 | } | 137 | } |
51 | 138 | } | 138 | } |
52 | 139 | Component.onCompleted: panel.open(); | ||
53 | 139 | } | 140 | } |
54 | 140 | \endqml | 141 | \endqml |
56 | 141 | Like this, the red rectangle accepts clicked() events, but the user can still swipe down on top | 142 | Like this, the red rectangle accepts click events, but the user can still swipe down on top |
57 | 142 | of the rectangle in order to hide the panel. | 143 | of the rectangle in order to hide the panel. |
58 | 143 | */ | 144 | */ |
59 | 144 | Item { | 145 | Item { |
60 | @@ -208,6 +209,7 @@ | |||
61 | 208 | // FIXME: When opened is made readonly, openedChangedWarning must be removed | 209 | // FIXME: When opened is made readonly, openedChangedWarning must be removed |
62 | 209 | internal.openedChangedWarning = false; | 210 | internal.openedChangedWarning = false; |
63 | 210 | panel.state = "spread"; | 211 | panel.state = "spread"; |
64 | 212 | hideTimer.conditionalRestart(); | ||
65 | 211 | } | 213 | } |
66 | 212 | 214 | ||
67 | 213 | /*! | 215 | /*! |
68 | @@ -217,9 +219,21 @@ | |||
69 | 217 | // FIXME: When opened is made readonly, openedChangedWarning must be removed. | 219 | // FIXME: When opened is made readonly, openedChangedWarning must be removed. |
70 | 218 | internal.openedChangedWarning = false; | 220 | internal.openedChangedWarning = false; |
71 | 219 | panel.state = ""; | 221 | panel.state = ""; |
72 | 222 | hideTimer.stop(); | ||
73 | 220 | } | 223 | } |
74 | 221 | 224 | ||
75 | 222 | /*! | 225 | /*! |
76 | 226 | The time in milliseconds before the panel automatically hides after inactivity | ||
77 | 227 | when it is not locked. Interacting with the panel resets the timer. | ||
78 | 228 | Note that adding contents to the panel that accepts mouse events will prevent | ||
79 | 229 | the panel from detecting interaction and the timer will not be reset. | ||
80 | 230 | Setting a negative value will disable automatic hiding. | ||
81 | 231 | Default value: -1 (automatic hiding is disabled). | ||
82 | 232 | \qmlproperty int hideTimeout | ||
83 | 233 | */ | ||
84 | 234 | property alias hideTimeout: hideTimer.interval | ||
85 | 235 | |||
86 | 236 | /*! | ||
87 | 223 | Disable edge swipe to open/close the panel. False by default. | 237 | Disable edge swipe to open/close the panel. False by default. |
88 | 224 | */ | 238 | */ |
89 | 225 | property bool locked: false | 239 | property bool locked: false |
90 | @@ -228,6 +242,35 @@ | |||
91 | 228 | if (state == "hint" || state == "moving") { | 242 | if (state == "hint" || state == "moving") { |
92 | 229 | draggingArea.finishMoving(); | 243 | draggingArea.finishMoving(); |
93 | 230 | } | 244 | } |
94 | 245 | if (!hideTimer.conditionalRestart()) { | ||
95 | 246 | hideTimer.stop(); | ||
96 | 247 | } | ||
97 | 248 | } | ||
98 | 249 | |||
99 | 250 | Timer { | ||
100 | 251 | id: hideTimer | ||
101 | 252 | interval: -1 | ||
102 | 253 | running: panel.opened && !panel.locked && interval >= 0 | ||
103 | 254 | |||
104 | 255 | function conditionalRestart() { | ||
105 | 256 | if (hideTimer.interval >= 0) { | ||
106 | 257 | if (!panel.locked && panel.opened) { | ||
107 | 258 | hideTimer.restart(); | ||
108 | 259 | return true; | ||
109 | 260 | } | ||
110 | 261 | } | ||
111 | 262 | return false; | ||
112 | 263 | } | ||
113 | 264 | onIntervalChanged: { | ||
114 | 265 | if (!conditionalRestart()) { | ||
115 | 266 | hideTimer.stop(); | ||
116 | 267 | } | ||
117 | 268 | } | ||
118 | 269 | onTriggered: { | ||
119 | 270 | if (!panel.locked) { | ||
120 | 271 | panel.close(); | ||
121 | 272 | } | ||
122 | 273 | } | ||
123 | 231 | } | 274 | } |
124 | 232 | 275 | ||
125 | 233 | /*! | 276 | /*! |
126 | @@ -485,6 +528,7 @@ | |||
127 | 485 | 528 | ||
128 | 486 | property int initialPosition | 529 | property int initialPosition |
129 | 487 | onPressed: { | 530 | onPressed: { |
130 | 531 | hideTimer.stop(); | ||
131 | 488 | pressedItem = getTriggerableItem(mouse); | 532 | pressedItem = getTriggerableItem(mouse); |
132 | 489 | if (panel.locked) return; | 533 | if (panel.locked) return; |
133 | 490 | initialPosition = getMousePosition(); | 534 | initialPosition = getMousePosition(); |
134 | @@ -514,12 +558,16 @@ | |||
135 | 514 | onReleased: { | 558 | onReleased: { |
136 | 515 | if (panel.state == "moving" || panel.state == "hint") { | 559 | if (panel.state == "moving" || panel.state == "hint") { |
137 | 516 | finishMoving(); | 560 | finishMoving(); |
138 | 561 | } else { | ||
139 | 562 | hideTimer.conditionalRestart(); | ||
140 | 517 | } | 563 | } |
141 | 518 | } | 564 | } |
142 | 519 | // Mouse cursor moving out of the window while pressed on desktop | 565 | // Mouse cursor moving out of the window while pressed on desktop |
143 | 520 | onCanceled: { | 566 | onCanceled: { |
144 | 521 | if (panel.state == "moving" || panel.state == "hint") { | 567 | if (panel.state == "moving" || panel.state == "hint") { |
145 | 522 | finishMoving(); | 568 | finishMoving(); |
146 | 569 | } else { | ||
147 | 570 | hideTimer.conditionalRestart(); | ||
148 | 523 | } | 571 | } |
149 | 524 | } | 572 | } |
150 | 525 | 573 | ||
151 | 526 | 574 | ||
152 | === modified file 'modules/Ubuntu/Components/Toolbar.qml' | |||
153 | --- modules/Ubuntu/Components/Toolbar.qml 2013-11-08 18:38:25 +0000 | |||
154 | +++ modules/Ubuntu/Components/Toolbar.qml 2013-12-03 18:38:40 +0000 | |||
155 | @@ -42,12 +42,7 @@ | |||
156 | 42 | */ | 42 | */ |
157 | 43 | property Item tools: null | 43 | property Item tools: null |
158 | 44 | 44 | ||
165 | 45 | /*! | 45 | hideTimeout: 5000 |
160 | 46 | \preliminary | ||
161 | 47 | The time in milliseconds before the toolbar automatically hides after inactivity | ||
162 | 48 | when it is not locked. | ||
163 | 49 | */ | ||
164 | 50 | property int hideTimeout: 5000 | ||
166 | 51 | 46 | ||
167 | 52 | /*! \internal */ | 47 | /*! \internal */ |
168 | 53 | onToolsChanged: { | 48 | onToolsChanged: { |
169 | @@ -66,10 +61,6 @@ | |||
170 | 66 | if (tools && tools.hasOwnProperty("opened")) { | 61 | if (tools && tools.hasOwnProperty("opened")) { |
171 | 67 | tools.opened = toolbar.opened; | 62 | tools.opened = toolbar.opened; |
172 | 68 | } | 63 | } |
173 | 69 | |||
174 | 70 | if (!toolbar.locked) { | ||
175 | 71 | hideTimer.restart(); | ||
176 | 72 | } | ||
177 | 73 | } else { // no tools | 64 | } else { // no tools |
178 | 74 | locked = true; | 65 | locked = true; |
179 | 75 | toolbar.close(); | 66 | toolbar.close(); |
180 | @@ -79,22 +70,10 @@ | |||
181 | 79 | // if tools is not specified, lock the toolbar in closed position | 70 | // if tools is not specified, lock the toolbar in closed position |
182 | 80 | locked: tools && tools.hasOwnProperty("locked") ? tools.locked : false | 71 | locked: tools && tools.hasOwnProperty("locked") ? tools.locked : false |
183 | 81 | 72 | ||
184 | 82 | Timer { | ||
185 | 83 | id: hideTimer | ||
186 | 84 | interval: toolbar.hideTimeout | ||
187 | 85 | running: toolbar.opened && !toolbar.locked | ||
188 | 86 | onTriggered: { | ||
189 | 87 | if (!toolbar.locked) { | ||
190 | 88 | toolbar.close(); | ||
191 | 89 | } | ||
192 | 90 | } | ||
193 | 91 | } | ||
194 | 92 | |||
195 | 93 | onOpenedChanged: { | 73 | onOpenedChanged: { |
196 | 94 | if (tools && tools.hasOwnProperty("opened")) { | 74 | if (tools && tools.hasOwnProperty("opened")) { |
197 | 95 | tools.opened = toolbar.opened; | 75 | tools.opened = toolbar.opened; |
198 | 96 | } | 76 | } |
199 | 97 | if (!toolbar.locked) hideTimer.restart(); | ||
200 | 98 | } | 77 | } |
201 | 99 | 78 | ||
202 | 100 | Connections { | 79 | Connections { |
203 | 101 | 80 | ||
204 | === modified file 'tests/unit_x11/tst_components/tst_panel.qml' | |||
205 | --- tests/unit_x11/tst_components/tst_panel.qml 2013-09-09 18:59:35 +0000 | |||
206 | +++ tests/unit_x11/tst_components/tst_panel.qml 2013-12-03 18:38:40 +0000 | |||
207 | @@ -31,6 +31,10 @@ | |||
208 | 31 | right: parent.right | 31 | right: parent.right |
209 | 32 | } | 32 | } |
210 | 33 | height: parent.height / 2 | 33 | height: parent.height / 2 |
211 | 34 | Rectangle { | ||
212 | 35 | color: "pink" | ||
213 | 36 | anchors.fill: parent | ||
214 | 37 | } | ||
215 | 34 | } | 38 | } |
216 | 35 | 39 | ||
217 | 36 | TestCase { | 40 | TestCase { |
218 | @@ -162,6 +166,35 @@ | |||
219 | 162 | panel.align = Qt.AlignBottom; | 166 | panel.align = Qt.AlignBottom; |
220 | 163 | } | 167 | } |
221 | 164 | 168 | ||
222 | 169 | function test_clickToDeactivate() { | ||
223 | 170 | panel.open(); | ||
224 | 171 | compare(panel.opened && panel.align === Qt.AlignBottom, true, "Panel is opened and bottom-aligned"); | ||
225 | 172 | mouseClick(root, root.width / 2, 5, Qt.LeftButton); | ||
226 | 173 | compare(panel.opened, false, "Panel is deactivated by clicking in the view outside of the panel"); | ||
227 | 174 | } | ||
228 | 175 | |||
229 | 176 | function test_hideTimeout_bug1249031() { | ||
230 | 177 | compare(panel.hideTimeout, -1, "Panel hide timeout is initially negative (no timeout)"); | ||
231 | 178 | panel.hideTimeout = 2000; | ||
232 | 179 | panel.open(); | ||
233 | 180 | compare(panel.opened, true, "Panel can be made opened"); | ||
234 | 181 | wait(panel.hideTimeout + 500); // add 500 ms margin | ||
235 | 182 | compare(panel.opened, false, "Panel automatically closes after timeout"); | ||
236 | 183 | |||
237 | 184 | // now, wait in total more than hideTimeout, but less than 2*hideTimeout, | ||
238 | 185 | // and have user interaction half-way to verify that the interaction | ||
239 | 186 | // resets the timer and the panel is not closed. | ||
240 | 187 | panel.open(); | ||
241 | 188 | wait(0.6*panel.hideTimeout); | ||
242 | 189 | mouseClick(panel, panel.width/2, panel.height/2); | ||
243 | 190 | wait(0.6*panel.hideTimeout); | ||
244 | 191 | compare(panel.opened, true, "Interacting with panel contents resets the hide timer"); | ||
245 | 192 | // verify that the timer is still running by waiting a bit longer: | ||
246 | 193 | wait(0.6*panel.hideTimeout); | ||
247 | 194 | compare(panel.opened, false, "Interacting with the panel contents does not stop the timer") | ||
248 | 195 | panel.hideTimeout = -1; | ||
249 | 196 | } | ||
250 | 197 | |||
251 | 165 | QtObject { | 198 | QtObject { |
252 | 166 | id: swipeTests | 199 | id: swipeTests |
253 | 167 | 200 | ||
254 | @@ -239,13 +272,6 @@ | |||
255 | 239 | testCase.mouseRelease(panel, x - dx, y - dy, Qt.LeftButton); | 272 | testCase.mouseRelease(panel, x - dx, y - dy, Qt.LeftButton); |
256 | 240 | testCase.compare(panel.opened, false, "Top-aligned panel deactivated by swiping up (delay: "+moveDelay+""); | 273 | testCase.compare(panel.opened, false, "Top-aligned panel deactivated by swiping up (delay: "+moveDelay+""); |
257 | 241 | } | 274 | } |
258 | 242 | |||
259 | 243 | function test_clickToDeactivate() { | ||
260 | 244 | panel.open(); | ||
261 | 245 | compare(panel.opened && panel.align === Qt.AlignBottom, true, "Panel is opened and bottom-aligned"); | ||
262 | 246 | mouseClick(root, root.width / 2, 5, Qt.LeftButton); | ||
263 | 247 | compare(panel.opened, false, "Panel is deactivated by clicking in the view outside of the panel"); | ||
264 | 248 | } | ||
265 | 249 | } | 275 | } |
266 | 250 | } | 276 | } |
267 | 251 | } | 277 | } |
268 | 252 | 278 | ||
269 | === modified file 'tests/unit_x11/tst_components/tst_toolbar.qml' | |||
270 | --- tests/unit_x11/tst_components/tst_toolbar.qml 2013-11-08 18:32:39 +0000 | |||
271 | +++ tests/unit_x11/tst_components/tst_toolbar.qml 2013-12-03 18:38:40 +0000 | |||
272 | @@ -36,6 +36,7 @@ | |||
273 | 36 | tools: ToolbarItems { | 36 | tools: ToolbarItems { |
274 | 37 | id: toolbarItems | 37 | id: toolbarItems |
275 | 38 | ToolbarButton { | 38 | ToolbarButton { |
276 | 39 | id: toolbarButton | ||
277 | 39 | text: "action1" | 40 | text: "action1" |
278 | 40 | } | 41 | } |
279 | 41 | } | 42 | } |
280 | @@ -74,12 +75,24 @@ | |||
281 | 74 | compare(mainView.__propagated.toolbar.opened, false, "Toolbar can be made closed by setting page.tools.opened to false"); | 75 | compare(mainView.__propagated.toolbar.opened, false, "Toolbar can be made closed by setting page.tools.opened to false"); |
282 | 75 | } | 76 | } |
283 | 76 | 77 | ||
285 | 77 | function test_hideTimeout() { | 78 | function test_hideTimeout_bug1249031() { |
286 | 78 | compare(mainView.__propagated.toolbar.hideTimeout, 5000, "Toolbar hide timeout is initially 5 seconds."); | 79 | compare(mainView.__propagated.toolbar.hideTimeout, 5000, "Toolbar hide timeout is initially 5 seconds."); |
287 | 79 | mainView.__propagated.toolbar.open(); | 80 | mainView.__propagated.toolbar.open(); |
288 | 80 | compare(mainView.__propagated.toolbar.opened, true, "Toolbar can be made opened"); | 81 | compare(mainView.__propagated.toolbar.opened, true, "Toolbar can be made opened"); |
289 | 81 | wait(mainView.__propagated.toolbar.hideTimeout + 500); // add 500 ms margin | 82 | wait(mainView.__propagated.toolbar.hideTimeout + 500); // add 500 ms margin |
290 | 82 | compare(mainView.__propagated.toolbar.opened, false, "Toolbar automatically closes after timeout"); | 83 | compare(mainView.__propagated.toolbar.opened, false, "Toolbar automatically closes after timeout"); |
291 | 84 | |||
292 | 85 | // now, wait in total more than hideTimeout, but less than 2*hideTimeout, | ||
293 | 86 | // and have user interaction half-way to verify that the interaction | ||
294 | 87 | // resets the timer and the toolbar is not closed. | ||
295 | 88 | mainView.__propagated.toolbar.open(); | ||
296 | 89 | wait(0.6*mainView.__propagated.toolbar.hideTimeout); | ||
297 | 90 | mouseClick(toolbarButton, toolbarButton.width/2, toolbarButton.height/2); | ||
298 | 91 | wait(0.6*mainView.__propagated.toolbar.hideTimeout); | ||
299 | 92 | compare(mainView.__propagated.toolbar.opened, true, "Interacting with toolbar contents resets the hide timer"); | ||
300 | 93 | // verify that the timer is still running by waiting a bit longer: | ||
301 | 94 | wait(0.6*mainView.__propagated.toolbar.hideTimeout); | ||
302 | 95 | compare(mainView.__propagated.toolbar.opened, false, "Interacting with the toolbar contents does not stop the timer") | ||
303 | 83 | } | 96 | } |
304 | 84 | 97 | ||
305 | 85 | function test_locked() { | 98 | function test_locked() { |
PASSED: Continuous integration, rev:889 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- ci/1377/ jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty/ 1366 jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty- touch/1339 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- trusty- amd64-ci/ 325 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- trusty- armhf-ci/ 325 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- trusty- armhf-ci/ 325/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-trusty/ 1216 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/1366 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/1366/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/1339 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/1339/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ generic- mediumtests- runner- mako/3878 s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 2001
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- ui-toolkit- ci/1377/ rebuild
http://