2 * Copyright 2014-2016 Canonical Ltd.
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.
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.
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/>.
18import QtQuick.Layouts 1.1
20import Unity.Test 0.1 as UT
22import "../../../qml/Stage"
23import Ubuntu.Components 1.3
24import Ubuntu.Components.ListItems 1.3 as ListItem
25import Unity.Application 0.1
33 Component.onCompleted: {
34 root.fakeApplication = ApplicationManager.add("gallery-app");
35 root.fakeApplication.manualSurfaceCreation = true;
36 applicationWindowLoader.item.application = root.fakeApplication;
38 property QtObject fakeApplication: null
43 id: applicationWindowLoader
51 property bool itemDestroyed: false
52 sourceComponent: Component {
55 surfaceOrientationAngle: 0
59 requestedHeight: height
60 Component.onDestruction: {
61 applicationWindowLoader.itemDestroyed = true;
72 left: applicationWindowLoader.right
77 anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
81 Layout.fillWidth: true
86 activeFocusOnPress: false
88 if (applicationWindowLoader.status !== Loader.Ready)
92 root.fakeApplication.createSurface();
93 applicationWindowLoader.item.surface = root.fakeApplication.surfaceList.get(0);
95 if (applicationWindowLoader.item.surface) {
96 applicationWindowLoader.item.surface.setLive(false);
103 anchors.verticalCenter: parent.verticalCenter
108 property var promptSurfaceList: root.fakeApplication ? root.fakeApplication.promptSurfaceList : null
110 enabled: root.fakeApplication && root.fakeApplication.promptSurfaceList.count > 0
111 activeFocusOnPress: false
113 onClicked: { root.fakeApplication.promptSurfaceList.get(0).close(); }
117 enabled: root.fakeApplication
118 activeFocusOnPress: false
119 text: "Add Prompt Surface"
120 onClicked: { root.fakeApplication.createPromptSurface(); }
124 ListItem.ItemSelector {
126 activeFocusOnPress: false
127 anchors { left: parent.left; right: parent.right }
128 text: "Application state"
133 property int selectedApplicationState: {
134 if (model[selectedIndex] === "Starting") {
135 return ApplicationInfoInterface.Starting;
136 } else if (model[selectedIndex] === "Running") {
137 return ApplicationInfoInterface.Running;
138 } else if (model[selectedIndex] === "Suspended") {
139 return ApplicationInfoInterface.Suspended;
141 return ApplicationInfoInterface.Stopped;
144 onSelectedApplicationStateChanged: {
145 // state is a read-only property, thus we have to call the setter function
146 if (fakeApplication && fakeApplication.state != selectedApplicationState) {
147 fakeApplication.setState(selectedApplicationState);
151 target: fakeApplication
153 testCase.setApplicationState(state);
162 name: "ApplicationWindow"
165 // just to make them shorter
166 property int appStarting: ApplicationInfoInterface.Starting
167 property int appRunning: ApplicationInfoInterface.Running
168 property int appSuspended: ApplicationInfoInterface.Suspended
169 property int appStopped: ApplicationInfoInterface.Stopped
171 function setApplicationState(appState) {
174 appStateSelector.selectedIndex = 0;
177 appStateSelector.selectedIndex = 1;
180 appStateSelector.selectedIndex = 2;
183 appStateSelector.selectedIndex = 3;
188 property var applicationWindow: applicationWindowLoader.item
190 // holds some of the internal ApplicationWindow objects we probe during the tests
191 property var stateGroup: null
193 function findInterestingApplicationWindowChildren() {
194 stateGroup = findInvisibleChild(applicationWindowLoader.item, "applicationWindowStateGroup");
198 function forgetApplicationWindowChildren() {
203 findInterestingApplicationWindowChildren();
207 forgetApplicationWindowChildren();
209 applicationWindowLoader.itemDestroyed = false;
211 // reload our test subject to get it in a fresh state once again
212 applicationWindowLoader.active = false;
214 tryCompare(applicationWindowLoader, "status", Loader.Null);
215 tryCompare(applicationWindowLoader, "item", null);
216 // Loader.status might be Loader.Null and Loader.item might be null but the Loader
217 // item might still be alive. So if we set Loader.active back to true
218 // again right now we will get the very same ApplicationWindow instance back. So no reload
219 // actually took place. Likely because Loader waits until the next event loop
220 // iteration to do its work. So to ensure the reload, we will wait until the
221 // ApplicationWindow instance gets destroyed.
222 // Another thing that happens is that we do get a new object but the old one doesn't get
223 // deleted, so you end up with two instances in memory.
224 tryCompare(applicationWindowLoader, "itemDestroyed", true);
226 surfaceCheckbox.checked = false;
230 root.fakeApplication = ApplicationManager.add("gallery-app");
231 root.fakeApplication.manualSurfaceCreation = true;
233 applicationWindowLoader.active = true;
235 applicationWindowLoader.item.application = root.fakeApplication;
238 function waitUntilSurfaceContainerStopsAnimating(container) {
239 var animationsLoader = findChild(container, "animationsLoader");
240 verify(animationsLoader);
241 tryCompare(animationsLoader, "status", Loader.Ready)
243 var animation = animationsLoader.item;
244 waitUntilTransitionsEnd(animation);
247 function test_showSplashUntilAppFullyInit_data() {
249 {tag: "state=Running then create surface", swapInitOrder: false},
251 {tag: "create surface then state=Running", swapInitOrder: true},
255 function test_showSplashUntilAppFullyInit() {
256 verify(stateGroup.state === "splashScreen");
258 if (data.swapInitOrder) {
259 surfaceCheckbox.checked = true;
261 setApplicationState(appRunning);
264 verify(stateGroup.state === "splashScreen");
266 if (data.swapInitOrder) {
267 setApplicationState(appRunning);
269 surfaceCheckbox.checked = true;
272 tryCompare(stateGroup, "state", "surface");
275 function test_suspendedAppShowsSurface() {
276 surfaceCheckbox.checked = true;
277 setApplicationState(appRunning);
279 tryCompare(stateGroup, "state", "surface");
281 waitUntilTransitionsEnd(stateGroup);
283 setApplicationState(appSuspended);
285 verify(stateGroup.state === "surface");
286 waitUntilTransitionsEnd(stateGroup);
289 function test_killedAppShowsScreenshot() {
290 surfaceCheckbox.checked = true;
291 setApplicationState(appRunning);
292 tryCompare(stateGroup, "state", "surface");
294 setApplicationState(appSuspended);
296 verify(stateGroup.state === "surface");
297 verify(fakeApplication.surface !== null);
300 surfaceCheckbox.checked = false;
301 setApplicationState(appStopped);
303 tryCompare(stateGroup, "state", "screenshot");
304 tryCompare(fakeApplication.surfaceList, "count", 0);
307 function test_restartApp() {
308 var screenshotImage = findChild(applicationWindow, "screenshotImage");
310 surfaceCheckbox.checked = true;
311 setApplicationState(appRunning);
312 tryCompare(stateGroup, "state", "surface");
313 waitUntilTransitionsEnd(stateGroup);
315 setApplicationState(appSuspended);
318 surfaceCheckbox.checked = false;
319 setApplicationState(appStopped);
321 tryCompare(stateGroup, "state", "screenshot");
322 waitUntilTransitionsEnd(stateGroup);
323 tryCompare(applicationWindow, "surface", null);
326 setApplicationState(appStarting);
328 waitUntilTransitionsEnd(stateGroup);
329 verify(stateGroup.state === "screenshot");
330 verify(applicationWindow.surface === null);
332 setApplicationState(appRunning);
334 waitUntilTransitionsEnd(stateGroup);
335 verify(stateGroup.state === "screenshot");
337 surfaceCheckbox.checked = true;
339 tryCompare(stateGroup, "state", "surface");
340 tryCompare(screenshotImage, "status", Image.Null);
343 function test_appCrashed() {
344 surfaceCheckbox.checked = true;
345 setApplicationState(appRunning);
346 tryCompare(stateGroup, "state", "surface");
347 waitUntilTransitionsEnd(stateGroup);
350 surfaceCheckbox.checked = false;
351 setApplicationState(appStopped);
353 tryCompare(stateGroup, "state", "screenshot");
354 tryCompare(applicationWindow, "surface", null);
357 function test_keepSurfaceWhileInvisible() {
358 surfaceCheckbox.checked = true;
359 setApplicationState(appRunning);
360 tryCompare(stateGroup, "state", "surface");
361 waitUntilTransitionsEnd(stateGroup);
362 verify(applicationWindow.surface !== null);
364 applicationWindow.visible = false;
366 waitUntilTransitionsEnd(stateGroup);
367 verify(stateGroup.state === "surface");
368 verify(applicationWindow.surface !== null);
370 applicationWindow.visible = true;
372 waitUntilTransitionsEnd(stateGroup);
373 verify(stateGroup.state === "surface");
374 verify(applicationWindow.surface !== null);
377 function test_touchesReachSurfaceWhenItsShown() {
378 setApplicationState(appRunning);
379 surfaceCheckbox.checked = true;
381 tryCompare(stateGroup, "state", "surface");
383 waitUntilTransitionsEnd(stateGroup);
385 var surfaceItem = findChild(applicationWindow, "surfaceItem");
387 verify(surfaceItem.surface === applicationWindow.surface);
389 surfaceItem.touchPressCount = 0;
390 surfaceItem.touchReleaseCount = 0;
392 tap(applicationWindow);
394 verify(surfaceItem.touchPressCount === 1);
395 verify(surfaceItem.touchReleaseCount === 1);
398 function test_showNothingOnSuddenSurfaceLoss() {
399 surfaceCheckbox.checked = true;
400 setApplicationState(appRunning);
401 tryCompare(stateGroup, "state", "surface");
402 waitUntilTransitionsEnd(stateGroup);
404 applicationWindow.surface = null;
406 tryCompare(stateGroup, "state", "void");
409 function test_surfaceActiveFocusFollowsAppWindowInterative() {
410 applicationWindow.interactive = false;
411 applicationWindow.interactive = true;
412 surfaceCheckbox.checked = true;
414 compare(applicationWindow.surface.activeFocus, true);
416 applicationWindow.interactive = false;
417 compare(applicationWindow.surface.activeFocus, false);
419 applicationWindow.interactive = true;
420 compare(applicationWindow.surface.activeFocus, true);
423 function test_promptSurfaceDestructionReturnsFocusToPreviousSurface() {
424 surfaceCheckbox.checked = true;
425 var promptSurfaces = testCase.findChild(applicationWindow, "promptSurfacesRepeater");
426 var promptSurfaceList = root.fakeApplication.promptSurfaceList;
427 compare(promptSurfaces.count, 0);
430 // 3 surfaces should cover all edge cases
431 for (i = 0; i < 3; i++) {
432 root.fakeApplication.createPromptSurface();
433 compare(promptSurfaces.count, i+1);
434 waitUntilSurfaceContainerStopsAnimating(promptSurfaces.itemAt(0));
437 for (i = 3; i > 0; --i) {
438 var promptSurface = promptSurfaceList.get(0);
439 compare(promptSurface.activeFocus, true);
441 promptSurface.close();
442 promptSurface = null;
443 tryCompareFunction(function() { return promptSurfaces.count; }, i-1);
445 if (promptSurfaces.count > 0) {
446 // active focus should have gone to the new head of the list
447 promptSurface = promptSurfaceList.get(0);
448 tryCompare(promptSurface, "activeFocus", true);
450 // active focus should have gone to the application surface
451 tryCompare(applicationWindow.surface, "activeFocus", true);
456 function test_promptSurfaceAdjustsForParentSize() {
457 root.fakeApplication.createPromptSurface();
459 var promptSurfaces = testCase.findChild(applicationWindow, "promptSurfacesRepeater");
461 var delegate = promptSurfaces.itemAt(0);
462 waitUntilSurfaceContainerStopsAnimating(delegate);
464 var promptSurfaceContainer = findChild(delegate, "surfaceContainer");
466 tryCompareFunction(function() { return promptSurfaceContainer.height === applicationWindow.height; }, true);
467 tryCompareFunction(function() { return promptSurfaceContainer.width === applicationWindow.width; }, true);
468 tryCompareFunction(function() { return promptSurfaceContainer.x === 0; }, true);
469 tryCompareFunction(function() { return promptSurfaceContainer.y === 0; }, true);
471 applicationWindow.anchors.margins = units.gu(2);
473 tryCompareFunction(function() { return promptSurfaceContainer.height === applicationWindow.height; }, true);
474 tryCompareFunction(function() { return promptSurfaceContainer.width === applicationWindow.width; }, true);
475 tryCompareFunction(function() { return promptSurfaceContainer.x === 0; }, true);
476 tryCompareFunction(function() { return promptSurfaceContainer.y === 0; }, true);
479 delegate.surface.close();
480 tryCompare(promptSurfaces, "count", 0);
483 // Check that the z value of SurfaceContainers for prompt surfaces go from highest
484 // for index 0 to lowest for the last index in the prompt surface list.
485 // Regression test for https://bugs.launchpad.net/bugs/1586219
486 function test_promptSurfacesZOrdering() {
487 var promptSurfaceList = root.fakeApplication.promptSurfaceList;
488 var promptSurfaces = testCase.findChild(applicationWindow, "promptSurfacesRepeater");
490 root.fakeApplication.createPromptSurface();
492 for (var i = 2; i <= 3; i++) {
493 root.fakeApplication.createPromptSurface();
494 tryCompare(promptSurfaces, "count", i);
495 waitUntilSurfaceContainerStopsAnimating(promptSurfaces.itemAt(0));
497 for (var j = 1; j < promptSurfaces.count; j++) {
498 var delegate = promptSurfaces.itemAt(j);
499 var previousDelegate = promptSurfaces.itemAt(j-1);
500 verify(previousDelegate.z > delegate.z);
505 while (promptSurfaceList.count > 0) {
506 var currentCount = promptSurfaceList.count;
507 promptSurfaceList.get(0).close();
508 tryCompare(promptSurfaceList, "count", currentCount - 1);
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list