on 4cd8d7c help sign in
unity8/tests/qmltests/Tutorial/tst_Tutorial.qml
365 lines 13 kB history raw
1/*
2 * Copyright (C) 2013,2014 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.0
18import QtTest 1.0
19import AccountsService 0.1
20import GSettings 1.0
21import IntegratedLightDM 0.1 as LightDM
22import Ubuntu.Components 1.1
23import Unity.Application 0.1
24import Unity.Test 0.1 as UT
26import "../../../qml"
28Item {
29 id: root
30 width: shellLoader.width + buttons.width
31 height: shellLoader.height
33 QtObject {
34 id: applicationArguments
36 function hasGeometry() {
37 return false;
38 }
40 function width() {
41 return 0;
42 }
44 function height() {
45 return 0;
46 }
47 }
49 Component.onCompleted: {
50 // must set the mock mode before loading the Shell
51 LightDM.Greeter.mockMode = "single-pin";
52 LightDM.Users.mockMode = "single-pin";
53 shellLoader.active = true;
54 }
56 Row {
57 spacing: 0
58 anchors.fill: parent
60 Loader {
61 id: shellLoader
63 active: false
64 width: units.gu(40)
65 height: units.gu(71)
67 property bool itemDestroyed: false
68 sourceComponent: Component {
69 Shell {
70 property string indicatorProfile: "phone"
72 Component.onDestruction: {
73 shellLoader.itemDestroyed = true;
74 }
75 }
76 }
77 }
79 Rectangle {
80 id: buttons
81 color: "white"
82 width: units.gu(30)
83 height: shellLoader.height
85 Column {
86 anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
87 spacing: units.gu(1)
88 Row {
89 anchors { left: parent.left; right: parent.right }
90 Button {
91 text: "Restart Tutorial"
92 onClicked: {
93 if (shellLoader.status !== Loader.Ready)
94 return;
96 AccountsService.demoEdges = false;
97 AccountsService.demoEdges = true;
98 }
99 }
100 }
101 }
102 }
103 }
105 UT.UnityTestCase {
106 id: testCase
107 name: "Tutorial"
108 when: windowShown
110 property Item shell: shellLoader.status === Loader.Ready ? shellLoader.item : null
111 property real halfWidth: shell ? shell.width / 2 : 0
112 property real halfHeight: shell ? shell.height / 2 : 0
114 function init() {
115 tryCompare(shell, "enabled", true); // enabled by greeter when ready
117 AccountsService.demoEdges = false;
118 AccountsService.demoEdges = true;
119 swipeAwayGreeter();
120 }
122 function cleanup() {
123 shellLoader.itemDestroyed = false;
125 shellLoader.active = false;
127 tryCompare(shellLoader, "status", Loader.Null);
128 tryCompare(shellLoader, "item", null);
129 // Loader.status might be Loader.Null and Loader.item might be null but the Loader
130 // item might still be alive. So if we set Loader.active back to true
131 // again right now we will get the very same Shell instance back. So no reload
132 // actually took place. Likely because Loader waits until the next event loop
133 // iteration to do its work. So to ensure the reload, we will wait until the
134 // Shell instance gets destroyed.
135 tryCompare(shellLoader, "itemDestroyed", true);
137 // kill all (fake) running apps
138 killApps();
140 // reload our test subject to get it in a fresh state once again
141 shellLoader.active = true;
143 tryCompare(shellLoader, "status", Loader.Ready);
144 removeTimeConstraintsFromDirectionalDragAreas(shellLoader.item);
145 }
147 function killApps() {
148 while (ApplicationManager.count > 1) {
149 var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0
150 ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId);
151 }
152 compare(ApplicationManager.count, 1)
153 }
155 function swipeAwayGreeter() {
156 var coverPage = findChild(shell, "coverPage");
157 tryCompare(coverPage, "showProgress", 1);
159 touchFlick(shell, halfWidth, halfHeight, shell.width, halfHeight);
161 // wait until the animation has finished
162 var greeter = findChild(shell, "greeter");
163 tryCompare(greeter, "required", false);
164 waitForRendering(greeter);
165 }
167 function waitForPage(name) {
168 waitForRendering(findChild(shell, name));
169 var page = findChild(shell, name);
170 tryCompare(page, "shown", true);
171 tryCompare(page.showAnimation, "running", false);
172 return page;
173 }
175 function checkTopEdge() {
176 touchFlick(shell, halfWidth, 0, halfWidth, halfHeight);
178 var panel = findChild(shell, "panel");
179 tryCompare(panel.indicators, "fullyClosed", true);
180 }
182 function checkLeftEdge() {
183 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
185 var launcher = findChild(shell, "launcher");
186 tryCompare(launcher, "state", "");
187 }
189 function checkRightEdge() {
190 if (shell.usageScenario === "phone") {
191 touchFlick(shell, shell.width, halfHeight, halfWidth, halfHeight);
193 var stage = findChild(shell, "stage");
194 var spreadView = findChild(stage, "spreadView");
195 tryCompare(spreadView, "phase", 0);
196 }
197 }
199 function checkBottomEdge() {
200 // Can't actually check effect of swipe, since dash isn't really loaded
201 var applicationsDisplayLoader = findChild(shell, "applicationsDisplayLoader");
202 tryCompare(applicationsDisplayLoader, "interactive", false);
203 }
205 function checkFinished() {
206 tryCompare(AccountsService, "demoEdges", false);
208 var tutorial = findChild(shell, "tutorial");
209 tryCompare(tutorial, "running", false);
211 var launcher = findChild(shell, "launcher");
212 tryCompare(launcher, "shown", false);
213 }
215 function goToPage(name) {
216 var page = waitForPage("tutorialLeft");
217 checkTopEdge();
218 checkRightEdge();
219 checkBottomEdge();
220 if (name === "tutorialLeft") return page;
221 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
223 page = waitForPage("tutorialLeftFinish");
224 if (name === "tutorialLeftFinish") return page;
225 var tick = findChild(page, "tick");
226 tap(tick);
228 page = waitForPage("tutorialRight");
229 checkTopEdge();
230 checkLeftEdge();
231 checkBottomEdge();
232 if (name === "tutorialRight") return page;
233 touchFlick(shell,
234 shell.width, halfHeight,
235 halfWidth, halfHeight,
236 true /* beginTouch */, true /* endTouch */,
237 20 /* speed */, 50 /* iterations */);
238 var overlay = findChild(page, "overlay");
239 tryCompare(overlay, "shown", true);
240 var tick = findChild(page, "tick");
241 tap(tick);
243 var page = waitForPage("tutorialBottom");
244 checkTopEdge();
245 checkLeftEdge();
246 checkRightEdge();
247 if (name === "tutorialBottom") return page;
248 touchFlick(shell, halfWidth, shell.height, halfWidth, halfHeight);
250 var page = waitForPage("tutorialBottomFinish");
251 checkTopEdge();
252 checkLeftEdge();
253 checkRightEdge();
254 checkBottomEdge();
255 if (name === "tutorialBottomFinish") return page;
256 var tick = findChild(page, "tick");
257 tap(tick);
259 checkFinished();
260 return null;
261 }
263 function test_walkthrough() {
264 goToPage(null);
265 }
267 function test_walkthroughOnDesktop() {
268 shell.usageScenario = "desktop";
269 var page = goToPage("tutorialLeftFinish");
270 var tick = findChild(page, "tick");
271 tap(tick);
272 checkFinished();
273 }
275 function test_launcherShortDrag() {
276 // goToPage does a normal launcher pull. But here we want to test
277 // just barely pulling the launcher out and letting go (i.e. not
278 // triggering the "progress" property of Launcher).
280 var left = goToPage("tutorialLeft");
282 // Make sure we don't do anything if we don't pull the launcher
283 // out much.
284 var launcher = findChild(shell, "launcher");
285 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight);
286 tryCompare(launcher, "state", ""); // should remain hidden
287 tryCompare(left, "shown", true); // and we should still be on left
289 // Now drag out but not past launcher itself
290 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.9, halfHeight);
292 waitForPage("tutorialLeftFinish");
293 }
295 function test_launcherLongDrag() {
296 // goToPage does a normal launcher pull. But here we want to test
297 // a full pull across the page.
299 var left = goToPage("tutorialLeft");
301 var launcher = findChild(shell, "launcher");
302 touchFlick(shell, 0, halfHeight, shell.width, halfHeight);
304 var errorTextLabel = findChild(left, "errorTextLabel");
305 var errorTitleLabel = findChild(left, "errorTitleLabel");
306 tryCompare(launcher, "state", ""); // launcher goes away
307 tryCompare(left, "shown", true); // still on left page
308 tryCompare(errorTextLabel, "opacity", 1); // show error
309 tryCompare(errorTitleLabel, "opacity", 1); // show error
310 }
312 function test_launcherDragBack() {
313 // goToPage does a full launcher pull. But here we test pulling
314 // all the way out, then dragging back into place.
316 var left = goToPage("tutorialLeft");
317 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight, true, false);
318 touchFlick(shell, halfWidth, halfHeight, 0, halfHeight, false, true);
320 tryCompare(left, "shown", true); // and we should still be on left
321 }
323 function test_spread() {
324 // Unfortunately, most of what we want to test of the spread is
325 // "did it render correctly?" but that's hard to test. So instead,
326 // just poke and prod it a little bit to see if some of the values
327 // we'd expect to be correct, are so.
329 var right = goToPage("tutorialRight");
330 var stage = findChild(right, "stage");
331 var delegate0 = findChild(right, "appDelegate0");
333 tryCompare(stage, "dragProgress", 0);
334 touchFlick(shell, shell.width, halfHeight, shell.width * 0.8, halfHeight, true, false);
335 verify(stage.dragProgress > 0);
336 compare(stage.dragProgress, -delegate0.xTranslate);
337 touchFlick(shell, shell.width * 0.8, halfHeight, shell.width, halfHeight, false, true);
338 tryCompare(stage, "dragProgress", 0);
340 tryCompare(delegate0, "x", shell.width);
342 var screenshotImage = findChild(right, "screenshotImage");
343 tryCompare(screenshotImage, "source", Qt.resolvedUrl("../../../qml/Tutorial/graphics/facebook.png"));
344 tryCompare(screenshotImage, "visible", true);
345 }
347 function test_bottomShortDrag() {
348 var bottom = goToPage("tutorialBottom");
350 touchFlick(shell, halfWidth, shell.height, halfWidth, shell.height * 0.8);
352 var errorTextLabel = findChild(bottom, "errorTextLabel");
353 var errorTitleLabel = findChild(bottom, "errorTitleLabel");
354 tryCompare(bottom, "shown", true); // still on bottom page
355 tryCompare(errorTextLabel, "opacity", 1); // show error
356 tryCompare(errorTitleLabel, "opacity", 1); // show error
357 }
359 function test_interrupted() {
360 goToPage("tutorialLeft");
361 ApplicationManager.startApplication("dialer-app");
362 checkFinished();
363 }
364 }