on c42e54e help sign in
unity8/tests/qmltests/Tutorial/tst_Tutorial.qml
370 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 LightDM 0.1 as LightDM
22import Ubuntu.Components 1.3
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 GSettings {
50 id: unity8Settings
51 schema.id: "com.canonical.Unity8"
52 }
54 Component.onCompleted: {
55 // must set the mock mode before loading the Shell
56 LightDM.Greeter.mockMode = "single-pin";
57 LightDM.Users.mockMode = "single-pin";
58 shellLoader.active = true;
59 }
61 Row {
62 spacing: 0
63 anchors.fill: parent
65 Loader {
66 id: shellLoader
68 active: false
69 width: units.gu(40)
70 height: units.gu(71)
72 property bool itemDestroyed: false
73 sourceComponent: Component {
74 Shell {
75 property string indicatorProfile: "phone"
77 Component.onDestruction: {
78 shellLoader.itemDestroyed = true;
79 }
80 }
81 }
82 }
84 Rectangle {
85 id: buttons
86 color: "white"
87 width: units.gu(30)
88 height: shellLoader.height
90 Column {
91 anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
92 spacing: units.gu(1)
93 Row {
94 anchors { left: parent.left; right: parent.right }
95 Button {
96 text: "Restart Tutorial"
97 onClicked: {
98 if (shellLoader.status !== Loader.Ready)
99 return;
101 AccountsService.demoEdges = false;
102 AccountsService.demoEdges = true;
103 }
104 }
105 }
106 }
107 }
108 }
110 UT.UnityTestCase {
111 id: testCase
112 name: "Tutorial"
113 when: windowShown
115 property Item shell: shellLoader.status === Loader.Ready ? shellLoader.item : null
116 property real halfWidth: shell ? shell.width / 2 : 0
117 property real halfHeight: shell ? shell.height / 2 : 0
119 function init() {
120 tryCompare(shell, "enabled", true); // enabled by greeter when ready
121 unity8Settings.usageMode = "Staged";
122 AccountsService.demoEdges = false;
123 AccountsService.demoEdges = true;
124 swipeAwayGreeter();
125 }
127 function cleanup() {
128 shellLoader.itemDestroyed = false;
130 shellLoader.active = false;
132 tryCompare(shellLoader, "status", Loader.Null);
133 tryCompare(shellLoader, "item", null);
134 // Loader.status might be Loader.Null and Loader.item might be null but the Loader
135 // item might still be alive. So if we set Loader.active back to true
136 // again right now we will get the very same Shell instance back. So no reload
137 // actually took place. Likely because Loader waits until the next event loop
138 // iteration to do its work. So to ensure the reload, we will wait until the
139 // Shell instance gets destroyed.
140 tryCompare(shellLoader, "itemDestroyed", true);
142 // kill all (fake) running apps
143 killApps();
145 // reload our test subject to get it in a fresh state once again
146 shellLoader.active = true;
148 tryCompare(shellLoader, "status", Loader.Ready);
149 removeTimeConstraintsFromDirectionalDragAreas(shellLoader.item);
150 }
152 function killApps() {
153 while (ApplicationManager.count > 1) {
154 var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0
155 ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId);
156 }
157 compare(ApplicationManager.count, 1)
158 }
160 function swipeAwayGreeter() {
161 var coverPage = findChild(shell, "coverPage");
162 tryCompare(coverPage, "showProgress", 1);
164 touchFlick(shell, halfWidth, halfHeight, shell.width, halfHeight);
166 // wait until the animation has finished
167 var greeter = findChild(shell, "greeter");
168 tryCompare(greeter, "required", false);
169 waitForRendering(greeter);
170 }
172 function waitForPage(name) {
173 waitForRendering(findChild(shell, name));
174 var page = findChild(shell, name);
175 tryCompare(page, "shown", true);
176 tryCompare(page.showAnimation, "running", false);
177 return page;
178 }
180 function checkTopEdge() {
181 touchFlick(shell, halfWidth, 0, halfWidth, halfHeight);
183 var panel = findChild(shell, "panel");
184 tryCompare(panel.indicators, "fullyClosed", true);
185 }
187 function checkLeftEdge() {
188 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
190 var launcher = findChild(shell, "launcher");
191 tryCompare(launcher, "state", "");
192 }
194 function checkRightEdge() {
195 if (unity8Settings.usageMode === "Staged") {
196 touchFlick(shell, shell.width, halfHeight, halfWidth, halfHeight);
198 var stage = findChild(shell, "stage");
199 var spreadView = findChild(stage, "spreadView");
200 tryCompare(spreadView, "phase", 0);
201 }
202 }
204 function checkBottomEdge() {
205 // Can't actually check effect of swipe, since dash isn't really loaded
206 var applicationsDisplayLoader = findChild(shell, "applicationsDisplayLoader");
207 tryCompare(applicationsDisplayLoader, "interactive", false);
208 }
210 function checkFinished() {
211 tryCompare(AccountsService, "demoEdges", false);
213 var tutorial = findChild(shell, "tutorial");
214 tryCompare(tutorial, "running", false);
216 var launcher = findChild(shell, "launcher");
217 tryCompare(launcher, "shown", false);
218 }
220 function goToPage(name) {
221 var page = waitForPage("tutorialLeft");
222 checkTopEdge();
223 checkRightEdge();
224 checkBottomEdge();
225 if (name === "tutorialLeft") return page;
226 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
228 page = waitForPage("tutorialLeftFinish");
229 if (name === "tutorialLeftFinish") return page;
230 var tick = findChild(page, "tick");
231 tap(tick);
233 page = waitForPage("tutorialRight");
234 checkTopEdge();
235 checkLeftEdge();
236 checkBottomEdge();
237 if (name === "tutorialRight") return page;
238 touchFlick(shell,
239 shell.width, halfHeight,
240 halfWidth, halfHeight,
241 true /* beginTouch */, true /* endTouch */,
242 20 /* speed */, 50 /* iterations */);
243 var overlay = findChild(page, "overlay");
244 tryCompare(overlay, "shown", true);
245 var tick = findChild(page, "tick");
246 tap(tick);
248 var page = waitForPage("tutorialBottom");
249 checkTopEdge();
250 checkLeftEdge();
251 checkRightEdge();
252 if (name === "tutorialBottom") return page;
253 touchFlick(shell, halfWidth, shell.height, halfWidth, halfHeight);
255 var page = waitForPage("tutorialBottomFinish");
256 checkTopEdge();
257 checkLeftEdge();
258 checkRightEdge();
259 checkBottomEdge();
260 if (name === "tutorialBottomFinish") return page;
261 var tick = findChild(page, "tick");
262 tap(tick);
264 checkFinished();
265 return null;
266 }
268 function test_walkthrough() {
269 goToPage(null);
270 }
272 function test_walkthroughOnDesktop() {
273 unity8Settings.usageMode = "Windowed";
274 var page = goToPage("tutorialLeftFinish");
275 var tick = findChild(page, "tick");
276 tap(tick);
277 checkFinished();
278 }
280 function test_launcherShortDrag() {
281 // goToPage does a normal launcher pull. But here we want to test
282 // just barely pulling the launcher out and letting go (i.e. not
283 // triggering the "progress" property of Launcher).
285 var left = goToPage("tutorialLeft");
287 // Make sure we don't do anything if we don't pull the launcher
288 // out much.
289 var launcher = findChild(shell, "launcher");
290 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight);
291 tryCompare(launcher, "state", ""); // should remain hidden
292 tryCompare(left, "shown", true); // and we should still be on left
294 // Now drag out but not past launcher itself
295 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.9, halfHeight);
297 waitForPage("tutorialLeftFinish");
298 }
300 function test_launcherLongDrag() {
301 // goToPage does a normal launcher pull. But here we want to test
302 // a full pull across the page.
304 var left = goToPage("tutorialLeft");
306 var launcher = findChild(shell, "launcher");
307 touchFlick(shell, 0, halfHeight, shell.width, halfHeight);
309 var errorTextLabel = findChild(left, "errorTextLabel");
310 var errorTitleLabel = findChild(left, "errorTitleLabel");
311 tryCompare(launcher, "state", ""); // launcher goes away
312 tryCompare(left, "shown", true); // still on left page
313 tryCompare(errorTextLabel, "opacity", 1); // show error
314 tryCompare(errorTitleLabel, "opacity", 1); // show error
315 }
317 function test_launcherDragBack() {
318 // goToPage does a full launcher pull. But here we test pulling
319 // all the way out, then dragging back into place.
321 var left = goToPage("tutorialLeft");
322 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight, true, false);
323 touchFlick(shell, halfWidth, halfHeight, 0, halfHeight, false, true);
325 tryCompare(left, "shown", true); // and we should still be on left
326 }
328 function test_spread() {
329 // Unfortunately, most of what we want to test of the spread is
330 // "did it render correctly?" but that's hard to test. So instead,
331 // just poke and prod it a little bit to see if some of the values
332 // we'd expect to be correct, are so.
334 var right = goToPage("tutorialRight");
335 var stage = findChild(right, "stage");
336 var delegate0 = findChild(right, "appDelegate0");
338 tryCompare(stage, "dragProgress", 0);
339 touchFlick(shell, shell.width, halfHeight, shell.width * 0.8, halfHeight, true, false);
340 verify(stage.dragProgress > 0);
341 compare(stage.dragProgress, -delegate0.xTranslate);
342 touchFlick(shell, shell.width * 0.8, halfHeight, shell.width, halfHeight, false, true);
343 tryCompare(stage, "dragProgress", 0);
345 tryCompare(delegate0, "x", shell.width);
347 var screenshotImage = findChild(right, "screenshotImage");
348 tryCompare(screenshotImage, "source", Qt.resolvedUrl("../../../qml/Tutorial/graphics/facebook.png"));
349 tryCompare(screenshotImage, "visible", true);
350 }
352 function test_bottomShortDrag() {
353 var bottom = goToPage("tutorialBottom");
355 touchFlick(shell, halfWidth, shell.height, halfWidth, shell.height * 0.8);
357 var errorTextLabel = findChild(bottom, "errorTextLabel");
358 var errorTitleLabel = findChild(bottom, "errorTitleLabel");
359 tryCompare(bottom, "shown", true); // still on bottom page
360 tryCompare(errorTextLabel, "opacity", 1); // show error
361 tryCompare(errorTitleLabel, "opacity", 1); // show error
362 }
364 function test_interrupted() {
365 goToPage("tutorialLeft");
366 ApplicationManager.startApplication("dialer-app");
367 checkFinished();
368 }
369 }