Merge lp:~mzanetti/unity8/fix_snap_decision_test-rtm into lp:unity8/rtm-14.09

Proposed by Michael Zanetti
Status: Merged
Approved by: Michał Sawicz
Approved revision: 1329
Merged at revision: 1357
Proposed branch: lp:~mzanetti/unity8/fix_snap_decision_test-rtm
Merge into: lp:unity8/rtm-14.09
Prerequisite: lp:~unity-team/unity8/rtm-sharedunitymenumodel
Diff against target: 244 lines (+132/-43)
3 files modified
qml/Notifications/Notifications.qml (+1/-0)
qml/Shell.qml (+1/-1)
tests/qmltests/tst_Shell.qml (+130/-42)
To merge this branch: bzr merge lp:~mzanetti/unity8/fix_snap_decision_test-rtm
Reviewer Review Type Date Requested Status
Michał Sawicz Approve
Review via email: mp+238282@code.launchpad.net

This proposal supersedes a proposal from 2014-10-14.

Commit message

Fix lp:1370240 by making stages interactive when a snap decision is dismissed.

Description of the change

 * Are there any related MPs required for this MP to build/function as expected? Please list.

no

 * Did you perform an exploratory manual test run of your code change and any related functionality?

yes

 * Did you make sure that your branch does not contain spurious tags?

yes

 * If you changed the packaging (debian), did you subscribe the ubuntu-unity team to this MP?

no

 * If you changed the UI, has there been a design review?

no

To post a comment you must log in.
1326. By Michael Zanetti

revert to activeFocus, make it a bit more robust

1327. By Michael Zanetti

s/compare/tryCompare/

1328. By Michael Zanetti

add more waitForRending

1329. By Michael Zanetti

cherry-pick over fixes

Revision history for this message
Michał Sawicz (saviq) wrote :

