~charlesk/unity8/lp-1410915-re-enable-rotation-lock-test

« back to all changes in this revision

Viewing changes to tests/qmltests/Greeter/tst_NarrowView.qml

  • Committer: CI Train Bot
  • Author(s): Michael Terry
  • Date: 2015-02-24 10:15:04 UTC
  • mfrom: (1432.6.56 greeter-refactor)
  • Revision ID: ci-train-bot@canonical.com-20150224101504-r428zccy160yhxq6
Refactor the greeter code to be more compartmented and isolatable.

This will help make it an optional piece of the shell when we allow a split greeter/shell.

My driving goals were:

- Remove as much logic from Shell.qml as possible. Right now, there is so much Greeter logic spread all throughout Shell.qml in different bits. For example, the Lockscreen widget sitting there instead of in qml/Greeter/.

- Clean up how we load the two different views (tablet & phone). Right now we have some widgets always present but sometimes hidden (Lockscreen) and Loaders within Loaders (LoginList inside GreeterContent). I wanted just two top-level view widgets that could be separately loaded depending on which mode we are in.

- Toward that end, I wanted to consolidate all the Greeter logic out of Shell and out of those two view classes to avoid duplication. So I made the main Greeter entry point widget handle all the login logic and interactions with LightDM. It controls the views, who always ask it to do things on their behalf. Classic MVC stuff.

- I separated out some of the widgetry from the previous Greeter class into a CoverPage class that both NarrowView and WideView use. This class now holds the drag handle for sliding the greeter away and the infographic.

- Now that each piece of the greeter has a much more brightly defined boundary, testing them in isolation is much easier. I've added tst_WideView, tst_NarrowView, and tst_Greeter files. I've moved existing tests around a bit and added some more. But it should be much more clear where a prospective test belongs now (logic tests in Greeter, visual tests in the respective View).

- I also moved some tests we had in qmluitests/ that were purely testing the LightDM plugin into their own plugin test file.
Approved by: Daniel d'Andrada

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 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
 */
 
16
 
 
17
import QtQuick 2.0
 
18
import QtTest 1.0
 
19
import ".."
 
20
import "../../../qml/Greeter"
 
21
import LightDM 0.1 as LightDM
 
22
import Ubuntu.Components 0.1
 
23
import Unity.Test 0.1 as UT
 
