on c15a702 help sign in
unity8/tests/qmltests/Tutorial/tst_Tutorial.qml
348 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 LightDM 0.1 as LightDM
21import Ubuntu.Components 1.1
22import Unity.Application 0.1
23import Unity.Test 0.1 as UT
25import "../../../qml"
27Item {
28 id: root
29 width: shellLoader.width + buttons.width
30 height: shellLoader.height
32 QtObject {
33 id: applicationArguments
35 function hasGeometry() {
36 return false;
37 }
39 function width() {
40 return 0;
41 }
43 function height() {
44 return 0;
45 }
46 }
48 Component.onCompleted: {
49 // must set the mock mode before loading the Shell
50 LightDM.Greeter.mockMode = "single-pin";
51 LightDM.Users.mockMode = "single-pin";
52 shellLoader.active = true;
53 }
55 Row {
56 spacing: 0
57 anchors.fill: parent
59 Loader {
60 id: shellLoader
62 active: false
63 width: units.gu(40)
64 height: units.gu(71)
66 property bool itemDestroyed: false
67 sourceComponent: Component {
68 Shell {
69 property string indicatorProfile: "phone"
71 Component.onDestruction: {
72 shellLoader.itemDestroyed = true;
73 }
74 }
75 }
76 }
78 Rectangle {
79 id: buttons
80 color: "white"
81 width: units.gu(30)
82 height: shellLoader.height
84 Column {
85 anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
86 spacing: units.gu(1)
87 Row {
88 anchors { left: parent.left; right: parent.right }
89 Button {
90 text: "Restart Tutorial"
91 onClicked: {
92 if (shellLoader.status !== Loader.Ready)
93 return;
95 AccountsService.demoEdges = false;
96 AccountsService.demoEdges = true;
97 }
98 }
99 }
100 }
101 }
102 }
104 UT.UnityTestCase {
105 id: testCase
106 name: "Tutorial"
107 when: windowShown
109 property Item shell: shellLoader.status === Loader.Ready ? shellLoader.item : null
110 property real halfWidth: shell ? shell.width / 2 : 0
111 property real halfHeight: shell ? shell.height / 2 : 0
113 function init() {
114 tryCompare(shell, "enabled", true); // enabled by greeter when ready
115 swipeAwayGreeter();
116 AccountsService.demoEdges = false;
117 AccountsService.demoEdges = true;
118 }
120 function cleanup() {
121 shellLoader.itemDestroyed = false;
123 shellLoader.active = false;
125 tryCompare(shellLoader, "status", Loader.Null);
126 tryCompare(shellLoader, "item", null);
127 // Loader.status might be Loader.Null and Loader.item might be null but the Loader
128 // item might still be alive. So if we set Loader.active back to true
129 // again right now we will get the very same Shell instance back. So no reload
130 // actually took place. Likely because Loader waits until the next event loop
131 // iteration to do its work. So to ensure the reload, we will wait until the
132 // Shell instance gets destroyed.
133 tryCompare(shellLoader, "itemDestroyed", true);
135 // kill all (fake) running apps
136 killApps();
138 // reload our test subject to get it in a fresh state once again
139 shellLoader.active = true;
141 tryCompare(shellLoader, "status", Loader.Ready);
142 removeTimeConstraintsFromDirectionalDragAreas(shellLoader.item);
143 }
145 function killApps() {
146 while (ApplicationManager.count > 1) {
147 var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0
148 ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId);
149 }
150 compare(ApplicationManager.count, 1)
151 }
153 function swipeAwayGreeter() {
154 var greeter = findChild(shell, "greeter");
155 tryCompare(greeter, "showProgress", 1);
157 touchFlick(shell, halfWidth, halfHeight, shell.width, halfHeight);
159 // wait until the animation has finished
160 tryCompare(greeter, "showProgress", 0);
161 waitForRendering(greeter);
162 }
164 function waitForPage(name) {
165 waitForRendering(findChild(shell, name));
166 var page = findChild(shell, name);
167 tryCompare(page, "shown", true);
168 tryCompare(page.showAnimation, "running", false);
169 return page;
170 }
172 function checkTopEdge() {
173 touchFlick(shell, halfWidth, 0, halfWidth, halfHeight);
175 var panel = findChild(shell, "panel");
176 tryCompare(panel.indicators, "fullyClosed", true);
177 }
179 function checkLeftEdge() {
180 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
182 var launcher = findChild(shell, "launcher");
183 tryCompare(launcher, "state", "");
184 }
186 function checkRightEdge() {
187 touchFlick(shell, shell.width, halfHeight, halfWidth, halfHeight);
189 var stage = findChild(shell, "stage");
190 var spreadView = findChild(stage, "spreadView");
191 tryCompare(spreadView, "phase", 0);
192 }
194 function checkBottomEdge() {
195 // Can't actually check effect of swipe, since dash isn't really loaded
196 var applicationsDisplayLoader = findChild(shell, "applicationsDisplayLoader");
197 tryCompare(applicationsDisplayLoader.item, "interactive", false);
198 }
200 function checkFinished() {
201 tryCompare(AccountsService, "demoEdges", false);
203 var tutorial = findChild(shell, "tutorial");
204 tryCompare(tutorial, "running", false);
206 var launcher = findChild(shell, "launcher");
207 tryCompare(launcher, "shown", false);
208 }
210 function goToPage(name) {
211 var page = waitForPage("tutorialLeft");
212 checkTopEdge();
213 checkRightEdge();
214 checkBottomEdge();
215 if (name === "tutorialLeft") return page;
216 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight);
218 page = waitForPage("tutorialLeftFinish");
219 if (name === "tutorialLeftFinish") return page;
220 var tick = findChild(page, "tick");
221 tap(tick);
223 page = waitForPage("tutorialRight");
224 checkTopEdge();
225 checkLeftEdge();
226 checkBottomEdge();
227 if (name === "tutorialRight") return page;
228 touchFlick(shell, shell.width, halfHeight, halfWidth, halfHeight);
229 var overlay = findChild(page, "overlay");
230 tryCompare(overlay, "shown", true);
231 var tick = findChild(page, "tick");
232 tap(tick);
234 var page = waitForPage("tutorialBottom");
235 checkTopEdge();
236 checkLeftEdge();
237 checkRightEdge();
238 if (name === "tutorialBottom") return page;
239 touchFlick(shell, halfWidth, shell.height, halfWidth, halfHeight);
241 var page = waitForPage("tutorialBottomFinish");
242 checkTopEdge();
243 checkLeftEdge();
244 checkRightEdge();
245 checkBottomEdge();
246 if (name === "tutorialBottomFinish") return page;
247 var tick = findChild(page, "tick");
248 tap(tick);
250 checkFinished();
251 return null;
252 }
254 function test_walkthrough() {
255 goToPage(null);
256 }
258 function test_launcherShortDrag() {
259 // goToPage does a normal launcher pull. But here we want to test
260 // just barely pulling the launcher out and letting go (i.e. not
261 // triggering the "progress" property of Launcher).
263 var left = goToPage("tutorialLeft");
265 // Make sure we don't do anything if we don't pull the launcher
266 // out much.
267 var launcher = findChild(shell, "launcher");
268 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.4, halfHeight);
269 tryCompare(launcher, "state", ""); // should remain hidden
270 tryCompare(left, "shown", true); // and we should still be on left
272 // Now drag out but not past launcher itself
273 touchFlick(shell, 0, halfHeight, launcher.panelWidth * 0.9, halfHeight);
275 waitForPage("tutorialLeftFinish");
276 }
278 function test_launcherLongDrag() {
279 // goToPage does a normal launcher pull. But here we want to test
280 // a full pull across the page.
282 var left = goToPage("tutorialLeft");
284 var launcher = findChild(shell, "launcher");
285 touchFlick(shell, 0, halfHeight, shell.width, halfHeight);
287 var errorTextLabel = findChild(left, "errorTextLabel");
288 var errorTitleLabel = findChild(left, "errorTitleLabel");
289 tryCompare(launcher, "state", ""); // launcher goes away
290 tryCompare(left, "shown", true); // still on left page
291 tryCompare(errorTextLabel, "opacity", 1); // show error
292 tryCompare(errorTitleLabel, "opacity", 1); // show error
293 }
295 function test_launcherDragBack() {
296 // goToPage does a full launcher pull. But here we test pulling
297 // all the way out, then dragging back into place.
299 var left = goToPage("tutorialLeft");
300 touchFlick(shell, 0, halfHeight, halfWidth, halfHeight, true, false);
301 touchFlick(shell, halfWidth, halfHeight, 0, halfHeight, false, true);
303 tryCompare(left, "shown", true); // and we should still be on left
304 }
306 function test_spread() {
307 // Unfortunately, most of what we want to test of the spread is
308 // "did it render correctly?" but that's hard to test. So instead,
309 // just poke and prod it a little bit to see if some of the values
310 // we'd expect to be correct, are so.
312 var right = goToPage("tutorialRight");
313 var stage = findChild(right, "stage");
314 var delegate0 = findChild(right, "appDelegate0");
316 tryCompare(stage, "dragProgress", 0);
317 touchFlick(shell, shell.width, halfHeight, shell.width * 0.8, halfHeight, true, false);
318 verify(stage.dragProgress > 0);
319 compare(stage.dragProgress, -delegate0.xTranslate);
320 touchFlick(shell, shell.width * 0.8, halfHeight, shell.width, halfHeight, false, true);
321 tryCompare(stage, "dragProgress", 0);
323 tryCompare(delegate0, "x", shell.width);
325 var screenshotImage = findChild(right, "screenshotImage");
326 tryCompare(screenshotImage, "source", Qt.resolvedUrl("../../../qml/Tutorial/graphics/facebook.png"));
327 tryCompare(screenshotImage, "visible", true);
328 }
330 function test_bottomShortDrag() {
331 var bottom = goToPage("tutorialBottom");
333 touchFlick(shell, halfWidth, shell.height, halfWidth, shell.height * 0.8);
335 var errorTextLabel = findChild(bottom, "errorTextLabel");
336 var errorTitleLabel = findChild(bottom, "errorTitleLabel");
337 tryCompare(bottom, "shown", true); // still on bottom page
338 tryCompare(errorTextLabel, "opacity", 1); // show error
339 tryCompare(errorTitleLabel, "opacity", 1); // show error
340 }
342 function test_interrupted() {
343 goToPage("tutorialLeft");
344 ApplicationManager.startApplication("dialer-app");
345 checkFinished();
346 }
347 }