@@ -51,47 +51,25 @@ Item {
5151 id: shell
5252 }
5353
54+ SignalSpy {
55+ id: sessionSpy
56+ signalName: "sessionStarted"
57+ }
58+
59+ SignalSpy {
60+ id: dashCommunicatorSpy
61+ signalName: "setCurrentScopeCalled"
62+ }
63+
5464 UT.UnityTestCase {
5565 name: "Shell"
5666 when: windowShown
5767
5868 function initTestCase() {
59− var ok = false;
60− var attempts = 0;
61− var maxAttempts = 1000;
62−
63− // Qt loads a qml scene asynchronously. So early on, some findChild() calls made in
64− // tests may fail because the desired child item wasn't loaded yet.
65− // Thus here we try to ensure the scene has been fully loaded before proceeding with the tests.
66− // As I couldn't find an API in QQuickView & friends to tell me that the scene is 100% loaded
67− // (all items instantiated, etc), I resort to checking the existence of some key items until
68− // repeatedly until they're all there.
69− do {
70− var dashContentList = findChild(shell, "dashContentList");
71− waitForRendering(dashContentList);
72− var homeLoader = findChild(dashContentList, "clickscope loader");
73− ok = homeLoader !== null
74− && homeLoader.item !== undefined;
75−
76− var greeter = findChild(shell, "greeter");
77− ok &= greeter !== null;
78−
79− var launcherPanel = findChild(shell, "launcherPanel");
80− ok &= launcherPanel !== null;
81−
82− attempts++;
83− if (!ok) {
84− console.log("Attempt " + attempts + " failed. Waiting a bit before trying again.");
85− // wait a bit before retrying
86− wait(100);
87− } else {
88− console.log("All seem fine after " + attempts + " attempts.");
89− }
90− } while (!ok && attempts <= maxAttempts);
91−
92− verify(ok);
93−
9469 swipeAwayGreeter();
70+
71+ sessionSpy.target = findChild(shell, "greeter")
72+ dashCommunicatorSpy.target = findInvisibleChild(shell, "dashCommunicator");
9573 }
9674
9775 function cleanup() {
@@ -104,56 +82,16 @@ Item {
10482 // kill all (fake) running apps
10583 killApps(ApplicationManager);
10684
107− var dashContent = findChild(shell, "dashContent");
108− dashContent.closePreview();
109−
110− var dashHome = findChild(shell, "clickscope loader");
111− swipeUntilScopeViewIsReached(dashHome);
112−
85+ waitForUIToSettle();
11386 hideIndicators();
11487 }
11588
116− function killApps(apps) {
117− if (!apps) return;
118− while (apps.count > 0) {
119− ApplicationManager.stopApplication(apps.get(0).appId);
89+ function killApps() {
90+ while (ApplicationManager.count > 1) {
91+ var appIndex = ApplicationManager.get(0).appId == "unity8-dash" ? 1 : 0
92+ ApplicationManager.stopApplication(ApplicationManager.get(appIndex).appId);
12093 }
121− compare(ApplicationManager.count, 0)
122− }
123−
124− /*
125− Test the effect of a right-edge drag on the dash in 3 situations:
126− 1 - when no application has been launched yet
127− 2 - when there's a minimized application
128− 3 - after the last running application has been closed/stopped
129−
130− The behavior of Dash on 3 should be the same as on 1.
131− */
132− function test_rightEdgeDrag() {
133− checkRightEdgeDragWithNoRunningApps();
134−
135− dragLauncherIntoView();
136−
137− // Launch an app from the launcher
138− tapOnAppIconInLauncher();
139− waitUntilApplicationWindowIsFullyVisible();
140−
141− // Minimize the application we just launched
142− swipeFromLeftEdge(units.gu(27));
143−
144− waitForUIToSettle();
145−
146− checkRightEdgeDragWithMinimizedApp();
147−
148− // Minimize that application once again
149− swipeFromLeftEdge(units.gu(27));
150−
151− // Right edge behavior should now be the same as before that app,
152− // was launched. Manually cleanup beforehand to get to initial
153− // state.
154− cleanup();
155− waitForUIToSettle();
156− checkRightEdgeDragWithNoRunningApps();
94+ compare(ApplicationManager.count, 1)
15795 }
15896
15997 function test_leftEdgeDrag_data() {
@@ -176,7 +114,7 @@ Item {
176114
177115 swipeFromLeftEdge(data.swipeLength);
178116 if (data.appHides)
179− waitUntilApplicationWindowIsFullyHidden();
117+ waitUntilDashIsFocused();
180118 else
181119 waitUntilApplicationWindowIsFullyVisible();
182120 }
@@ -229,133 +167,114 @@ Item {
229167
230168 // wait until the animation has finished
231169 tryCompare(greeter, "showProgress", 0);
170+ waitForRendering(greeter);
232171 }
233172
234173 /*
235− Perform a right-edge drag when the Dash is being show and there are
236− no running/minimized apps to be restored.
174+ Regression test for bug https://bugs.launchpad.net/touch-preview-images/+bug/1193419
175+
176+ When the user minimizes an application (left-edge swipe) he should always end up in the
177+ "Applications" scope view.
237178
238− The expected behavior is that an animation should be played to hint the
239− user that his right-edge drag gesture has been successfully recognized
240− but there is no application to be brought to foreground.
179+ Steps:
180+ - reveal launcher and launch an app that covers the dash
181+ - perform long left edge swipe to go minimize the app and go back to the dash.
182+ - verify the setCurrentScope() D-Bus call to the dash has been called for the correct scope id.
241183 */
242− function checkRightEdgeDragWithNoRunningApps() {
243− var touchX = shell.width - (shell.edgeSize / 2);
244− var touchY = shell.height / 2;
184+ function test_minimizingAppTakesToDashApps() {
185+ dragLauncherIntoView();
245186
246− var dash = findChild(shell, "dash");
247− // check that dash has normal scale and opacity
248− tryCompare(dash, "contentScale", 1.0);
249− tryCompare(dash, "opacity", 1.0);
187+ // Launch an app from the launcher
188+ tapOnAppIconInLauncher();
250189
251− touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY,
252− true /* beginTouch */, false /* endTouch */, units.gu(10), 50);
190+ waitUntilApplicationWindowIsFullyVisible();
253191
254− // check that Dash has been scaled down and had its opacity reduced
255− tryCompareFunction(function() { return dash.contentScale <= 0.9; }, true);
256− tryCompareFunction(function() { return dash.opacity <= 0.5; }, true);
192+ verify(ApplicationManager.focusedApplicationId !== "unity8-dash")
257193
258− touchRelease(shell, shell.width * 0.1, touchY);
194+ dashCommunicatorSpy.clear();
195+ // Minimize the application we just launched
196+ swipeFromLeftEdge(units.gu(27));
259197
260− // and now everything should have gone back to normal
261− tryCompare(dash, "contentScale", 1.0);
262− tryCompare(dash, "opacity", 1.0);
263− }
198+ tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash");
264199
265− /*
266− Perform a right-edge drag when the Dash is being show and there is
267− a running/minimized app to be restored.
200+ compare(dashCommunicatorSpy.count, 1);
201+ compare(dashCommunicatorSpy.signalArguments[0][0], "clickscope");
202+ }
268203
269− The expected behavior is that the dash should fade away and ultimately be
270− made invisible once the gesture is finished as the restored app will now
271− be on foreground.
272− */
273− function checkRightEdgeDragWithMinimizedApp() {
274− var touchX = shell.width - (shell.edgeSize / 2);
275− var touchY = shell.height / 2;
204+ function test_showInputMethod() {
205+ var item = findChild(shell, "inputMethod");
206+ var surface = SurfaceManager.inputMethodSurface();
276207
277− var dash = findChild(shell, "dash");
278− // check that dash has normal scale and opacity
279− tryCompare(dash, "contentScale", 1.0);
280− tryCompare(dash, "opacity", 1.0);
208+ surface.setState(MirSurfaceItem.Minimized);
209+ tryCompare(item, "visible", false);
281210
282− touchFlick(shell, touchX, touchY, shell.width * 0.1, touchY,
283− true /* beginTouch */, false /* endTouch */, units.gu(10), 50);
211+ surface.setState(MirSurfaceItem.Restored);
212+ tryCompare(item, "visible", true);
284213
285− // check that Dash has been scaled down and had its opacity reduced
286− tryCompareFunction(function() { return dash.contentScale <= 0.9; }, true);
287− tryCompareFunction(function() { return dash.opacity <= 0.5; }, true);
214+ surface.setState(MirSurfaceItem.Minimized);
215+ tryCompare(item, "visible", false);
288216
289− touchRelease(shell, shell.width * 0.1, touchY);
217+ surface.setState(MirSurfaceItem.Maximized);
218+ tryCompare(item, "visible", true);
290219
291− // dash should have gone away, now that the app is on foreground
292− tryCompare(dash, "visible", false);
220+ surface.setState(MirSurfaceItem.Minimized);
221+ tryCompare(item, "visible", false);
293222 }
294223
295− /*
296− Regression test for bug https://bugs.launchpad.net/touch-preview-images/+bug/1193419
297−
298− When the user minimizes an application (left-edge swipe) he should always end up in the "Running Apps"
299− category of the "Applications" scope view.
224+ function test_surfaceLosesFocusWhilePanelIsOpen() {
225+ var app = ApplicationManager.startApplication("dialer-app");
226+ // wait until the app is fully loaded (ie, real surface replaces splash screen)
227+ tryCompareFunction(function() { return app.surface != null }, true);
300228
301− Steps:
302− - go to apps lens
303− - scroll to the bottom
304− - reveal launcher and launch an app
305− - perform long left edge swipe to go minimize the app and go back to the dash.
229+ tryCompare(app.surface, "focus", true);
306230
307− Expected Results
308− - apps lens shown and Running Apps visible on screen
309− */
310− function test_minimizingAppTakesToRunningApps() {
311− var dashApps = findChild(shell, "clickscope");
312− swipeUntilScopeViewIsReached(dashApps);
313−
314− // swipe finger up until the running/recent apps section (which we assume
315− // it's the first one) is as far from view as possible.
316− // We also assume that DashApps is tall enough that it's scrollable
317− var appsCategoryListView = findChild(dashApps, "categoryListView");
318− while (!appsCategoryListView.atYEnd) {
319− swipeUpFromCenter();
320− tryCompare(appsCategoryListView, "moving", false);
321− }
231+ // Drag the indicators panel half-open
232+ var touchX = shell.width / 2;
233+ var indicators = findChild(shell, "indicators");
234+ touchFlick(indicators,
235+ touchX /* fromX */, indicators.panelHeight * 0.5 /* fromY */,
236+ touchX /* toX */, shell.height * 0.5 /* toY */,
237+ true /* beginTouch */, false /* endTouch */);
238+ verify(indicators.partiallyOpened);
239+
240+ tryCompare(app.surface, "focus", false);
241+
242+ // And finish getting it open
243+ touchFlick(indicators,
244+ touchX /* fromX */, shell.height * 0.5 /* fromY */,
245+ touchX /* toX */, shell.height * 0.9 /* toY */,
246+ false /* beginTouch */, true /* endTouch */);
247+ tryCompare(indicators, "fullyOpened", true);
322248
323− // Switch away from the Applications scope.
324− swipeRightFromCenter();
325− waitUntilItemStopsMoving(dashApps);
326− verify(!itemIsOnScreen(dashApps));
249+ tryCompare(app.surface, "focus", false);
327250
328− dragLauncherIntoView();
251+ dragToCloseIndicatorsPanel();
329252
330− // Launch an app from the launcher
331− tapOnAppIconInLauncher();
332−
333− waitUntilApplicationWindowIsFullyVisible();
334−
335− // Dragging launcher into view with a little bit of gap (units.gu(1)) should switch to Apps scope
336− dragLauncherIntoView();
337− verify(itemIsOnScreen(dashApps));
253+ tryCompare(app.surface, "focus", true);
254+ }
338255
339− // Minimize the application we just launched
340− swipeFromLeftEdge(units.gu(27));
256+ // Wait for the whole UI to settle down
257+ function waitForUIToSettle() {
258+ var launcher = findChild(shell, "launcherPanel")
259+ tryCompareFunction(function() {return launcher.x === 0 || launcher.x === -launcher.width;}, true);
260+ if (launcher.x === 0) {
261+ mouseClick(shell, shell.width / 2, shell.height / 2)
262+ }
263+ tryCompare(launcher, "x", -launcher.width)
341264
342− // Wait for the whole UI to settle down
343− waitUntilApplicationWindowIsFullyHidden();
344− waitUntilItemStopsMoving(dashApps);
345− tryCompare(appsCategoryListView, "moving", false);
265+ waitForRendering(shell)
266+ }
346267
347− verify(itemIsOnScreen(dashApps));
268+ function dragToCloseIndicatorsPanel() {
269+ var indicators = findChild(shell, "indicators");
348270
349− var runningApplicationsGrid = findChild(appsCategoryListView, "running.apps.category");
350− verify(runningApplicationsGrid);
351− verify(itemIsOnScreen(runningApplicationsGrid));
352− }
271+ var touchStartX = shell.width / 2;
272+ var touchStartY = shell.height - (indicators.panelHeight * 0.5);
273+ touchFlick(shell,
274+ touchStartX, touchStartY,
275+ touchStartX, shell.height * 0.1);
353276
354− // Wait for the whole UI to settle down
355− function waitForUIToSettle() {
356− waitUntilApplicationWindowIsFullyHidden();
357− var dashContentList = findChild(shell, "dashContentList");
358− tryCompare(dashContentList, "moving", false);
277+ tryCompare(indicators, "fullyClosed", true);
359278 }
360279
361280 function dragLauncherIntoView() {
@@ -400,24 +319,13 @@ Item {
400319 }
401320
402321 function waitUntilApplicationWindowIsFullyVisible() {
403− var underlay = findChild(shell, "underlay");
404− tryCompare(underlay, "visible", false);
322+ var appDelegate = findChild(shell, "appDelegate0")
323+ var surfaceContainer = findChild(appDelegate, "surfaceContainer");
324+ tryCompareFunction(function() { return surfaceContainer.surface !== null; }, true);
405325 }
406326
407− function waitUntilApplicationWindowIsFullyHidden() {
408− var stages = findChild(shell, "stages");
409− tryCompare(stages, "fullyHidden", true);
410− }
411−
412− function swipeUntilScopeViewIsReached(scopeView) {
413− while (!itemIsOnScreen(scopeView)) {
414− if (itemIsToLeftOfScreen(scopeView)) {
415− swipeRightFromCenter();
416− } else {
417− swipeLeftFromCenter();
418− }
419− waitUntilItemStopsMoving(scopeView);
420− }
327+ function waitUntilDashIsFocused() {
328+ tryCompare(ApplicationManager, "focusedApplicationId", "unity8-dash");
421329 }
422330
423331 function swipeFromLeftEdge(swipeLength) {
@@ -426,24 +334,6 @@ Item {
426334 touchFlick(shell, touchStartX, touchStartY, swipeLength, touchStartY);
427335 }
428336
429− function swipeLeftFromCenter() {
430− var touchStartX = shell.width * 3 / 4;
431− var touchStartY = shell.height / 2;
432− touchFlick(shell, touchStartX, touchStartY, 0, touchStartY);
433− }
434−
435− function swipeRightFromCenter() {
436− var touchStartX = shell.width * 3 / 4;
437− var touchStartY = shell.height / 2;
438− touchFlick(shell, touchStartX, touchStartY, shell.width, touchStartY);
439− }
440−
441− function swipeUpFromCenter() {
442− var touchStartX = shell.width / 2;
443− var touchStartY = shell.height / 2;
444− touchFlick(shell, touchStartX, touchStartY, touchStartX, 0);
445− }
446−
447337 function itemIsOnScreen(item) {
448338 var itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height);
449339
@@ -453,80 +343,93 @@ Item {
453343 && itemRectInShell.y + itemRectInShell.height <= shell.height;
454344 }
455345
456− function itemIsToLeftOfScreen(item) {
457− var itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height);
458− return itemRectInShell.x < 0;
459− }
460−
461− function waitUntilItemStopsMoving(item) {
462− var itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height);
463− var previousX = itemRectInShell.x;
464− var previousY = itemRectInShell.y;
465− var isStill = false;
466−
467− do {
468− wait(100);
469− itemRectInShell = item.mapToItem(shell, 0, 0, item.width, item.height);
470− if (itemRectInShell.x == previousX && itemRectInShell.y == previousY) {
471− isStill = true;
472− } else {
473− previousX = itemRectInShell.x;
474− previousY = itemRectInShell.y;
475− }
476− } while (!isStill);
477− }
478−
479− function test_DashShown_data() {
480− return [
481− {tag: "in focus", greeter: false, app: false, launcher: false, indicators: false, expectedShown: true},
482− {tag: "under greeter", greeter: true, app: false, launcher: false, indicators: false, expectedShown: false},
483− {tag: "under app", greeter: false, app: true, launcher: false, indicators: false, expectedShown: false},
484− {tag: "under launcher", greeter: false, app: false, launcher: true, indicators: false, expectedShown: true},
485− {tag: "under indicators", greeter: false, app: false, launcher: false, indicators: true, expectedShown: true},
486− ]
487− }
346+ function test_focusRequestedHidesGreeter() {
347+ var greeter = findChild(shell, "greeter");
488348
489− function test_DashShown(data) {
490− if (data.greeter) {
491− // Swipe the greeter in
492− var greeter = findChild(shell, "greeter");
493− Powerd.displayPowerStateChange(Powerd.Off, 0);
494− tryCompare(greeter, "showProgress", 1);
495− }
349+ var app = ApplicationManager.startApplication("dialer-app");
350+ // wait until the app is fully loaded (ie, real surface replaces splash screen)
351+ tryCompareFunction(function() { return app.surface != null }, true);
496352
497− if (data.app) {
498− dragLauncherIntoView();
499− tapOnAppIconInLauncher();
500− }
353+ // Minimize the application we just launched
354+ swipeFromLeftEdge(units.gu(26) + 1);
501355
502− if (data.launcher) {
503− dragLauncherIntoView();
504− }
356+ waitUntilDashIsFocused();
505357
506− if (data.indicators) {
507− showIndicators();
508− }
358+ greeter.show();
359+ tryCompare(greeter, "showProgress", 1);
509360
510− var dash = findChild(shell, "dash");
511− tryCompare(dash, "shown", data.expectedShown);
361+ // The main point of this test
362+ ApplicationManager.requestFocusApplication("dialer-app");
363+ tryCompare(greeter, "showProgress", 0);
364+ waitForRendering(greeter);
512365 }
513366
514− function test_focusRequestedHidesGreeter() {
515− var greeter = findChild(shell, "greeter")
367+ function test_focusRequestedHidesIndicators() {
368+ var indicators = findChild(shell, "indicators");
516369
517− greeter.show()
518− tryCompare(greeter, "showProgress", 1)
370+ showIndicators();
519371
520− ApplicationManager.focusRequested("notes-app")
521− tryCompare(greeter, "showProgress", 0)
522− waitUntilApplicationWindowIsFullyVisible()
372+ var oldCount = ApplicationManager.count;
373+ ApplicationManager.startApplication("camera-app");
374+ tryCompare(ApplicationManager, "count", oldCount + 1);
375+
376+ tryCompare(indicators, "fullyClosed", true);
523377 }
524378
379+
525380 function test_showGreeterDBusCall() {
526381 var greeter = findChild(shell, "greeter")
527382 tryCompare(greeter, "showProgress", 0)
383+ waitForRendering(greeter);
528384 LightDM.Greeter.showGreeter()
529385 tryCompare(greeter, "showProgress", 1)
530386 }
387+
388+ function test_login() {
389+ sessionSpy.clear()
390+
391+ var greeter = findChild(shell, "greeter")
392+ waitForRendering(greeter)
393+ greeter.show()
394+ tryCompare(greeter, "showProgress", 1)
395+
396+ tryCompare(sessionSpy, "count", 0)
397+ swipeAwayGreeter()
398+ tryCompare(sessionSpy, "count", 1)
399+ }
400+
401+ function test_fullscreen() {
402+ var panel = findChild(shell, "panel");
403+ compare(panel.fullscreenMode, false);
404+ ApplicationManager.startApplication("camera-app");
405+ tryCompare(panel, "fullscreenMode", true);
406+ ApplicationManager.startApplication("gallery-app");
407+ tryCompare(panel, "fullscreenMode", false);
408+ ApplicationManager.requestFocusApplication("camera-app");
409+ tryCompare(panel, "fullscreenMode", true);
410+ ApplicationManager.requestFocusApplication("gallery-app");
411+ tryCompare(panel, "fullscreenMode", false);
412+ }
413+
414+ function test_leftEdgeDragFullscreen() {
415+ var panel = findChild(shell, "panel");
416+ tryCompare(panel, "fullscreenMode", false)
417+
418+ ApplicationManager.startApplication("camera-app");
419+ tryCompare(panel, "fullscreenMode", true)
420+
421+ var touchStartX = 2;
422+ var touchStartY = shell.height / 2;
423+
424+ touchFlick(shell, touchStartX, touchStartY, units.gu(2), touchStartY, true, false);
425+
426+ compare(panel.fullscreenMode, true);
427+
428+ touchFlick(shell, units.gu(2), touchStartY, units.gu(10), touchStartY, false, false);
429+
430+ tryCompare(panel, "fullscreenMode", false);
431+
432+ touchRelease(shell);
433+ }
531434 }
532435}