As per the upstream change.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qml/Notifications/Notifications.qml'
2--- qml/Notifications/Notifications.qml 2014-08-25 11:31:05 +0000
3+++ qml/Notifications/Notifications.qml 2014-10-15 09:16:33 +0000
4@@ -31,6 +31,7 @@
5
6 SortFilterProxyModel {
7 id: snapDecisionProxyModel
8+ objectName: "snapDecisionProxyModel"
9
10 model: notificationList.model
11 filterRole: UnityNotifications.ModelInterface != undefined ? UnityNotifications.ModelInterface.RoleType : 0
12
13=== modified file 'qml/Shell.qml'
14--- qml/Shell.qml 2014-10-08 20:36:48 +0000
15+++ qml/Shell.qml 2014-10-15 09:16:33 +0000
16@@ -240,7 +240,7 @@
17 Binding {
18 target: applicationsDisplayLoader.item
19 property: "interactive"
20- value: edgeDemo.stagesEnabled && !greeter.shown && !lockscreen.shown && panel.indicators.fullyClosed && launcher.progress == 0
21+ value: edgeDemo.stagesEnabled && !greeter.shown && !lockscreen.shown && panel.indicators.fullyClosed && launcher.progress == 0 && !notifications.useModal
22 }
23 Binding {
24 target: applicationsDisplayLoader.item
25
26=== modified file 'tests/qmltests/tst_Shell.qml'
27--- tests/qmltests/tst_Shell.qml 2014-10-15 09:16:32 +0000
28+++ tests/qmltests/tst_Shell.qml 2014-10-15 09:16:33 +0000
29@@ -25,14 +25,17 @@
30 import Ubuntu.Telephony 0.1 as Telephony
31 import Unity.Application 0.1
32 import Unity.Connectivity 0.1
33+import Unity.Notifications 1.0
34 import Unity.Test 0.1 as UT
35 import Powerd 0.1
36
37 import "../../qml"
38
39-Row {
40+Item {
41 id: root
42- spacing: 0
43+
44+ width: units.gu(60)
45+ height: units.gu(71)
46
47 QtObject {
48 id: applicationArguments
49@@ -50,49 +53,42 @@
50 }
51 }
52
53- Loader {
54- id: shellLoader
55-
56- // Copied from Shell.qml
57- property bool tablet: false
58- width: tablet ? units.gu(160)
59- : applicationArguments.hasGeometry() ? applicationArguments.width()
60- : units.gu(40)
61- height: tablet ? units.gu(100)
62- : applicationArguments.hasGeometry() ? applicationArguments.height()
63- : units.gu(71)
64-
65- property bool itemDestroyed: false
66- sourceComponent: Component {
67- Shell {
68- property string indicatorProfile: "phone"
69-
70- Component.onDestruction: {
71- shellLoader.itemDestroyed = true;
72+ Row {
73+ anchors.fill: parent
74+
75+ Loader {
76+ id: shellLoader
77+
78+ property bool itemDestroyed: false
79+ sourceComponent: Component {
80+ Shell {
81+ Component.onDestruction: {
82+ shellLoader.itemDestroyed = true;
83+ }
84 }
85 }
86 }
87- }
88-
89- Rectangle {
90- color: "white"
91- width: units.gu(30)
92- height: shellLoader.height
93-
94- Column {
95- anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
96- spacing: units.gu(1)
97- Row {
98- anchors { left: parent.left; right: parent.right }
99- Button {
100- text: "Show Greeter"
101- onClicked: {
102- if (shellLoader.status !== Loader.Ready)
103- return;
104-
105- var greeter = testCase.findChild(shellLoader.item, "greeter");
106- if (!greeter.shown) {
107- greeter.show();
108+
109+ Rectangle {
110+ color: "white"
111+ width: units.gu(30)
112+ height: shellLoader.height
113+
114+ Column {
115+ anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
116+ spacing: units.gu(1)
117+ Row {
118+ anchors { left: parent.left; right: parent.right }
119+ Button {
120+ text: "Show Greeter"
121+ onClicked: {
122+ if (shellLoader.status !== Loader.Ready)
123+ return;
124+
125+ var greeter = testCase.findChild(shellLoader.item, "greeter");
126+ if (!greeter.shown) {
127+ greeter.show();
128+ }
129 }
130 }
131 }
132@@ -100,6 +96,33 @@
133 }
134 }
135
136+ Component {
137+ id: mockNotification
138+
139+ QtObject {
140+ function invokeAction(actionId) {
141+ mockNotificationsModel.actionInvoked(actionId)
142+ }
143+ }
144+ }
145+
146+ ListModel {
147+ id: mockNotificationsModel
148+
149+ signal actionInvoked(string actionId)
150+
151+ function getRaw(id) {
152+ return mockNotification.createObject(mockNotificationsModel)
153+ }
154+
155+ onActionInvoked: {
156+ if(actionId == "ok_id") {
157+ mockNotificationsModel.clear()
158+ }
159+ }
160+ }
161+
162+
163 SignalSpy {
164 id: sessionSpy
165 signalName: "sessionStarted"
166@@ -116,6 +139,12 @@
167 signalName: "unlockingAllModems"
168 }
169
170+ SignalSpy {
171+ id: notificationActionSpy
172+ target: mockNotificationsModel
173+ signalName: "actionInvoked"
174+ }
175+
176 Telephony.CallEntry {
177 id: phoneCall
178 phoneNumber: "+447812221111"
179@@ -170,6 +199,65 @@
180 compare(ApplicationManager.count, 1)
181 }
182
183+ function test_snapDecisionDismissalReturnsFocus() {
184+ var notifications = findChild(shell, "notificationList");
185+ var app = ApplicationManager.startApplication("camera-app");
186+ var stage = findChild(shell, "stage")
187+ // Open an application and focus
188+ waitUntilApplicationWindowIsFullyVisible(app);
189+ ApplicationManager.focusApplication(app);
190+ tryCompare(app.session.surface, "activeFocus", true);
191+
192+ notifications.model = mockNotificationsModel;
193+
194+ // FIXME: Hack: SortFilterProxyModelQML doesn't work with QML ListModels which we use
195+ // for mocking here (RoleType can't be found in the QML model). As we only need to show
196+ // one SnapDecision lets just disable the filtering and make appear any notification as a
197+ // SnapDecision.
198+ var snapDecisionProxyModel = findInvisibleChild(shell, "snapDecisionProxyModel");
199+ snapDecisionProxyModel.filterRegExp = RegExp("");
200+
201+ // Pop-up a notification
202+ addSnapDecisionNotification();
203+ waitForRendering(shell);
204+
205+ // Make sure the notification really opened
206+ var notification = findChild(notifications, "notification" + (mockNotificationsModel.count - 1));
207+ verify(notification !== undefined && notification != null, "notification wasn't found");
208+ tryCompare(notification, "height", notification.implicitHeight)
209+ waitForRendering(notification);
210+
211+ // Make sure activeFocus went away from the app window
212+ tryCompare(app.session.surface, "activeFocus", false);
213+ tryCompare(stage, "interactive", false);
214+
215+ // Clicking the button should dismiss the notification and return focus
216+ var buttonAccept = findChild(notification, "notify_button0");
217+ mouseClick(buttonAccept, buttonAccept.width / 2, buttonAccept.height / 2);
218+
219+ // Make sure we're back to normal
220+ tryCompare(app.session.surface, "activeFocus", true);
221+ compare(stage.interactive, true, "Stages not interactive again after modal notification has closed");
222+ }
223+
224+ function addSnapDecisionNotification() {
225+ var n = {
226+ type: Notification.SnapDecision,
227+ hints: {"x-canonical-private-affirmative-tint": "true"},
228+ summary: "Tom Ato",
229+ body: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua.",
230+ icon: "../graphics/avatars/funky.png",
231+ secondaryIcon: "../graphics/applicationIcons/facebook.png",
232+ actions: [{ id: "ok_id", label: "Ok"},
233+ { id: "cancel_id", label: "Cancel"},
234+ { id: "notreally_id", label: "Not really"},
235+ { id: "noway_id", label: "messages:No way"},
236+ { id: "nada_id", label: "messages:Nada"}]
237+ }
238+
239+ mockNotificationsModel.append(n)
240+ }
241+
242 function test_leftEdgeDrag_data() {
243 return [
244 {tag: "without launcher", revealLauncher: false, swipeLength: units.gu(27), appHides: true, focusedApp: "dialer-app", launcherHides: true},

Subscribers

People subscribed via source and target branches

to all changes: