2 * Copyright (C) 2014-2015 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/>.
18import Ubuntu.Components 1.3
20import AccountsService 0.1
22import IntegratedLightDM 0.1 as LightDM
23import Ubuntu.SystemImage 0.1
24import Ubuntu.Telephony 0.1 as Telephony
25import Unity.Application 0.1
26import Unity.Test 0.1 as UT
33 width: contentRow.width
34 height: contentRow.height
36 Component.onCompleted: {
37 // must set the mock mode before loading the Shell
38 LightDM.Greeter.mockMode = "single-pin";
39 LightDM.Users.mockMode = "single-pin";
40 shellLoader.active = true;
44 id: applicationArguments
46 function hasGeometry() {
69 property bool itemDestroyed: false
70 sourceComponent: Component {
72 Component.onDestruction: {
73 shellLoader.itemDestroyed = true
82 height: shellLoader.height
85 anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
88 anchors { left: parent.left; right: parent.right }
90 onClicked: LightDM.Greeter.showGreeter()
98 id: maxRetriesTextField
101 var greeter = testCase.findChild(shellLoader.item, "greeter");
102 greeter.maxFailedLogins = text;
111 signalName: "sessionStarted"
117 signalName: "resettingDevice"
122 target: LightDM.Greeter
123 signalName: "showPrompt"
126 Telephony.CallEntry {
128 phoneNumber: "+447812221111"
136 property Item shell: shellLoader.status === Loader.Ready ? shellLoader.item : null
139 tryCompare(shell, "enabled", true); // will be enabled when greeter is all ready
140 var greeter = findChild(shell, "greeter");
141 sessionSpy.target = greeter;
142 swipeAwayGreeter(true);
144 greeter.failedLoginsDelayAttempts = -1;
145 greeter.maxFailedLogins = -1;
149 tryCompare(shell, "enabled", true); // make sure greeter didn't leave us in disabled state
151 shellLoader.itemDestroyed = false
153 shellLoader.active = false
155 tryCompare(shellLoader, "status", Loader.Null)
156 tryCompare(shellLoader, "item", null)
157 // Loader.status might be Loader.Null and Loader.item might be null but the Loader
158 // item might still be alive. So if we set Loader.active back to true
159 // again right now we will get the very same Shell instance back. So no reload
160 // actually took place. Likely because Loader waits until the next event loop
161 // iteration to do its work. So to ensure the reload, we will wait until the
162 // Shell instance gets destroyed.
163 tryCompare(shellLoader, "itemDestroyed", true)
165 // kill all (fake) running apps
168 AccountsService.enableLauncherWhileLocked = true
169 AccountsService.enableIndicatorsWhileLocked = true
170 AccountsService.demoEdges = false
171 callManager.foregroundCall = null
172 LightDM.Greeter.authenticate(""); // reset greeter
174 // reload our test subject to get it in a fresh state once again
175 shellLoader.active = true
177 tryCompare(shellLoader, "status", Loader.Ready)
178 removeTimeConstraintsFromDirectionalDragAreas(shellLoader.item)
181 function killApps() {
182 while (ApplicationManager.count > 1) {
183 var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0
184 ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId);
186 compare(ApplicationManager.count, 1)
189 function swipeAwayGreeter(waitForCoverPage) {
190 var greeter = findChild(shell, "greeter");
191 waitForRendering(greeter)
192 var coverPage = findChild(shell, "coverPage");
193 tryCompare(coverPage, "showProgress", 1);
195 var touchX = shell.width - (shell.edgeSize / 2);
196 var touchY = shell.height / 2;
197 touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY);
199 if (waitForCoverPage) {
200 // wait until the animation has finished
201 var coverPage = findChild(shell, "coverPage");
202 tryCompare(coverPage, "showProgress", 0);
206 function waitForLockscreen() {
207 var lockscreen = findChild(shell, "lockscreen");
208 var pinPadLoader = findChild(lockscreen, "pinPadLoader");
209 tryCompare(pinPadLoader, "status", Loader.Ready)
210 waitForRendering(lockscreen)
213 function enterPin(pin) {
214 for (var i = 0; i < pin.length; ++i) {
215 var character = pin.charAt(i)
216 var button = findChild(shell, "pinPadButton" + character)
217 tryCompare(button, "enabled", true);
222 function confirmLockedApp(app) {
223 var greeter = findChild(shell, "greeter")
224 tryCompare(greeter, "shown", false)
225 tryCompare(greeter, "hasLockedApp", true)
226 tryCompare(greeter, "lockedApp", app)
227 tryCompare(LightDM.Greeter, "active", true)
228 tryCompare(ApplicationManager, "focusedApplicationId", app)
231 function test_greeterChangesIndicatorProfile() {
232 skip("Not supported yet, waiting on design for new settings panel");
234 var panel = findChild(shell, "panel");
235 tryCompare(panel.indicators.indicatorsModel, "profile", shell.indicatorProfile + "_greeter");
237 LightDM.Greeter.hideGreeter();
238 tryCompare(panel.indicators.indicatorsModel, "profile", shell.indicatorProfile);
240 LightDM.Greeter.showGreeter();
241 tryCompare(panel.indicators.indicatorsModel, "profile", shell.indicatorProfile + "_greeter");
243 LightDM.Greeter.hideGreeter();
244 tryCompare(panel.indicators.indicatorsModel, "profile", shell.indicatorProfile);
247 function test_login() {
249 tryCompare(sessionSpy, "count", 0)
251 tryCompare(sessionSpy, "count", 1)
254 function test_edgeDemoHidesLockscreen() {
255 LightDM.Greeter.showGreeter()
257 var lockscreen = findChild(shell, "lockscreen")
259 tryCompare(lockscreen, "shown", true)
260 AccountsService.demoEdges = true
261 tryCompare(lockscreen, "shown", false)
263 var greeter = findChild(shell, "greeter");
264 swipeAwayGreeter(false);
265 tryCompare(greeter, "shown", false);
266 tryCompare(sessionSpy, "count", 1)
268 // Lockscreen is only hidden by the edge demo, so if we turn that
269 // off and show greeter again, lockscreen should appear
270 AccountsService.demoEdges = false
271 LightDM.Greeter.showGreeter()
272 lockscreen = findChild(shell, "lockscreen");
273 tryCompare(lockscreen, "shown", true)
276 function test_disabledEdges() {
277 var launcher = findChild(shell, "launcher")
278 tryCompare(launcher, "available", true)
279 AccountsService.enableLauncherWhileLocked = false
280 tryCompare(launcher, "available", false)
282 var indicators = findChild(shell, "indicators")
283 tryCompare(indicators, "available", true)
284 AccountsService.enableIndicatorsWhileLocked = false
285 tryCompare(indicators, "available", false)
288 function test_emergencyCall() {
289 var greeter = findChild(shell, "greeter")
290 var panel = findChild(shell, "panel")
291 var indicators = findChild(shell, "indicators")
292 var launcher = findChild(shell, "launcher")
293 var stage = findChild(shell, "stage")
295 tap(findChild(greeter, "emergencyCallLabel"));
297 tryCompare(greeter, "lockedApp", "dialer-app")
298 tryCompare(greeter, "hasLockedApp", true)
299 tryCompare(greeter, "shown", false);
300 tryCompare(panel, "fullscreenMode", true)
301 tryCompare(indicators, "available", false)
302 tryCompare(launcher, "available", false)
303 tryCompare(stage, "spreadEnabled", false)
305 // Cancel emergency mode, and go back to normal
306 waitForRendering(greeter)
307 LightDM.Greeter.showGreeter()
309 tryCompare(greeter, "shown", true)
310 tryCompare(greeter, "lockedApp", "")
311 tryCompare(greeter, "hasLockedApp", false)
312 tryCompare(greeter, "fullyShown", true);
313 tryCompare(panel, "fullscreenMode", false)
314 tryCompare(indicators, "available", true)
315 tryCompare(launcher, "available", true)
316 tryCompare(stage, "spreadEnabled", false)
319 function test_emergencyCallCrash() {
320 var greeter = findChild(shell, "greeter");
321 var emergencyButton = findChild(greeter, "emergencyCallLabel");
324 tryCompare(greeter, "shown", false);
325 killApps() // kill dialer-app, as if it crashed
326 tryCompare(greeter, "shown", true);
327 tryCompare(findChild(greeter, "lockscreen"), "shown", true);
328 tryCompare(findChild(greeter, "coverPage"), "shown", false);
331 function test_emergencyCallAppLaunch() {
332 var greeter = findChild(shell, "greeter");
333 var emergencyButton = findChild(greeter, "emergencyCallLabel");
336 tryCompare(greeter, "shown", false);
337 ApplicationManager.startApplication("gallery-app", ApplicationManager.NoFlag)
338 tryCompare(greeter, "shown", true);
341 function test_failedLoginsCount() {
342 AccountsService.failedLogins = 0
345 tryCompare(AccountsService, "failedLogins", 1)
348 tryCompare(AccountsService, "failedLogins", 0)
351 function test_wrongEntries() {
352 var greeter = findChild(shell, "greeter");
353 greeter.failedLoginsDelayAttempts = 3;
355 var placeHolder = findChild(shell, "wrongNoticeLabel")
356 tryCompare(placeHolder, "text", "")
359 tryCompare(placeHolder, "text", "Sorry, incorrect passcode")
362 tryCompare(placeHolder, "text", "Sorry, incorrect passcode")
364 var lockscreen = findChild(shell, "lockscreen")
365 tryCompare(lockscreen, "delayMinutes", 0)
367 tryCompare(lockscreen, "delayMinutes", greeter.failedLoginsDelayMinutes);
370 function test_factoryReset() {
371 maxRetriesTextField.text = "3"
376 tryCompareFunction(function() {return findChild(root, "infoPopup") !== null}, true)
378 var dialog = findChild(root, "infoPopup")
379 var button = findChild(dialog, "infoPopupOkButton")
381 tryCompareFunction(function() {return findChild(root, "infoPopup")}, null)
383 tryCompare(resetSpy, "count", 0)
385 tryCompare(resetSpy, "count", 1)
388 function test_emergencyDialerLockOut() {
389 // This is a theoretical attack on the lockscreen: Enter emergency
390 // dialer mode on a phone, then plug into a larger screen,
391 // switching to a tablet interface. This would in theory move the
392 // dialer to a side stage and give access to other apps. So just
393 // confirm that such an attack doesn't work.
395 var applicationsDisplayLoader = findChild(shell, "applicationsDisplayLoader")
397 // We start in phone mode
398 compare(shell.usageScenario, "phone");
399 compare(applicationsDisplayLoader.usageScenario, "phone");
401 var lockscreen = findChild(shell, "lockscreen")
402 lockscreen.emergencyCall()
403 confirmLockedApp("dialer-app")
405 // OK, we're in. Now try (but fail) to switch to tablet mode
406 shell.usageScenario = "tablet";
407 compare(applicationsDisplayLoader.usageScenario, "phone");
409 // And when we kill the app, we go back to locked tablet mode
411 var greeter = findChild(shell, "greeter")
412 tryCompare(greeter, "fullyShown", true)
413 compare(applicationsDisplayLoader.usageScenario, "tablet");
416 function test_emergencyDialerIncoming() {
417 callManager.foregroundCall = phoneCall
418 confirmLockedApp("dialer-app")
421 function test_emergencyDialerActiveCallPanel() {
422 // Make sure that the following sequence works:
423 // - Enter emergency mode call
424 // - Return to greeter
425 // - Click on active call panel
426 // - Should be back in emergency mode dialer
428 var greeter = findChild(shell, "greeter");
429 var lockscreen = findChild(shell, "lockscreen");
431 lockscreen.emergencyCall();
432 confirmLockedApp("dialer-app");
433 callManager.foregroundCall = phoneCall;
435 LightDM.Greeter.showGreeter();
436 tryCompare(lockscreen, "shown", true);
437 tryCompare(greeter, "hasLockedApp", false);
439 // simulate a callHint press, the real thing requires dialer: url support
440 ApplicationManager.requestFocusApplication("dialer-app");
442 confirmLockedApp("dialer-app");
445 function test_normalDialerActiveCallPanel() {
446 // Make sure that the following sequence works:
450 // - Click on active call panel
451 // - Should be back in normal dialer
452 // (we've had a bug where we locked screen in this case)
454 var greeter = findChild(shell, "greeter");
455 var panel = findChild(shell, "panel");
458 tryCompare(greeter, "shown", false);
459 tryCompare(LightDM.Greeter, "active", false);
461 ApplicationManager.startApplication("dialer-app", ApplicationManager.NoFlag);
462 tryCompare(ApplicationManager, "focusedApplicationId", "dialer-app");
463 callManager.foregroundCall = phoneCall;
465 ApplicationManager.requestFocusApplication("unity8-dash");
466 tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash");
467 tryCompare(panel.callHint, "visible", true);
469 // simulate a callHint press, the real thing requires dialer: url support
470 ApplicationManager.requestFocusApplication("dialer-app");
472 tryCompare(ApplicationManager, "focusedApplicationId", "dialer-app");
473 tryCompare(greeter, "shown", false);
474 tryCompare(LightDM.Greeter, "active", false);
477 function test_focusRequestedHidesCoverPage() {
478 LightDM.Greeter.showGreeter();
480 var app = ApplicationManager.startApplication("gallery-app");
481 // wait until the app is fully loaded (ie, real surface replaces splash screen)
482 tryCompareFunction(function() { return app.session !== null && app.session.lastSurface !== null }, true);
484 // New app hides coverPage?
485 var greeter = findChild(shell, "greeter");
486 var coverPage = testCase.findChild(shell, "coverPage");
487 tryCompare(coverPage, "showProgress", 0);
488 tryCompare(greeter, "fullyShown", true);
490 LightDM.Greeter.showGreeter();
491 tryCompare(coverPage, "showProgress", 1);
493 // Make sure focusing same app triggers same behavior
494 ApplicationManager.requestFocusApplication("gallery-app");
495 tryCompare(coverPage, "showProgress", 0);
496 tryCompare(greeter, "fullyShown", true);
499 function test_suspend() {
500 var greeter = findChild(shell, "greeter");
501 var applicationsDisplayLoader = findChild(shell, "applicationsDisplayLoader")
504 Powerd.setStatus(Powerd.Off, Powerd.Unknown);
506 // If locked, applicationsDisplayLoader.item.suspended should be true
507 tryCompare(applicationsDisplayLoader.item, "suspended", true);
510 Powerd.setStatus(Powerd.On, Powerd.Unknown);
511 tryCompare(greeter, "fullyShown", true);
513 // Swipe away greeter to focus app
514 swipeAwayGreeter(true);
516 // We have a lockscreen, make sure we're still suspended
517 tryCompare(applicationsDisplayLoader.item, "suspended", true);
521 // Now that the lockscreen has gone too, make sure we're waking up
522 tryCompare(applicationsDisplayLoader.item, "suspended", false);
526 /* We had a bug (1395075) where if a user kept swiping as the greeter
527 loaded, they would be able to get into the session before the
528 lockscreen appeared. Make sure that doesn't happen. */
529 function test_earlyDisable() {
530 // Kill current shell
531 shellLoader.itemDestroyed = false;
532 shellLoader.active = false;
533 tryCompare(shellLoader, "itemDestroyed", true);
534 LightDM.Greeter.authenticate(""); // reset greeter
538 shellLoader.active = true;
539 tryCompareFunction(function() {return shell !== null}, true);
541 // Confirm that we start disabled
542 compare(promptSpy.count, 0);
543 verify(!shell.enabled);
545 // And that we only become enabled once the lockscreen is up
546 tryCompare(shell, "enabled", true);
547 verify(promptSpy.count > 0);
548 var lockscreen = findChild(shell, "lockscreen");
549 verify(lockscreen.shown);
553 Regression test for https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1393447
555 Do a left edge drag that is long enough to start displacing the greeter
556 but short engough so that the greeter comes back into place once the
559 In this situation the launcher should remaing fully shown and hide itself
560 only after its idle timeout is triggered.
562 function test_shortLeftEdgeSwipeMakesLauncherStayVisible() {
563 LightDM.Greeter.showGreeter();
564 var coverPage = testCase.findChild(shell, "coverPage");
565 tryCompare(coverPage, "showProgress", 1);
567 var launcher = testCase.findChild(shell, "launcher")
569 var dismissTimer = testCase.findInvisibleChild(launcher, "dismissTimer");
570 // effectively disable the dismiss timer
571 dismissTimer.interval = 24 * 60 * 60 * 1000 // 24 hours
573 var launcherPanel = testCase.findChild(launcher, "launcherPanel");
575 var toX = shell.width * 0.45;
577 1 /* fromX */, shell.height * 0.5 /* fromY */,
578 toX /* toX */, shell.height * 0.5 /* toY */,
579 true /* beginTouch */, false /* endTouch */,
582 // Launcher must be fully shown by now
583 tryCompare(launcherPanel, "x", 0);
585 // Greeter should be displaced
586 tryCompareFunction(function() { return coverPage.mapToItem(shell, 0, 0).x > shell.width*0.2; }, true);
588 touchRelease(shell, toX, shell.height * 0.5);
590 // Upon release the greeter should have slid back into full view
591 tryCompareFunction(function() { return coverPage.mapToItem(shell, 0, 0).x === 0; }, true);
593 // And the launcher should stay fully shown
594 for (var i = 0; i < 10; ++i) {
596 compare(launcherPanel.x, 0);
600 function test_longLeftEdgeDrags() {
601 var coverPage = findChild(shell, "coverPage");
602 var lockscreen = findChild(shell, "lockscreen");
603 var launcher = findChild(shell, "launcherPanel");
604 ApplicationManager.startApplication("gallery-app");
605 tryCompare(ApplicationManager, "focusedApplicationId", "gallery-app");
608 LightDM.Greeter.showGreeter();
609 tryCompare(coverPage, "showProgress", 1);
611 // Swipe cover page away
612 touchFlick(shell, 2, shell.height / 2, units.gu(30), shell.height / 2);
613 tryCompare(launcher, "x", -launcher.width);
614 tryCompare(coverPage, "showProgress", 0);
615 compare(lockscreen.shown, true);
616 compare(ApplicationManager.focusedApplicationId, "gallery-app");
618 // Now attempt a swipe on lockscreen
619 touchFlick(shell, 2, shell.height / 2, units.gu(30), shell.height / 2);
620 tryCompare(launcher, "x", 0);
621 compare(lockscreen.shown, true);
622 compare(ApplicationManager.focusedApplicationId, "gallery-app");
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list