on dbb8563 help sign in
unity8/tests/qmltests/Tutorial/tst_Tutorial.qml
826 lines 33 kB history raw
1/*
2 * Copyright (C) 2013,2014,2015 Canonical, Ltd.
3 *
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.
7 *
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.
12 *
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/>.
15 */
17import QtQuick 2.4
18import QtTest 1.0
19import AccountsService 0.1
20import IntegratedLightDM 0.1 as LightDM
21import Ubuntu.Components 1.3
22import Ubuntu.Components.ListItems 1.3
23import Ubuntu.Telephony 0.1 as Telephony
24import Unity.Application 0.1
25import Unity.Test 0.1 as UT
26import Utils 0.1
28import "../../../qml"
29import "../../../qml/Components"
31Rectangle {
32 id: root
33 color: UbuntuColors.lightGrey
34 width: units.gu(100) + buttons.width
35 height: units.gu(71)
37 QtObject {
38 id: applicationArguments
40 function hasGeometry() {
41 return false;
42 }
44 function width() {
45 return 0;
46 }
48 function height() {
49 return 0;
50 }
51 }
53 Telephony.CallEntry {
54 id: phoneCall
55 phoneNumber: "+447812221111"
56 }
58 Component.onCompleted: {
59 // must set the mock mode before loading the Shell
60 LightDM.Greeter.mockMode = "single-pin";
61 LightDM.Users.mockMode = "single-pin";
62 shellLoader.active = true;
63 }
65 Item {
66 id: shellContainer
67 anchors.left: root.left
68 anchors.right: buttons.left
69 anchors.top: root.top
70 anchors.bottom: root.bottom
72 Loader {
73 id: shellLoader
75 active: false
76 anchors.horizontalCenter: parent.horizontalCenter
77 anchors.top: parent.top
78 anchors.bottom: parent.bottom
80 property int shellOrientation: Qt.PortraitOrientation
81 property int nativeOrientation: Qt.PortraitOrientation
82 property int primaryOrientation: Qt.PortraitOrientation
84 state: modeSelector.model[modeSelector.selectedIndex]
85 states: [
86 State {
87 name: "phone"
88 PropertyChanges {
89 target: shellLoader
90 width: units.gu(40)
91 }
92 },
93 State {
94 name: "tablet"
95 PropertyChanges {
96 target: shellLoader
97 width: units.gu(100)
98 shellOrientation: Qt.LandscapeOrientation
99 nativeOrientation: Qt.LandscapeOrientation
100 primaryOrientation: Qt.LandscapeOrientation
101 }
102 },
103 State {
104 name: "desktop"
105 PropertyChanges {
106 target: shellLoader
107 width: units.gu(100)
108 }
109 }
110 ]
112 property bool itemDestroyed: false
113 sourceComponent: Component {
114 Shell {
115 usageScenario: shellLoader.state
116 nativeWidth: width
117 nativeHeight: height
118 property string indicatorProfile: "phone"
119 orientation: shellLoader.shellOrientation
120 orientations: Orientations {
121 native_: shellLoader.nativeOrientation
122 primary: shellLoader.primaryOrientation
123 }
125 Component.onDestruction: {
126 shellLoader.itemDestroyed = true;
127 }
128 }
129 }
130 }
131 }
133 Rectangle {
134 id: buttons
135 color: UbuntuColors.darkGrey
136 width: units.gu(30)
137 anchors.top: root.top
138 anchors.bottom: root.bottom
139 anchors.right: root.right
141 Column {
142 anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
143 spacing: units.gu(1)
144 Row {
145 anchors { left: parent.left; right: parent.right }
146 Button {
147 text: "Hide Greeter"
148 onClicked: {
149 if (shellLoader.status !== Loader.Ready)
150 return;
152 var greeter = testCase.findChild(shellLoader.item, "greeter");
153 if (greeter.shown) {
154 greeter.hide();
155 }
156 }
157 }
158 }
160 Row {
161 anchors { left: parent.left; right: parent.right }
162 Button {
163 text: "Restart Tutorial"
164 onClicked: {
165 if (shellLoader.status !== Loader.Ready)
166 return;
168 AccountsService.demoEdges = false;
169 AccountsService.demoEdgesCompleted = [];
170 AccountsService.demoEdges = true;
171 }
172 }
173 }
175 Row {
176 anchors { left: parent.left; right: parent.right }
177 CheckBox {
178 onCheckedChanged: {
179 if (checked) {
180 callManager.foregroundCall = phoneCall;
181 } else {
182 callManager.foregroundCall = null;
183 }
184 }
185 }
186 Label {
187 text: "Active Call"
188 anchors.verticalCenter: parent.verticalCenter
189 }
190 }
192 Row {
193 anchors { left: parent.left; right: parent.right }
194 CheckBox {
195 activeFocusOnPress: false
196 onCheckedChanged: {
197 var surface = SurfaceManager.inputMethodSurface;
198 if (checked) {
199 surface.setState(Mir.RestoredState);
200 } else {
201 surface.setState(Mir.MinimizedState);
202 }
203 }
204 }
205 Label {
206 text: "Input Method"
207 anchors.verticalCenter: parent.verticalCenter
208 }
209 }
211 ItemSelector {
212 id: modeSelector
213 anchors { left: parent.left; right: parent.right }
214 activeFocusOnPress: false
215 text: "Mode"
216 model: ["phone", "tablet", "desktop"]
217 }
218 }
219 }
221 UT.UnityTestCase {
222 id: testCase
223 name: "Tutorial"
224 when: windowShown
226 property Item shell: shellLoader.status === Loader.Ready ? shellLoader.item : null
227 property real halfWidth: shell ? shell.width / 2 : 0
228 property real halfHeight: shell ? shell.height / 2 : 0
230 function init() {
231 prepareShell();
233 var tutorialLeft = findChild(shell, "tutorialLeft");
234 tryCompare(tutorialLeft, "opacity", 1);
235 }
237 function cleanup() {
238 resetLoader("phone");
239 }
241 function resetLoader(state) {
242 shellLoader.itemDestroyed = false;
244 shellLoader.active = false;
245 shellLoader.state = state;
247 tryCompare(shellLoader, "status", Loader.Null);
248 tryCompare(shellLoader, "item", null);
249 // Loader.status might be Loader.Null and Loader.item might be null but the Loader
250 // item might still be alive. So if we set Loader.active back to true
251 // again right now we will get the very same Shell instance back. So no reload
252 // actually took place. Likely because Loader waits until the next event loop
253 // iteration to do its work. So to ensure the reload, we will wait until the
254 // Shell instance gets destroyed.
255 tryCompare(shellLoader, "itemDestroyed", true);
257 // kill all (fake) running apps
258 killApps();
260 // reload our test subject to get it in a fresh state once again
261 shellLoader.active = true;
263 tryCompare(shellLoader, "status", Loader.Ready);
264 removeTimeConstraintsFromDirectionalDragAreas(shellLoader.item);
265 }
267 function prepareShell() {
268 tryCompare(shell, "enabled", true); // enabled by greeter when ready
270 WindowStateStorage.clear();
271 SurfaceManager.inputMethodSurface.setState(Mir.MinimizedState);
272 callManager.foregroundCall = null;
273 AccountsService.demoEdges = false;
274 AccountsService.demoEdgesCompleted = [];
275 AccountsService.demoEdges = true;
277 LightDM.Greeter.hideGreeter();
278 }
280 function loadShell(state) {
281 resetLoader(state);
282 prepareShell();
283 }
285 function swipeAwayGreeter() {
286 var coverPage = findChild(shell, "coverPage");
287 tryCompare(coverPage, "showProgress", 1);
289 touchFlick(shell, halfWidth, halfHeight, shell.width, halfHeight);
291 // wait until the animation has finished
292 var greeter = findChild(shell, "greeter");
293 tryCompare(greeter, "required", false);
294 waitForRendering(greeter);
295 }
297 function openTutorialTop() {
298 var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
299 var tutorialTop = findChild(shell, "tutorialTop");
300 var tutorialTopTimer = findInvisibleChild(tutorialTop, "tutorialTopTimer");
302 tutorialTopTimer.interval = 1;
303 AccountsService.demoEdgesCompleted = ["left", "left-long"];
305 tryCompare(tutorialLeftLoader, "active", false);
306 tryCompare(tutorialTop, "shown", true);
307 tryCompare(tutorialTop, "opacity", 1);
308 }
310 function openTutorialRight() {
311 var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
312 var tutorialRight = findChild(shell, "tutorialRight");
314 AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
315 ApplicationManager.startApplication("gallery-app");
316 ApplicationManager.startApplication("facebook-webapp");
318 tryCompare(tutorialLeftLoader, "active", false);
319 tryCompare(tutorialRight, "shown", true);
320 tryCompare(tutorialRight, "opacity", 1);
321 }
323 function openTutorialBottom() {
324 var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
325 var tutorialBottom = findChild(shell, "tutorialBottom");
327 AccountsService.demoEdgesCompleted = ["left", "left-long", "top", "right"];
328 tryCompare(tutorialLeftLoader, "active", false);
330 ApplicationManager.startApplication("dialer-app");
331 ApplicationManager.requestFocusApplication("dialer-app");
333 tryCompare(tutorialBottom, "shown", true);
334 tryCompare(tutorialBottom, "opacity", 1);
335 }
337 function test_tutorialLeftEdges() {
338 var tutorial = findChild(shell, "tutorial");
339 var tutorialLeft = findChild(tutorial, "tutorialLeft");
340 var launcher = findChild(shell, "launcher");
341 var stage = findChild(shell, "stage");
342 var panel = findChild(shell, "panel");
344 verify(tutorial.running);
345 verify(tutorial.launcherEnabled);
346 verify(!tutorial.spreadEnabled);
347 verify(!tutorial.panelEnabled);
348 verify(tutorialLeft.shown);
349 verify(launcher.available);
350 verify(!stage.spreadEnabled);
351 verify(!panel.indicators.available);
352 }
354 function test_tutorialLeftFinish() {
355 var tutorial = findChild(shell, "tutorial");
356 var tutorialLeft = findChild(tutorial, "tutorialLeft");
357 var launcher = findChild(shell, "launcher");
359 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
361 tryCompare(tutorialLeft, "shown", false);
362 tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
363 tryCompare(launcher, "state", "visible");
364 }
366 function test_tutorialLeftShortDrag() {
367 // Here we want to test just barely pulling the launcher out and
368 // letting go (i.e. not triggering the "progress" property of
369 // Launcher).
370 var tutorialLeft = findChild(shell, "tutorialLeft");
371 var launcher = findChild(shell, "launcher");
373 // Confirm fade during drag
374 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight, true, false);
375 // compare opacity with a bound rather than hard 0.6 because progress doesn't
376 // always match the drag perfectly (takes a moment for drag to kick in)
377 tryCompareFunction(function() {
378 return tutorialLeft.opacity >= 0.6 && tutorialLeft.opacity < 0.8;
379 }, true);
380 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight, false, true);
383 // Make sure we don't do anything if we don't pull the launcher
384 // out much.
385 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight);
386 tryCompare(launcher, "state", ""); // should remain hidden
387 tryCompare(tutorialLeft, "shown", true); // and we should still be on left
390 // Now drag out but not past launcher itself
391 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.9, halfHeight);
393 tryCompare(tutorialLeft, "shown", false);
394 tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
395 tryCompare(launcher, "state", "visible");
396 }
398 function test_tutorialLeftLongDrag() {
399 // Just confirm that a long drag ("dash" drag) doesn't confuse us
401 // So that we actually switch to dash and launcher hides
402 ApplicationManager.startApplication("gallery-app");
404 var launcher = findChild(shell, "launcher");
405 var tutorialLeft = findChild(shell, "tutorialLeftLoader");
406 verify(tutorialLeft);
408 touchFlick(shell, 0, halfHeight, shell.width, halfHeight);
410 tryCompare(tutorialLeft, "shown", false);
411 tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long"]);
412 }
414 function test_tutorialLeftAutoSkipped() {
415 // Test that we skip the tutorial if user uses left edge themselves
417 var tutorialLeft = findChild(shell, "tutorialLeft");
418 LightDM.Greeter.showGreeter();
419 tryCompare(tutorialLeft, "visible", false);
420 compare(AccountsService.demoEdgesCompleted, []);
422 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
423 tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
424 }
426 function test_tutorialTopEdges() {
427 var tutorial = findChild(shell, "tutorial");
428 var tutorialTop = findChild(tutorial, "tutorialTop");
429 var launcher = findChild(shell, "launcher");
430 var stage = findChild(shell, "stage");
431 var panel = findChild(shell, "panel");
433 openTutorialTop();
435 tryCompare(tutorial, "running", true);
436 verify(!tutorial.launcherEnabled);
437 verify(!tutorial.spreadEnabled);
438 verify(tutorial.panelEnabled);
439 verify(tutorialTop.shown);
440 verify(!launcher.available);
441 verify(!stage.spreadEnabled);
442 verify(panel.indicators.available);
443 }
445 function test_tutorialTopFinish() {
446 var tutorial = findChild(shell, "tutorial");
447 var tutorialTop = findChild(tutorial, "tutorialTop");
448 var panel = findChild(shell, "panel");
450 openTutorialTop();
451 touchFlick(shell, halfWidth, 0, halfWidth, shell.height);
453 tryCompare(tutorialTop, "shown", false);
454 tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "top"]);
455 tryCompare(panel.indicators, "fullyOpened", true);
456 }
458 function test_tutorialTopShortDrag() {
459 var tutorial = findChild(shell, "tutorial");
460 var tutorialTop = findChild(tutorial, "tutorialTop");
461 var panel = findChild(shell, "panel");
463 openTutorialTop();
464 touchFlick(shell, halfWidth, 0, halfWidth, shell.height * 0.4, true, false);
465 // compare opacity with a bound rather than hard 0.6 because progress doesn't
466 // always match the drag perfectly (takes a moment for drag to kick in)
467 tryCompareFunction(function() {
468 return tutorialTop.opacity >= 0.6 && tutorialTop.opacity < 0.7;
469 }, true);
470 touchFlick(shell, halfWidth, 0, halfWidth, shell.height * 0.4, false, true);
472 compare(tutorialTop.shown, true);
473 }
475 function test_tutorialTopAutoSkipped() {
476 // Test that we skip the tutorial if user uses top edge themselves
478 var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
479 var tutorialTop = findChild(shell, "tutorialTop");
480 AccountsService.demoEdgesCompleted = ["left", "left-long"];
481 tryCompare(tutorialLeftLoader, "active", false);
482 verify(!tutorialTop.shown);
484 touchFlick(shell, halfWidth, 0, halfWidth, shell.height);
485 tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "top"]);
486 }
488 function test_tutorialRightEdges() {
489 var tutorial = findChild(shell, "tutorial");
490 var tutorialRight = findChild(tutorial, "tutorialRight");
491 var launcher = findChild(shell, "launcher");
492 var stage = findChild(shell, "stage");
493 var panel = findChild(shell, "panel");
495 openTutorialRight();
497 tryCompare(tutorial, "running", true);
498 verify(!tutorial.launcherEnabled);
499 verify(tutorial.spreadEnabled);
500 verify(!tutorial.panelEnabled);
501 verify(tutorialRight.shown);
502 verify(!launcher.available);
503 verify(stage.spreadEnabled);
504 verify(!panel.indicators.available);
505 }
507 function test_tutorialRightFinish() {
508 var tutorial = findChild(shell, "tutorial");
509 var tutorialRight = findChild(tutorial, "tutorialRight");
510 var stage = findChild(shell, "stage");
512 openTutorialRight();
513 touchFlick(shell, shell.width, halfHeight, 0, halfHeight);
515 tryCompare(tutorialRight, "shown", false);
516 tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "top", "right"]);
517 }
519 function test_tutorialRightShortDrag() {
520 var tutorial = findChild(shell, "tutorial");
521 var tutorialRight = findChild(tutorial, "tutorialRight");
522 var stage = findChild(shell, "stage");
524 openTutorialRight();
525 touchFlick(shell, shell.width, halfHeight, shell.width * 0.8, halfHeight, true, false);
526 // compare opacity with a bound rather than hard 0.6 because progress doesn't
527 // always match the drag perfectly (takes a moment for drag to kick in)
528 tryCompareFunction(function() {
529 return tutorialRight.opacity >= 0.6 && tutorialRight.opacity < 0.8;
530 }, true);
531 touchFlick(shell, shell.width, halfHeight, shell.width * 0.8, halfHeight, false, true);
533 compare(tutorialRight.shown, true);
534 }
536 function test_tutorialRightDelay() {
537 // Test that if we exit the top tutorial, we don't immediately
538 // jump into right tutorial.
539 var tutorialRight = findChild(shell, "tutorialRight");
540 var tutorialRightTimer = findInvisibleChild(tutorialRight, "tutorialRightInactivityTimer");
542 tutorialRightTimer.interval = 1;
543 openTutorialTop();
544 ApplicationManager.startApplication("gallery-app");
545 ApplicationManager.startApplication("facebook-webapp");
546 tryCompare(ApplicationManager, "count", 3);
548 AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
549 verify(tutorialRightTimer.running, true);
550 verify(!tutorialRight.shown);
551 tryCompare(tutorialRight, "shown", true);
552 }
554 function test_tutorialRightAutoSkipped() {
555 // Test that we skip the tutorial if user uses right edge themselves
557 var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
558 AccountsService.demoEdgesCompleted = ["left", "left-long"];
559 tryCompare(tutorialLeftLoader, "active", false);
561 touchFlick(shell, shell.width, halfHeight, 0, halfHeight);
562 tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "right"]);
563 }
565 function test_tutorialBottomEdges() {
566 var tutorial = findChild(shell, "tutorial");
567 var tutorialBottom = findChild(tutorial, "tutorialBottom");
568 var tutorialLabel = findChild(tutorialBottom, "tutorialLabel");
569 var launcher = findChild(shell, "launcher");
570 var stage = findChild(shell, "stage");
571 var panel = findChild(shell, "panel");
573 openTutorialBottom();
575 tryCompare(tutorial, "running", true);
576 verify(!tutorial.launcherEnabled);
577 verify(!tutorial.spreadEnabled);
578 verify(!tutorial.panelEnabled);
579 verify(tutorialBottom.shown);
580 verify(!launcher.available);
581 verify(!stage.spreadEnabled);
582 verify(!panel.indicators.available);
583 compare(tutorialLabel.text, "Swipe up for recent calls");
584 }
586 function test_tutorialBottomFinish() {
587 var tutorial = findChild(shell, "tutorial");
588 var tutorialBottom = findChild(tutorial, "tutorialBottom");
590 openTutorialBottom();
591 touchFlick(shell, halfWidth, shell.height, halfWidth, halfHeight);
593 tryCompare(tutorialBottom, "shown", false);
594 tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "top", "right", "bottom-dialer-app"]);
596 // OK, we did one, just confirm that when all are done, we mark whole tutorial as done.
597 verify(AccountsService.demoEdges);
598 AccountsService.demoEdgesCompleted = ["left", "left-long", "top", "right",
599 "bottom-address-book-app",
600 "bottom-com.ubuntu.calculator_calculator",
601 "bottom-dialer-app",
602 "bottom-messaging-app"];
603 verify(!AccountsService.demoEdges);
604 }
606 function test_tutorialBottomAppearsBeforeRight() {
607 // Confirm that if bottom edge and right edge would appear on the
608 // the same app open, bottom edge appears first. (this is a lightly
609 // edited version of openTutorialRight)
610 var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
611 var tutorialRight = findChild(shell, "tutorialRight");
612 var tutorialBottom = findChild(shell, "tutorialBottom");
614 AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
615 ApplicationManager.startApplication("gallery-app");
616 ApplicationManager.startApplication("dialer-app");
618 tryCompare(tutorialLeftLoader, "active", false);
619 tryCompare(tutorialBottom, "shown", true);
620 tryCompare(tutorialBottom, "opacity", 1);
621 tryCompare(tutorialRight, "visible", false);
622 }
624 function test_tutorialBottomOnlyCoversSideStageOnTablet() {
625 loadShell("tablet");
627 var tutorialBottom = findChild(shell, "tutorialBottom");
628 var targetHeight = shell.height - units.gu(4);
629 var mainStageX = units.gu(20);
630 var sideStageX = shell.width - units.gu(20);
632 WindowStateStorage.saveStage("dialer-app", ApplicationInfoInterface.SideStage);
633 openTutorialBottom();
635 touchFlick(shell, mainStageX, shell.height, mainStageX, targetHeight, true, false);
636 compare(tutorialBottom.opacity, 1);
637 touchFlick(shell, mainStageX, shell.height, mainStageX, targetHeight, false, true);
639 touchFlick(shell, sideStageX, shell.height, sideStageX, targetHeight, true, false);
640 verify(tutorialBottom.opacity < 1);
641 touchFlick(shell, sideStageX, shell.height, sideStageX, targetHeight, false, true);
642 }
644 function test_tutorialBottomOnlyCoversMainStageOnTablet() {
645 loadShell("tablet");
647 var tutorialBottom = findChild(shell, "tutorialBottom");
648 var targetHeight = shell.height - units.gu(4);
649 var mainStageX = units.gu(20);
650 var sideStageX = shell.width - units.gu(20);
652 WindowStateStorage.saveStage("notes-app", ApplicationInfoInterface.SideStage);
653 ApplicationManager.startApplication("notes-app");
655 openTutorialBottom();
657 touchFlick(shell, sideStageX, shell.height, sideStageX, targetHeight, true, false);
658 compare(tutorialBottom.opacity, 1);
659 touchFlick(shell, sideStageX, shell.height, sideStageX, targetHeight, false, true);
661 touchFlick(shell, mainStageX, shell.height, mainStageX, targetHeight, true, false);
662 verify(tutorialBottom.opacity < 1);
663 touchFlick(shell, mainStageX, shell.height, mainStageX, targetHeight, false, true);
664 }
666 function test_activeCallInterruptsTutorial() {
667 var tutorialLeft = findChild(shell, "tutorialLeft");
668 verify(tutorialLeft.shown);
669 verify(!tutorialLeft.paused);
671 callManager.foregroundCall = phoneCall;
672 verify(!tutorialLeft.shown);
673 verify(tutorialLeft.paused);
674 tryCompare(tutorialLeft, "visible", false);
676 callManager.foregroundCall = null;
677 tryCompare(tutorialLeft, "shown", true);
678 verify(!tutorialLeft.paused);
679 }
681 function test_dialerInterruptionWithNoOverlappingTutorials() {
682 var tutorialLeft = findChild(shell, "tutorialLeft");
683 var tutorialBottom = findChild(shell, "tutorialBottom");
684 verify(tutorialLeft.shown);
686 // Start call, hiding left tutorial
687 callManager.foregroundCall = phoneCall;
688 tryCompare(tutorialLeft, "shown", false);
690 // Start dialer app
691 ApplicationManager.startApplication("dialer-app");
692 tryCompare(ApplicationManager, "focusedApplicationId", "dialer-app");
693 verify(!tutorialBottom.shown);
695 // Dismiss call, bottom tutorial should appear
696 callManager.foregroundCall = null;
697 tryCompare(tutorialBottom, "shown", true);
698 verify(!tutorialLeft.shown);
700 // Get rid of bottom tutorial, left should now be shown
701 touchFlick(shell, halfWidth, shell.height, halfWidth, halfHeight);
702 tryCompare(tutorialBottom, "shown", false);
703 tryCompare(tutorialLeft, "shown", true);
704 }
706 function test_greeterInterruptsTutorial() {
707 var tutorialLeft = findChild(shell, "tutorialLeft");
708 verify(tutorialLeft.shown);
709 verify(!tutorialLeft.paused);
711 LightDM.Greeter.showGreeter();
712 verify(!tutorialLeft.shown);
713 verify(tutorialLeft.paused);
714 tryCompare(tutorialLeft, "visible", false);
716 LightDM.Greeter.hideGreeter();
717 tryCompare(tutorialLeft, "shown", true);
718 verify(!tutorialLeft.paused);
719 }
721 function test_interruptionChecksReadyStateWhenDone() {
722 // If we're done with an interruption (like active call), make sure
723 // that we don't blindly resume the tutorial -- our trigger
724 // conditions still need to be met. For example, there need to be
725 // enough apps open for the right edge tutorial.
727 openTutorialRight();
729 var tutorialRight = findChild(shell, "tutorialRight");
730 verify(tutorialRight.isReady);
731 verify(tutorialRight.shown);
732 verify(!tutorialRight.paused);
734 callManager.foregroundCall = phoneCall;
735 killApps();
736 callManager.foregroundCall = null;
738 verify(!tutorialRight.isReady);
739 verify(!tutorialRight.shown);
740 verify(!tutorialRight.paused);
741 compare(AccountsService.demoEdgesCompleted, ["left", "left-long", "top"]);
742 }
744 function test_desktopOnlyShowsTutorialRight() {
745 loadShell("desktop");
747 var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
748 var tutorialTopLoader = findChild(shell, "tutorialTopLoader");
749 var tutorialRightLoader = findChild(shell, "tutorialRightLoader");
750 var tutorialBottomLoader = findChild(shell, "tutorialBottomLoader");
751 verify(!tutorialLeftLoader.active);
752 verify(!tutorialTopLoader.active);
753 verify(tutorialRightLoader.active);
754 verify(!tutorialBottomLoader.active);
755 compare(AccountsService.demoEdgesCompleted, []);
757 ApplicationManager.startApplication("dialer-app");
758 ApplicationManager.startApplication("camera-app");
759 tryCompare(tutorialRightLoader.item, "isReady", true);
760 tryCompare(tutorialRightLoader, "shown", true);
761 }
763 function test_desktopTutorialRightFinish() {
764 loadShell("desktop");
766 var tutorialRight = findChild(shell, "tutorialRight");
767 ApplicationManager.startApplication("dialer-app");
768 ApplicationManager.startApplication("camera-app");
769 tryCompare(tutorialRight, "shown", true);
771 var stage = findChild(shell, "stage");
772 mouseMove(shell, shell.width, shell.height / 2);
773 stage.pushRightEdge(units.gu(8));
774 tryCompare(tutorialRight, "shown", false);
776 tryCompare(AccountsService, "demoEdges", false);
777 }
779 function test_oskDoesNotHideTutorial() {
780 var tutorialLeft = findChild(shell, "tutorialLeft");
781 verify(tutorialLeft.shown);
783 var surface = SurfaceManager.inputMethodSurface;
784 surface.setState(Mir.RestoredState);
786 var inputMethod = findInvisibleChild(shell, "inputMethod");
787 tryCompare(inputMethod, "state", "shown");
789 verify(tutorialLeft.shown);
790 }
792 function test_oskPreventsTutorial() {
793 var surface = SurfaceManager.inputMethodSurface;
794 var inputMethod = findInvisibleChild(shell, "inputMethod");
796 AccountsService.demoEdges = false;
797 surface.setState(Mir.RestoredState);
798 tryCompare(inputMethod, "state", "shown");
800 var tutorial = findChild(shell, "tutorial");
801 tryCompare(tutorial, "keyboardVisible", true);
803 AccountsService.demoEdges = true;
804 var tutorialLeft = findChild(shell, "tutorialLeft");
805 verify(!tutorialLeft.shown);
807 surface.setState(Mir.MinimizedState);
808 tryCompare(inputMethod, "state", "hidden");
809 tryCompare(tutorialLeft, "shown", false);
810 }
812 function test_accountsServiceSettings() {
813 var tutorialLeft = findChild(shell, "tutorialLeft");
814 verify(tutorialLeft != null);
815 verify(tutorialLeft.shown);
817 AccountsService.demoEdges = false;
818 verify(findChild(shell, "tutorialLeft") == null);
820 AccountsService.demoEdges = true;
821 tutorialLeft = findChild(shell, "tutorialLeft");
822 verify(tutorialLeft != null);
823 tryCompare(tutorialLeft, "shown", true);
824 }
825 }