@@ -267,10 +267,10 @@ Rectangle {
267267 function init() {
268268 prepareShell();
269269
270− var tutorialLeft = findChild(shell, "tutorialLeft");
271− var tutorialLeftTimer = findInvisibleChild(tutorialLeft, "tutorialLeftTimer");
272− tutorialLeftTimer.interval = 0;
273− tryCompare(tutorialLeft, "opacity", 1);
270+ var tutorialTop = findChild(shell, "tutorialTop");
271+ var tutorialTopTimer = findInvisibleChild(tutorialTop, "tutorialTopTimer");
272+ tutorialTopTimer.interval = 0;
273+ tryCompare(tutorialTop, "opacity", 1);
274274 }
275275
276276 function cleanup() {
@@ -308,7 +308,6 @@ Rectangle {
308308 tryCompare(shell, "waitingOnGreeter", false); // reset by greeter when ready
309309
310310 WindowStateStorage.clear();
311− //topLevelSurfaceList.inputMethodSurface.setState(Mir.MinimizedState);
312311 callManager.foregroundCall = null;
313312 AccountsService.demoEdges = false;
314313 AccountsService.demoEdgesCompleted = [];
@@ -317,8 +316,6 @@ Rectangle {
317316 LightDM.Greeter.hideGreeter();
318317
319318 stage = findChild(shell, "stage"); // from StageTestCase
320−
321− startApplication("unity8-dash");
322319 }
323320
324321 function loadShell(state) {
@@ -334,37 +331,25 @@ Rectangle {
334331 tryCompareFunction(function() { return topLevelSurfaceList.inputMethodSurface !== null }, true);
335332 }
336333
337− function swipeAwayGreeter() {
338− var coverPage = findChild(shell, "coverPage");
339− tryCompare(coverPage, "showProgress", 1);
340−
341− touchFlick(shell, halfWidth, halfHeight, shell.width, halfHeight);
342−
343− // wait until the animation has finished
344− var greeter = findChild(shell, "greeter");
345− tryCompare(greeter, "required", false);
346− waitForRendering(greeter);
347− }
348−
349− function openTutorialTop() {
334+ function openTutorialLeft() {
335+ var tutorialTopLoader = findChild(shell, "tutorialTopLoader");
350336 var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
351− var tutorialTop = findChild(shell, "tutorialTop");
352− var tutorialTopTimer = findInvisibleChild(tutorialTop, "tutorialTopTimer");
337+ var tutorialLeft = findInvisibleChild(tutorialLeftLoader, "tutorialLeft");
338+ var tutorialLeftTimer = findInvisibleChild(tutorialLeft, "tutorialLeftTimer");
353339
354− tutorialTopTimer.interval = 1;
355− AccountsService.demoEdgesCompleted = ["left"];
340+ tutorialLeftTimer.interval = 1;
341+ AccountsService.demoEdgesCompleted = ["top"];
356342
357− tryCompare(tutorialLeftLoader, "active", false);
358− tryCompare(tutorialTop, "shown", true);
359− tryCompare(tutorialTop, "opacity", 1);
343+ tryCompare(tutorialTopLoader, "active", false);
344+ tryCompare(tutorialLeft, "shown", true);
345+ tryCompare(tutorialLeft, "opacity", 1);
360346 }
361347
362348 function openTutorialLeftLong() {
363349 var tutorialLeftLong = findChild(shell, "tutorialLeftLong");
364350 var tutorialLeftLongTimer = findChild(tutorialLeftLong, "tutorialLeftLongTimer");
365351
366− AccountsService.demoEdgesCompleted = ["left", "top"];
367− ApplicationManager.startApplication("gallery-app");
352+ AccountsService.demoEdgesCompleted = ["top", "left"];
368353
369354 tutorialLeftLongTimer.interval = 1;
370355 tryCompare(tutorialLeftLong, "shown", true);
@@ -372,21 +357,29 @@ Rectangle {
372357 }
373358
374359 function openTutorialRight() {
375− var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
360+ var tutorialLeftLongLoader = findChild(shell, "tutorialLeftLongLoader");
376361 var tutorialRight = findChild(shell, "tutorialRight");
377362 var tutorialRightTimer = findChild(tutorialRight, "tutorialRightTimer");
378363
379− AccountsService.demoEdgesCompleted = ["left", "top", "left-long"];
380− ApplicationManager.startApplication("gallery-app");
364+ AccountsService.demoEdgesCompleted = ["top", "left", "left-long"];
381365 ApplicationManager.startApplication("facebook-webapp");
382− ApplicationManager.startApplication("camera-app");
383366
384− tryCompare(tutorialLeftLoader, "active", false);
367+ tryCompare(tutorialLeftLongLoader, "active", false);
385368 tutorialRightTimer.interval = 1;
386369 tryCompare(tutorialRight, "shown", true);
387370 tryCompare(tutorialRight, "opacity", 1);
388371 }
389372
373+ function longLeftSwipe() {
374+ // Perform a long enough swipe to cause the Drawer to appear
375+ var launcher = findChild(shell, "launcher");
376+ var startX = launcher.dragAreaWidth/2;
377+ var startY = launcher.height/2;
378+ touchFlick(launcher,
379+ startX, startY,
380+ startX+units.gu(35), startY);
381+ }
382+
390383 function test_tutorialLeftEdges() {
391384 var tutorial = findChild(shell, "tutorial");
392385 var tutorialLeft = findChild(tutorial, "tutorialLeft");
@@ -394,6 +387,8 @@ Rectangle {
394387 var stage = findChild(shell, "stage");
395388 var panel = findChild(shell, "panel");
396389
390+ openTutorialLeft();
391+
397392 verify(tutorial.running);
398393 verify(tutorial.launcherEnabled);
399394 verify(!tutorial.spreadEnabled);
@@ -409,10 +404,12 @@ Rectangle {
409404 var tutorialLeftLoader = findChild(tutorial, "tutorialLeftLoader");
410405 var launcher = findChild(shell, "launcher");
411406
407+ openTutorialLeft();
408+
412409 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
413410
414411 tryCompare(tutorialLeftLoader, "shown", false);
415− tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
412+ tryCompare(AccountsService, "demoEdgesCompleted", ["top", "left"]);
416413 tryCompare(launcher, "state", "visible");
417414 }
418415
@@ -424,6 +421,8 @@ Rectangle {
424421 var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
425422 var launcher = findChild(shell, "launcher");
426423
424+ openTutorialLeft();
425+
427426 // Confirm fade during drag
428427 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight, true, false);
429428 // compare opacity with a bound rather than hard 0.6 because progress doesn't
@@ -445,55 +444,65 @@ Rectangle {
445444 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.9, halfHeight);
446445
447446 tryCompare(tutorialLeftLoader, "shown", false);
448− tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
447+ tryCompare(AccountsService, "demoEdgesCompleted", ["top", "left"]);
449448 tryCompare(launcher, "state", "visible");
450449 }
451450
452451 function test_tutorialLeftLongFinish() {
453− AccountsService.demoEdgesCompleted = ["left", "top"];
454−
455− var tutorialLeftLongTimer = findInvisibleChild(shell, "tutorialLeftLongTimer");
456− tutorialLeftLongTimer.interval = 1;
457−
458− ApplicationManager.startApplication("gallery-app");
459−
460452 var tutorialLeftLongLoader = findChild(shell, "tutorialLeftLongLoader");
453+ openTutorialLeftLong();
454+
461455 tryCompare(tutorialLeftLongLoader, "shown", true);
462456
463457 touchFlick(shell, 0, halfHeight, shell.width, halfHeight);
464458
465459 tryCompare(tutorialLeftLongLoader, "shown", false);
466− tryCompare(AccountsService, "demoEdgesCompleted", ["left", "top", "left-long"]);
460+ tryCompare(AccountsService, "demoEdgesCompleted", ["top", "left", "left-long"]);
467461 }
468462
469463 function test_tutorialLeftAutoSkipped() {
470464 // Test that we skip the tutorial if user uses left edge themselves
465+ var launcher = findChild(shell, "launcher");
471466
467+ AccountsService.demoEdgesCompleted = ["top"]
472468 var tutorialLeft = findChild(shell, "tutorialLeft");
473− LightDM.Greeter.showGreeter();
469+ launcher.show();
474470 tryCompare(tutorialLeft, "visible", false);
475− compare(AccountsService.demoEdgesCompleted, []);
471+ compare(AccountsService.demoEdgesCompleted, ["top"]);
476472
477473 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
478− tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
474+ tryCompare(AccountsService, "demoEdgesCompleted", ["top", "left"]);
479475 }
480476
481477 function test_tutorialLongLeftSwipeDisabled() {
482478 // Test that a long left swipe is disabled until we get to or pass
483479 // the long left tutorial.
484480 var tutorial = findChild(shell, "tutorial");
481+ var launcher = findChild(shell, "launcher");
482+ var drawer = findChild(launcher, "drawer");
485483
486− verify(!tutorial.launcherLongSwipeEnabled);
484+ // Waiting for top tutorial, the Launcher should be unavailable
485+ longLeftSwipe();
486+ tryCompare(launcher, "state", "");
487487
488− openTutorialLeftLong();
489− verify(tutorial.launcherLongSwipeEnabled);
488+ // Swipe the left edge far enough to open the Drawer. Only the
489+ // Launcher should appear.
490+ openTutorialLeft();
491+ longLeftSwipe();
492+ tryCompare(launcher, "state", "visible");
490493
491− openTutorialRight();
492− verify(tutorial.launcherLongSwipeEnabled);
494+ // Once the Drawer tutorial is open, the Drawer should appear on
495+ // a long swipe.
496+ openTutorialLeftLong();
497+ longLeftSwipe();
498+ tryCompare(launcher, "state", "drawer");
499+ launcher.hide();
493500
501+ // That should continue after the Tutorial is no more
494502 AccountsService.demoEdges = false;
495503 tryCompare(tutorial, "running", false);
496− verify(tutorial.launcherLongSwipeEnabled);
504+ longLeftSwipe();
505+ tryCompare(launcher, "state", "drawer");
497506 }
498507
499508 function test_tutorialTopEdges() {
@@ -503,8 +512,6 @@ Rectangle {
503512 var stage = findChild(shell, "stage");
504513 var panel = findChild(shell, "panel");
505514
506− openTutorialTop();
507−
508515 tryCompare(tutorial, "running", true);
509516 verify(!tutorial.launcherEnabled);
510517 verify(!tutorial.spreadEnabled);
@@ -520,11 +527,10 @@ Rectangle {
520527 var tutorialTopLoader = findChild(tutorial, "tutorialTopLoader");
521528 var panel = findChild(shell, "panel");
522529
523− openTutorialTop();
524530 touchFlick(shell, halfWidth, 0, halfWidth, shell.height);
525531
526532 tryCompare(tutorialTopLoader, "shown", false);
527− tryCompare(AccountsService, "demoEdgesCompleted", ["left", "top"]);
533+ tryCompare(AccountsService, "demoEdgesCompleted", ["top"]);
528534 tryCompare(panel.indicators, "fullyOpened", true);
529535 }
530536
@@ -533,7 +539,6 @@ Rectangle {
533539 var tutorialTop = findChild(tutorial, "tutorialTop");
534540 var panel = findChild(shell, "panel");
535541
536− openTutorialTop();
537542 touchFlick(shell, halfWidth, 0, halfWidth, shell.height * 0.4, true, false);
538543 // compare opacity with a bound rather than hard 0.6 because progress doesn't
539544 // always match the drag perfectly (takes a moment for drag to kick in)
@@ -545,19 +550,6 @@ Rectangle {
545550 compare(tutorialTop.shown, true);
546551 }
547552
548− function test_tutorialTopAutoSkipped() {
549− // Test that we skip the tutorial if user uses top edge themselves
550−
551− var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
552− var tutorialTopLoader = findChild(shell, "tutorialTopLoader");
553− AccountsService.demoEdgesCompleted = ["left"];
554− tryCompare(tutorialLeftLoader, "active", false);
555− verify(!tutorialTopLoader.shown);
556−
557− touchFlick(shell, halfWidth, 0, halfWidth, shell.height);
558− tryCompare(AccountsService, "demoEdgesCompleted", ["left", "top"]);
559− }
560−
561553 function test_tutorialRightEdges() {
562554 var tutorial = findChild(shell, "tutorial");
563555 var tutorialRight = findChild(tutorial, "tutorialRight");
@@ -581,7 +573,7 @@ Rectangle {
581573 openTutorialRight();
582574 touchFlick(shell, shell.width, halfHeight, 0, halfHeight);
583575
584− tryCompare(AccountsService, "demoEdgesCompleted", ["left", "top", "left-long", "right"]);
576+ tryCompare(AccountsService, "demoEdgesCompleted", ["top", "left", "left-long", "right"]);
585577 tryCompare(AccountsService, "demoEdges", false);
586578 }
587579
@@ -608,13 +600,10 @@ Rectangle {
608600 var tutorialRightLoader = findChild(shell, "tutorialRightLoader");
609601 var tutorialRightTimer = findInvisibleChild(tutorialRightLoader, "tutorialRightTimer");
610602
611− openTutorialTop();
612603 ApplicationManager.startApplication("gallery-app");
613− ApplicationManager.startApplication("facebook-webapp");
614− ApplicationManager.startApplication("camera-app");
615− tryCompare(ApplicationManager, "count", 4);
604+ tryCompare(ApplicationManager, "count", 1);
616605
617− AccountsService.demoEdgesCompleted = ["left", "top", "left-long"];
606+ AccountsService.demoEdgesCompleted = ["top", "left", "left-long"];
618607 verify(tutorialRightTimer.running);
619608 verify(!tutorialRightLoader.shown);
620609 tutorialRightTimer.interval = 1;
@@ -624,18 +613,30 @@ Rectangle {
624613 function test_tutorialRightAutoSkipped() {
625614 // Test that we skip the tutorial if user uses right edge themselves
626615
627− var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
628− AccountsService.demoEdgesCompleted = ["left"];
629− tryCompare(tutorialLeftLoader, "active", false);
616+ var tutorialLeftLongLoader = findChild(shell, "tutorialLeftLongLoader");
617+ var tutorialRight = findChild(shell, "tutorialRight");
618+ var tutorialRightTimer = findChild(tutorialRight, "tutorialRightTimer");
619+
620+ tutorialRightTimer.interval = 9999999;
621+
622+ ApplicationManager.startApplication("facebook-webapp");
623+ tryCompare(ApplicationManager, "count", 1);
624+
625+ AccountsService.demoEdgesCompleted = ["top", "left", "left-long"];
626+ tryCompare(tutorialLeftLongLoader, "skipped", true);
627+ verify(tutorialRightTimer.running);
628+ tryCompare(tutorialRight, "isReady", true);
629+
630+ // If the app isn't fully started, it may interrupt our attempt to swipe
631+ wait(1000);
630632
631633 touchFlick(shell, shell.width, halfHeight, 0, halfHeight);
632− tryCompare(AccountsService, "demoEdgesCompleted", ["left", "right"]);
634+ tryCompare(AccountsService, "demoEdgesCompleted", ["top", "left", "left-long", "right"]);
633635 }
634636
635637 function test_activeCallInterruptsTutorial() {
636638 var tutorialLeft = findChild(shell, "tutorialLeft");
637− verify(tutorialLeft.shown);
638− verify(!tutorialLeft.paused);
639+ openTutorialLeft();
639640
640641 callManager.foregroundCall = phoneCall;
641642 verify(!tutorialLeft.shown);
@@ -648,18 +649,18 @@ Rectangle {
648649 }
649650
650651 function test_greeterInterruptsTutorial() {
651− var tutorialLeft = findChild(shell, "tutorialLeft");
652− verify(tutorialLeft.shown);
653− verify(!tutorialLeft.paused);
652+ var tutorialTop = findChild(shell, "tutorialTop");
653+ verify(tutorialTop.shown);
654+ verify(!tutorialTop.paused);
654655
655656 LightDM.Greeter.showGreeter();
656− verify(!tutorialLeft.shown);
657− verify(tutorialLeft.paused);
658− tryCompare(tutorialLeft, "visible", false);
657+ verify(!tutorialTop.shown);
658+ verify(tutorialTop.paused);
659+ tryCompare(tutorialTop, "visible", false);
659660
660661 LightDM.Greeter.hideGreeter();
661− tryCompare(tutorialLeft, "shown", true);
662− verify(!tutorialLeft.paused);
662+ tryCompare(tutorialTop, "shown", true);
663+ verify(!tutorialTop.paused);
663664 }
664665
665666 function test_interruptionChecksReadyStateWhenDone() {
@@ -682,7 +683,7 @@ Rectangle {
682683 verify(!tutorialRight.isReady);
683684 verify(!tutorialRight.shown);
684685 verify(!tutorialRight.paused);
685− compare(AccountsService.demoEdgesCompleted, ["left", "top", "left-long"]);
686+ compare(AccountsService.demoEdgesCompleted, ["top", "left", "left-long"]);
686687 }
687688
688689 function test_desktopOnlyShowsTutorialRight() {
@@ -701,8 +702,6 @@ Rectangle {
701702 var tutorialRightTimer = findInvisibleChild(tutorialRightLoader, "tutorialRightTimer");
702703 tutorialRightTimer.interval = 1;
703704
704− ApplicationManager.startApplication("dialer-app");
705− ApplicationManager.startApplication("camera-app");
706705 ApplicationManager.startApplication("facebook-webapp");
707706 tryCompare(tutorialRightLoader.item, "isReady", true);
708707
@@ -715,8 +714,6 @@ Rectangle {
715714 var tutorialRightLoader = findChild(shell, "tutorialRightLoader");
716715 var tutorialRightTimer = findInvisibleChild(tutorialRightLoader, "tutorialRightTimer");
717716 tutorialRightTimer.interval = 1;
718− ApplicationManager.startApplication("dialer-app");
719− ApplicationManager.startApplication("camera-app");
720717 ApplicationManager.startApplication("facebook-webapp");
721718 tryCompare(tutorialRightLoader, "shown", true);
722719
@@ -729,8 +726,8 @@ Rectangle {
729726 }
730727
731728 function test_oskDoesNotHideTutorial() {
732− var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
733− verify(tutorialLeftLoader.shown);
729+ var tutorialTopLoader = findChild(shell, "tutorialTopLoader");
730+ verify(tutorialTopLoader.shown);
734731
735732 ensureInputMethodSurface();
736733 var surface = topLevelSurfaceList.inputMethodSurface;
@@ -739,7 +736,7 @@ Rectangle {
739736 var inputMethod = findInvisibleChild(shell, "inputMethod");
740737 tryCompare(inputMethod, "visible", true);
741738
742− verify(tutorialLeftLoader.shown);
739+ verify(tutorialTopLoader.shown);
743740 }
744741
745742 function test_oskDelaysTutorial() {
@@ -775,41 +772,58 @@ Rectangle {
775772 }
776773
777774 function test_delayedTutorial() {
775+ var launcher = findChild(shell, "launcher");
778776 var tutorial = findChild(shell, "tutorial");
779− var tutorialTop = findChild(tutorial, "tutorialTop");
780− var tutorialTopTimer = findChild(tutorialTop, "tutorialTopTimer");
777+ var tutorialLeft = findChild(tutorial, "tutorialLeft");
778+ var tutorialLeftTimer = findChild(tutorial, "tutorialLeftTimer");
779+ // Since we'll be using the Launcher and Drawer, the left tutorial
780+ // will be skipped entirely and we'll show the left long one.
781+ var tutorialLeftLong = findChild(tutorial, "tutorialLeftLong");
782+ var tutorialLeftLongTimer = findChild(tutorialLeftLong, "tutorialLeftLongTimer");
781783
782− // Get top tutorial ready
783− AccountsService.demoEdgesCompleted = ["left"];
784− verify(tutorialTop.isReady);
785− verify(tutorialTopTimer.running);
784+ // Don't need these to start before we're ready
785+ tutorialLeftTimer.interval = 999999;
786+ tutorialLeftLongTimer.interval = 1;
787+
788+ // Get left tutorial ready to be skipped
789+ AccountsService.demoEdgesCompleted = ["top"];
790+ tryCompare(tutorialLeft, "isReady", true);
791+ tryCompare(tutorialLeftTimer, "running", true);
786792
787793 // Confirm that we become unready when delayed, but timer still goes
788794 tutorial.delayed = true;
789− verify(!tutorialTop.isReady);
790− verify(tutorialTopTimer.running);
795+ tryCompare(tutorialLeft, "isReady", false);
796+ tryCompare(tutorialLeftTimer, "running", true);
791797
792798 // Confirm that we don't open the tutorial when delayed
793− tutorialTopTimer.interval = 1;
794− wait(5);
795− verify(!tutorialTop.shown);
799+ tutorialLeftTimer.interval = 1;
800+ wait(500);
801+ verify(!tutorialLeft.shown);
802+
803+ // Confirm the Launcher and Drawer can be opened when delayed
804+ tryCompare(tutorial, "launcherEnabled", true);
805+ tryCompare(tutorial, "launcherLongSwipeEnabled", true);
806+ longLeftSwipe();
807+ tryCompare(launcher, "state", "drawer");
808+ launcher.hide();
796809
797810 // Confirm we go back to normal when undelayed
798811 tutorial.delayed = false;
799− tryCompare(tutorialTop, "shown", true);
812+ tryCompare(tutorialLeftLong, "shown", true);
800813 }
801814
802815 function test_accountsServiceSettings() {
803− var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
804− verify(tutorialLeftLoader.shown);
816+ var tutorial = findChild(shell, "tutorial");
817+ var tutorialTopLoader = findChild(tutorial, "tutorialTopLoader");
818+ verify(tutorialTopLoader.shown);
805819
806820 AccountsService.demoEdges = false;
807− verify(findChild(shell, "tutorialLeftLoader") == null);
821+ verify(findChild(tutorial, "tutorialTopLoader", 1) == null);
808822
809823 AccountsService.demoEdges = true;
810− tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
811− var tutorialLeftTimer = findChild(tutorialLeftLoader, "tutorialLeftTimer");
812− verify(tutorialLeftTimer.running);
824+ tutorialTopLoader = findChild(shell, "tutorialTopLoader");
825+ var tutorialTopTimer = findChild(tutorialTopLoader, "tutorialTopTimer");
826+ verify(tutorialTopTimer.running);
813827 }
814828 }
815829}