@@ -0,0 +1,362 @@
2+ * Copyright (C) 2013,2014 Canonical, Ltd.
4+ * This program is free software; you can redistribute it and/or modify
5+ * it under the terms of the GNU General Public License as published by
6+ * the Free Software Foundation; version 3.
8+ * This program is distributed in the hope that it will be useful,
9+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
10+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11+ * GNU General Public License for more details.
13+ * You should have received a copy of the GNU General Public License
14+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
19+import AccountsService 0.1
21+import LightDM 0.1 as LightDM
22+import Ubuntu.Components 1.1
23+import Ubuntu.Telephony 0.1 as Telephony
24+import Unity.Application 0.1
25+import Unity.Connectivity 0.1
38+ target: MouseTouchAdaptor
43+ Component.onCompleted: {
44+ // must set the mock mode before loading the Shell
45+ LightDM.Greeter.mockMode = "full";
46+ LightDM.Users.mockMode = "full";
48+ // ensures apps which are tested decorations are in view.
49+ WindowStateStorage.geometry = {
50+ 'unity8-dash': Qt.rect(0, units.gu(3), units.gu(50), units.gu(40)),
51+ 'dialer-app': Qt.rect(units.gu(51), units.gu(3), units.gu(50), units.gu(40)),
52+ 'camera-app': Qt.rect(0, units.gu(44), units.gu(50), units.gu(40)),
55+ shellLoader.active = true;
59+ id: applicationArguments
61+ function hasGeometry() {
81+ height: parent.height
83+ property bool itemDestroyed: false
84+ sourceComponent: Component {
86+ usageMode: "Windowed"
87+ property string indicatorProfile: "desktop"
89+ Component.onDestruction: {
90+ shellLoader.itemDestroyed = true
99+ height: parent.height
102+ anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
103+ spacing: units.gu(1)
105+ text: "Show Greeter"
107+ if (shellLoader.status !== Loader.Ready)
110+ var greeter = testCase.findChild(shellLoader.item, "greeter")
111+ if (!greeter.shown) {
119+ model: ApplicationManager.availableApplications()
124+ height: childrenRect.height
128+ enabled: modelData != "unity8-dash"
129+ property var application: null
131+ Component.onCompleted: {
132+ application = ApplicationManager.findApplication(modelData);
136+ target: ApplicationManager
138+ appColumn.application = ApplicationManager.findApplication(modelData);
145+ if (checked) ApplicationManager.startApplication(modelData);
146+ else ApplicationManager.stopApplication(modelData);
151+ value: appColumn.application != null
156+ text: appColumn.application ? appColumn.application.name : modelData
167+ signalName: "sessionStarted"
171+ id: dashCommunicatorSpy
172+ signalName: "setCurrentScopeCalled"
176+ id: unlockAllModemsSpy
177+ target: Connectivity
178+ signalName: "unlockingAllModems"
183+ name: "DesktopShell"
186+ property Item shell: shellLoader.status === Loader.Ready ? shellLoader.item : null
189+ tryCompare(shell, "enabled", true); // will be enabled when greeter is all ready
190+ var userList = findChild(shell, "userList");
191+ tryCompare(userList, "movingInternally", false);
193+ sessionSpy.target = findChild(shell, "greeter")
194+ dashCommunicatorSpy.target = findInvisibleChild(shell, "dashCommunicator")
197+ function cleanup() {
198+ tryCompare(shell, "enabled", true); // make sure greeter didn't leave us in disabled state
200+ shellLoader.itemDestroyed = false
202+ shellLoader.active = false
204+ tryCompare(shellLoader, "status", Loader.Null)
205+ tryCompare(shellLoader, "item", null)
206+ // Loader.status might be Loader.Null and Loader.item might be null but the Loader
207+ // item might still be alive. So if we set Loader.active back to true
208+ // again right now we will get the very same Shell instance back. So no reload
209+ // actually took place. Likely because Loader waits until the next event loop
210+ // iteration to do its work. So to ensure the reload, we will wait until the
211+ // Shell instance gets destroyed.
212+ tryCompare(shellLoader, "itemDestroyed", true)
214+ // kill all (fake) running apps
217+ unlockAllModemsSpy.clear()
218+ AccountsService.demoEdges = false
219+ LightDM.Greeter.authenticate(""); // reset greeter
221+ // reload our test subject to get it in a fresh state once again
222+ shellLoader.active = true
224+ tryCompare(shellLoader, "status", Loader.Ready)
225+ removeTimeConstraintsFromDirectionalDragAreas(shellLoader.item)
228+ function killApps() {
229+ while (ApplicationManager.count > 1) {
230+ var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0
231+ ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId)
233+ compare(ApplicationManager.count, 1)
236+ function selectIndex(i) {
237+ // We could be anywhere in list; find target index to know which direction
238+ var greeter = findChild(shell, "greeter")
239+ var userlist = findChild(greeter, "userList")
240+ if (userlist.currentIndex == i)
241+ keyClick(Qt.Key_Escape) // Reset state if we're not moving
242+ while (userlist.currentIndex != i) {
243+ var next = userlist.currentIndex + 1
244+ if (userlist.currentIndex > i) {
245+ next = userlist.currentIndex - 1
247+ tap(findChild(greeter, "username"+next));
248+ tryCompare(userlist, "currentIndex", next)
249+ tryCompare(userlist, "movingInternally", false)
253+ function selectUser(name) {
254+ // Find index of user with the right name
255+ for (var i = 0; i < LightDM.Users.count; i++) {
256+ if (LightDM.Users.data(i, LightDM.UserRoles.NameRole) == name) {
260+ if (i == LightDM.Users.count) {
261+ fail("Didn't find name")
268+ function clickPasswordInput(isButton) {
269+ var greeter = findChild(shell, "greeter")
270+ tryCompare(greeter, "fullyShown", true);
272+ var passwordMouseArea = findChild(shell, "passwordMouseArea")
273+ tryCompare(passwordMouseArea, "enabled", isButton)
275+ var passwordInput = findChild(shell, "passwordInput")
276+ mouseClick(passwordInput)
279+ function confirmLoggedIn(loggedIn) {
280+ var greeter = findChild(shell, "greeter");
281+ tryCompare(greeter, "shown", loggedIn ? false : true);
282+ verify(loggedIn ? sessionSpy.count > 0 : sessionSpy.count === 0);
285+ function swipeFromLeftEdge(swipeLength) {
287+ var touchStartY = shell.height / 2
288+ touchFlick(shell, touchStartX, touchStartY, swipeLength, touchStartY)
291+ function waitUntilAppSurfaceShowsUp(appId) {
292+ var appWindow = findChild(shell, "appWindow_" + appId);
294+ var appWindowStates = findInvisibleChild(appWindow, "applicationWindowStateGroup");
295+ verify(appWindowStates);
296+ tryCompare(appWindowStates, "state", "surface");
299+ function startApplication(appId) {
300+ var app = ApplicationManager.findApplication(appId);
302+ app = ApplicationManager.startApplication(appId);
305+ waitUntilAppSurfaceShowsUp(appId);
306+ verify(app.session.surface);
310+ function test_appFocusSwitch_data() {
312+ {tag: "dash", apps: [ "unity8-dash", "dialer-app", "camera-app" ], focusfrom: 0, focusTo: 1 },
313+ {tag: "dash", apps: [ "unity8-dash", "dialer-app", "camera-app" ], focusfrom: 1, focusTo: 0 },
317+ function test_appFocusSwitch(data) {
318+ selectUser("no-password");
319+ clickPasswordInput(true)
320+ confirmLoggedIn(true);
323+ for (i = 0; i < data.apps.length; i++) {
324+ startApplication(data.apps[i]);
327+ ApplicationManager.requestFocusApplication(data.apps[data.focusfrom]);
328+ tryCompare(ApplicationManager.findApplication(data.apps[data.focusfrom]).session.surface, "activeFocus", true);
330+ ApplicationManager.requestFocusApplication(data.apps[data.focusTo]);
331+ tryCompare(ApplicationManager.findApplication(data.apps[data.focusTo]).session.surface, "activeFocus", true);
334+ function test_decorationPressFocusesApplication_data() {
336+ {tag: "dash", apps: [ "unity8-dash", "dialer-app", "camera-app" ], focusfrom: 0, focusTo: 1 },
337+ {tag: "dash", apps: [ "unity8-dash", "dialer-app", "camera-app" ], focusfrom: 1, focusTo: 0 },
341+ function test_decorationPressFocusesApplication(data) {
342+ selectUser("no-password");
343+ clickPasswordInput(true)
344+ confirmLoggedIn(true);
347+ for (i = 0; i < data.apps.length; i++) {
348+ startApplication(data.apps[i]);
351+ var fromAppDecoration = findChild(shell, "appWindowDecoration_" + data.apps[data.focusfrom]);
352+ verify(fromAppDecoration);
353+ mouseClick(fromAppDecoration);
354+ tryCompare(ApplicationManager.findApplication(data.apps[data.focusfrom]).session.surface, "activeFocus", true);
356+ var toAppDecoration = findChild(shell, "appWindowDecoration_" + data.apps[data.focusTo]);
357+ verify(toAppDecoration);
358+ mouseClick(toAppDecoration);
359+ tryCompare(ApplicationManager.findApplication(data.apps[data.focusTo]).session.surface, "activeFocus", true);