Merge lp:~nik90/ubuntu-clock-app/add-world-qml-tests into lp:ubuntu-clock-app
- add-world-qml-tests
- Merge into trunk
Proposed by
Nekhelesh Ramananthan
Status: | Superseded |
---|---|
Proposed branch: | lp:~nik90/ubuntu-clock-app/add-world-qml-tests |
Merge into: | lp:ubuntu-clock-app |
Diff against target: |
809 lines (+518/-74) 11 files modified
app/alarm/AlarmList.qml (+1/-1) app/alarm/EditAlarmPage.qml (+3/-0) app/worldclock/WorldCityList.qml (+3/-3) debian/changelog (+3/-0) tests/autopilot/ubuntu_clock_app/emulators.py (+9/-5) tests/unit/CMakeLists.txt (+9/-0) tests/unit/MockClockApp.qml (+88/-0) tests/unit/Utils.qml (+89/-0) tests/unit/tst_alarm.qml (+114/-56) tests/unit/tst_alarmLabel.qml (+5/-9) tests/unit/tst_worldClock.qml (+194/-0) |
To merge this branch: | bzr merge lp:~nik90/ubuntu-clock-app/add-world-qml-tests |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Clock Developers | Pending | ||
Review via email:
|
Commit message
Added world clock feature qml tests.
Description of the change
Added world clock feature qml tests.
The QML Test Suite now comprises of Feature, Unit and Integration tests and collectively has a far higher test coverage of the clock app than AP test have. A few more MPs later, I might propose removing AP tests.
To post a comment you must log in.
- 160. By Nekhelesh Ramananthan
-
merged trunk
- 161. By Nekhelesh Ramananthan
-
Migrated tst_worldClock over to ClockTestCase
- 162. By Nekhelesh Ramananthan
-
renamed confirmWorldCit
yAddition( ) to assertWorldCity Addition( ) - 163. By Nekhelesh Ramananthan
-
Removed unnecessary confirm statement iat the start of a test
- 164. By Nekhelesh Ramananthan
-
Added TODO comment for mocking the searchOnline function
- 165. By Nekhelesh Ramananthan
-
Improved if logic in emulators.py
- 166. By Nekhelesh Ramananthan
-
Simplified code a bit
- 167. By Nekhelesh Ramananthan
-
Merged prerequisite branch
- 168. By Nekhelesh Ramananthan
-
Merged prerequisite branch
Unmerged revisions
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'app/alarm/AlarmList.qml' |
2 | --- app/alarm/AlarmList.qml 2014-10-05 15:33:27 +0000 |
3 | +++ app/alarm/AlarmList.qml 2014-10-13 20:56:20 +0000 |
4 | @@ -129,7 +129,7 @@ |
5 | |
6 | else { |
7 | pageStack.push(Qt.resolvedUrl("EditAlarmPage.qml"), |
8 | - {"isNewAlarm": false, "alarmIndex": index}) |
9 | + {isNewAlarm: false, alarmIndex: index, alarmModel: alarmModel}) |
10 | } |
11 | } |
12 | |
13 | |
14 | === modified file 'app/alarm/EditAlarmPage.qml' |
15 | --- app/alarm/EditAlarmPage.qml 2014-10-10 19:58:49 +0000 |
16 | +++ app/alarm/EditAlarmPage.qml 2014-10-13 20:56:20 +0000 |
17 | @@ -37,6 +37,9 @@ |
18 | // Temporary alarm used to read saved alarm and modify them |
19 | property var tempAlarm |
20 | |
21 | + // Property to store the alarm model |
22 | + property var alarmModel |
23 | + |
24 | title: isNewAlarm ? i18n.tr("New alarm") : i18n.tr("Edit alarm") |
25 | visible: false |
26 | |
27 | |
28 | === modified file 'app/worldclock/WorldCityList.qml' |
29 | --- app/worldclock/WorldCityList.qml 2014-10-10 10:55:27 +0000 |
30 | +++ app/worldclock/WorldCityList.qml 2014-10-13 20:56:20 +0000 |
31 | @@ -251,7 +251,7 @@ |
32 | |
33 | delegate: ListItem.Base { |
34 | showDivider: false |
35 | - objectName: "worldCityItem" + index |
36 | + objectName: "defaultWorldCityItem" + index |
37 | |
38 | Column { |
39 | id: worldCityDelegateColumn |
40 | @@ -265,7 +265,7 @@ |
41 | |
42 | Label { |
43 | text: city |
44 | - objectName: "cityNameText" |
45 | + objectName: "defaultCityNameText" |
46 | width: parent.width |
47 | elide: Text.ElideRight |
48 | color: UbuntuColors.midAubergine |
49 | @@ -273,7 +273,7 @@ |
50 | |
51 | Label { |
52 | text: country |
53 | - objectName: "countryNameText" |
54 | + objectName: "defaultCountryNameText" |
55 | fontSize: "xx-small" |
56 | width: parent.width |
57 | elide: Text.ElideRight |
58 | |
59 | === modified file 'debian/changelog' |
60 | --- debian/changelog 2014-10-11 11:46:39 +0000 |
61 | +++ debian/changelog 2014-10-13 20:56:20 +0000 |
62 | @@ -12,6 +12,9 @@ |
63 | * Synced ListItemWithActions with upstream |
64 | * Delayed loading of AlarmModel to improve app startup time (LP: #1362140) |
65 | * Fixed alarm page header width warning and corrected icon spacing. |
66 | + * Added edit alarm qml tests and added a library helper which contains commonly |
67 | + used test functions to avoid code duplication in future tests. |
68 | + * Added world clock feature qml tests |
69 | |
70 | [Akiva Shammai Avraham] |
71 | * Improved the analog clock performance by updating the clock hands every second |
72 | |
73 | === modified file 'tests/autopilot/ubuntu_clock_app/emulators.py' |
74 | --- tests/autopilot/ubuntu_clock_app/emulators.py 2014-10-10 22:12:50 +0000 |
75 | +++ tests/autopilot/ubuntu_clock_app/emulators.py 2014-10-13 20:56:20 +0000 |
76 | @@ -267,14 +267,18 @@ |
77 | |
78 | for index in range(int(cityList.count)): |
79 | if cityList.wait_select_single( |
80 | - objectName="worldCityItem{}".format(index)).wait_select_single( |
81 | - "Label", objectName="cityNameText").text == city_Name: |
82 | + objectName="defaultWorldCityItem{}".format(index)).\ |
83 | + wait_select_single( |
84 | + "Label", |
85 | + objectName="defaultCityNameText").text == city_Name: |
86 | if cityList.wait_select_single( |
87 | - objectName="worldCityItem{}".format(index)).\ |
88 | - wait_select_single("Label", objectName="countryNameText").\ |
89 | + objectName="defaultWorldCityItem{}".format(index)).\ |
90 | + wait_select_single( |
91 | + "Label", |
92 | + objectName="defaultCountryNameText").\ |
93 | text == country_Name: |
94 | cityList.click_element( |
95 | - "worldCityItem{}".format(index), direction=None) |
96 | + "defaultWorldCityItem{}".format(index), direction=None) |
97 | break |
98 | |
99 | @autopilot_logging.log_action(logger.info) |
100 | |
101 | === modified file 'tests/unit/CMakeLists.txt' |
102 | --- tests/unit/CMakeLists.txt 2014-10-05 21:22:25 +0000 |
103 | +++ tests/unit/CMakeLists.txt 2014-10-13 20:56:20 +0000 |
104 | @@ -26,6 +26,7 @@ |
105 | declare_qml_test("Alarm" tst_alarm.qml) |
106 | declare_qml_test("AlarmSound" tst_alarmSound.qml) |
107 | declare_qml_test("AlarmUtils" tst_alarmUtils.qml) |
108 | + declare_qml_test("WorldClock" tst_worldClock.qml) |
109 | else() |
110 | if (NOT QMLTESTRUNNER_BIN) |
111 | message(WARNING "Qml tests disabled: qmltestrunner not found") |
112 | @@ -40,5 +41,13 @@ |
113 | tst_alarm.qml |
114 | tst_alarmSound.qml |
115 | tst_alarmUtils.qml |
116 | + tst_worldClock.qml |
117 | ) |
118 | add_custom_target(tst_QmlFiles ALL SOURCES ${QML_TST_FILES}) |
119 | + |
120 | +set(QML_TST_UTILS |
121 | + Utils.qml |
122 | + MockClockApp.qml |
123 | +) |
124 | + |
125 | +add_custom_target(tst_Utils ALL SOURCES ${QML_TST_UTILS}) |
126 | |
127 | === added file 'tests/unit/MockClockApp.qml' |
128 | --- tests/unit/MockClockApp.qml 1970-01-01 00:00:00 +0000 |
129 | +++ tests/unit/MockClockApp.qml 2014-10-13 20:56:20 +0000 |
130 | @@ -0,0 +1,88 @@ |
131 | +/* |
132 | + * Copyright (C) 2014 Canonical Ltd |
133 | + * |
134 | + * This file is part of Ubuntu Clock App |
135 | + * |
136 | + * Ubuntu Clock App is free software: you can redistribute it and/or modify |
137 | + * it under the terms of the GNU General Public License version 3 as |
138 | + * published by the Free Software Foundation. |
139 | + * |
140 | + * Ubuntu Clock App is distributed in the hope that it will be useful, |
141 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
142 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
143 | + * GNU General Public License for more details. |
144 | + * |
145 | + * You should have received a copy of the GNU General Public License |
146 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
147 | + */ |
148 | + |
149 | +import QtQuick 2.3 |
150 | +import DateTime 1.0 |
151 | +import U1db 1.0 as U1db |
152 | +import Ubuntu.Components 1.1 |
153 | +import "../../app/clock" |
154 | + |
155 | +/* |
156 | + This file is meant to create a fake but fully fleshed clock app with its |
157 | + own database and settings. This will avoid messing with the user data while |
158 | + running the tests. |
159 | +*/ |
160 | + |
161 | +MainView { |
162 | + id: clockApp |
163 | + |
164 | + // Property to store the state of an application (active or suspended) |
165 | + property bool applicationState: Qt.application.active |
166 | + |
167 | + width: units.gu(40) |
168 | + height: units.gu(70) |
169 | + useDeprecatedToolbar: false |
170 | + applicationName: "com.ubuntu.fakeclock.test" |
171 | + |
172 | + U1db.Database { |
173 | + id: clockDB |
174 | + path: "user-preferences" |
175 | + } |
176 | + |
177 | + U1db.Document { |
178 | + id: clockModeDocument |
179 | + create: true |
180 | + database: clockDB |
181 | + docId: "clockModeDocument" |
182 | + defaults: { "digitalMode": false } |
183 | + } |
184 | + |
185 | + DateTime { |
186 | + id: localTimeSource |
187 | + updateInterval: 1000 |
188 | + } |
189 | + |
190 | + PageStack { |
191 | + id: mainStack |
192 | + objectName: "pageStack" |
193 | + |
194 | + Component.onCompleted: push(clockPage) |
195 | + |
196 | + ClockPage { |
197 | + id: clockPage |
198 | + |
199 | + Loader { |
200 | + id: alarmModelLoader |
201 | + asynchronous: false |
202 | + } |
203 | + |
204 | + alarmModel: alarmModelLoader.item |
205 | + bottomEdgeEnabled: alarmModelLoader.status === Loader.Ready |
206 | + clockTime: new Date |
207 | + ( |
208 | + localTimeSource.localDateString.split(":")[0], |
209 | + localTimeSource.localDateString.split(":")[1]-1, |
210 | + localTimeSource.localDateString.split(":")[2], |
211 | + localTimeSource.localTimeString.split(":")[0], |
212 | + localTimeSource.localTimeString.split(":")[1], |
213 | + localTimeSource.localTimeString.split(":")[2], |
214 | + localTimeSource.localTimeString.split(":")[3] |
215 | + ) |
216 | + } |
217 | + } |
218 | +} |
219 | |
220 | === added file 'tests/unit/Utils.qml' |
221 | --- tests/unit/Utils.qml 1970-01-01 00:00:00 +0000 |
222 | +++ tests/unit/Utils.qml 2014-10-13 20:56:20 +0000 |
223 | @@ -0,0 +1,89 @@ |
224 | +/* |
225 | + * Copyright (C) 2014 Canonical Ltd |
226 | + * |
227 | + * This file is part of Ubuntu Clock App |
228 | + * |
229 | + * Ubuntu Clock App is free software: you can redistribute it and/or modify |
230 | + * it under the terms of the GNU General Public License version 3 as |
231 | + * published by the Free Software Foundation. |
232 | + * |
233 | + * Ubuntu Clock App is distributed in the hope that it will be useful, |
234 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
235 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
236 | + * GNU General Public License for more details. |
237 | + * |
238 | + * You should have received a copy of the GNU General Public License |
239 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
240 | + */ |
241 | + |
242 | +import QtTest 1.0 |
243 | +import QtQuick 2.3 |
244 | +import Ubuntu.Test 1.0 |
245 | + |
246 | +/* |
247 | + Utils.qml includes a set of commonly used test functions like pressing header |
248 | + buttons and helps reduce code duplication. |
249 | + |
250 | + Usage: |
251 | + Utils { |
252 | + id: testUtils |
253 | + } |
254 | + |
255 | + UbuntuTestCase { |
256 | + id: sampleTest |
257 | + name: "SampleTest" |
258 | + |
259 | + when: windowShown |
260 | + |
261 | + function initTestCase() { |
262 | + header = findChild(mainView, "MainView_Header") |
263 | + backButton = findChild(alarmTest.header, "customBackButton") |
264 | + } |
265 | + |
266 | + function test_something() { |
267 | + testUtils._pressHeaderButton(header, "addAlarmAction") |
268 | + } |
269 | + } |
270 | +*/ |
271 | + |
272 | +UbuntuTestCase { |
273 | + id: testUtils |
274 | + |
275 | + function pressHeaderButton(header, objectName) { |
276 | + var headerButton = findChild(header, objectName + "_header_button") |
277 | + mouseClick(headerButton, centerOf(headerButton).x, centerOf(headerButton).y) |
278 | + } |
279 | + |
280 | + function pressButton(objectName) { |
281 | + mouseClick(objectName, centerOf(objectName).x, centerOf(objectName).y) |
282 | + } |
283 | + |
284 | + function getPage(pageStack, objectName) { |
285 | + var page = findChild(pageStack, objectName) |
286 | + waitForRendering(page) |
287 | + return page |
288 | + } |
289 | + |
290 | + function swipeToDeleteItem(item) |
291 | + { |
292 | + var startX = item.threshold |
293 | + var startY = item.height / 2 |
294 | + var endX = item.width |
295 | + var endY = startY |
296 | + mousePress(item, startX, startY) |
297 | + mouseMoveSlowly(item, |
298 | + startX, startY, |
299 | + endX - startX, endY - startY, |
300 | + 10, 100) |
301 | + mouseRelease(item, endX, endY) |
302 | + mouseClick(item, startX, startY) |
303 | + } |
304 | + |
305 | + function clearTextField(textfield) { |
306 | + // Get textfield focus by clicking once |
307 | + mouseClick(textfield, textfield.width - units.gu(2), centerOf(textfield).y) |
308 | + |
309 | + // Click on the clear button shown on the right |
310 | + mouseClick(textfield, textfield.width - units.gu(2), centerOf(textfield).y) |
311 | + } |
312 | +} |
313 | |
314 | === modified file 'tests/unit/tst_alarm.qml' |
315 | --- tests/unit/tst_alarm.qml 2014-10-10 21:24:28 +0000 |
316 | +++ tests/unit/tst_alarm.qml 2014-10-13 20:56:20 +0000 |
317 | @@ -63,6 +63,10 @@ |
318 | id: alarmPage |
319 | } |
320 | |
321 | + Utils { |
322 | + id: utils |
323 | + } |
324 | + |
325 | UbuntuTestCase { |
326 | id: alarmTest |
327 | name: "AlarmTest" |
328 | @@ -79,31 +83,11 @@ |
329 | |
330 | // ************* Helper Functions ************ |
331 | |
332 | - function _pressAddAlarmHeaderButton() { |
333 | - var addButton = findChild(header, "addAlarmAction" + "_header_button") |
334 | - mouseClick(addButton, centerOf(addButton).x, centerOf(addButton).y) |
335 | - } |
336 | - |
337 | - function _pressSaveAlarmHeaderButton() { |
338 | - var saveButton = findChild(alarmTest.header, "saveAlarmAction" + "_header_button") |
339 | - mouseClick(saveButton, centerOf(saveButton).x, centerOf(saveButton).y) |
340 | - } |
341 | - |
342 | - function _pressBackButton() { |
343 | - mouseClick(backButton, centerOf(backButton).x, centerOf(backButton).y) |
344 | - } |
345 | - |
346 | function _pressListItem(page, objectName) { |
347 | var listitem = findChild(page, objectName) |
348 | mouseClick(listitem, centerOf(listitem).x, centerOf(listitem).y) |
349 | } |
350 | |
351 | - function _getPage(objectName) { |
352 | - var page = findChild(pageStack, objectName) |
353 | - waitForRendering(page) |
354 | - return page |
355 | - } |
356 | - |
357 | function _waitForPickerToStopMoving(picker) { |
358 | waitForRendering(picker); |
359 | tryCompareFunction(function(){return picker.moving}, false); |
360 | @@ -112,7 +96,6 @@ |
361 | function _setAlarmTime(picker, time) { |
362 | picker.date = time |
363 | _waitForPickerToStopMoving(picker) |
364 | - return picker.date |
365 | } |
366 | |
367 | function _setAlarmRepeatDays(alarmRepeatPage, days) { |
368 | @@ -136,8 +119,7 @@ |
369 | |
370 | function _setAlarmLabel(alarmLabelPage, label) { |
371 | var alarmLabel = findChild(alarmLabelPage, "labelEntry") |
372 | - mouseClick(alarmLabel, alarmLabel.width - units.gu(2), centerOf(alarmLabel).y) |
373 | - mouseClick(alarmLabel, alarmLabel.width - units.gu(2), centerOf(alarmLabel).y) |
374 | + utils.clearTextField(alarmLabel) |
375 | typeString(label) |
376 | } |
377 | |
378 | @@ -173,19 +155,9 @@ |
379 | } |
380 | } |
381 | |
382 | - function _swipeToDeleteItem(item) |
383 | - { |
384 | - var startX = item.threshold |
385 | - var startY = item.height / 2 |
386 | - var endX = item.width |
387 | - var endY = startY |
388 | - mousePress(item, startX, startY) |
389 | - mouseMoveSlowly(item, |
390 | - startX, startY, |
391 | - endX - startX, endY - startY, |
392 | - 10, 100) |
393 | - mouseRelease(item, endX, endY) |
394 | - mouseClick(item, startX, startY) |
395 | + function _confirmListItemValue(page, objectName, expectedValue, message) { |
396 | + var listitem = findChild(page, objectName) |
397 | + compare(listitem.subText, expectedValue, message) |
398 | } |
399 | |
400 | function _deleteAlarm(label, repeat, time, status) { |
401 | @@ -196,50 +168,104 @@ |
402 | var alarmObject = findChild(alarmsList, "alarm"+index) |
403 | |
404 | if (index !== -1) { |
405 | - _swipeToDeleteItem(alarmObject) |
406 | + utils.swipeToDeleteItem(alarmObject) |
407 | } |
408 | |
409 | tryCompare(alarmsList, "count", oldCount-1, 10000, "Alarm count did not decrease after deleting the alarm") |
410 | } |
411 | |
412 | function _setAlarm(label, repeat, time) { |
413 | - _pressAddAlarmHeaderButton() |
414 | + utils.pressHeaderButton(header, "addAlarmAction") |
415 | |
416 | var addAlarmPage = findChild(pageStack, "AddAlarmPage") |
417 | waitForRendering(addAlarmPage) |
418 | |
419 | + // Set the alarm time |
420 | var alarmTimePicker = findChild(pageStack, "alarmTime") |
421 | - var date = _setAlarmTime(alarmTimePicker, time) |
422 | + _setAlarmTime(alarmTimePicker, time) |
423 | |
424 | + // Set the alarm repeat options |
425 | _pressListItem(addAlarmPage, "alarmRepeat") |
426 | - var alarmRepeatPage = _getPage("alarmRepeatPage") |
427 | + var alarmRepeatPage = utils.getPage(pageStack, "alarmRepeatPage") |
428 | _setAlarmRepeatDays(alarmRepeatPage, repeat) |
429 | - _pressBackButton() |
430 | + utils.pressButton(backButton) |
431 | |
432 | waitForRendering(addAlarmPage) |
433 | |
434 | + // Set the alarm label |
435 | _pressListItem(addAlarmPage, "alarmLabel") |
436 | - var alarmLabelPage = _getPage("alarmLabelPage") |
437 | + var alarmLabelPage = utils.getPage(pageStack, "alarmLabelPage") |
438 | _setAlarmLabel(alarmLabelPage, label) |
439 | - _pressBackButton() |
440 | - |
441 | - waitForRendering(addAlarmPage) |
442 | - |
443 | - _pressListItem(addAlarmPage, "alarmSound") |
444 | - var alarmSoundPage = _getPage("alarmSoundPage") |
445 | - _setAlarmSound(alarmSoundPage) |
446 | - _pressBackButton() |
447 | - |
448 | - waitForRendering(addAlarmPage) |
449 | - |
450 | - _pressSaveAlarmHeaderButton() |
451 | + utils.pressButton(backButton) |
452 | + |
453 | + waitForRendering(addAlarmPage) |
454 | + |
455 | + // Set the alarm sound |
456 | + _pressListItem(addAlarmPage, "alarmSound") |
457 | + var alarmSoundPage = utils.getPage(pageStack, "alarmSoundPage") |
458 | + _setAlarmSound(alarmSoundPage) |
459 | + utils.pressButton(backButton) |
460 | + |
461 | + waitForRendering(addAlarmPage) |
462 | + |
463 | + utils.pressHeaderButton(header, "saveAlarmAction") |
464 | + |
465 | + waitForRendering(alarmPage) |
466 | + } |
467 | + |
468 | + function _editAlarm(oldlabel, oldrepeat, oldtime, status, newlabel, newrepeat, newtime) { |
469 | + // Find the index of the alarm which needs to be edited |
470 | + var alarmIndex = findAlarm(oldlabel, oldrepeat, oldtime, status) |
471 | + |
472 | + if (alarmIndex === -1) { |
473 | + fail("Cannot find saved alarm to edit") |
474 | + } |
475 | + |
476 | + // Press the alarm to be edited |
477 | + var alarmsList = findChild(alarmPage, "alarmListView") |
478 | + var alarmObject = findChild(alarmsList, "alarm"+alarmIndex) |
479 | + mouseClick(alarmObject, centerOf(alarmObject).x, centerOf(alarmObject).y) |
480 | + |
481 | + // Proceed to verify the alarm read is correct and then set new values |
482 | + var addAlarmPage = findChild(pageStack, "AddAlarmPage") |
483 | + waitForRendering(addAlarmPage) |
484 | + |
485 | + var alarmTimePicker = findChild(pageStack, "alarmTime") |
486 | + compare(Qt.formatTime(alarmTimePicker.date), oldtime, "Time read from the saved alarm is incorrect") |
487 | + _setAlarmTime(alarmTimePicker, newtime) |
488 | + |
489 | + _confirmListItemValue(addAlarmPage, "alarmRepeat", oldrepeat, "Alarm repeat options read from the saved alarm is incorrect") |
490 | + _pressListItem(addAlarmPage, "alarmRepeat") |
491 | + var alarmRepeatPage = utils.getPage(pageStack, "alarmRepeatPage") |
492 | + _setAlarmRepeatDays(alarmRepeatPage, newrepeat) |
493 | + utils.pressButton(backButton) |
494 | + |
495 | + waitForRendering(addAlarmPage) |
496 | + |
497 | + _confirmListItemValue(addAlarmPage, "alarmLabel", oldlabel, "Alarm name read from the saved alarm is incorrect") |
498 | + _pressListItem(addAlarmPage, "alarmLabel") |
499 | + var alarmLabelPage = utils.getPage(pageStack, "alarmLabelPage") |
500 | + _setAlarmLabel(alarmLabelPage, newlabel) |
501 | + utils.pressButton(backButton) |
502 | + |
503 | + waitForRendering(addAlarmPage) |
504 | + |
505 | + _confirmListItemValue(addAlarmPage, "alarmSound", "Celestial", "Alarm sound read from the saved alarm is incorrect") |
506 | + _pressListItem(addAlarmPage, "alarmSound") |
507 | + var alarmSoundPage = utils.getPage(pageStack, "alarmSoundPage") |
508 | + _setAlarmSound(alarmSoundPage) |
509 | + utils.pressButton(backButton) |
510 | + |
511 | + waitForRendering(addAlarmPage) |
512 | + |
513 | + utils.pressHeaderButton(header, "saveAlarmAction") |
514 | |
515 | waitForRendering(alarmPage) |
516 | } |
517 | |
518 | // ************* Test Functions ************ |
519 | |
520 | - function test_createAlarm_data() { |
521 | + function test_01_createAlarm_data() { |
522 | return [ |
523 | {tag: "Weekday Alarms", name: "Weekday Alarm", repeat: [0,1,2,3,4], repeatLabel: "Weekdays"}, |
524 | {tag: "Weekend Alarms", name: "Weekend Alarm", repeat: [5,6], repeatLabel: "Weekends"}, |
525 | @@ -248,7 +274,7 @@ |
526 | } |
527 | |
528 | // Test to check if creating an alarm works as expected |
529 | - function test_createAlarm(data) { |
530 | + function test_01_createAlarm(data) { |
531 | var date = new Date() |
532 | date.setHours((date.getHours() + 10) % 24) |
533 | date.setMinutes((date.getMinutes() + 40) % 60) |
534 | @@ -263,5 +289,37 @@ |
535 | */ |
536 | _deleteAlarm(data.name, data.repeatLabel, Qt.formatTime(date), true) |
537 | } |
538 | + |
539 | + // Test to check if editing an alarm and saving it works as expected |
540 | + function test_02_editAlarm() { |
541 | + var date = new Date() |
542 | + date.setHours((date.getHours() + 10) % 24) |
543 | + date.setMinutes((date.getMinutes() + 40) % 60) |
544 | + date.setSeconds(0) |
545 | + |
546 | + _setAlarm("Test Edit Alarm", [0,1,2,3,4], date) |
547 | + |
548 | + var newDate = new Date() |
549 | + newDate.setHours((newDate.getHours() + 5) % 24) |
550 | + newDate.setMinutes((newDate.getMinutes() + 15) % 60) |
551 | + newDate.setSeconds(0) |
552 | + |
553 | + _editAlarm("Test Edit Alarm", "Weekdays", Qt.formatTime(date), true, "Alarm Edited", [5,6], newDate) |
554 | + |
555 | + /* |
556 | + #NOTE: This wait is required since as per the design after an alarm is edited and saved |
557 | + it shows the remaining time to that alarm and then after 5 secs shows the alarm |
558 | + frequency. Hence we need to wait for 5 seconds before confirming alarm creation. |
559 | + */ |
560 | + wait(6000) |
561 | + |
562 | + _confirmAlarmCreation("Alarm Edited", "Weekends", Qt.formatTime(newDate), true) |
563 | + |
564 | + /* |
565 | + #FIXME: This won't be required once we mock up alarm data. Until |
566 | + then we need to delete alarms to cleanup after the tests. |
567 | + */ |
568 | + _deleteAlarm("Alarm Edited", "Weekends", Qt.formatTime(newDate), true) |
569 | + } |
570 | } |
571 | } |
572 | |
573 | === modified file 'tests/unit/tst_alarmLabel.qml' |
574 | --- tests/unit/tst_alarmLabel.qml 2014-09-25 11:14:24 +0000 |
575 | +++ tests/unit/tst_alarmLabel.qml 2014-10-13 20:56:20 +0000 |
576 | @@ -38,6 +38,10 @@ |
577 | alarm: _alarm |
578 | } |
579 | |
580 | + Utils { |
581 | + id: utils |
582 | + } |
583 | + |
584 | UbuntuTestCase { |
585 | id: alarmLabelPageTest |
586 | name: "AlarmLabelPage" |
587 | @@ -55,14 +59,6 @@ |
588 | backButton = findChild(header, "customBackButton") |
589 | } |
590 | |
591 | - function clearTextField(textfield) { |
592 | - // Get textfield focus by clicking once |
593 | - mouseClick(textfield, textfield.width - units.gu(2), textfield.height/2) |
594 | - |
595 | - // Click on the clear button shown on the right |
596 | - mouseClick(textfield, textfield.width - units.gu(2), textfield.height/2) |
597 | - } |
598 | - |
599 | /* |
600 | Test to check if the alarm label has focus true by default to ensure |
601 | that the OSK is shown when the opens the alarm label page. |
602 | @@ -87,7 +83,7 @@ |
603 | compare(alarmLabel.text, "Alarm", "Default alarm label is not Alarm") |
604 | compare(backButton.enabled, true, "Back header button is not enabled by default") |
605 | |
606 | - clearTextField(alarmLabel) |
607 | + utils.clearTextField(alarmLabel) |
608 | typeString(data.string) |
609 | |
610 | compare(alarmLabel.text, data.string, "Alarm label is not what was type in the textfield") |
611 | |
612 | === added file 'tests/unit/tst_worldClock.qml' |
613 | --- tests/unit/tst_worldClock.qml 1970-01-01 00:00:00 +0000 |
614 | +++ tests/unit/tst_worldClock.qml 2014-10-13 20:56:20 +0000 |
615 | @@ -0,0 +1,194 @@ |
616 | +/* |
617 | + * Copyright (C) 2014 Canonical Ltd |
618 | + * |
619 | + * This file is part of Ubuntu Clock App |
620 | + * |
621 | + * Ubuntu Clock App is free software: you can redistribute it and/or modify |
622 | + * it under the terms of the GNU General Public License version 3 as |
623 | + * published by the Free Software Foundation. |
624 | + * |
625 | + * Ubuntu Clock App is distributed in the hope that it will be useful, |
626 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
627 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
628 | + * GNU General Public License for more details. |
629 | + * |
630 | + * You should have received a copy of the GNU General Public License |
631 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
632 | + */ |
633 | + |
634 | +import QtQuick 2.0 |
635 | +import QtTest 1.0 |
636 | +import Ubuntu.Test 1.0 |
637 | +import Ubuntu.Components 1.1 |
638 | + |
639 | +MockClockApp { |
640 | + id: clockApp |
641 | + |
642 | + Utils { |
643 | + id: utils |
644 | + } |
645 | + |
646 | + UbuntuTestCase { |
647 | + id: worldClockFeatureTest |
648 | + name: "WorldClockFeatureTest" |
649 | + |
650 | + when: windowShown |
651 | + |
652 | + property var header |
653 | + property var backButton |
654 | + property var clockPage |
655 | + property var pageStack |
656 | + |
657 | + function initTestCase() { |
658 | + header = findChild(clockApp, "MainView_Header") |
659 | + backButton = findChild(header, "customBackButton") |
660 | + pageStack = findChild(clockApp, "pageStack") |
661 | + clockPage = findChild(clockApp, "clockPage") |
662 | + } |
663 | + |
664 | + // *********** Helper Functions ************ |
665 | + |
666 | + function _pressAddWorldCityButton() { |
667 | + var addWorldCityButton = findChild(clockApp, "addWorldCityButton") |
668 | + utils.pressButton(addWorldCityButton) |
669 | + } |
670 | + |
671 | + function _findWorldCity(cityList, type, cityName, countryName) { |
672 | + /* |
673 | + The list view for the user world city list and the available world |
674 | + city list have the same structure with some minor object name |
675 | + changes. The 'objectPrefix' varible is used to handle that. |
676 | + */ |
677 | + var objectPrefix = type === "user" ? "user" : "default" |
678 | + |
679 | + for(var i=0; i<cityList.count; i++) { |
680 | + var cityListItem = findChild(clockApp, objectPrefix+"WorldCityItem"+i) |
681 | + var city = findChild(cityListItem, objectPrefix+"CityNameText") |
682 | + var country = findChild(cityListItem, objectPrefix+"CountryNameText") |
683 | + |
684 | + if (city.text === cityName && country.text === countryName) { |
685 | + return i |
686 | + } |
687 | + } |
688 | + |
689 | + return -1; |
690 | + } |
691 | + |
692 | + function _confirmWorldCityAddition(cityName, countryName) { |
693 | + var cityList = findChild(clockApp, "userWorldCityRepeater") |
694 | + |
695 | + /* |
696 | + Confirm that at least one world city is saved before proceeding |
697 | + to check if that's the city added during the test. |
698 | + */ |
699 | + tryCompareFunction(function() { return cityList.count > 0}, true) |
700 | + |
701 | + var cityIndex = _findWorldCity(cityList, "user", cityName, countryName) |
702 | + |
703 | + if (cityIndex === -1) { |
704 | + // If city couldn't be found in the saved city list, fail the test |
705 | + fail("City added during the test cannot be found in the user world city list!") |
706 | + } |
707 | + } |
708 | + |
709 | + function _deleteWorldCity(cityName, countryName) { |
710 | + var cityList = findChild(clockApp, "userWorldCityRepeater") |
711 | + |
712 | + /* |
713 | + Confirm that at least one world city is saved before proceeding |
714 | + to delete the city added during the test. |
715 | + */ |
716 | + tryCompareFunction(function() { return cityList.count > 0}, true) |
717 | + |
718 | + var oldCount = cityList.count |
719 | + var cityIndex = _findWorldCity(cityList, "user", cityName, countryName) |
720 | + |
721 | + if (cityIndex === -1) { |
722 | + fail("City added during the test cannot be found in the user world city list!") |
723 | + } |
724 | + else { |
725 | + var cityListItem = findChild(clockApp, "userWorldCityItem"+cityIndex) |
726 | + utils.swipeToDeleteItem(cityListItem) |
727 | + } |
728 | + |
729 | + /* |
730 | + #FIXME: Commented out the following line as deleting a world city |
731 | + when there is only one world city does not decrease the count to 0 |
732 | + but leaves it as 1 causing the test to fail. This has been reported |
733 | + in bug #1368393. (Also fails in Autopilot) |
734 | + |
735 | + tryCompare(cityList, "count", oldCount-1, 5000, "city list count did not decrease") |
736 | + |
737 | + The wait() call below is to ensure that the world city is deleted properly |
738 | + which wouldn't be required if could do the count decrease check mentioned above. |
739 | + */ |
740 | + |
741 | + wait(1000) |
742 | + } |
743 | + |
744 | + function _addCityFromList(cityName, countryName) { |
745 | + var worldCityPage = utils.getPage(pageStack, "worldCityList") |
746 | + var cityList = findChild(worldCityPage, "cityList") |
747 | + |
748 | + // Wait for the list to be populated with results |
749 | + tryCompareFunction(function() { return cityList.count > 0}, true) |
750 | + |
751 | + var cityIndex = _findWorldCity(cityList, "default", cityName, countryName) |
752 | + |
753 | + if (cityIndex === -1) { |
754 | + fail("City cannot be found in the local world city list") |
755 | + } |
756 | + |
757 | + var cityListItem = findChild(cityList, "defaultWorldCityItem"+cityIndex) |
758 | + mouseClick(cityListItem, centerOf(cityListItem).x, centerOf(cityListItem).y) |
759 | + } |
760 | + |
761 | + function _addCityBySearchingOnline(cityName, countryName) { |
762 | + utils.pressHeaderButton(header, "searchButton") |
763 | + var searchField = findChild(clockApp, "searchField") |
764 | + tryCompare(searchField, "visible", true, 5000, "Search field is not visible") |
765 | + typeString(cityName) |
766 | + _addCityFromList(cityName, countryName) |
767 | + } |
768 | + |
769 | + // *********** Test Functions ************* |
770 | + |
771 | + /* |
772 | + Test to check if a city found in the world city list can be added |
773 | + to the user world city list. |
774 | + */ |
775 | + function test_addCityAlreadyPresentInWorldCityList() { |
776 | + var clockPage = utils.getPage(pageStack, "clockPage") |
777 | + |
778 | + _pressAddWorldCityButton() |
779 | + |
780 | + var worldCityPage = utils.getPage(pageStack, "worldCityList") |
781 | + waitForRendering(worldCityPage) |
782 | + |
783 | + _addCityFromList("Amsterdam", "Netherlands") |
784 | + _confirmWorldCityAddition("Amsterdam", "Netherlands") |
785 | + |
786 | + // Clean up after the test by deleting the city which was added during the test |
787 | + _deleteWorldCity("Amsterdam", "Netherlands") |
788 | + } |
789 | + |
790 | + /* |
791 | + Test to check if a city now found in the world city list can be added |
792 | + by searcing it online and then adding it from the results returned. |
793 | + */ |
794 | + function test_addCityBySearchingOnline() { |
795 | + var clockPage = utils.getPage(pageStack, "clockPage") |
796 | + |
797 | + _pressAddWorldCityButton() |
798 | + |
799 | + var worldCityPage = utils.getPage(pageStack, "worldCityList") |
800 | + waitForRendering(worldCityPage) |
801 | + |
802 | + _addCityBySearchingOnline("Venice", "Provincia di Venezia, Veneto, Italy") |
803 | + _confirmWorldCityAddition("Venice", " Veneto, Italy") |
804 | + |
805 | + // Clean up after the test by deleting the city which was added during the test |
806 | + _deleteWorldCity("Venice", " Veneto, Italy") |
807 | + } |
808 | + } |
809 | +} |