Merge lp:~macslow/unity8/snap-decisions-states into lp:unity8
- snap-decisions-states
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~macslow/unity8/snap-decisions-states |
Merge into: | lp:unity8 |
Diff against target: |
584 lines (+402/-15) 6 files modified
qml/Notifications/Notification.qml (+57/-3) qml/Notifications/Notifications.qml (+16/-0) tests/autopilot/unity8/shell/tests/test_notifications.py (+1/-1) tests/qmltests/CMakeLists.txt (+1/-0) tests/qmltests/Notifications/tst_Notifications.qml (+19/-11) tests/qmltests/Notifications/tst_VisualQueue.qml (+308/-0) |
To merge this branch: | bzr merge lp:~macslow/unity8/snap-decisions-states |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Michael Zanetti (community) | Needs Fixing | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
Review via email: mp+195394@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-03-12.
Commit message
Make visual queue of (up to five) snap-decisions contract and expand according to visual design-spec.
Description of the change
Make visual queue of (up to five) snap-decisions contract and expand according to visual design-spec.
* Are there any related MPs required for this MP to build/function as expected?
There are two prerequiste branches needed for this to work. lp:~macslow/unity8/fix-object-name-of-notification-ap-test for lp:unity8 and lp:~macslow/unity-notifications/dont-ignore-placeholder for lp:unity-notifications
* Did you perform an exploratory manual test run of your code change and any related functionality?
Yes.
* If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?
Not applicable.
* If you changed the UI, has there been a design review?
Showed http://
PS Jenkins bot (ps-jenkins) wrote : | # |
- 535. By Mirco Müller
-
Fix trailing whitespace issue.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:535
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:535
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:535
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 536. By Mirco Müller
-
Use symbolic icons from the ubuntu-mobile icon-set.
- 537. By Mirco Müller
-
Use more symbolic icons.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:536
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:537
http://
Executed test runs:
UNSTABLE: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 538. By Mirco Müller
-
Trying to make the qmltest for notification-
renderer pass on jenkins.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:538
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
FAILURE: 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) wrote : | # |
FAILED: Continuous integration, rev:538
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:538
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:538
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:538
http://
Executed test runs:
FAILURE: http://
SUCCESS: http://
UNSTABLE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:538
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 539. By Mirco Müller
-
Trying to avoid the segfault in waitForRendering() when qmltest is run on jenkins.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:539
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 540. By Mirco Müller
-
That didn't work... and would not have been approved anyway.
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:540
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Michael Zanetti (mzanetti) wrote : | # |
15 + var result = "undefined";
I think this should be "" instead of "undefined" otherwise leaving a state might not reset stuff correctly.
===
18 + if (notificationLi
and following lines...
You shouldn't reach out of scope here (Can break if someone. Please either user ListView.view instead of notificationList or move the logic out into the containing ListView.
===
small coding style nitpick
70 anchors.fill: parent
71 - anchors.margins: notification.
72 + anchors.leftMargin: notification.
73 + anchors.
anchors { fill: parent; ... }
===
117 + Component.
118 + if (fullscreen) {
119 + notificationLis
120 + } else {
121 + notificationLis
122 + }
123 + }
Why can't this be a binding in the ListView? Not sure why this needs to be called every time a new delegate is created.
===
Not sure if related to this branch (and if its a real issue after all), but if I trigger sd-example-
===
I'm calling this in a script:
./sd-example-
./sd-example-
./sd-example-
./sd-example-
./sd-example-
./sd-example-
./sd-example-
./sd-example-
./sd-example-
=> unity crashes.
After that I added a sleep 1 in between the lines, it still causes issues and at some point an empty rectangle appears.
===
If the first notification is expanded, and a new one comes in at position 0, the new one shows up expanded and then quickly collapses. I think that might be related to this:
125 + ListView.onAdd: {
126 + if (notificationLi
127 + notificationLis
128 + }
The problem here is that you only correct the currentIndex after everything is built up. If you make it a binding it should work better.
===
207 + wait(500);
Is that a leftover from testing?
===
tests look good. Maybe rename them to give it a more meaningful name? make testVisualQueue does not really tell its notifications.
- 542. By Mirco Müller
-
Fixed the first set of issues from the MP-comments.
- 543. By Mirco Müller
-
More MP-comment fixes.
- 544. By Mirco Müller
-
Fixing more MP-comments... moving more control to bindings.
- 545. By Mirco Müller
-
Rename qml-test for visual snap-decision queue to make it more obvious what it is about.
- 546. By Mirco Müller
-
Typo
- 547. By Mirco Müller
-
Merged mzanetti's wait()-crushing power :)
- 548. By Mirco Müller
-
Got rid of the last wait(), but now have to fight the initialHeight assertion again... :/
- 549. By Mirco Müller
-
Added another WaitForRendering() to make the test pass again... most of the time :/
- 550. By Mirco Müller
-
This second waitForRendering() seems to help fix the issue.
- 551. By Mirco Müller
-
That didn't really help either.
- 552. By Mirco Müller
-
Rather use implicitHeight then height to get the correct value.
- 553. By Mirco Müller
-
Forgot to also use the renamed test in the cmakefile.
- 554. By Mirco Müller
-
Possible fix for segfault in notification-
qmltest - 555. By Mirco Müller
-
Add the five test Snap-Decisions for the visual-queue test in one go.
- 556. By Mirco Müller
-
Using the fill-model function from the interactive test.
Unmerged revisions
Preview Diff
1 | === modified file 'qml/Notifications/Notification.qml' |
2 | --- qml/Notifications/Notification.qml 2014-01-03 10:29:25 +0000 |
3 | +++ qml/Notifications/Notification.qml 2014-03-12 14:26:44 +0000 |
4 | @@ -39,12 +39,61 @@ |
5 | |
6 | fullscreen: false |
7 | objectName: "background" |
8 | - implicitHeight: type !== Notification.PlaceHolder ? (fullscreen ? maxHeight : contentColumn.height + contentColumn.spacing * 4) : 0 |
9 | + implicitHeight: type !== Notification.PlaceHolder ? (fullscreen ? maxHeight : contentColumn.height + contentColumn.spacing * 2) : 0 |
10 | |
11 | color: Qt.rgba(0.132, 0.117, 0.109, 0.97) |
12 | opacity: 0 |
13 | |
14 | + state: { |
15 | + var result = "undefined"; |
16 | + |
17 | + if (type == Notification.SnapDecision) { |
18 | + if (notificationList.currentIndex == index) { |
19 | + result = "expanded"; |
20 | + } else { |
21 | + if (notificationList.count > 2) { |
22 | + if (notificationList.currentIndex == -1 && index == 1) { |
23 | + result = "expanded"; |
24 | + } else { |
25 | + result = "contracted"; |
26 | + } |
27 | + } else { |
28 | + result = "expanded"; |
29 | + } |
30 | + } |
31 | + } |
32 | + |
33 | + return result; |
34 | + } |
35 | + |
36 | + Behavior on height { |
37 | + id: normalHeightBehavior |
38 | + |
39 | + //enabled: menuItemFactory.progress == 1 |
40 | + enabled: true |
41 | + SequentialAnimation { |
42 | + PauseAnimation { |
43 | + duration: UbuntuAnimation.SnapDuration |
44 | + } |
45 | + UbuntuNumberAnimation { |
46 | + duration: UbuntuAnimation.SnapDuration |
47 | + } |
48 | + } |
49 | + } |
50 | + |
51 | + states:[ |
52 | + State { |
53 | + name: "contracted" |
54 | + PropertyChanges {target: notification; height: units.gu(8)} |
55 | + }, |
56 | + State { |
57 | + name: "expanded" |
58 | + PropertyChanges {target: notification; height: implicitHeight} |
59 | + } |
60 | + ] |
61 | + |
62 | clip: fullscreen ? false : true |
63 | + |
64 | visible: type != Notification.PlaceHolder |
65 | |
66 | UbuntuShape { |
67 | @@ -52,7 +101,8 @@ |
68 | |
69 | visible: !fullscreen |
70 | anchors.fill: parent |
71 | - anchors.margins: notification.margins |
72 | + anchors.leftMargin: notification.margins |
73 | + anchors.rightMargin: notification.margins |
74 | color: parent.color |
75 | opacity: parent.opacity |
76 | radius: "medium" |
77 | @@ -104,11 +154,13 @@ |
78 | MouseArea { |
79 | id: interactiveArea |
80 | |
81 | - anchors.fill: contentColumn |
82 | + anchors.fill: parent |
83 | objectName: "interactiveArea" |
84 | onClicked: { |
85 | if (notification.type == Notification.Interactive) { |
86 | notification.notification.invokeAction(actionRepeater.itemAt(0).actionId) |
87 | + } else { |
88 | + notificationList.currentIndex = index; |
89 | } |
90 | } |
91 | } |
92 | @@ -207,6 +259,8 @@ |
93 | model: unityMenuModel |
94 | |
95 | NotificationMenuItemFactory { |
96 | + id: menuItemFactory |
97 | + |
98 | anchors.left: parent.left; anchors.right: parent.right |
99 | |
100 | menuModel: unityMenuModel |
101 | |
102 | === modified file 'qml/Notifications/Notifications.qml' |
103 | --- qml/Notifications/Notifications.qml 2013-12-18 12:50:55 +0000 |
104 | +++ qml/Notifications/Notifications.qml 2014-03-12 14:26:44 +0000 |
105 | @@ -25,6 +25,7 @@ |
106 | interactive: false |
107 | |
108 | property real margin |
109 | + spacing: units.gu(.5) |
110 | |
111 | delegate: Notification { |
112 | objectName: "notification" + index |
113 | @@ -44,6 +45,20 @@ |
114 | maxHeight: notificationList.height |
115 | margins: notificationList.margin |
116 | |
117 | + Component.onCompleted: { |
118 | + if (fullscreen) { |
119 | + notificationList.spacing = 0 |
120 | + } else { |
121 | + notificationList.spacing = units.gu(.5) |
122 | + } |
123 | + } |
124 | + |
125 | + ListView.onAdd: { |
126 | + if (notificationList.currentIndex < 1 && notificationList.count > 1) { |
127 | + notificationList.currentIndex = 1 |
128 | + } |
129 | + } |
130 | + |
131 | // make sure there's no opacity-difference between the several |
132 | // elements in a notification |
133 | layer.enabled: add.running || remove.running || populate.running |
134 | @@ -75,6 +90,7 @@ |
135 | displaced: Transition { |
136 | UbuntuNumberAnimation { |
137 | properties: "x,y" |
138 | + duration: UbuntuAnimation.SnapDuration |
139 | } |
140 | } |
141 | } |
142 | |
143 | === modified file 'tests/autopilot/unity8/shell/tests/test_notifications.py' |
144 | --- tests/autopilot/unity8/shell/tests/test_notifications.py 2014-02-23 01:28:40 +0000 |
145 | +++ tests/autopilot/unity8/shell/tests/test_notifications.py 2014-03-12 14:26:44 +0000 |
146 | @@ -194,7 +194,7 @@ |
147 | |
148 | notify_list = self._get_notifications_list() |
149 | get_notification = lambda: notify_list.wait_select_single( |
150 | - 'Notification', objectName='notification0') |
151 | + 'Notification', objectName='notification1') |
152 | notification = get_notification() |
153 | self._assert_notification(notification, None, None, True, True, 1.0) |
154 | initial_height = notification.height |
155 | |
156 | === modified file 'tests/qmltests/CMakeLists.txt' |
157 | --- tests/qmltests/CMakeLists.txt 2014-02-20 17:01:45 +0000 |
158 | +++ tests/qmltests/CMakeLists.txt 2014-03-12 14:26:44 +0000 |
159 | @@ -82,6 +82,7 @@ |
160 | add_qml_test(Hud Result) |
161 | add_qml_test(Launcher Launcher IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}) |
162 | add_qml_test(Notifications Notifications IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins) |
163 | +add_qml_test(Notifications VisualQueue IMPORT_PATHS ${qmltest_DEFAULT_IMPORT_PATHS} ${CMAKE_BINARY_DIR}/plugins) |
164 | add_qml_test(Panel IndicatorRow) |
165 | add_qml_test(Panel Indicators IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}) |
166 | add_qml_test(Panel MenuContent IMPORT_PATHS ${CMAKE_BINARY_DIR}/plugins ${qmltest_DEFAULT_IMPORT_PATHS}) |
167 | |
168 | === modified file 'tests/qmltests/Notifications/tst_Notifications.qml' |
169 | --- tests/qmltests/Notifications/tst_Notifications.qml 2014-01-03 10:29:25 +0000 |
170 | +++ tests/qmltests/Notifications/tst_Notifications.qml 2014-03-12 14:26:44 +0000 |
171 | @@ -43,6 +43,21 @@ |
172 | function getRaw(id) { |
173 | return mockNotification.createObject(mockModel) |
174 | } |
175 | + |
176 | + // add the default/PlaceHolder notification to the model |
177 | + Component.onCompleted: { |
178 | + var n = { |
179 | + type: Notification.PlaceHolder, |
180 | + hints: {}, |
181 | + summary: "", |
182 | + body: "", |
183 | + icon: "", |
184 | + secondaryIcon: "", |
185 | + actions: [] |
186 | + } |
187 | + |
188 | + append(n) |
189 | + } |
190 | } |
191 | |
192 | function addSnapDecisionNotification() { |
193 | @@ -370,12 +385,13 @@ |
194 | mockModel.append(data) |
195 | |
196 | // make sure the view is properly updated before going on |
197 | - notifications.forceLayout(); |
198 | waitForRendering(notifications); |
199 | |
200 | var notification = findChild(notifications, "notification" + (mockModel.count - 1)) |
201 | verify(notification !== undefined, "notification wasn't found"); |
202 | |
203 | + waitForRendering(notification); |
204 | + |
205 | var icon = findChild(notification, "icon") |
206 | var shapedIcon = findChild(notification, "shapedIcon") |
207 | var nonShapedIcon = findChild(notification, "nonShapedIcon") |
208 | @@ -384,7 +400,6 @@ |
209 | var summaryLabel = findChild(notification, "summaryLabel") |
210 | var bodyLabel = findChild(notification, "bodyLabel") |
211 | var buttonRow = findChild(notification, "buttonRow") |
212 | - waitForRendering(buttonRow) |
213 | |
214 | compare(icon.visible, data.iconVisible, "avatar-icon visibility is incorrect") |
215 | compare(shapedIcon.visible, data.shapedIcon, "shaped-icon visibility is incorrect") |
216 | @@ -402,17 +417,15 @@ |
217 | compare(summaryLabel.visible, data.summaryVisible, "summary-text visibility is incorrect") |
218 | compare(bodyLabel.visible, data.bodyVisible, "body-text visibility is incorrect") |
219 | compare(buttonRow.visible, data.buttonRowVisible, "button visibility is incorrect") |
220 | + wait(500); |
221 | |
222 | if(data.buttonRowVisible) { |
223 | var buttonCancel = findChild(buttonRow, "button1") |
224 | var buttonAccept = findChild(buttonRow, "button0") |
225 | |
226 | - waitForRendering(notification) |
227 | - |
228 | // only test the left/cancel-button if two actions have been passed in |
229 | if (data.actions.length == 2) { |
230 | mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2) |
231 | - actionSpy.wait() |
232 | compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action") |
233 | actionSpy.clear() |
234 | } |
235 | @@ -422,7 +435,6 @@ |
236 | |
237 | // click the positive/right button |
238 | mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2) |
239 | - actionSpy.wait() |
240 | compare(actionSpy.signalArguments[0][0], data.actions[0]["id"], "got wrong id positive action") |
241 | actionSpy.clear() |
242 | |
243 | @@ -432,27 +444,23 @@ |
244 | |
245 | // click to expand |
246 | mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2) |
247 | - waitForRendering(notification) |
248 | + wait(500); |
249 | actionSpy.clear() |
250 | |
251 | // test the additional buttons |
252 | for (var i = 2; i < data.actions.length; i++) { |
253 | - waitForRendering(notification) |
254 | var buttonColumn = findChild(notification, "buttonColumn") |
255 | var button = findChild(buttonColumn, "button" + i) |
256 | mouseClick(button, button.width / 2, button.height / 2) |
257 | - actionSpy.wait() |
258 | compare(actionSpy.signalArguments[0][0], data.actions[i]["id"], "got wrong id for additional negative action") |
259 | actionSpy.clear() |
260 | } |
261 | |
262 | // click to collapse |
263 | mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2) |
264 | - waitForRendering(notification) |
265 | tryCompare(notification, "height", initialHeight) |
266 | } else { |
267 | mouseClick(buttonCancel, buttonCancel.width / 2, buttonCancel.height / 2) |
268 | - actionSpy.wait() |
269 | compare(actionSpy.signalArguments[0][0], data.actions[1]["id"], "got wrong id for negative action") |
270 | } |
271 | } |
272 | |
273 | === added file 'tests/qmltests/Notifications/tst_VisualQueue.qml' |
274 | --- tests/qmltests/Notifications/tst_VisualQueue.qml 1970-01-01 00:00:00 +0000 |
275 | +++ tests/qmltests/Notifications/tst_VisualQueue.qml 2014-03-12 14:26:44 +0000 |
276 | @@ -0,0 +1,308 @@ |
277 | +/* |
278 | + * Copyright (C) 2014 Canonical, Ltd. |
279 | + * |
280 | + * This program is free software; you can redistribute it and/or modify |
281 | + * it under the terms of the GNU General Public License as published by |
282 | + * the Free Software Foundation; version 3. |
283 | + * |
284 | + * This program is distributed in the hope that it will be useful, |
285 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
286 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
287 | + * GNU General Public License for more details. |
288 | + * |
289 | + * You should have received a copy of the GNU General Public License |
290 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
291 | + */ |
292 | + |
293 | +import QtQuick 2.0 |
294 | +import QtTest 1.0 |
295 | +import ".." |
296 | +import "../../../qml/Notifications" |
297 | +import Ubuntu.Components 0.1 |
298 | +import Unity.Test 0.1 |
299 | +import Unity.Notifications 1.0 |
300 | + |
301 | +Row { |
302 | + id: rootRow |
303 | + |
304 | + Component { |
305 | + id: mockNotification |
306 | + |
307 | + QtObject { |
308 | + function invokeAction(actionId) { |
309 | + mockModel.actionInvoked(actionId) |
310 | + } |
311 | + } |
312 | + } |
313 | + |
314 | + ListModel { |
315 | + id: mockModel |
316 | + |
317 | + signal actionInvoked(string actionId) |
318 | + |
319 | + function getRaw(id) { |
320 | + return mockNotification.createObject(mockModel) |
321 | + } |
322 | + |
323 | + // add the default/PlaceHolder notification to the model |
324 | + Component.onCompleted: { |
325 | + var n = { |
326 | + type: Notification.PlaceHolder, |
327 | + hints: {}, |
328 | + summary: "", |
329 | + body: "", |
330 | + icon: "", |
331 | + secondaryIcon: "", |
332 | + actions: [] |
333 | + } |
334 | + |
335 | + append(n) |
336 | + } |
337 | + } |
338 | + |
339 | + function addSomeSnapDecisionNotifications() { |
340 | + var n = [{ |
341 | + type: Notification.SnapDecision, |
342 | + hints: {"x-canonical-private-button-tint": "true"}, |
343 | + summary: "Incoming call", |
344 | + body: "Frank Zappa\n+44 (0)7736 027340", |
345 | + icon: "../graphics/avatars/funky.png", |
346 | + secondaryIcon: "../graphics/applicationIcons/phone-app.png", |
347 | + actions: [{ id: "pickup_id", label: "Pick up"}, |
348 | + { id: "decline_1_id", label: "Decline"}, |
349 | + { id: "decline_2_id", label: "Can't talk now, what's up?"}, |
350 | + { id: "decline_3_id", label: "I call you back."}, |
351 | + { id: "decline_4_id", label: "Send custom message..."}] |
352 | + }, |
353 | + { |
354 | + type: Notification.SnapDecision, |
355 | + hints: {"x-canonical-private-button-tint": "true", |
356 | + "x-canonical-non-shaped-icon": "true"}, |
357 | + summary: "Incoming file", |
358 | + body: "Frank would like to send you the file: essay.pdf.", |
359 | + icon: "image://theme/search", |
360 | + actions: [{ id: "accept_id", label: "Accept"}, |
361 | + { id: "reject_id", label: "Reject"}] |
362 | + }, |
363 | + { |
364 | + type: Notification.SnapDecision, |
365 | + hints: {"x-canonical-private-button-tint": "true", |
366 | + "x-canonical-non-shaped-icon": "true"}, |
367 | + summary: "Authentication error", |
368 | + body: "Please authorise Ubuntu to access your Google account.", |
369 | + icon: "image://theme/search", |
370 | + actions: [{ id: "settings_id", label: "Settings..."}, |
371 | + { id: "cancel_id", label: "Cancel"}] |
372 | + }, |
373 | + { |
374 | + type: Notification.SnapDecision, |
375 | + hints: {"x-canonical-private-button-tint": "true", |
376 | + "x-canonical-non-shaped-icon": "true"}, |
377 | + summary: "Morning alarm", |
378 | + body: "It's 6:30... time to get up!", |
379 | + icon: "image://theme/search", |
380 | + actions: [{ id: "ok_reply", label: "Ok"}, |
381 | + { id: "snooze_id", label: "Snooze"}] |
382 | + }, |
383 | + { |
384 | + type: Notification.SnapDecision, |
385 | + hints: {"x-canonical-private-button-tint": "true"}, |
386 | + summary: "Jenny Sample", |
387 | + body: "Hey there! Have you been watching the latest episode of that TV-show I told you about last week?", |
388 | + icon: "../graphics/avatars/amanda.png", |
389 | + secondaryIcon: "../graphics/applicationIcons/messages-app.png", |
390 | + actions: [{ id: "reply_id", label: "Reply"}, |
391 | + { id: "ignore_id", label: "Ignore"}] |
392 | + }] |
393 | + |
394 | + mockModel.append(n) |
395 | + } |
396 | + |
397 | + function clearNotifications() { |
398 | + // remove all but the first (PlaceHolder) notification |
399 | + mockModel.remove(1, mockModel.count - 1) |
400 | + } |
401 | + |
402 | + function removeTopMostNotification() { |
403 | + // leave real/first (PlaceHolder) notification untouched |
404 | + if (mockModel.count > 1) |
405 | + mockModel.remove(1) |
406 | + } |
407 | + |
408 | + Rectangle { |
409 | + id: notificationsRect |
410 | + |
411 | + width: units.gu(40) |
412 | + height: units.gu(71) |
413 | + |
414 | + MouseArea{ |
415 | + id: clickThroughCatcher |
416 | + |
417 | + anchors.fill: parent |
418 | + } |
419 | + |
420 | + Notifications { |
421 | + id: notifications |
422 | + |
423 | + margin: units.gu(1) |
424 | + |
425 | + anchors.fill: parent |
426 | + model: mockModel |
427 | + } |
428 | + } |
429 | + |
430 | + Rectangle { |
431 | + id: interactiveControls |
432 | + |
433 | + width: units.gu(30) |
434 | + height: units.gu(81) |
435 | + color: "grey" |
436 | + |
437 | + Column { |
438 | + spacing: units.gu(1) |
439 | + anchors.fill: parent |
440 | + anchors.margins: units.gu(1) |
441 | + |
442 | + Button { |
443 | + width: parent.width |
444 | + text: "add some snap-decisions" |
445 | + onClicked: addSomeSnapDecisionNotifications() |
446 | + } |
447 | + |
448 | + Button { |
449 | + width: parent.width |
450 | + text: "remove top-most notification" |
451 | + onClicked: removeTopMostNotification() |
452 | + } |
453 | + |
454 | + Button { |
455 | + width: parent.width |
456 | + text: "clear model" |
457 | + onClicked: clearNotifications() |
458 | + } |
459 | + } |
460 | + } |
461 | + |
462 | + UnityTestCase { |
463 | + id: root |
464 | + name: "VisualQueueTest" |
465 | + when: windowShown |
466 | + |
467 | + function test_VisualQueue_data() { |
468 | + return [ |
469 | + { |
470 | + tag: "Snap Decision 1", |
471 | + type: Notification.SnapDecision, |
472 | + hints: {"x-canonical-private-button-tint": "true"}, |
473 | + summary: "Incoming call", |
474 | + body: "Frank Zappa\n+44 (0)7736 027340", |
475 | + icon: "../graphics/avatars/funky.png", |
476 | + secondaryIcon: "../graphics/applicationIcons/phone-app.png", |
477 | + actions: [{ id: "pickup_id", label: "Pick up"}, |
478 | + { id: "decline_1_id", label: "Decline"}, |
479 | + { id: "decline_2_id", label: "Can't talk now, what's up?"}, |
480 | + { id: "decline_3_id", label: "I call you back."}, |
481 | + { id: "decline_4_id", label: "Send custom message..."}] |
482 | + }, |
483 | + { |
484 | + tag: "Snap Decision 2", |
485 | + type: Notification.SnapDecision, |
486 | + hints: {"x-canonical-private-button-tint": "true", |
487 | + "x-canonical-non-shaped-icon": "true"}, |
488 | + summary: "Incoming file", |
489 | + body: "Frank would like to send you the file: essay.pdf.", |
490 | + icon: "image://theme/search", |
491 | + secondaryIcon: "", |
492 | + actions: [{ id: "accept_id", label: "Accept"}, |
493 | + { id: "reject_id", label: "Reject"}] |
494 | + }, |
495 | + { |
496 | + tag: "Snap Decision 3", |
497 | + type: Notification.SnapDecision, |
498 | + hints: {"x-canonical-private-button-tint": "true", |
499 | + "x-canonical-non-shaped-icon": "true"}, |
500 | + summary: "Authentication error", |
501 | + body: "Please authorise Ubuntu to access your Google account.", |
502 | + icon: "image://theme/search", |
503 | + secondaryIcon: "", |
504 | + actions: [{ id: "settings_id", label: "Settings..."}, |
505 | + { id: "cancel_id", label: "Cancel"}] |
506 | + }, |
507 | + { |
508 | + tag: "Snap Decision 4", |
509 | + type: Notification.SnapDecision, |
510 | + hints: {"x-canonical-private-button-tint": "true", |
511 | + "x-canonical-non-shaped-icon": "true"}, |
512 | + summary: "Morning alarm", |
513 | + body: "It's 6:30... time to get up!", |
514 | + icon: "image://theme/search", |
515 | + secondaryIcon: "", |
516 | + actions: [{ id: "ok_reply", label: "Ok"}, |
517 | + { id: "snooze_id", label: "Snooze"}] |
518 | + }, |
519 | + { |
520 | + tag: "Snap Decision 5", |
521 | + type: Notification.SnapDecision, |
522 | + hints: {"x-canonical-private-button-tint": "true"}, |
523 | + summary: "Jenny Sample", |
524 | + body: "Hey there! Have you been watching the latest episode of that TV-show I told you about last week?", |
525 | + icon: "../graphics/avatars/amanda.png", |
526 | + secondaryIcon: "../graphics/applicationIcons/messages-app.png", |
527 | + actions: [{ id: "reply_id", label: "Reply"}, |
528 | + { id: "ignore_id", label: "Ignore"}] |
529 | + } |
530 | + ] |
531 | + } |
532 | + |
533 | + function test_VisualQueue(data) { |
534 | + // populate model with some mock notifications |
535 | + mockModel.append(data) |
536 | + |
537 | + // make sure the view is properly updated before going on |
538 | + waitForRendering(notifications); |
539 | + |
540 | + if (mockModel.count > 5) { |
541 | + var snap_decision = [findChild(notifications, "notification1"), |
542 | + findChild(notifications, "notification2"), |
543 | + findChild(notifications, "notification3"), |
544 | + findChild(notifications, "notification4"), |
545 | + findChild(notifications, "notification5")] |
546 | + |
547 | + for (var index = 0; index < snap_decision.length; index++) { |
548 | + verify(snap_decision[index] !== undefined, index + ". snap-decision wasn't found"); |
549 | + } |
550 | + |
551 | + // check initial states once all five snap-decisions were appended to the model |
552 | + compare(snap_decision[0].state, "expanded", "state of first snap-decision is not expanded"); |
553 | + for (var index = 1; index < snap_decision.length; index++) { |
554 | + compare(snap_decision[index].state, "contracted", "state of "+ index + ".snap-decision is not contracted"); |
555 | + } |
556 | + } |
557 | + |
558 | + // click/tap on each snap-decision and verify only one is in expanded-state at any time |
559 | + if (mockModel.count > 5) { |
560 | + for (var index = 0; index < snap_decision.length; index++) { |
561 | + mouseClick(snap_decision[index], snap_decision[index].width / 2, snap_decision[index].height / 2) |
562 | + for (var kindex = 0; kindex < snap_decision.length; kindex++) { |
563 | + if (kindex == index) { |
564 | + compare(snap_decision[kindex].state, "expanded", "state of "+ kindex + ".snap-decision is not expanded"); |
565 | + } else { |
566 | + compare(snap_decision[kindex].state, "contracted", "state of "+ kindex + ".snap-decision is not contracted"); |
567 | + } |
568 | + } |
569 | + } |
570 | + } |
571 | + |
572 | + // once all five snap-decisions are appended to the model remove top-most and verify one of the remaining ones is still getting expanded |
573 | + if (mockModel.count > 5) { |
574 | + // make first snap-decision expand |
575 | + mouseClick(snap_decision[0], snap_decision[0].width / 2, snap_decision[0].height / 2); |
576 | + |
577 | + for (var index = 1; index < snap_decision.length; index++) { |
578 | + removeTopMostNotification(); |
579 | + compare(snap_decision[index].state, "expanded", "state of " + index + ". snap-decision is not expanded"); |
580 | + } |
581 | + } |
582 | + } |
583 | + } |
584 | +} |
FAILED: Continuous integration, rev:534 jenkins. qa.ubuntu. com/job/ unity8- ci/2287/ jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty/ 3068/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty- touch/2781/ console jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- trusty/ 1158/console jenkins. qa.ubuntu. com/job/ unity8- trusty- amd64-ci/ 809/console jenkins. qa.ubuntu. com/job/ unity8- trusty- armhf-ci/ 811/console jenkins. qa.ubuntu. com/job/ unity8- trusty- i386-ci/ 809/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/3070/ console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/2782/ console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity8- ci/2287/ rebuild
http://