Merge lp:~nik90/ubuntu-clock-app/add-feature-qml-tests into lp:ubuntu-clock-app
- add-feature-qml-tests
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Nekhelesh Ramananthan |
Approved revision: | 135 |
Merged at revision: | 122 |
Proposed branch: | lp:~nik90/ubuntu-clock-app/add-feature-qml-tests |
Merge into: | lp:ubuntu-clock-app |
Diff against target: |
643 lines (+434/-15) 11 files modified
app/alarm/AlarmList.qml (+1/-1) app/alarm/AlarmPage.qml (+2/-4) app/alarm/AlarmSound.qml (+1/-0) app/alarm/EditAlarmPage.qml (+7/-6) debian/changelog (+4/-0) debian/control (+6/-3) tests/unit/CMakeLists.txt (+4/-0) tests/unit/tst_alarm.qml (+233/-0) tests/unit/tst_alarmLabel.qml (+18/-0) tests/unit/tst_alarmRepeat.qml (+19/-1) tests/unit/tst_alarmSound.qml (+139/-0) |
To merge this branch: | bzr merge lp:~nik90/ubuntu-clock-app/add-feature-qml-tests |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ubuntu Phone Apps Jenkins Bot | continuous-integration | Approve | |
Leo Arias (community) | Approve | ||
Nekhelesh Ramananthan | Needs Information | ||
Review via email:
|
Commit message
Added QML units tests for AlarmSound.qml page and also a user feature test for creating alarms.
Description of the change
Added QML units tests for AlarmSound.qml page and also a user feature test for creating alarms.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:123
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Leo Arias (elopio) wrote : | # |
241 + function _getAlarmRepeat
247 + function _getAlarmLabelP
253 + function _getAlarmSoundP
These three methods have the same code, so you can extract a function getPage(objectName)
259 + function _waitPickerMovi
I would rename this to waitForPickerTo
274 + for (var j=0; j<repeater.count; j++) {
281 + for (var i=0; i<days.length; i++) {
You can merge these two into a single loop, like:
for index=0; index<count; index++ {
if switch.checked != days.contains(
clickSwitch
}
}
I would need to refresh my javascript to know the real code needed, but if the result is not more complex and looks clear it's worth changing it.
298 + mouseClick(
595 + mouseClick(
I like center of better than /2.
IMHO, the tst_alarm code is too complex and would be more expressive and clear on python. I would write the alarm tests in autopilot. The sound tests seem good to me as QML tests. But it's your choice, as long as it is tested I'm happy.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Leo Arias (elopio) wrote : | # |
Sorry, I didn't mean to approve it yet. We need first the tests to pass :)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:130
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Nekhelesh Ramananthan (nik90) wrote : | # |
> 241 + function _getAlarmRepeat
> 247 + function _getAlarmLabelP
> 253 + function _getAlarmSoundP
>
> These three methods have the same code, so you can extract a function
> getPage(objectName)
Fixed in rev 124. In fact I went one step further and did that for other functions as well.
>
> 259 + function _waitPickerMovi
>
> I would rename this to waitForPickerTo
Done in rev 126.
>
> 274 + for (var j=0; j<repeater.count; j++) {
> 281 + for (var i=0; i<days.length; i++) {
>
> You can merge these two into a single loop, like:
>
> for index=0; index<count; index++ {
> if switch.checked != days.contains(
> clickSwitch
> }
> }
>
> I would need to refresh my javascript to know the real code needed, but if the
> result is not more complex and looks clear it's worth changing it.
>
Hmm I will have to rethink why I used 2 loops. Give me some time for this.
> 298 + mouseClick(
> secondSwitch.
> 595 + mouseClick(
> alarmSoundSwitc
>
> I like center of better than /2.
Yup me too I like centerOf() better than height/2, width/2 stuff. I fixed this in rev 129.
>
> IMHO, the tst_alarm code is too complex and would be more expressive and clear
> on python. I would write the alarm tests in autopilot. The sound tests seem
> good to me as QML tests. But it's your choice, as long as it is tested I'm
> happy.
Actually I prefer QML tests for the following reasons,
1. I feel that tst_alarm.qml is actually much simpler than its AP counterpart since in AP you have so many helper functions defined to do the test.
2. AP tests always are troublesome to deal with due to timing issues while QML tests has this super simple function waitForRendering(). I know AP has self.waitFor(), but it isn't the same thing.
3. The whole QML test suite took about 8.09s to complete and cover far more test cases. AP on the other hand only tests a limited set of use cases and takes too long to execute.
4. Since the whole thing is written in QML+JS which I am more comfortable with, maintaining and creating new tests is so simple now. In fact I can now actually follow the test driven development approach by actually writing tests as soon I implement a feature/bug fix as you noticed previously.
My goal was to eventual remove AP tests and use it very sparingly. I believe Unity 8 has over 900 QML tests and they barely use AP tests which might be the way to go. Please do feel free to give your opinion since I value that quite a bit.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:130
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:131
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:132
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Continuous integration, rev:133
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
PASSED: Continuous integration, rev:134
http://
Executed test runs:
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Leo Arias (elopio) wrote : | # |
As I said, as long as the code is covered by tests, I can't ask for more. If you feel more comfortable with QML tests and that will make you write more tests, that's perfect for me.
Now that the tests are passing, I'll leave you my +1.
Just one small detail remains:
154 + suru-icon-theme | ubuntu-
You seem to have a weird indentation there.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Nekhelesh Ramananthan (nik90) wrote : | # |
Thanks for the review :-)
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote : | # |
FAILED: Autolanding.
More details in the following jenkins job:
http://
Executed test runs:
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) : | # |
Preview Diff
1 | === modified file 'app/alarm/AlarmList.qml' |
2 | --- app/alarm/AlarmList.qml 2014-08-24 12:47:50 +0000 |
3 | +++ app/alarm/AlarmList.qml 2014-09-26 10:56:53 +0000 |
4 | @@ -131,7 +131,7 @@ |
5 | } |
6 | |
7 | else { |
8 | - mainStack.push(Qt.resolvedUrl("EditAlarmPage.qml"), |
9 | + pageStack.push(Qt.resolvedUrl("EditAlarmPage.qml"), |
10 | {"isNewAlarm": false, "alarmIndex": index}) |
11 | } |
12 | } |
13 | |
14 | === modified file 'app/alarm/AlarmPage.qml' |
15 | --- app/alarm/AlarmPage.qml 2014-09-18 11:31:14 +0000 |
16 | +++ app/alarm/AlarmPage.qml 2014-09-26 10:56:53 +0000 |
17 | @@ -18,9 +18,7 @@ |
18 | |
19 | import QtQuick 2.3 |
20 | import Ubuntu.Components 1.1 |
21 | - |
22 | import "../components" |
23 | -import "../components/Utils.js" as Utils |
24 | |
25 | Page { |
26 | id: alarmPage |
27 | @@ -28,7 +26,7 @@ |
28 | title: i18n.tr("Alarms") |
29 | objectName: 'AlarmPage' |
30 | |
31 | - Component.onCompleted: Utils.log(debugMode, "Alarm Page loaded") |
32 | + Component.onCompleted: console.log("Alarm Page loaded") |
33 | |
34 | flickable: null |
35 | |
36 | @@ -44,7 +42,7 @@ |
37 | iconName: "add" |
38 | text: i18n.tr("Alarm") |
39 | onTriggered: { |
40 | - mainStack.push(Qt.resolvedUrl("EditAlarmPage.qml")) |
41 | + pageStack.push(Qt.resolvedUrl("EditAlarmPage.qml")) |
42 | } |
43 | } |
44 | ] |
45 | |
46 | === modified file 'app/alarm/AlarmSound.qml' |
47 | --- app/alarm/AlarmSound.qml 2014-09-09 13:08:42 +0000 |
48 | +++ app/alarm/AlarmSound.qml 2014-09-26 10:56:53 +0000 |
49 | @@ -23,6 +23,7 @@ |
50 | |
51 | Page { |
52 | id: _alarmSoundPage |
53 | + objectName: "alarmSoundPage" |
54 | |
55 | title: i18n.tr("Sound") |
56 | flickable: _pageFlickable |
57 | |
58 | === modified file 'app/alarm/EditAlarmPage.qml' |
59 | --- app/alarm/EditAlarmPage.qml 2014-09-21 14:21:15 +0000 |
60 | +++ app/alarm/EditAlarmPage.qml 2014-09-26 10:56:53 +0000 |
61 | @@ -95,7 +95,7 @@ |
62 | tempAlarm.cancel() |
63 | |
64 | if(validateAlarm(tempAlarm)) { |
65 | - mainStack.pop() |
66 | + pageStack.pop() |
67 | } |
68 | } |
69 | |
70 | @@ -118,7 +118,7 @@ |
71 | tempAlarm.save() |
72 | |
73 | if(validateAlarm(tempAlarm)) { |
74 | - mainStack.pop() |
75 | + pageStack.pop() |
76 | } |
77 | } |
78 | |
79 | @@ -186,7 +186,7 @@ |
80 | return; |
81 | if ((operation > Alarm.NoOperation) && |
82 | (operation < Alarm.Reseting)) { |
83 | - mainStack.pop(); |
84 | + pageStack.pop(); |
85 | } |
86 | } |
87 | |
88 | @@ -246,6 +246,7 @@ |
89 | |
90 | DatePicker { |
91 | id: _timePicker |
92 | + objectName: "alarmTime" |
93 | |
94 | /* |
95 | #FIXME: DatePicker does not respect the user's locale. The bug |
96 | @@ -288,7 +289,7 @@ |
97 | |
98 | text: i18n.tr("Repeat") |
99 | subText: alarmUtils.format_day_string(_alarm.daysOfWeek, _alarm.type) |
100 | - onClicked: mainStack.push(Qt.resolvedUrl("AlarmRepeat.qml"), |
101 | + onClicked: pageStack.push(Qt.resolvedUrl("AlarmRepeat.qml"), |
102 | {"alarm": _alarm}) |
103 | } |
104 | |
105 | @@ -298,7 +299,7 @@ |
106 | |
107 | text: i18n.tr("Label") |
108 | subText: _alarm.message |
109 | - onClicked: mainStack.push(Qt.resolvedUrl("AlarmLabel.qml"), |
110 | + onClicked: pageStack.push(Qt.resolvedUrl("AlarmLabel.qml"), |
111 | {"alarm": _alarm}) |
112 | } |
113 | |
114 | @@ -310,7 +311,7 @@ |
115 | property string _soundName: "Suru arpeggio" |
116 | |
117 | text: i18n.tr("Sound") |
118 | - onClicked: mainStack.push(Qt.resolvedUrl("AlarmSound.qml"), { |
119 | + onClicked: pageStack.push(Qt.resolvedUrl("AlarmSound.qml"), { |
120 | "alarmSound": _alarmSound, |
121 | "alarm": _alarm, |
122 | "soundModel": soundModel |
123 | |
124 | === modified file 'debian/changelog' |
125 | --- debian/changelog 2014-09-24 12:35:03 +0000 |
126 | +++ debian/changelog 2014-09-26 10:56:53 +0000 |
127 | @@ -37,6 +37,7 @@ |
128 | anchors in the alarm settings page. |
129 | * Enabled alarms automatically after updating it (LP: #1372090) |
130 | * Automatically focus textfield (LP: #1372089) |
131 | + * Added alarm feature qml tests and alarm sound unit tests |
132 | |
133 | [Zsombor Egri] |
134 | * Fixed alarm status toggle being reverted immediately (LP: #1272337) |
135 | @@ -56,6 +57,9 @@ |
136 | * Fixed wrong alignment of "Add city" button when the application is not |
137 | localized in English. (LP: #1371229) |
138 | |
139 | + [Leo Arias] |
140 | + * Fixed CMake and debian/control to run the qml tests during a deb package build |
141 | + |
142 | -- Nekhelesh Ramananthan <krnekhelesh@gmail.com> Wed, 13 Aug 2014 15:46:12 +0200 |
143 | |
144 | ubuntu-clock-app (3.0-0ubuntu1) utopic; urgency=medium |
145 | |
146 | === modified file 'debian/control' |
147 | --- debian/control 2014-09-16 20:00:34 +0000 |
148 | +++ debian/control 2014-09-26 10:56:53 +0000 |
149 | @@ -7,11 +7,16 @@ |
150 | intltool, |
151 | python3 | python3-all | python3-dev | python3-all-dev, |
152 | python3-minimal, |
153 | + ubuntu-touch-sounds, |
154 | + suru-icon-theme | ubuntu-mobile-icons, |
155 | qml-module-qttest, |
156 | + qtdeclarative5-u1db1.0, |
157 | + qtdeclarative5-qtmultimedia-plugin, |
158 | qt5-default, |
159 | qtbase5-dev, |
160 | qtdeclarative5-dev, |
161 | qtdeclarative5-dev-tools, |
162 | + qtdeclarative5-folderlistmodel-plugin, |
163 | qtdeclarative5-ubuntu-ui-toolkit-plugin, |
164 | xvfb, |
165 | Standards-Version: 3.9.5 |
166 | @@ -23,12 +28,10 @@ |
167 | Package: ubuntu-clock-app |
168 | Architecture: any |
169 | Depends: qmlscene, |
170 | - qtdeclarative5-localstorage-plugin, |
171 | - qtdeclarative5-qtquick2-plugin, |
172 | qtdeclarative5-u1db1.0, |
173 | qtdeclarative5-ubuntu-ui-toolkit-plugin | qt-components-ubuntu, |
174 | qtdeclarative5-xmllistmodel-plugin, |
175 | - qtdeclarative5-qtmultimedia-plugin, |
176 | + qtdeclarative5-qtmultimedia-plugin, |
177 | ubuntu-touch-sounds, |
178 | suru-icon-theme | ubuntu-mobile-icons, |
179 | ${misc:Depends}, |
180 | |
181 | === modified file 'tests/unit/CMakeLists.txt' |
182 | --- tests/unit/CMakeLists.txt 2014-09-12 05:05:03 +0000 |
183 | +++ tests/unit/CMakeLists.txt 2014-09-26 10:56:53 +0000 |
184 | @@ -23,6 +23,8 @@ |
185 | if(QMLTESTRUNNER_BIN AND XVFB_RUN_BIN) |
186 | declare_qml_test("AlarmLabel" tst_alarmLabel.qml) |
187 | declare_qml_test("AlarmRepeat" tst_alarmRepeat.qml) |
188 | + declare_qml_test("Alarm" tst_alarm.qml) |
189 | + declare_qml_test("AlarmSound" tst_alarmSound.qml) |
190 | else() |
191 | if (NOT QMLTESTRUNNER_BIN) |
192 | message(WARNING "Qml tests disabled: qmltestrunner not found") |
193 | @@ -34,5 +36,7 @@ |
194 | set(QML_TST_FILES |
195 | tst_alarmLabel.qml |
196 | tst_alarmRepeat.qml |
197 | + tst_alarm.qml |
198 | + tst_alarmSound.qml |
199 | ) |
200 | add_custom_target(tst_QmlFiles ALL SOURCES ${QML_TST_FILES}) |
201 | |
202 | === added file 'tests/unit/tst_alarm.qml' |
203 | --- tests/unit/tst_alarm.qml 1970-01-01 00:00:00 +0000 |
204 | +++ tests/unit/tst_alarm.qml 2014-09-26 10:56:53 +0000 |
205 | @@ -0,0 +1,233 @@ |
206 | +/* |
207 | + * Copyright (C) 2014 Canonical Ltd |
208 | + * |
209 | + * This file is part of Ubuntu Clock App |
210 | + * |
211 | + * Ubuntu Clock App is free software: you can redistribute it and/or modify |
212 | + * it under the terms of the GNU General Public License version 3 as |
213 | + * published by the Free Software Foundation. |
214 | + * |
215 | + * Ubuntu Clock App is distributed in the hope that it will be useful, |
216 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
217 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
218 | + * GNU General Public License for more details. |
219 | + * |
220 | + * You should have received a copy of the GNU General Public License |
221 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
222 | + */ |
223 | + |
224 | +import QtQuick 2.3 |
225 | +import QtTest 1.0 |
226 | +import Ubuntu.Test 1.0 |
227 | +import Ubuntu.Components 1.1 |
228 | +import "../../app/alarm" |
229 | + |
230 | +MainView { |
231 | + id: mainView |
232 | + |
233 | + width: units.gu(40) |
234 | + height: units.gu(70) |
235 | + useDeprecatedToolbar: false |
236 | + |
237 | + AlarmModel { |
238 | + id: alarmModel |
239 | + } |
240 | + |
241 | + PageStack { |
242 | + id: pageStack |
243 | + Component.onCompleted: push(alarmPage) |
244 | + } |
245 | + |
246 | + AlarmPage { |
247 | + id: alarmPage |
248 | + } |
249 | + |
250 | + UbuntuTestCase { |
251 | + id: alarmTest |
252 | + name: "AlarmTest" |
253 | + |
254 | + when: windowShown |
255 | + |
256 | + property var header |
257 | + property var backButton |
258 | + |
259 | + function initTestCase() { |
260 | + header = findChild(mainView, "MainView_Header") |
261 | + backButton = findChild(alarmTest.header, "customBackButton") |
262 | + } |
263 | + |
264 | + // ************* Helper Functions ************ |
265 | + |
266 | + function _pressAddAlarmHeaderButton() { |
267 | + var addButton = findChild(header, "addAlarmAction" + "_header_button") |
268 | + mouseClick(addButton, centerOf(addButton).x, centerOf(addButton).y) |
269 | + } |
270 | + |
271 | + function _pressSaveAlarmHeaderButton() { |
272 | + var saveButton = findChild(alarmTest.header, "saveAlarmAction" + "_header_button") |
273 | + mouseClick(saveButton, centerOf(saveButton).x, centerOf(saveButton).y) |
274 | + } |
275 | + |
276 | + function _pressBackButton() { |
277 | + mouseClick(backButton, centerOf(backButton).x, centerOf(backButton).y) |
278 | + } |
279 | + |
280 | + function _pressListItem(page, objectName) { |
281 | + var listitem = findChild(page, objectName) |
282 | + mouseClick(listitem, centerOf(listitem).x, centerOf(listitem).y) |
283 | + } |
284 | + |
285 | + function _getPage(objectName) { |
286 | + var page = findChild(pageStack, objectName) |
287 | + waitForRendering(page) |
288 | + return page |
289 | + } |
290 | + |
291 | + function _waitForPickerToStopMoving(picker) { |
292 | + waitForRendering(picker); |
293 | + tryCompareFunction(function(){return picker.moving}, false); |
294 | + } |
295 | + |
296 | + function _setAlarmTime(picker, time) { |
297 | + picker.date = time |
298 | + _waitForPickerToStopMoving(picker) |
299 | + return picker.date |
300 | + } |
301 | + |
302 | + function _setAlarmRepeatDays(alarmRepeatPage, days) { |
303 | + var repeater = findChild(alarmRepeatPage, "alarmDays") |
304 | + var daySwitch |
305 | + |
306 | + for (var j=0; j<repeater.count; j++) { |
307 | + daySwitch = findChild(alarmRepeatPage, "daySwitch"+j) |
308 | + if(daySwitch.checked) { |
309 | + mouseClick(daySwitch, centerOf(daySwitch).x, centerOf(daySwitch).y) |
310 | + } |
311 | + } |
312 | + |
313 | + for (var i=0; i<days.length; i++) { |
314 | + daySwitch = findChild(alarmRepeatPage, "daySwitch"+days[i]) |
315 | + if(!daySwitch.checked) { |
316 | + mouseClick(daySwitch, centerOf(daySwitch).x, centerOf(daySwitch).y) |
317 | + } |
318 | + } |
319 | + } |
320 | + |
321 | + function _setAlarmLabel(alarmLabelPage, label) { |
322 | + var alarmLabel = findChild(alarmLabelPage, "labelEntry") |
323 | + mouseClick(alarmLabel, alarmLabel.width - units.gu(2), centerOf(alarmLabel).y) |
324 | + mouseClick(alarmLabel, alarmLabel.width - units.gu(2), centerOf(alarmLabel).y) |
325 | + typeString(label) |
326 | + } |
327 | + |
328 | + function _setAlarmSound(alarmSoundPage) { |
329 | + var secondSwitch = findChild(alarmSoundPage, "soundStatus"+2) |
330 | + mouseClick(secondSwitch, centerOf(secondSwitch).x, centerOf(secondSwitch).y) |
331 | + } |
332 | + |
333 | + function findAlarm(label, repeat, time, status) { |
334 | + var alarmsList = findChild(alarmPage, "alarmListView") |
335 | + |
336 | + for (var i=0; i<alarmsList.count; i++) { |
337 | + var alarmLabel = findChild(alarmsList, "listAlarmLabel"+i) |
338 | + var alarmRepeat = findChild(alarmsList, "listAlarmSubtitle"+i) |
339 | + var alarmTime = findChild(alarmsList, "listAlarmTime"+i) |
340 | + var alarmStatus = findChild(alarmsList, "listAlarmStatus"+i) |
341 | + |
342 | + if (label === alarmLabel.text |
343 | + && time === alarmTime.text |
344 | + && repeat === alarmRepeat.text |
345 | + && status === alarmStatus.checked) |
346 | + { |
347 | + return i; |
348 | + } |
349 | + } |
350 | + |
351 | + return -1; |
352 | + } |
353 | + |
354 | + function _confirmAlarmCreation(label, repeat, time, status) { |
355 | + if (findAlarm(label, repeat, time, status) === -1) { |
356 | + fail("No Alarm found with the specified characteristics") |
357 | + } |
358 | + } |
359 | + |
360 | + function _deleteAlarm(label, repeat, time, status) { |
361 | + var alarmsList = findChild(alarmPage, "alarmListView") |
362 | + var oldCount = alarmsList.count |
363 | + |
364 | + var index = findAlarm(label, repeat, time, status) |
365 | + var alarmObject = findChild(alarmsList, "alarm"+index) |
366 | + |
367 | + if (index !== -1) { |
368 | + mouseDrag(alarmObject, alarmObject.width/4, alarmObject.height/2, units.gu(10), 0) |
369 | + mouseRelease(alarmObject, alarmObject.width/4+units.gu(10), alarmObject.height/2) |
370 | + mouseClick(alarmObject, units.gu(5), alarmObject.height/2) |
371 | + } |
372 | + |
373 | + tryCompare(alarmsList, "count", oldCount-1, 10000, "Alarm count did not decrease after deleting the alarm") |
374 | + } |
375 | + |
376 | + function _setAlarm(label, repeat, time) { |
377 | + _pressAddAlarmHeaderButton() |
378 | + |
379 | + var addAlarmPage = findChild(pageStack, "AddAlarmPage") |
380 | + waitForRendering(addAlarmPage) |
381 | + |
382 | + var alarmTimePicker = findChild(pageStack, "alarmTime") |
383 | + var date = _setAlarmTime(alarmTimePicker, time) |
384 | + |
385 | + _pressListItem(addAlarmPage, "alarmRepeat") |
386 | + var alarmRepeatPage = _getPage("alarmRepeatPage") |
387 | + _setAlarmRepeatDays(alarmRepeatPage, repeat) |
388 | + _pressBackButton() |
389 | + |
390 | + waitForRendering(addAlarmPage) |
391 | + |
392 | + _pressListItem(addAlarmPage, "alarmLabel") |
393 | + var alarmLabelPage = _getPage("alarmLabelPage") |
394 | + _setAlarmLabel(alarmLabelPage, label) |
395 | + _pressBackButton() |
396 | + |
397 | + waitForRendering(addAlarmPage) |
398 | + |
399 | + _pressListItem(addAlarmPage, "alarmSound") |
400 | + var alarmSoundPage = _getPage("alarmSoundPage") |
401 | + _setAlarmSound(alarmSoundPage) |
402 | + _pressBackButton() |
403 | + |
404 | + waitForRendering(addAlarmPage) |
405 | + |
406 | + _pressSaveAlarmHeaderButton() |
407 | + |
408 | + waitForRendering(alarmPage) |
409 | + } |
410 | + |
411 | + // ************* Test Functions ************ |
412 | + |
413 | + function test_createAlarm_data() { |
414 | + return [ |
415 | + {tag: "Weekday Alarms", name: "Weekday Alarm", repeat: [0,1,2,3,4], repeatLabel: "Weekdays"}, |
416 | + {tag: "Weekend Alarms", name: "Weekend Alarm", repeat: [5,6], repeatLabel: "Weekends"}, |
417 | + {tag: "Random Day Alarm", name: "Random Day Alarm", repeat: [1,3], repeatLabel: String("%1, %2").arg(Qt.locale().standaloneDayName(2, Locale.LongFormat)).arg(Qt.locale().standaloneDayName(4, Locale.LongFormat))} |
418 | + ] |
419 | + } |
420 | + |
421 | + // Test to check if creating an alarm works as expected |
422 | + function test_createAlarm(data) { |
423 | + var date = new Date() |
424 | + date.setHours((date.getHours() + 10) % 24) |
425 | + date.setMinutes((date.getMinutes() + 40) % 60) |
426 | + date.setSeconds(0) |
427 | + |
428 | + _setAlarm(data.name, data.repeat, date) |
429 | + _confirmAlarmCreation(data.name, data.repeatLabel, Qt.formatTime(date), true) |
430 | + |
431 | + /* |
432 | + #FIXME: This won't be required once we mock up alarm data. Until |
433 | + then we need to delete alarms to cleanup after the tests. |
434 | + */ |
435 | + _deleteAlarm(data.name, data.repeatLabel, Qt.formatTime(date), true) |
436 | + } |
437 | + } |
438 | +} |
439 | |
440 | === modified file 'tests/unit/tst_alarmLabel.qml' |
441 | --- tests/unit/tst_alarmLabel.qml 2014-09-23 15:15:21 +0000 |
442 | +++ tests/unit/tst_alarmLabel.qml 2014-09-26 10:56:53 +0000 |
443 | @@ -1,3 +1,21 @@ |
444 | +/* |
445 | + * Copyright (C) 2014 Canonical Ltd |
446 | + * |
447 | + * This file is part of Ubuntu Clock App |
448 | + * |
449 | + * Ubuntu Clock App is free software: you can redistribute it and/or modify |
450 | + * it under the terms of the GNU General Public License version 3 as |
451 | + * published by the Free Software Foundation. |
452 | + * |
453 | + * Ubuntu Clock App is distributed in the hope that it will be useful, |
454 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
455 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
456 | + * GNU General Public License for more details. |
457 | + * |
458 | + * You should have received a copy of the GNU General Public License |
459 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
460 | + */ |
461 | + |
462 | import QtQuick 2.0 |
463 | import QtTest 1.0 |
464 | import Ubuntu.Test 1.0 |
465 | |
466 | === modified file 'tests/unit/tst_alarmRepeat.qml' |
467 | --- tests/unit/tst_alarmRepeat.qml 2014-09-23 15:15:21 +0000 |
468 | +++ tests/unit/tst_alarmRepeat.qml 2014-09-26 10:56:53 +0000 |
469 | @@ -1,3 +1,21 @@ |
470 | +/* |
471 | + * Copyright (C) 2014 Canonical Ltd |
472 | + * |
473 | + * This file is part of Ubuntu Clock App |
474 | + * |
475 | + * Ubuntu Clock App is free software: you can redistribute it and/or modify |
476 | + * it under the terms of the GNU General Public License version 3 as |
477 | + * published by the Free Software Foundation. |
478 | + * |
479 | + * Ubuntu Clock App is distributed in the hope that it will be useful, |
480 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
481 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
482 | + * GNU General Public License for more details. |
483 | + * |
484 | + * You should have received a copy of the GNU General Public License |
485 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
486 | + */ |
487 | + |
488 | import QtQuick 2.0 |
489 | import QtTest 1.0 |
490 | import Ubuntu.Test 1.0 |
491 | @@ -115,7 +133,7 @@ |
492 | var currentDaySwitch = findChild(alarmRepeatPageLoader.item, "daySwitch"+i) |
493 | |
494 | if(!currentDaySwitch.checked) { |
495 | - mouseClick(dayListItem, dayListItem.width/2, dayListItem.height/2) |
496 | + mouseClick(dayListItem, centerOf(dayListItem).x, centerOf(dayListItem).y) |
497 | } |
498 | } |
499 | |
500 | |
501 | === added file 'tests/unit/tst_alarmSound.qml' |
502 | --- tests/unit/tst_alarmSound.qml 1970-01-01 00:00:00 +0000 |
503 | +++ tests/unit/tst_alarmSound.qml 2014-09-26 10:56:53 +0000 |
504 | @@ -0,0 +1,139 @@ |
505 | +/* |
506 | + * Copyright (C) 2014 Canonical Ltd |
507 | + * |
508 | + * This file is part of Ubuntu Clock App |
509 | + * |
510 | + * Ubuntu Clock App is free software: you can redistribute it and/or modify |
511 | + * it under the terms of the GNU General Public License version 3 as |
512 | + * published by the Free Software Foundation. |
513 | + * |
514 | + * Ubuntu Clock App is distributed in the hope that it will be useful, |
515 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of |
516 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
517 | + * GNU General Public License for more details. |
518 | + * |
519 | + * You should have received a copy of the GNU General Public License |
520 | + * along with this program. If not, see <http://www.gnu.org/licenses/>. |
521 | + */ |
522 | + |
523 | +import QtQuick 2.3 |
524 | +import QtTest 1.0 |
525 | +import Ubuntu.Test 1.0 |
526 | +import Ubuntu.Components 1.1 |
527 | +import Qt.labs.folderlistmodel 2.1 |
528 | +import "../../app/alarm" |
529 | + |
530 | +MainView { |
531 | + id: mainView |
532 | + |
533 | + width: units.gu(40) |
534 | + height: units.gu(70) |
535 | + useDeprecatedToolbar: false |
536 | + |
537 | + Alarm { |
538 | + id: _alarm |
539 | + } |
540 | + |
541 | + FolderListModel { |
542 | + id: _soundModel |
543 | + |
544 | + showDirs: false |
545 | + nameFilters: [ "*.ogg", "*.mp3" ] |
546 | + folder: "/usr/share/sounds/ubuntu/ringtones" |
547 | + } |
548 | + |
549 | + AlarmSound { |
550 | + id: alarmSoundPage |
551 | + alarm: _alarm |
552 | + soundModel: _soundModel |
553 | + alarmSound: { "subText": "Bliss" } |
554 | + } |
555 | + |
556 | + UbuntuTestCase { |
557 | + id: alarmSoundPageTest |
558 | + name: "AlarmSoundPage" |
559 | + |
560 | + when: windowShown |
561 | + |
562 | + property var repeater |
563 | + |
564 | + function initTestCase() { |
565 | + alarmSoundPage.visible = true |
566 | + repeater = findChild(alarmSoundPage, "alarmSounds") |
567 | + } |
568 | + |
569 | + function cleanup() { |
570 | + alarmSoundPage.alarmSound.subText = "Bliss" |
571 | + for(var i=0; i<repeater.count; i++) { |
572 | + var alarmSoundSwitch = findChild(alarmSoundPage, "soundStatus"+i) |
573 | + var alarmSoundLabel = findChild(alarmSoundPage, "soundName"+i) |
574 | + |
575 | + if(alarmSoundPage.alarmSound.subText === alarmSoundLabel.text) { |
576 | + alarmSoundSwitch.checked = true |
577 | + } |
578 | + |
579 | + else { |
580 | + alarmSoundSwitch.checked = false |
581 | + } |
582 | + } |
583 | + } |
584 | + |
585 | + /* |
586 | + Test to check if the default alarm sound is checked while the rest are not. |
587 | + */ |
588 | + function test_defaultAlarmSoundIsChecked() { |
589 | + for(var i=0; i<repeater.count; i++) { |
590 | + var alarmSoundSwitch = findChild(alarmSoundPage, "soundStatus"+i) |
591 | + var alarmSoundLabel = findChild(alarmSoundPage, "soundName"+i) |
592 | + |
593 | + if(alarmSoundPage.alarmSound.subText === alarmSoundLabel.text) { |
594 | + compare(alarmSoundSwitch.checked, true, "Default alarm sound is not checked by default") |
595 | + } |
596 | + |
597 | + else { |
598 | + compare(alarmSoundSwitch.checked, false, "Switch for alarm sounds not default is enabled incorrectly") |
599 | + } |
600 | + } |
601 | + } |
602 | + |
603 | + /* |
604 | + Test to check if only one alarm sound is checked at all times |
605 | + */ |
606 | + function test_onlyOneAlarmSoundIsSelected() { |
607 | + |
608 | + // Click on some random alarm sounds |
609 | + var secondSwitch = findChild(alarmSoundPage, "soundStatus"+2) |
610 | + mouseClick(secondSwitch, centerOf(secondSwitch).x, centerOf(secondSwitch).y) |
611 | + |
612 | + var fourthSwitch = findChild(alarmSoundPage, "soundStatus"+2) |
613 | + mouseClick(fourthSwitch, centerOf(fourthSwitch.width).x, centerOf(fourthSwitch.height).y) |
614 | + |
615 | + // Check if only that alarm sound is check while the rest is disabled |
616 | + for(var i=0; i<repeater.count; i++) { |
617 | + var alarmSoundSwitch = findChild(alarmSoundPage, "soundStatus"+i) |
618 | + var alarmSoundLabel = findChild(alarmSoundPage, "soundName"+i) |
619 | + |
620 | + if(i !== 2) { |
621 | + compare(alarmSoundSwitch.checked, false, "More than one alarm sound selected") |
622 | + } |
623 | + } |
624 | + } |
625 | + |
626 | + /* |
627 | + Test to check if clicking on the only selected alarm sound does not disable |
628 | + it which would other wise leave no alarm sound being selected. |
629 | + */ |
630 | + function test_soundListHasNoEmptySelection() { |
631 | + |
632 | + for(var i=0; i<repeater.count; i++) { |
633 | + var alarmSoundSwitch = findChild(alarmSoundPage, "soundStatus"+i) |
634 | + |
635 | + if(alarmSoundSwitch.checked) { |
636 | + mouseClick(alarmSoundSwitch, centerOf(alarmSoundSwitch).x, centerOf(alarmSoundSwitch.height).y) |
637 | + compare(alarmSoundSwitch.checked, true, "Clicking on the only selected alarm sound disabled it") |
638 | + break; |
639 | + } |
640 | + } |
641 | + } |
642 | + } |
643 | +} |
@elopio, Just a note, I did,
bzr branch thisMPbranch qml-tests
cd add-feature-
mkdir builddir && cd builddir
cmake .. && make
ctest -V
At this point usually the qml test runs, but in this MP it says it cannot find the test suite. How does one run all qml tests in one go like jenkins does?