24
 
 
25
Item {
 
26
    id: root
 
27
    width: units.gu(90)
 
28
    height: units.gu(80)
 
29
 
 
30
    Row {
 
31
        anchors.fill: parent
 
32
        Loader {
 
33
            id: loader
 
34
            width: root.width - controls.width
 
35
            height: parent.height
 
36
 
 
37
            property bool itemDestroyed: false
 
38
            sourceComponent: Component {
 
39
                NarrowView {
 
40
                    background: Qt.resolvedUrl("../../../qml/graphics/phone_background.jpg")
 
41
                    userModel: LightDM.Users
 
42
                    infographicModel: LightDM.Infographic
 
43
 
 
44
                    launcherOffset: parseFloat(launcherOffsetField.text)
 
45
                    currentIndex: parseInt(currentIndexField.text, 10)
 
46
                    delayMinutes: parseInt(delayMinutesField.text, 10)
 
47
                    backgroundTopMargin: parseFloat(backgroundTopMarginField.text)
 
48
                    locked: lockedCheckBox.checked
 
49
                    alphanumeric: alphanumericCheckBox.checked
 
50
 
 
51
                    Component.onDestruction: {
 
52
                        loader.itemDestroyed = true
 
53
                    }
 
54
 
 
55
                    onSelected: {
 
56
                        currentIndexField.text = index;
 
57
                    }
 
58
                }
 
59
            }
 
60
        }
 
61
 
 
62
        Rectangle {
 
63
            id: controls
 
64
            color: "white"
 
65
            width: units.gu(40)
 
66
            height: parent.height
 
67
 
 
68
            Column {
 
69
                anchors { left: parent.left; right: parent.right; top: parent.top; margins: units.gu(1) }
 
70
                spacing: units.gu(1)
 
71
 
 
72
                Row {
 
73
                    Button {
 
74
                        text: "Show Last Chance"
 
75
                        onClicked: loader.item.showLastChance()
 
76
                    }
 
77
                }
 
78
                Row {
 
79
                    Button {
 
80
                        text: "Hide"
 
81
                        onClicked: loader.item.hide()
 
82
                    }
 
83
                }
 
84
                Row {
 
85
                    Button {
 
86
                        text: "Reset"
 
87
                        onClicked: loader.item.reset()
 
88
                    }
 
89
                }
 
90
                Row {
 
91
                    Button {
 
92
                        text: "Show Message"
 
93
                        onClicked: loader.item.showMessage(messageField.text)
 
94
                    }
 
95
                    TextField {
 
96
                        id: messageField
 
97
                        width: units.gu(10)
 
98
                        text: ""
 
99
                    }
 
100
                }
 
101
                Row {
 
102
                    Button {
 
103
                        text: "Show Prompt"
 
104
                        onClicked: loader.item.showPrompt(promptField.text, isSecretCheckBox.checked, isDefaultPromptCheckBox.checked)
 
105
                    }
 
106
                    TextField {
 
107
                        id: promptField
 
108
                        width: units.gu(10)
 
109
                        text: ""
 
110
                    }
 
111
                    CheckBox {
 
112
                        id: isSecretCheckBox
 
113
                    }
 
114
                    Label {
 
115
                        text: "secret"
 
116
                    }
 
117
                    CheckBox {
 
118
                        id: isDefaultPromptCheckBox
 
119
                    }
 
120
                    Label {
 
121
                        text: "default"
 
122
                    }
 
123
                }
 
124
                Row {
 
125
                    Button {
 
126
                        text: "Authenticated"
 
127
                        onClicked: {
 
128
                            if (successCheckBox.checked) {
 
129
                                loader.item.notifyAuthenticationSucceeded();
 
130
                            } else {
 
131
                                loader.item.notifyAuthenticationFailed();
 
132
                            }
 
133
                        }
 
134
                    }
 
135
                    CheckBox {
 
136
                        id: successCheckBox
 
137
                    }
 
138
                    Label {
 
139
                        text: "success"
 
140
                    }
 
141
                }
 
142
                Row {
 
143
                    Button {
 
144
                        text: "Try To Unlock"
 
145
                        onClicked: loader.item.tryToUnlock(toTheRightCheckBox.checked)
 
146
                    }
 
147
                    CheckBox {
 
148
                        id: toTheRightCheckBox
 
149
                    }
 
150
                    Label {
 
151
                        text: "toTheRight"
 
152
                    }
 
153
                }
 
154
                Row {
 
155
                    TextField {
 
156
                        id: launcherOffsetField
 
157
                        width: units.gu(10)
 
158
                        text: "0"
 
159
                    }
 
160
                    Label {
 
161
                        text: "launcherOffset"
 
162
                    }
 
163
                }
 
164
                Row {
 
165
                    TextField {
 
166
                        id: currentIndexField
 
167
                        width: units.gu(10)
 
168
                        text: "0"
 
169
                    }
 
170
                    Label {
 
171
                        text: "currentIndex"
 
172
                    }
 
173
                }
 
174
                Row {
 
175
                    TextField {
 
176
                        id: delayMinutesField
 
177
                        width: units.gu(10)
 
178
                        text: "0"
 
179
                    }
 
180
                    Label {
 
181
                        text: "delayMinutes"
 
182
                    }
 
183
                }
 
184
                Row {
 
185
                    TextField {
 
186
                        id: backgroundTopMarginField
 
187
                        width: units.gu(10)
 
188
                        text: "0"
 
189
                    }
 
190
                    Label {
 
191
                        text: "backgroundTopMargin"
 
192
                    }
 
193
                }
 
194
                Row {
 
195
                    CheckBox {
 
196
                        id: lockedCheckBox
 
197
                    }
 
198
                    Label {
 
199
                        text: "locked"
 
200
                    }
 
201
                }
 
202
                Row {
 
203
                    CheckBox {
 
204
                        id: alphanumericCheckBox
 
205
                    }
 
206
                    Label {
 
207
                        text: "alphanumeric"
 
208
                    }
 
209
                }
 
210
                Row {
 
211
                    Label {
 
212
                        text: "selected: " + selectedSpy.count
 
213
                    }
 
214
                }
 
215
                Row {
 
216
                    Label {
 
217
                        text: "responded: " + respondedSpy.count
 
218
                    }
 
219
                }
 
220
                Row {
 
221
                    Label {
 
222
                        text: "teased: " + teaseSpy.count
 
223
                    }
 
224
                }
 
225
                Row {
 
226
                    Label {
 
227
                        text: "emergency: " + emergencySpy.count
 
228
                    }
 
229
                }
 
230
                Row {
 
231
                    Button {
 
232
                        text: "Reload View"
 
233
                        onClicked: {
 
234
                            loader.active = false;
 
235
                            loader.active = true;
 
236
                        }
 
237
                    }
 
238
                }
 
239
            }
 
240
        }
 
241
    }
 
242
 
 
243
    Binding {
 
244
        target: LightDM.Infographic
 
245
        property: "username"
 
246
        value: "single"
 
247
    }
 
248
 
 
249
    SignalSpy {
 
250
        id: selectedSpy
 
251
        target: loader.item
 
252
        signalName: "selected"
 
253
    }
 
254
 
 
255
    SignalSpy {
 
256
        id: respondedSpy
 
257
        target: loader.item
 
258
        signalName: "responded"
 
259
    }
 
260
 
 
261
    SignalSpy {
 
262
        id: teaseSpy
 
263
        target: loader.item
 
264
        signalName: "tease"
 
265
    }
 
266
 
 
267
    SignalSpy {
 
268
        id: emergencySpy
 
269
        target: loader.item
 
270
        signalName: "emergencyCall"
 
271
    }
 
272
 
 
273
    SignalSpy {
 
274
        id: infographicDataChangedSpy
 
275
        target: LightDM.Infographic
 
276
        signalName: "dataChanged"
 
277
    }
 
278
 
 
279
    UT.UnityTestCase {
 
280
        name: "NarrowView"
 
281
        when: windowShown
 
282
 
 
283
        property Item view: loader.status === Loader.Ready ? loader.item : null
 
284
 
 
285
        function init() {
 
286
            view.currentIndex = 0; // break binding with text field
 
287
 
 
288
            selectedSpy.clear();
 
289
            respondedSpy.clear();
 
290
            teaseSpy.clear();
 
291
            emergencySpy.clear();
 
292
            infographicDataChangedSpy.clear();
 
293
        }
 
294
 
 
295
        function cleanup() {
 
296
            loader.itemDestroyed = false;
 
297
            loader.active = false;
 
298
            tryCompare(loader, "status", Loader.Null);
 
299
            tryCompare(loader, "item", null);
 
300
            tryCompare(loader, "itemDestroyed", true);
 
301
            loader.active = true;
 
302
            tryCompare(loader, "status", Loader.Ready);
 
303
            removeTimeConstraintsFromDirectionalDragAreas(loader.item);
 
304
        }
 
305
 
 
306
        function swipeAwayCover(toTheRight) {
 
307
            if (toTheRight === undefined) {
 
308
                toTheRight = false;
 
309
            }
 
310
 
 
311
            tryCompare(view, "fullyShown", true);
 
312
            var touchY = view.height / 2;
 
313
            if (toTheRight) {
 
314
                touchFlick(view, 0, touchY, view.width, touchY);
 
315
            } else {
 
316
                touchFlick(view, view.width, touchY, 0, touchY);
 
317
            }
 
318
            var coverPage = findChild(view, "coverPage");
 
319
            tryCompare(coverPage, "showProgress", 0);
 
320
            waitForRendering(view);
 
321
        }
 
322
 
 
323
        function enterPin(pin) {
 
324
            for (var i = 0; i < pin.length; ++i) {
 
325
                var character = pin.charAt(i);
 
326
                var button = findChild(view, "pinPadButton" + character);
 
327
                tap(button);
 
328
            }
 
329
        }
 
330
 
 
331
        function test_tease_data() {
 
332
            return [
 
333
                {tag: "left", x: 0, offset: 0, count: 1},
 
334
                {tag: "leftWithOffsetPass", x: 10, offset: 10, count: 1},
 
335
                {tag: "leftWithOffsetFail", x: 9, offset: 10, count: 0},
 
336
                {tag: "right", x: view.width, offset: 0, count: 1},
 
337
            ]
 
338
        }
 
339
        function test_tease(data) {
 
340
            view.dragHandleLeftMargin = data.offset;
 
341
            tap(view, data.x, 0);
 
342
            compare(teaseSpy.count, data.count);
 
343
        }
 
344
 
 
345
        function test_respondedWithPin() {
 
346
            view.locked = true;
 
347
            swipeAwayCover();
 
348
            enterPin("1234");
 
349
            compare(respondedSpy.count, 1);
 
350
            compare(respondedSpy.signalArguments[0][0], "1234");
 
351
        }
 
352
 
 
353
        function test_respondedWithPassphrase() {
 
354
            view.locked = true;
 
355
            view.alphanumeric = true;
 
356
            swipeAwayCover();
 
357
            typeString("test");
 
358
            keyClick(Qt.Key_Enter);
 
359
            compare(respondedSpy.count, 1);
 
360
            compare(respondedSpy.signalArguments[0][0], "test");
 
361
        }
 
362
 
 
363
        function test_respondedWithSwipe_data() {
 
364
            return [
 
365
                {tag: "left", toTheRight: false, hiddenX: -view.width},
 
366
                {tag: "right", toTheRight: true, hiddenX: view.width},
 
367
            ];
 
368
        }
 
369
        function test_respondedWithSwipe(data) {
 
370
            swipeAwayCover(data.toTheRight);
 
371
            var coverPage = findChild(view, "coverPage");
 
372
            compare(coverPage.x, data.hiddenX);
 
373
            compare(respondedSpy.count, 1);
 
374
            compare(respondedSpy.signalArguments[0][0], "");
 
375
        }
 
376
 
 
377
        function test_emergencyCall() {
 
378
            view.locked = true;
 
379
            swipeAwayCover();
 
380
            var emergencyCallLabel = findChild(view, "emergencyCallLabel");
 
381
            tap(emergencyCallLabel);
 
382
            compare(emergencySpy.count, 1);
 
383
        }
 
384
 
 
385
        function test_fullyShown() {
 
386
            tryCompare(view, "fullyShown", true);
 
387
            swipeAwayCover();
 
388
            tryCompare(view, "fullyShown", false);
 
389
            view.locked = true;
 
390
            tryCompare(view, "fullyShown", true);
 
391
            view.locked = false;
 
392
            tryCompare(view, "fullyShown", false);
 
393
        }
 
394
 
 
395
        function test_required() {
 
396
            tryCompare(view, "required", true);
 
397
            swipeAwayCover();
 
398
            tryCompare(view, "required", false);
 
399
            view.locked = true;
 
400
            tryCompare(view, "required", true);
 
401
            view.locked = false;
 
402
            tryCompare(view, "required", false);
 
403
        }
 
404
 
 
405
        function test_tryToUnlock() {
 
406
            var coverPage = findChild(view, "coverPage");
 
407
            tryCompare(coverPage, "showProgress", 1);
 
408
            compare(view.tryToUnlock(false), true);
 
409
            tryCompare(coverPage, "showProgress", 0);
 
410
            compare(view.tryToUnlock(false), false);
 
411
        }
 
412
 
 
413
        /*
 
414
            Regression test for https://bugs.launchpad.net/ubuntu/+source/unity8/+bug/1388359
 
415
            "User metrics can no longer be changed by double tap"
 
416
        */
 
417
        function test_doubleTapSwitchesToNextInfographic() {
 
418
            var infographicPrivate = findInvisibleChild(view, "infographicPrivate");
 
419
            verify(infographicPrivate);
 
420
 
 
421
            // wait for the UI to settle down before double tapping it
 
422
            tryCompare(infographicPrivate, "animating", false);
 
423
 
 
424
            var dataCircle = findChild(view, "dataCircle");
 
425
            verify(dataCircle);
 
426
 
 
427
            tap(dataCircle);
 
428
            wait(1);
 
429
            tap(dataCircle);
 
430
 
 
431
            tryCompare(infographicDataChangedSpy, "count", 1);
 
432
        }
 
433
 
 
434
        function test_movesBackIntoPlaceWhenNotDraggedFarEnough() {
 
435
            var coverPage = findChild(view, "coverPage");
 
436
 
 
437
            var dragEvaluator = findInvisibleChild(coverPage, "edgeDragEvaluator");
 
438
            verify(dragEvaluator);
 
439
 
 
440
            // Make it easier to get a rejection/rollback. Otherwise would have to inject
 
441
            // a fake timer into dragEvaluator.
 
442
            // Afterall, we are testing if the CoverPage indeed moves back on a
 
443
            // rollback decision, not the drag evaluation itself.
 
444
            dragEvaluator.minDragDistance = dragEvaluator.maxDragDistance / 2;
 
445
 
 
446
            // it starts as fully shown
 
447
            compare(coverPage.x, 0);
 
448
 
 
449
            // then we drag it a bit
 
450
            var startX = coverPage.width - 1;
 
451
            var touchY = coverPage.height / 2;
 
452
            var dragXDelta = -(dragEvaluator.minDragDistance * 0.3);
 
453
            touchFlick(coverPage,
 
454
                       startX , touchY, // start pos
 
455
                       startX + dragXDelta, touchY, // end pos
 
456
                       true /* beginTouch */, false /* endTouch  */);
 
457
 
 
458
            // which should make it move a bit
 
459
            tryCompareFunction(function() {return coverPage.x < 0;}, true);
 
460
 
 
461
            // then we release it
 
462
            touchRelease(coverPage, startX + dragXDelta, touchY);
 
463
 
 
464
            // which should make it move back into its original position as it didn't move
 
465
            // far enough to have it hidden
 
466
            tryCompare(coverPage, "x", 0);
 
467
        }
 
468
 
 
469
        function test_dragToHide_data() {
 
470
            return [
 
471
                {tag: "left", startX: view.width * 0.95, endX: view.width * 0.1, hiddenX: -view.width},
 
472
                {tag: "right", startX: view.width * 0.1, endX: view.width * 0.95, hiddenX: view.width},
 
473
            ];
 
474
        }
 
475
        function test_dragToHide(data) {
 
476
            var coverPage = findChild(view, "coverPage");
 
477
            compare(coverPage.x, 0);
 
478
            compare(coverPage.visible, true);
 
479
            compare(coverPage.shown, true);
 
480
            compare(coverPage.showProgress, 1);
 
481
            compare(view.fullyShown, true);
 
482
 
 
483
            touchFlick(view,
 
484
                    data.startX, view.height / 2, // start pos
 
485
                    data.endX, view.height / 2); // end pos
 
486
 
 
487
            tryCompare(coverPage, "x", data.hiddenX);
 
488
            tryCompare(coverPage, "visible", false);
 
489
            tryCompare(coverPage, "shown", false);
 
490
            tryCompare(coverPage, "showProgress", 0);
 
491
            compare(view.fullyShown, false);
 
492
        }
 
493
 
 
494
        function test_hiddenViewRemainsHiddenAfterResize_data() {
 
495
            return [
 
496
                {tag: "left", startX: view.width * 0.95, endX: view.width * 0.1},
 
497
                {tag: "right", startX: view.width * 0.1, endX: view.width * 0.95},
 
498
            ];
 
499
        }
 
500
        function test_hiddenViewRemainsHiddenAfterResize(data) {
 
501
            touchFlick(view,
 
502
                    data.startX, view.height / 2, // start pos
 
503
                    data.endX, view.height / 2); // end pos
 
504
 
 
505
            var coverPage = findChild(view, "coverPage");
 
506
            tryCompare(coverPage, "x", data.tag == "left" ? -view.width : view.width);
 
507
            tryCompare(coverPage, "visible", false);
 
508
            tryCompare(coverPage, "shown", false);
 
509
            tryCompare(coverPage, "showProgress", 0);
 
510
 
 
511
            // flip dimensions to simulate an orientation change
 
512
            view.width = loader.height;
 
513
            view.height = loader.width;
 
514
 
 
515
            // All properties should remain consistent
 
516
            tryCompare(coverPage, "x", data.tag == "left" ? -view.width : view.width);
 
517
            tryCompare(coverPage, "visible", false);
 
518
            tryCompare(coverPage, "shown", false);
 
519
            tryCompare(coverPage, "showProgress", 0);
 
520
        }
 
521
    }
 
522
}