@@ -19,15 +19,20 @@ import QtTest 1.0
19import AccountsService 0.1
19import AccountsService 0.1
20import IntegratedLightDM 0.1 as LightDM
20import IntegratedLightDM 0.1 as LightDM
21import Ubuntu.Components 1.3
21import Ubuntu.Components 1.3
22+import Ubuntu.Components.ListItems 1.3
23+import Ubuntu.Telephony 0.1 as Telephony
22import Unity.Application 0.1
24import Unity.Application 0.1
23import Unity.Test 0.1 as UT
25import Unity.Test 0.1 as UT
25import "../../../qml"
28import "../../../qml"
29+import "../../../qml/Components"
33+ color: UbuntuColors.lightGrey
29− width: shellLoader.width + buttons.width
34+ width: units.gu(100) + buttons.width
30− height: shellLoader.height
35+ height: units.gu(71)
32 QtObject {
37 QtObject {
33 id: applicationArguments
38 id: applicationArguments
@@ -45,6 +50,11 @@ Item {
53+ Telephony.CallEntry {
55+ phoneNumber: "+447812221111"
48 Component.onCompleted: {
58 Component.onCompleted: {
49 // must set the mock mode before loading the Shell
59 // must set the mock mode before loading the Shell
50 LightDM.Greeter.mockMode = "single-pin";
60 LightDM.Greeter.mockMode = "single-pin";
@@ -52,21 +62,63 @@ Item {
52 shellLoader.active = true;
62 shellLoader.active = true;
56− spacing: 0
66+ id: shellContainer
57− anchors.fill: parent
67+ anchors.left: root.left
68+ anchors.right: buttons.left
69+ anchors.top: root.top
70+ anchors.bottom: root.bottom
60 id: shellLoader
73 id: shellLoader
62 active: false
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]
63− width: units.gu(40)
90+ width: units.gu(40)
98+ shellOrientation: Qt.LandscapeOrientation
99+ nativeOrientation: Qt.LandscapeOrientation
100+ primaryOrientation: Qt.LandscapeOrientation
64− height: units.gu(71)
107+ width: units.gu(100)
66 property bool itemDestroyed: false
112 property bool itemDestroyed: false
67 sourceComponent: Component {
113 sourceComponent: Component {
115+ usageScenario: shellLoader.state
69 property string indicatorProfile: "phone"
116 property string indicatorProfile: "phone"
117+ orientation: shellLoader.shellOrientation
118+ orientations: Orientations {
119+ native_: shellLoader.nativeOrientation
120+ primary: shellLoader.primaryOrientation
71 Component.onDestruction: {
123 Component.onDestruction: {
72 shellLoader.itemDestroyed = true;
124 shellLoader.itemDestroyed = true;
@@ -74,29 +126,92 @@ Item {
133+ color: UbuntuColors.darkGrey
135+ anchors.top: root.top
136+ anchors.bottom: root.bottom
137+ anchors.right: root.right
140+ anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
141+ spacing: units.gu(1)
143+ anchors { left: parent.left; right: parent.right }
145+ text: "Hide Greeter"
147+ if (shellLoader.status !== Loader.Ready)
150+ var greeter = testCase.findChild(shellLoader.item, "greeter");
151+ if (greeter.shown) {
159+ anchors { left: parent.left; right: parent.right }
161+ text: "Restart Tutorial"
163+ if (shellLoader.status !== Loader.Ready)
166+ AccountsService.demoEdges = false;
167+ AccountsService.demoEdgesCompleted = [];
168+ AccountsService.demoEdges = 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 }
174+ anchors { left: parent.left; right: parent.right }
89− Button {
175+ CheckBox {
90− text: "Restart Tutorial"
176+ onCheckedChanged: {
91− onClicked: {
177+ if (checked) {
92− if (shellLoader.status !== Loader.Ready)
178+ callManager.foregroundCall = phoneCall;
94−
180+ callManager.foregroundCall = null;
95− AccountsService.demoEdges = false;
96− AccountsService.demoEdges = true;
186+ anchors.verticalCenter: parent.verticalCenter
191+ anchors { left: parent.left; right: parent.right }
193+ activeFocusOnPress: false
195+ var surface = SurfaceManager.inputMethodSurface;
197+ surface.setState(Mir.RestoredState);
199+ surface.setState(Mir.MinimizedState);
204+ text: "Input Method"
205+ anchors.verticalCenter: parent.verticalCenter
211+ anchors { left: parent.left; right: parent.right }
212+ activeFocusOnPress: false
214+ model: ["phone", "tablet", "desktop"]
@@ -111,17 +226,21 @@ Item {
111 property real halfHeight: shell ? shell.height / 2 : 0
226 property real halfHeight: shell ? shell.height / 2 : 0
113 function init() {
228 function init() {
114− tryCompare(shell, "enabled", true); // enabled by greeter when ready
229+ prepareShell();
116− AccountsService.demoEdges = false;
231+ var tutorialLeft = findChild(shell, "tutorialLeft");
117− AccountsService.demoEdges = true;
232+ tryCompare(tutorialLeft, "opacity", 1);
121 function cleanup() {
235 function cleanup() {
236+ resetLoader("phone");
239+ function resetLoader(state) {
122 shellLoader.itemDestroyed = false;
240 shellLoader.itemDestroyed = false;
124 shellLoader.active = false;
242 shellLoader.active = false;
243+ shellLoader.state = state;
126 tryCompare(shellLoader, "status", Loader.Null);
245 tryCompare(shellLoader, "status", Loader.Null);
127 tryCompare(shellLoader, "item", null);
246 tryCompare(shellLoader, "item", null);
@@ -143,6 +262,24 @@ Item {
143 removeTimeConstraintsFromDirectionalDragAreas(shellLoader.item);
262 removeTimeConstraintsFromDirectionalDragAreas(shellLoader.item);
265+ function prepareShell() {
266+ tryCompare(shell, "enabled", true); // enabled by greeter when ready
268+ WindowStateStorage.clear();
269+ SurfaceManager.inputMethodSurface.setState(Mir.MinimizedState);
270+ callManager.foregroundCall = null;
271+ AccountsService.demoEdges = false;
272+ AccountsService.demoEdgesCompleted = [];
273+ AccountsService.demoEdges = true;
275+ LightDM.Greeter.hideGreeter();
278+ function loadShell(state) {
146 function killApps() {
283 function killApps() {
147 while (ApplicationManager.count > 1) {
284 while (ApplicationManager.count > 1) {
148 var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0
285 var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0
@@ -163,234 +300,515 @@ Item {
163 waitForRendering(greeter);
300 waitForRendering(greeter);
166− function waitForPage(name) {
303+ function openTutorialTop() {
167− waitForRendering(findChild(shell, name));
304+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
168− var page = findChild(shell, name);
305+ var tutorialTop = findChild(shell, "tutorialTop");
169− tryCompare(page, "shown", true);
306+ var tutorialTopTimer = findInvisibleChild(tutorialTop, "tutorialTopTimer");
170− tryCompare(page.showAnimation, "running", false);
307+
171− return page;
308+ tutorialTopTimer.interval = 1;
309+ AccountsService.demoEdgesCompleted = ["left", "left-long"];
311+ tryCompare(tutorialLeftLoader, "active", false);
312+ tryCompare(tutorialTop, "shown", true);
313+ tryCompare(tutorialTop, "opacity", 1);
174− function checkTopEdge() {
316+ function openTutorialRight() {
175− touchFlick(shell, halfWidth, 0, halfWidth, halfHeight);
317+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
318+ var tutorialRight = findChild(shell, "tutorialRight");
177− var panel = findChild(shell, "panel");
320+ AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
178− tryCompare(panel.indicators, "fullyClosed", true);
321+ ApplicationManager.startApplication("gallery-app");
322+ ApplicationManager.startApplication("facebook-webapp");
324+ tryCompare(tutorialLeftLoader, "active", false);
325+ tryCompare(tutorialRight, "shown", true);
326+ tryCompare(tutorialRight, "opacity", 1);
181− function checkLeftEdge() {
329+ function openTutorialBottom() {
182− touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
330+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
331+ var tutorialBottom = findChild(shell, "tutorialBottom");
333+ AccountsService.demoEdgesCompleted = ["left", "left-long", "top", "right"];
334+ tryCompare(tutorialLeftLoader, "active", false);
336+ ApplicationManager.startApplication("dialer-app");
337+ ApplicationManager.requestFocusApplication("dialer-app");
339+ tryCompare(tutorialBottom, "shown", true);
340+ tryCompare(tutorialBottom, "opacity", 1);
343+ function test_tutorialLeftEdges() {
344+ var tutorial = findChild(shell, "tutorial");
345+ var tutorialLeft = findChild(tutorial, "tutorialLeft");
184 var launcher = findChild(shell, "launcher");
346 var launcher = findChild(shell, "launcher");
185− tryCompare(launcher, "state", "");
347+ var stage = findChild(shell, "stage");
348+ var panel = findChild(shell, "panel");
350+ verify(tutorial.running);
351+ verify(tutorial.launcherEnabled);
352+ verify(!tutorial.spreadEnabled);
353+ verify(!tutorial.panelEnabled);
354+ verify(tutorialLeft.shown);
355+ verify(launcher.available);
356+ verify(!stage.spreadEnabled);
357+ verify(!panel.indicators.available);
188− function checkRightEdge() {
360+ function test_tutorialLeftFinish() {
189− if (shell.usageScenario === "phone") {
361+ var tutorial = findChild(shell, "tutorial");
190− touchFlick(shell, shell.width, halfHeight, halfWidth, halfHeight);
362+ var tutorialLeft = findChild(tutorial, "tutorialLeft");
363+ var launcher = findChild(shell, "launcher");
192− var stage = findChild(shell, "stage");
365+ touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
193− var spreadView = findChild(stage, "spreadView");
366+
194− tryCompare(spreadView, "phase", 0);
367+ tryCompare(tutorialLeft, "shown", false);
195− }
368+ tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
369+ tryCompare(launcher, "state", "visible");
198− function checkBottomEdge() {
372+ function test_tutorialLeftShortDrag() {
199− // Can't actually check effect of swipe, since dash isn't really loaded
373+ // Here we want to test just barely pulling the launcher out and
200− var applicationsDisplayLoader = findChild(shell, "applicationsDisplayLoader");
374+ // letting go (i.e. not triggering the "progress" property of
201− tryCompare(applicationsDisplayLoader, "interactive", false);
375+ // Launcher).
376+ var tutorialLeft = findChild(shell, "tutorialLeft");
377+ var launcher = findChild(shell, "launcher");
379+ // Confirm fade during drag
380+ touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight, true, false);
381+ // compare opacity with a bound rather than hard 0.6 because progress doesn't
382+ // always match the drag perfectly (takes a moment for drag to kick in)
383+ tryCompareFunction(function() {
384+ return tutorialLeft.opacity >= 0.6 && tutorialLeft.opacity < 0.8;
386+ touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight, false, true);
389+ // Make sure we don't do anything if we don't pull the launcher
391+ touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight);
392+ tryCompare(launcher, "state", ""); // should remain hidden
393+ tryCompare(tutorialLeft, "shown", true); // and we should still be on left
396+ // Now drag out but not past launcher itself
397+ touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.9, halfHeight);
399+ tryCompare(tutorialLeft, "shown", false);
400+ tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
401+ tryCompare(launcher, "state", "visible");
204− function checkFinished() {
404+ function test_tutorialLeftLongDrag() {
205− tryCompare(AccountsService, "demoEdges", false);
405+ // Just confirm that a long drag ("dash" drag) doesn't confuse us
207− var tutorial = findChild(shell, "tutorial");
407+ // So that we actually switch to dash and launcher hides
208− tryCompare(tutorial, "running", false);
408+ ApplicationManager.startApplication("gallery-app");
210 var launcher = findChild(shell, "launcher");
410 var launcher = findChild(shell, "launcher");
411+ var tutorialLeft = findChild(shell, "tutorialLeft");
412+ touchFlick(shell, 0, halfHeight, shell.width, halfHeight);
211− tryCompare(launcher, "shown", false);
414+ tryCompare(tutorialLeft, "shown", false);
415+ tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long"]);
214− function goToPage(name) {
418+ function test_tutorialLeftAutoSkipped() {
419+ // Test that we skip the tutorial if user uses left edge themselves
215− var page = waitForPage("tutorialLeft");
421+ var tutorialLeft = findChild(shell, "tutorialLeft");
216− checkTopEdge();
422+ LightDM.Greeter.showGreeter();
217− checkRightEdge();
423+ tryCompare(tutorialLeft, "visible", false);
218− checkBottomEdge();
424+ compare(AccountsService.demoEdgesCompleted, []);
219− if (name === "tutorialLeft") return page;
425+
220 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
426 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
427+ tryCompare(AccountsService, "demoEdgesCompleted", ["left"]);
222− page = waitForPage("tutorialLeftFinish");
430+ function test_tutorialTopEdges() {
223− if (name === "tutorialLeftFinish") return page;
224− var tick = findChild(page, "tick");
431+ var tutorial = findChild(shell, "tutorial");
225− tap(tick);
432+ var tutorialTop = findChild(tutorial, "tutorialTop");
226−
433+ var launcher = findChild(shell, "launcher");
227− page = waitForPage("tutorialRight");
231− if (name === "tutorialRight") return page;
233− shell.width, halfHeight,
234− halfWidth, halfHeight,
235− true /* beginTouch */, true /* endTouch */,
236− 20 /* speed */, 50 /* iterations */);
237− var overlay = findChild(page, "overlay");
238− tryCompare(overlay, "shown", true);
239− var tick = findChild(page, "tick");
434+ var stage = findChild(shell, "stage");
240− tap(tick);
435+ var panel = findChild(shell, "panel");
242− var page = waitForPage("tutorialBottom");
246− if (name === "tutorialBottom") return page;
247− touchFlick(shell, halfWidth, shell.height, halfWidth, halfHeight);
249− var page = waitForPage("tutorialBottomFinish");
437+ openTutorialTop();
254− if (name === "tutorialBottomFinish") return page;
255− var tick = findChild(page, "tick");
258− checkFinished();
439+ tryCompare(tutorial, "running", true);
259− return null;
440+ verify(!tutorial.launcherEnabled);
441+ verify(!tutorial.spreadEnabled);
442+ verify(tutorial.panelEnabled);
443+ verify(tutorialTop.shown);
444+ verify(!launcher.available);
445+ verify(!stage.spreadEnabled);
446+ verify(panel.indicators.available);
262− function test_walkthrough() {
449+ function test_tutorialTopFinish() {
263− goToPage(null);
450+ var tutorial = findChild(shell, "tutorial");
451+ var tutorialTop = findChild(tutorial, "tutorialTop");
452+ var panel = findChild(shell, "panel");
455+ touchFlick(shell, halfWidth, 0, halfWidth, shell.height);
457+ tryCompare(tutorialTop, "shown", false);
458+ tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "top"]);
459+ tryCompare(panel.indicators, "fullyOpened", true);
266− function test_skipOnDesktop() {
462+ function test_tutorialTopShortDrag() {
267 var tutorial = findChild(shell, "tutorial");
463 var tutorial = findChild(shell, "tutorial");
268− tryCompare(tutorial, "active", true);
464+ var tutorialTop = findChild(tutorial, "tutorialTop");
269− tryCompare(tutorial, "running", true);
465+ var panel = findChild(shell, "panel");
271− shell.usageScenario = "desktop";
467+ openTutorialTop();
272− tryCompare(tutorial, "active", false);
468+ touchFlick(shell, halfWidth, 0, halfWidth, shell.height * 0.4, true, false);
273− tryCompare(tutorial, "running", false);
469+ // compare opacity with a bound rather than hard 0.6 because progress doesn't
470+ // always match the drag perfectly (takes a moment for drag to kick in)
471+ tryCompareFunction(function() {
472+ return tutorialTop.opacity >= 0.6 && tutorialTop.opacity < 0.7;
474+ touchFlick(shell, halfWidth, 0, halfWidth, shell.height * 0.4, false, true);
476+ compare(tutorialTop.shown, true);
276− function test_launcherShortDrag() {
479+ function test_tutorialTopAutoSkipped() {
277− // goToPage does a normal launcher pull. But here we want to test
480+ // Test that we skip the tutorial if user uses top edge themselves
278− // just barely pulling the launcher out and letting go (i.e. not
279− // triggering the "progress" property of Launcher).
281− var left = goToPage("tutorialLeft");
482+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
483+ var tutorialTop = findChild(shell, "tutorialTop");
484+ AccountsService.demoEdgesCompleted = ["left", "left-long"];
485+ tryCompare(tutorialLeftLoader, "active", false);
486+ verify(!tutorialTop.shown);
283− // Make sure we don't do anything if we don't pull the launcher
488+ touchFlick(shell, halfWidth, 0, halfWidth, shell.height);
284− // out much.
489+ tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "top"]);
492+ function test_tutorialRightEdges() {
493+ var tutorial = findChild(shell, "tutorial");
494+ var tutorialRight = findChild(tutorial, "tutorialRight");
285 var launcher = findChild(shell, "launcher");
495 var launcher = findChild(shell, "launcher");
286− touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight);
496+ var stage = findChild(shell, "stage");
287− tryCompare(launcher, "state", ""); // should remain hidden
497+ var panel = findChild(shell, "panel");
288− tryCompare(left, "shown", true); // and we should still be on left
290− // Now drag out but not past launcher itself
499+ openTutorialRight();
501+ tryCompare(tutorial, "running", true);
502+ verify(!tutorial.launcherEnabled);
503+ verify(tutorial.spreadEnabled);
504+ verify(!tutorial.panelEnabled);
505+ verify(tutorialRight.shown);
506+ verify(!launcher.available);
507+ verify(stage.spreadEnabled);
508+ verify(!panel.indicators.available);
511+ function test_tutorialRightFinish() {
512+ var tutorial = findChild(shell, "tutorial");
513+ var tutorialRight = findChild(tutorial, "tutorialRight");
514+ var stage = findChild(shell, "stage");
516+ openTutorialRight();
517+ touchFlick(shell, shell.width, halfHeight, 0, halfHeight);
519+ tryCompare(tutorialRight, "shown", false);
520+ tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "top", "right"]);
523+ function test_tutorialRightShortDrag() {
524+ var tutorial = findChild(shell, "tutorial");
525+ var tutorialRight = findChild(tutorial, "tutorialRight");
526+ var stage = findChild(shell, "stage");
528+ openTutorialRight();
529+ touchFlick(shell, shell.width, halfHeight, shell.width * 0.8, halfHeight, true, false);
530+ // compare opacity with a bound rather than hard 0.6 because progress doesn't
531+ // always match the drag perfectly (takes a moment for drag to kick in)
532+ tryCompareFunction(function() {
533+ return tutorialRight.opacity >= 0.6 && tutorialRight.opacity < 0.8;
291− touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.9, halfHeight);
535+ touchFlick(shell, shell.width, halfHeight, shell.width * 0.8, halfHeight, false, true);
537+ compare(tutorialRight.shown, true);
293− waitForPage("tutorialLeftFinish");
540+ function test_tutorialRightDelay() {
541+ // Test that if we exit the top tutorial, we don't immediately
542+ // jump into right tutorial.
543+ var tutorialRight = findChild(shell, "tutorialRight");
544+ var tutorialRightTimer = findInvisibleChild(tutorialRight, "tutorialRightInactivityTimer");
546+ tutorialRightTimer.interval = 1;
548+ ApplicationManager.startApplication("gallery-app");
549+ ApplicationManager.startApplication("facebook-webapp");
550+ tryCompare(ApplicationManager, "count", 3);
552+ AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
553+ verify(tutorialRightTimer.running, true);
554+ verify(!tutorialRight.shown);
555+ tryCompare(tutorialRight, "shown", true);
296− function test_launcherLongDrag() {
558+ function test_tutorialRightAutoSkipped() {
297− // goToPage does a normal launcher pull. But here we want to test
559+ // Test that we skip the tutorial if user uses right edge themselves
298− // a full pull across the page.
300− var left = goToPage("tutorialLeft");
561+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
562+ AccountsService.demoEdgesCompleted = ["left", "left-long"];
563+ tryCompare(tutorialLeftLoader, "active", false);
565+ touchFlick(shell, shell.width, halfHeight, 0, halfHeight);
566+ tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "right"]);
569+ function test_tutorialBottomEdges() {
570+ var tutorial = findChild(shell, "tutorial");
571+ var tutorialBottom = findChild(tutorial, "tutorialBottom");
572+ var tutorialLabel = findChild(tutorialBottom, "tutorialLabel");
302 var launcher = findChild(shell, "launcher");
573 var launcher = findChild(shell, "launcher");
303− touchFlick(shell, 0, halfHeight, shell.width, halfHeight);
574+ var stage = findChild(shell, "stage");
575+ var panel = findChild(shell, "panel");
305− var errorTextLabel = findChild(left, "errorTextLabel");
577+ openTutorialBottom();
306− var errorTitleLabel = findChild(left, "errorTitleLabel");
578+
307− tryCompare(launcher, "state", ""); // launcher goes away
579+ tryCompare(tutorial, "running", true);
308− tryCompare(left, "shown", true); // still on left page
580+ verify(!tutorial.launcherEnabled);
309− tryCompare(errorTextLabel, "opacity", 1); // show error
581+ verify(!tutorial.spreadEnabled);
310− tryCompare(errorTitleLabel, "opacity", 1); // show error
582+ verify(!tutorial.panelEnabled);
583+ verify(tutorialBottom.shown);
584+ verify(!launcher.available);
585+ verify(!stage.spreadEnabled);
586+ verify(!panel.indicators.available);
587+ compare(tutorialLabel.text, "Swipe up for recent calls");
313− function test_launcherDragBack() {
590+ function test_tutorialBottomFinish() {
314− // goToPage does a full launcher pull. But here we test pulling
591+ var tutorial = findChild(shell, "tutorial");
315− // all the way out, then dragging back into place.
592+ var tutorialBottom = findChild(tutorial, "tutorialBottom");
317− var left = goToPage("tutorialLeft");
594+ openTutorialBottom();
318− touchFlick(shell, 0, halfHeight, halfWidth, halfHeight, true, false);
595+ touchFlick(shell, halfWidth, shell.height, halfWidth, halfHeight);
319− touchFlick(shell, halfWidth, halfHeight, 0, halfHeight, false, true);
321− tryCompare(left, "shown", true); // and we should still be on left
597+ tryCompare(tutorialBottom, "shown", false);
598+ tryCompare(AccountsService, "demoEdgesCompleted", ["left", "left-long", "top", "right", "bottom-dialer-app"]);
600+ // OK, we did one, just confirm that when all are done, we mark whole tutorial as done.
601+ verify(AccountsService.demoEdges);
602+ AccountsService.demoEdgesCompleted = ["left", "left-long", "top", "right",
603+ "bottom-address-book-app",
604+ "bottom-com.ubuntu.calculator_calculator",
605+ "bottom-dialer-app",
606+ "bottom-messaging-app"];
607+ verify(!AccountsService.demoEdges);
324− function test_launcherNoDragGap() {
610+ function test_tutorialBottomAppearsBeforeRight() {
325− // See bug 1454882, where if you dragged the launcher while it was
611+ // Confirm that if bottom edge and right edge would appear on the
326− // visible, you could pull it further than the edge of the screen.
612+ // the same app open, bottom edge appears first. (this is a lightly
613+ // edited version of openTutorialRight)
614+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
615+ var tutorialRight = findChild(shell, "tutorialRight");
616+ var tutorialBottom = findChild(shell, "tutorialBottom");
328− var left = goToPage("tutorialLeft");
618+ AccountsService.demoEdgesCompleted = ["left", "left-long", "top"];
329− var launcher = findChild(shell, "launcher");
619+ ApplicationManager.startApplication("gallery-app");
330− var teaseAnimation = findInvisibleChild(left, "teaseAnimation");
620+ ApplicationManager.startApplication("dialer-app");
622+ tryCompare(tutorialLeftLoader, "active", false);
623+ tryCompare(tutorialBottom, "shown", true);
624+ tryCompare(tutorialBottom, "opacity", 1);
625+ tryCompare(tutorialRight, "visible", false);
332− // Wait for launcher to be really out there
628+ function test_tutorialBottomOnlyCoversSideStageOnTablet() {
333− tryCompareFunction(function() {return launcher.x > teaseAnimation.maxBounce/2}, true);
629+ loadShell("tablet");
334− verify(teaseAnimation.running);
336− // Start a drag, make sure animation stops
631+ var tutorialBottom = findChild(shell, "tutorialBottom");
337− touchFlick(shell, 0, halfHeight, units.gu(4), halfHeight, true, false);
632+ var targetHeight = shell.height - units.gu(4);
338− verify(!teaseAnimation.running);
633+ var mainStageX = units.gu(20);
339− verify(launcher.visibleWidth > 0);
634+ var sideStageX = shell.width - units.gu(20);
340− verify(launcher.x > 0);
341− compare(launcher.x, teaseAnimation.bounce);
343− // Continue drag, make sure we don't create a gap on the left hand side
636+ WindowStateStorage.saveStage("dialer-app", ApplicationInfoInterface.SideStage);
344− touchFlick(shell, units.gu(4), halfHeight, shell.width, halfHeight, false, false);
637+ openTutorialBottom();
345− verify(!teaseAnimation.running);
346− compare(launcher.visibleWidth, launcher.panelWidth);
347− compare(launcher.x, 0);
349− // Finish and make sure we continue animation
639+ touchFlick(shell, mainStageX, shell.height, mainStageX, targetHeight, true, false);
350− touchFlick(shell, shell.width, halfHeight, shell.width, halfHeight, false, true);
640+ compare(tutorialBottom.opacity, 1);
351− tryCompare(teaseAnimation, "running", true);
641+ touchFlick(shell, mainStageX, shell.height, mainStageX, targetHeight, false, true);
643+ touchFlick(shell, sideStageX, shell.height, sideStageX, targetHeight, true, false);
644+ verify(tutorialBottom.opacity < 1);
645+ touchFlick(shell, sideStageX, shell.height, sideStageX, targetHeight, false, true);
354− function test_spread() {
648+ function test_tutorialBottomOnlyCoversMainStageOnTablet() {
355− // Unfortunately, most of what we want to test of the spread is
649+ loadShell("tablet");
356− // "did it render correctly?" but that's hard to test. So instead,
357− // just poke and prod it a little bit to see if some of the values
358− // we'd expect to be correct, are so.
360− var right = goToPage("tutorialRight");
651+ var tutorialBottom = findChild(shell, "tutorialBottom");
361− var stage = findChild(right, "stage");
652+ var targetHeight = shell.height - units.gu(4);
362− var delegate0 = findChild(right, "appDelegate0");
653+ var mainStageX = units.gu(20);
654+ var sideStageX = shell.width - units.gu(20);
364− tryCompare(stage, "dragProgress", 0);
656+ WindowStateStorage.saveStage("notes-app", ApplicationInfoInterface.SideStage);
365− touchFlick(shell, shell.width, halfHeight, shell.width * 0.8, halfHeight, true, false);
657+ ApplicationManager.startApplication("notes-app");
366− verify(stage.dragProgress > 0);
367− compare(stage.dragProgress, -delegate0.xTranslate);
368− touchFlick(shell, shell.width * 0.8, halfHeight, shell.width, halfHeight, false, true);
369− tryCompare(stage, "dragProgress", 0);
371− tryCompare(delegate0, "x", shell.width);
659+ openTutorialBottom();
373− var screenshotImage = findChild(right, "screenshotImage");
661+ touchFlick(shell, sideStageX, shell.height, sideStageX, targetHeight, true, false);
374− tryCompare(screenshotImage, "source", Qt.resolvedUrl("../../../qml/Tutorial/graphics/facebook.png"));
662+ compare(tutorialBottom.opacity, 1);
375− tryCompare(screenshotImage, "visible", true);
663+ touchFlick(shell, sideStageX, shell.height, sideStageX, targetHeight, false, true);
665+ touchFlick(shell, mainStageX, shell.height, mainStageX, targetHeight, true, false);
666+ verify(tutorialBottom.opacity < 1);
667+ touchFlick(shell, mainStageX, shell.height, mainStageX, targetHeight, false, true);
378− function test_bottomShortDrag() {
670+ function test_activeCallInterruptsTutorial() {
379− var bottom = goToPage("tutorialBottom");
671+ var tutorialLeft = findChild(shell, "tutorialLeft");
672+ verify(tutorialLeft.shown);
673+ verify(!tutorialLeft.paused);
381− touchFlick(shell, halfWidth, shell.height, halfWidth, shell.height * 0.8);
675+ callManager.foregroundCall = phoneCall;
676+ verify(!tutorialLeft.shown);
677+ verify(tutorialLeft.paused);
678+ tryCompare(tutorialLeft, "visible", false);
383− var errorTextLabel = findChild(bottom, "errorTextLabel");
680+ callManager.foregroundCall = null;
384− var errorTitleLabel = findChild(bottom, "errorTitleLabel");
385− tryCompare(bottom, "shown", true); // still on bottom page
681+ tryCompare(tutorialLeft, "shown", true);
386− tryCompare(errorTextLabel, "opacity", 1); // show error
682+ verify(!tutorialLeft.paused);
387− tryCompare(errorTitleLabel, "opacity", 1); // show error
390− function test_interrupted() {
685+ function test_dialerInterruptionWithNoOverlappingTutorials() {
391− goToPage("tutorialLeft");
686+ var tutorialLeft = findChild(shell, "tutorialLeft");
687+ var tutorialBottom = findChild(shell, "tutorialBottom");
688+ verify(tutorialLeft.shown);
690+ // Start call, hiding left tutorial
691+ callManager.foregroundCall = phoneCall;
692+ tryCompare(tutorialLeft, "shown", false);
695+ ApplicationManager.startApplication("dialer-app");
696+ tryCompare(ApplicationManager, "focusedApplicationId", "dialer-app");
697+ verify(!tutorialBottom.shown);
699+ // Dismiss call, bottom tutorial should appear
700+ callManager.foregroundCall = null;
701+ tryCompare(tutorialBottom, "shown", true);
702+ verify(!tutorialLeft.shown);
704+ // Get rid of bottom tutorial, left should now be shown
705+ touchFlick(shell, halfWidth, shell.height, halfWidth, halfHeight);
706+ tryCompare(tutorialBottom, "shown", false);
707+ tryCompare(tutorialLeft, "shown", true);
710+ function test_greeterInterruptsTutorial() {
711+ var tutorialLeft = findChild(shell, "tutorialLeft");
712+ verify(tutorialLeft.shown);
713+ verify(!tutorialLeft.paused);
715+ LightDM.Greeter.showGreeter();
716+ verify(!tutorialLeft.shown);
717+ verify(tutorialLeft.paused);
718+ tryCompare(tutorialLeft, "visible", false);
720+ LightDM.Greeter.hideGreeter();
721+ tryCompare(tutorialLeft, "shown", true);
722+ verify(!tutorialLeft.paused);
725+ function test_interruptionChecksReadyStateWhenDone() {
726+ // If we're done with an interruption (like active call), make sure
727+ // that we don't blindly resume the tutorial -- our trigger
728+ // conditions still need to be met. For example, there need to be
729+ // enough apps open for the right edge tutorial.
731+ openTutorialRight();
733+ var tutorialRight = findChild(shell, "tutorialRight");
734+ verify(tutorialRight.isReady);
735+ verify(tutorialRight.shown);
736+ verify(!tutorialRight.paused);
738+ callManager.foregroundCall = phoneCall;
740+ callManager.foregroundCall = null;
742+ verify(!tutorialRight.isReady);
743+ verify(!tutorialRight.shown);
744+ verify(!tutorialRight.paused);
745+ compare(AccountsService.demoEdgesCompleted, ["left", "left-long", "top"]);
748+ function test_desktopOnlyShowsTutorialRight() {
749+ loadShell("desktop");
751+ var tutorialLeftLoader = findChild(shell, "tutorialLeftLoader");
752+ var tutorialTopLoader = findChild(shell, "tutorialTopLoader");
753+ var tutorialRightLoader = findChild(shell, "tutorialRightLoader");
754+ var tutorialBottomLoader = findChild(shell, "tutorialBottomLoader");
755+ verify(!tutorialLeftLoader.active);
756+ verify(!tutorialTopLoader.active);
757+ verify(tutorialRightLoader.active);
758+ verify(!tutorialBottomLoader.active);
759+ compare(AccountsService.demoEdgesCompleted, []);
392 ApplicationManager.startApplication("dialer-app");
761 ApplicationManager.startApplication("dialer-app");
393− checkFinished();
762+ ApplicationManager.startApplication("camera-app");
763+ tryCompare(tutorialRightLoader.item, "isReady", true);
764+ tryCompare(tutorialRightLoader, "shown", true);
767+ function test_oskDoesNotHideTutorial() {
768+ var tutorialLeft = findChild(shell, "tutorialLeft");
769+ verify(tutorialLeft.shown);
771+ var surface = SurfaceManager.inputMethodSurface;
772+ surface.setState(Mir.RestoredState);
774+ var inputMethod = findInvisibleChild(shell, "inputMethod");
775+ tryCompare(inputMethod, "state", "shown");
777+ verify(tutorialLeft.shown);
780+ function test_oskPreventsTutorial() {
781+ var surface = SurfaceManager.inputMethodSurface;
782+ var inputMethod = findInvisibleChild(shell, "inputMethod");
784+ AccountsService.demoEdges = false;
785+ surface.setState(Mir.RestoredState);
786+ tryCompare(inputMethod, "state", "shown");
788+ var tutorial = findChild(shell, "tutorial");
789+ tryCompare(tutorial, "keyboardVisible", true);
791+ AccountsService.demoEdges = true;
792+ var tutorialLeft = findChild(shell, "tutorialLeft");
793+ verify(!tutorialLeft.shown);
795+ surface.setState(Mir.MinimizedState);
796+ tryCompare(inputMethod, "state", "hidden");
797+ tryCompare(tutorialLeft, "shown", false);
800+ function test_accountsServiceSettings() {
801+ var tutorialLeft = findChild(shell, "tutorialLeft");
802+ verify(tutorialLeft != null);
803+ verify(tutorialLeft.shown);
805+ AccountsService.demoEdges = false;
806+ verify(findChild(shell, "tutorialLeft") == null);
808+ AccountsService.demoEdges = true;
809+ tutorialLeft = findChild(shell, "tutorialLeft");
810+ verify(tutorialLeft != null);
811+ tryCompare(tutorialLeft, "shown", true);