Merge lp:~mzanetti/unity/phablet-greeter-tests into lp:unity/phablet

Proposed by Michael Zanetti
Status: Merged
Approved by: Albert Astals Cid
Approved revision: no longer in the source branch.
Merged at revision: 486
Proposed branch: lp:~mzanetti/unity/phablet-greeter-tests
Merge into: lp:unity/phablet
Diff against target: 330 lines (+227/-4)
7 files modified
Greeter/Greeter.qml (+14/-2)
Greeter/GreeterContent.qml (+6/-2)
Greeter/LoginList.qml (+1/-0)
Shell.qml (+4/-0)
tests/qmluitests/CMakeLists.txt (+1/-0)
tests/qmluitests/UnityTestCase.qml (+89/-0)
tests/qmluitests/tst_Greeter.qml (+112/-0)
To merge this branch: bzr merge lp:~mzanetti/unity/phablet-greeter-tests
Reviewer Review Type Date Requested Status
PS Jenkins bot (community) continuous-integration Approve
Albert Astals Cid (community) Approve
Review via email: mp+153963@code.launchpad.net

Commit message

add tests for the greeter

Description of the change

add tests for the greeter

To post a comment you must log in.
Revision history for this message
Albert Astals Cid (aacid) wrote :

Looks good besides the typeString thing, but we will improve Qt to remove it.

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Greeter/Greeter.qml'
2--- Greeter/Greeter.qml 2013-03-13 18:54:11 +0000
3+++ Greeter/Greeter.qml 2013-03-19 12:02:23 +0000
4@@ -24,14 +24,18 @@
5 enabled: shown
6 created: greeterContentLoader.status == Loader.Ready && greeterContentLoader.item.ready
7
8+ property alias model: userList
9 property bool locked: shown && multiUser && !greeterContentLoader.guestAccount
10
11 readonly property bool narrowMode: width <= units.gu(60)
12 readonly property bool multiUser: !narrowMode // TODO: populate with real value
13
14+ signal selected(int uid)
15+ signal unlocked(int uid)
16+
17 ListModel {
18 id: userList
19- ListElement { name: "Guest"; background: "../graphics/tablet_background.jpg" }
20+ ListElement { name: "Guest"; background: "graphics/tablet_background.jpg" }
21 }
22
23 // TODO: Replace with a ModelAggregator once we have one.
24@@ -57,7 +61,7 @@
25 for (var i = 0; i < xmlReader.count; i++) {
26 userList.append(xmlReader.get(i));
27 }
28- userList.append({ "name": "Guest", background: "../graphics/tablet_background.jpg" });
29+ userList.append({ "name": "Guest", background: "graphics/tablet_background.jpg" });
30
31 greeterContentLoader.model = userList;
32 greeterContentLoader.currentIndex = 0;
33@@ -74,5 +78,13 @@
34 property bool guestAccount: item ? item.guestAccount : false
35
36 source: required ? "GreeterContent.qml" : ""
37+
38+
39+ Connections {
40+ target: greeterContentLoader.item
41+
42+ onSelected: greeter.selected(uid);
43+ onUnlocked: greeter.unlocked(uid);
44+ }
45 }
46 }
47
48=== modified file 'Greeter/GreeterContent.qml'
49--- Greeter/GreeterContent.qml 2013-02-28 15:56:55 +0000
50+++ Greeter/GreeterContent.qml 2013-03-19 12:02:23 +0000
51@@ -19,10 +19,14 @@
52 import "../Components"
53
54 MouseArea {
55+ id: root
56 anchors.fill: parent
57
58 property bool guestAccount: loginLoader.status == Loader.Ready && loginLoader.item.guestAccount
59 property bool ready: wallpaper.status == Image.Ready
60+
61+ signal selected(int uid)
62+ signal unlocked(int uid)
63
64 CrossFadeImage {
65 id: wallpaper
66@@ -77,11 +81,11 @@
67 target: loginLoader.item
68
69 onSelected: {
70- shell.background = userList.get(uid).background;
71+ root.selected(uid);
72 }
73
74 onUnlocked: {
75- greeter.hide();
76+ root.unlocked(uid);
77 }
78
79 onCurrentIndexChanged: {
80
81=== modified file 'Greeter/LoginList.qml'
82--- Greeter/LoginList.qml 2013-03-18 21:10:01 +0000
83+++ Greeter/LoginList.qml 2013-03-19 12:02:23 +0000
84@@ -140,6 +140,7 @@
85 }
86
87 delegate: Item {
88+ objectName: "username" + index
89 width: parent.width
90 // Adding 2 gus in height to close gaps in draggable area between items
91 height: (index == userList.currentIndex ? root.highlightedHeight : root.cellHeight) + units.gu(2)
92
93=== modified file 'Shell.qml'
94--- Shell.qml 2013-03-12 12:26:25 +0000
95+++ Shell.qml 2013-03-19 12:02:23 +0000
96@@ -408,6 +408,10 @@
97 height: parent.height - panel.panelHeight
98
99 onShownChanged: if (shown) greeter.forceActiveFocus()
100+
101+ onUnlocked: greeter.hide()
102+ onSelected: shell.background = greeter.model.get(uid).background;
103+
104 }
105
106 Revealer {
107
108=== modified file 'tests/qmluitests/CMakeLists.txt'
109--- tests/qmluitests/CMakeLists.txt 2013-03-15 19:01:53 +0000
110+++ tests/qmluitests/CMakeLists.txt 2013-03-19 12:02:23 +0000
111@@ -23,3 +23,4 @@
112 add_qml_test(DraggingArea)
113 add_qml_test(FilterGrid ${CMAKE_BINARY_DIR}/plugins)
114 add_qml_test(Hud ${CMAKE_CURRENT_BINARY_DIR}/qml)
115+add_qml_test(Greeter)
116
117=== modified file 'tests/qmluitests/UnityTestCase.qml'
118--- tests/qmluitests/UnityTestCase.qml 2013-03-19 09:34:54 +0000
119+++ tests/qmluitests/UnityTestCase.qml 2013-03-19 12:02:23 +0000
120@@ -33,4 +33,93 @@
121 if (releaseMouse)
122 mouseRelease(item, toX, toY)
123 }
124+
125+
126+ // Find an object with the given name recursively, starting
127+ // at the given object "obj"
128+ function findChild(obj,objectName) {
129+ for (var i in obj.children) {
130+ var child = obj.children[i];
131+ if (child.objectName === objectName) return child;
132+ var subChild = findChild(child,objectName);
133+ if (subChild !== undefined) return subChild;
134+ }
135+ return undefined;
136+ }
137+
138+ // Type a full string instead of keyClick letter by letter
139+ // TODO: this is not ugly, this is uber-ugly and does not support
140+ // any special character. Remove the keyMap once keyClick(obj, char)
141+ // has landed in upstream Qt.
142+ function typeString(str) {
143+ var keyMap = {
144+ "a": Qt.Key_A,
145+ "b": Qt.Key_B,
146+ "c": Qt.Key_C,
147+ "d": Qt.Key_D,
148+ "e": Qt.Key_E,
149+ "f": Qt.Key_F,
150+ "g": Qt.Key_G,
151+ "h": Qt.Key_H,
152+ "i": Qt.Key_I,
153+ "j": Qt.Key_J,
154+ "k": Qt.Key_K,
155+ "l": Qt.Key_L,
156+ "m": Qt.Key_M,
157+ "n": Qt.Key_N,
158+ "o": Qt.Key_O,
159+ "p": Qt.Key_P,
160+ "q": Qt.Key_Q,
161+ "r": Qt.Key_R,
162+ "s": Qt.Key_S,
163+ "t": Qt.Key_T,
164+ "u": Qt.Key_U,
165+ "v": Qt.Key_V,
166+ "w": Qt.Key_W,
167+ "x": Qt.Key_X,
168+ "y": Qt.Key_Y,
169+ "z": Qt.Key_Z,
170+ "A": Qt.Key_A,
171+ "B": Qt.Key_B,
172+ "C": Qt.Key_C,
173+ "D": Qt.Key_D,
174+ "E": Qt.Key_E,
175+ "F": Qt.Key_F,
176+ "G": Qt.Key_G,
177+ "H": Qt.Key_H,
178+ "I": Qt.Key_I,
179+ "J": Qt.Key_J,
180+ "K": Qt.Key_K,
181+ "L": Qt.Key_L,
182+ "M": Qt.Key_M,
183+ "N": Qt.Key_N,
184+ "O": Qt.Key_O,
185+ "P": Qt.Key_P,
186+ "Q": Qt.Key_Q,
187+ "R": Qt.Key_R,
188+ "S": Qt.Key_S,
189+ "T": Qt.Key_T,
190+ "U": Qt.Key_U,
191+ "V": Qt.Key_V,
192+ "W": Qt.Key_W,
193+ "X": Qt.Key_X,
194+ "Y": Qt.Key_Y,
195+ "Z": Qt.Key_Z,
196+ "0": Qt.Key_0,
197+ "1": Qt.Key_1,
198+ "2": Qt.Key_2,
199+ "3": Qt.Key_3,
200+ "4": Qt.Key_4,
201+ "5": Qt.Key_5,
202+ "6": Qt.Key_6,
203+ "7": Qt.Key_7,
204+ "8": Qt.Key_8,
205+ "9": Qt.Key_9,
206+ " ": Qt.Key_Space,
207+ }
208+ for (var i = 0; i < str.length; i++) {
209+ keyClick(keyMap[str[i]])
210+ }
211+ }
212+
213 }
214
215=== added file 'tests/qmluitests/tst_Greeter.qml'
216--- tests/qmluitests/tst_Greeter.qml 1970-01-01 00:00:00 +0000
217+++ tests/qmluitests/tst_Greeter.qml 2013-03-19 12:02:23 +0000
218@@ -0,0 +1,112 @@
219+/*
220+ * Copyright 2013 Canonical Ltd.
221+ *
222+ * This program is free software; you can redistribute it and/or modify
223+ * it under the terms of the GNU General Public License as published by
224+ * the Free Software Foundation; version 3.
225+ *
226+ * This program is distributed in the hope that it will be useful,
227+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
228+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
229+ * GNU General Public License for more details.
230+ *
231+ * You should have received a copy of the GNU General Public License
232+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
233+ */
234+
235+import QtQuick 2.0
236+import QtTest 1.0
237+import "../../Greeter"
238+import Ubuntu.Components 0.1
239+
240+Item {
241+ width: units.gu(120)
242+ height: units.gu(80)
243+ UnityTestCase {
244+ name: "GreeterTest"
245+ when: windowShown
246+
247+ function test_cycle_data() {
248+ var data = new Array()
249+ for (var i = 1; i < greeter.model.count; i++) {
250+ data[i] = {tag: greeter.model.get(i).name, username: "username"+i, uid: i }
251+ }
252+ data[greeter.model.count] = {tag: greeter.model.get(0).name, username: "username0", uid: 0 }
253+ return data
254+ }
255+
256+ function test_cycle(data) {
257+ selectionSpy.clear();
258+ var user = findChild(greeter, data.username)
259+ mouseClick(user, user.width / 2, user.height / 2)
260+ var pathview = findChild(greeter, "userList")
261+ tryCompare(pathview, "currentIndex", data.uid)
262+ tryCompare(greeter, "locked", greeter.model.get(data.uid).password !== undefined)
263+ selectionSpy.wait()
264+ compare(selectionSpy.count, 1)
265+ }
266+
267+ function test_unlock_password() {
268+ unlockSpy.clear()
269+ // First one is Lolas account right now. Replace with password protected user from lightdm
270+ var account = findChild(greeter, "username1")
271+ mouseClick(account, 1, 1)
272+ account = findChild(greeter, "username0")
273+ mouseClick(account, 1, 1)
274+ var passwordInput = findChild(greeter, "passwordInput")
275+ tryCompare(passwordInput, "opacity", 0)
276+ tryCompare(passwordInput, "opacity", 1)
277+ mouseClick(passwordInput, 1, 1)
278+ compare(unlockSpy.count, 0)
279+ typeString(greeter.model.get(0).password)
280+ keyClick(Qt.Key_Enter)
281+ unlockSpy.wait()
282+ }
283+
284+ function test_unlock_wrong_password() {
285+ unlockSpy.clear()
286+ // First one is Lolas account right now. Replace with password protected user from lightdm
287+ var account = findChild(greeter, "username1")
288+ mouseClick(account, 1, 1)
289+ account = findChild(greeter, "username0")
290+ mouseClick(account, 1, 1)
291+ var passwordInput = findChild(greeter, "passwordInput")
292+ tryCompare(passwordInput, "opacity", 0)
293+ tryCompare(passwordInput, "opacity", 1)
294+ mouseClick(passwordInput, 1, 1)
295+ compare(unlockSpy.count, 0)
296+ typeString("wr0ng p4ssw0rd")
297+ keyClick(Qt.Key_Enter)
298+ compare(unlockSpy.count, 0)
299+ }
300+
301+ function test_unlock_no_password() {
302+ unlockSpy.clear()
303+ // Last one is the guest account for now. Replace with passwordless user from lightdm
304+ var guestAccount = findChild(greeter, "username" + (greeter.model.count - 1))
305+ mouseClick(guestAccount, guestAccount.width / 2, guestAccount.height / 2)
306+ var passwordInput = findChild(greeter, "passwordInput")
307+ tryCompare(passwordInput, "opacity", 1)
308+ mouseClick(passwordInput, 1, 1)
309+ unlockSpy.wait()
310+ compare(unlockSpy.count, 1)
311+ }
312+ }
313+
314+ Greeter {
315+ id: greeter
316+ anchors.fill: parent
317+ }
318+
319+ SignalSpy {
320+ id: unlockSpy
321+ target: greeter
322+ signalName: "unlocked"
323+ }
324+
325+ SignalSpy {
326+ id: selectionSpy
327+ target: greeter
328+ signalName: "selected"
329+ }
330+}

Subscribers

People subscribed via source and target branches