Merge lp:~carla-sella/ubuntu-clock-app/add-alarm-test into lp:ubuntu-clock-app

Proposed by Carla Sella
Status: Merged
Merged at revision: 38
Proposed branch: lp:~carla-sella/ubuntu-clock-app/add-alarm-test
Merge into: lp:ubuntu-clock-app
Prerequisite: lp:~nik90/ubuntu-clock-app/implement-change-time-settings
Diff against target: 1268 lines (+799/-218)
20 files modified
README.autopilot (+45/-0)
app/alarm/AlarmLabel.qml (+2/-0)
app/alarm/AlarmList.qml (+7/-0)
app/alarm/AlarmPage.qml (+2/-0)
app/alarm/AlarmRepeat.qml (+4/-0)
app/alarm/AlarmSound.qml (+3/-0)
app/alarm/EditAlarmPage.qml (+5/-0)
app/tests/autopilot/run (+0/-11)
app/tests/autopilot/ubuntu-clock-app/__init__.py (+0/-132)
app/tests/autopilot/ubuntu-clock-app/main/__init__.py (+0/-1)
app/tests/autopilot/ubuntu-clock-app/main/test_main.py (+0/-23)
app/tests/unit/tst_hellocomponent.qml (+0/-49)
manifest.json (+5/-2)
tests/autopilot/run (+11/-0)
tests/autopilot/ubuntu_clock_app/__init__.py (+18/-0)
tests/autopilot/ubuntu_clock_app/emulators.py (+395/-0)
tests/autopilot/ubuntu_clock_app/tests/__init__.py (+125/-0)
tests/autopilot/ubuntu_clock_app/tests/test_alarm.py (+84/-0)
tests/autopilot/ubuntu_clock_app/tests/test_clock.py (+44/-0)
tests/unit/tst_hellocomponent.qml (+49/-0)
To merge this branch: bzr merge lp:~carla-sella/ubuntu-clock-app/add-alarm-test
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Needs Fixing
Nekhelesh Ramananthan Approve
Review via email: mp+229084@code.launchpad.net

Commit message

Autopilot test for clock/reboot app

To post a comment you must log in.
Revision history for this message
Carla Sella (carla-sella) wrote :

I am having a UnicodeDecodeError and not sure how to handle it.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

I took the README.autopilot and improved it further at http://paste.ubuntu.com/7923533/. I added some intro and improving structuring. Please incorporate that into the branch.

review: Needs Fixing
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

518 +# Copyright (C) 2013, 2014 Canonical Ltd
519 +#
520 +# This program is free software: you can redistribute it and/or modify
521 +# it under the terms of the GNU General Public License version 3 as
522 +# published by the Free Software Foundation.
523 +#
524 +# This program is distributed in the hope that it will be useful,
525 +# but WITHOUT ANY WARRANTY; without even the implied warranty of
526 +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
527 +# GNU General Public License for more details.
528 +#
529 +# You should have received a copy of the GNU General Public License
530 +# along with this program. If not, see <http://www.gnu.org/licenses/>.
531 +#
532 +# Authored by: Renato Araujo Oliveira Filho <email address hidden>

Please replace all copyright headers with the new ones we added in the QML files please to maintain consistency throughout the source package.

review: Needs Fixing
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

563 +from ubuntuuitoolkit import emulators as toolkit_emulators, pickers

I believe balloons submitted a merge proposal against the old clock app where he switches the import statement to

import ubuntuuitoolkit

You can find his MP at https://code.launchpad.net/~nskaggs/ubuntu-clock-app/switch-emulators-to-proxy-object/+merge/227103. Since we are adding new tests for the clock app, it would be best if we could do this from the start. Can you make the appropriate changes? Remember that whereever you import the ubuntu emulator, you will need to make changes there as well. Best to look at balloons's MP to see what needs to be done.

review: Needs Fixing
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

729 + if mode == 'time':
730 + mode_value = 'Hours|Minutes'
731 + else:
732 + mode_value = 'Years|Months|Days'
733 + picker = self.wait_select_single(
734 + pickers.DatePicker, mode=mode_value, visible=True)
735 + if mode_value == 'Hours|Minutes':
736 + picker.pick_time(value)
737 + else:
738 + picker.pick_date(value)

Hmm, I am not sure why this is required. For the clock app, we will always only show the time picker, so can't we assume that the mode is time and proceed with that? Unless I am missing something here.

review: Needs Information
Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

> 563 +from ubuntuuitoolkit import emulators as toolkit_emulators, pickers
>
> I believe balloons submitted a merge proposal against the old clock app where
> he switches the import statement to
>
> import ubuntuuitoolkit
>
> You can find his MP at https://code.launchpad.net/~nskaggs/ubuntu-clock-app
> /switch-emulators-to-proxy-object/+merge/227103. Since we are adding new tests
> for the clock app, it would be best if we could do this from the start. Can
> you make the appropriate changes? Remember that whereever you import the
> ubuntu emulator, you will need to make changes there as well. Best to look at
> balloons's MP to see what needs to be done.

I would not hold the MP on this, but yes, it's simply changing the imports a little.

Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

640 +class Page11(Page):
641 +
642 + """Autopilot helper for the Alarm page."""

Why is this Page11 and not AlarmPage?

review: Needs Information
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

803 + def _select_single_alarm_day(self, index):
804 + """ function for selecting the day passed to the function.
805 +
806 + :param index: the day to be selected
807 +
808 + """
809 + dayCheckbox = self.wait_select_single(
810 + 'CheckBox', objectName='daySwitch{}'.format(index))
811 + if not dayCheckbox.checked:
812 + self.pointing_device.click_object(dayCheckbox)
813 +
814 + @autopilot_logging.log_action(logger.info)
815 + def unselect_selected_days(self):
816 + """ function for unselecting already selected days. """
817 + for index in range(self._get_num_of_days()):
818 + if self.wait_select_single(
819 + 'CheckBox', objectName='daySwitch{}'.format(index))\
820 + .checked:
821 + self.pointing_device.click_object(self.wait_select_single(
822 + 'CheckBox', objectName='daySwitch{}'.format(index)))
823 + break

In these 2 functions, you are using the IF loop to check if the switch is checked or not. Why not use the Ubuntu SDK helpers for this? http://developer.ubuntu.com/api/devel/ubuntu-14.10/python/autopilot-emulator/ubuntuuitoolkit.html#ubuntuuitoolkit.emulators.CheckBox has two functions check() and uncheck() which will automatically check and do the respective actions.

This would make it as simple as,

dayCheckbox.check()

or

dayCheckbox.uncheck()

review: Needs Fixing
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

848 + def _select_alarm_sound(self, index):
849 + """ function for selecting the sound passed to the function.
850 +
851 + :param index: the sound to be selected
852 +
853 + """
854 + soundCheckbox = self.wait_select_single(
855 + 'CheckBox', objectName='soundStatus{}'.format(index))
856 + if not soundCheckbox.checked:
857 + self.pointing_device.click_object(soundCheckbox)

Same here. It would be better to use the SDK helper functions.

review: Needs Fixing
Revision history for this message
Carla Sella (carla-sella) wrote :

Ok done.

Revision history for this message
Carla Sella (carla-sella) wrote :

> 640 +class Page11(Page):
> 641 +
> 642 + """Autopilot helper for the Alarm page."""
>
> Why is this Page11 and not AlarmPage?

Because in autopilot vis I see Page11: https://dl.dropboxusercontent.com/u/10083981/page11.png.

Do you want me to change it in AlarmPage anyway ?

Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

> > 640 +class Page11(Page):
> > 641 +
> > 642 + """Autopilot helper for the Alarm page."""
> >
> > Why is this Page11 and not AlarmPage?
>
> Because in autopilot vis I see Page11:
> https://dl.dropboxusercontent.com/u/10083981/page11.png.
>
> Do you want me to change it in AlarmPage anyway ?

Lets give it a try, and see if it recognizes AlarmPage instead of Page11. If it doesn't work, we can stick to Page11. The reason being in the SDK I saw Page10, Page11 etc. and I don't want this test to break everytime they make a change in the SDK.

Revision history for this message
Carla Sella (carla-sella) wrote :

> > > 640 +class Page11(Page):
> > > 641 +
> > > 642 + """Autopilot helper for the Alarm page."""
> > >
> > > Why is this Page11 and not AlarmPage?
> >
> > Because in autopilot vis I see Page11:
> > https://dl.dropboxusercontent.com/u/10083981/page11.png.
> >
> > Do you want me to change it in AlarmPage anyway ?
>
> Lets give it a try, and see if it recognizes AlarmPage instead of Page11. If
> it doesn't work, we can stick to Page11. The reason being in the SDK I saw
> Page10, Page11 etc. and I don't want this test to break everytime they make a
> change in the SDK.

Nope, if I use AlarmPage I get errors, I've tried various ways. Maybe it will work if I change the code, but not sure you want me to change quite abit of it.

Revision history for this message
Carla Sella (carla-sella) wrote :

@Nik: only skipping the test unless model is desktop is missing, but cannot recall the skip syntax and cannot seem to find it using google.
Can you help ?
Thanks.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Carla Sella (carla-sella) wrote :

Ok so now I think I got everything, also skipping the test if not Desktop model.

Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

> > > > 640 +class Page11(Page):
> > > > 641 +
> > > > 642 + """Autopilot helper for the Alarm page."""
> > > >
> > > > Why is this Page11 and not AlarmPage?
> > >
> > > Because in autopilot vis I see Page11:
> > > https://dl.dropboxusercontent.com/u/10083981/page11.png.
> > >
> > > Do you want me to change it in AlarmPage anyway ?
> >
> > Lets give it a try, and see if it recognizes AlarmPage instead of Page11. If
> > it doesn't work, we can stick to Page11. The reason being in the SDK I saw
> > Page10, Page11 etc. and I don't want this test to break everytime they make
> a
> > change in the SDK.
>
> Nope, if I use AlarmPage I get errors, I've tried various ways. Maybe it will
> work if I change the code, but not sure you want me to change quite abit of
> it.

No if its too much work leave it, its fine.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

Thanks for the fixes. Looks better. Some more small ones left,

527 +# -#- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -#-
528 +#
529 +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-

963 +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
964 +#
965 +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
966 +#

1098 +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
1099 +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-

Duplicated lines

548 +#
549 +# Authored by: Renato Araujo Oliveira Filho <email address hidden>

575 +# Authored by: Nekhelesh Ramananthan <email address hidden>
576 +# Nicholas Skaggs <email address hidden>

Remove these as with the new copyright headers, we don't anymore include these.

Please check if there any other places in this MP where the above 2 issues are there. I might have missed some.

review: Needs Fixing
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

1150 + def test_add_single_type_alarm_must_add_to_alarm_list(self):

This test needs to be renamed to,

def test_add_recurring_type_alarm_must_add_to_alarm_list(self):

In the new clock app, we haven't added support yet for recurring alarms. All the alarms created are recurring alarms by default. In the next MP, we can make this test to be specific like weekend, weekday alarms etc etc.

review: Needs Fixing
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

1148 + @unittest.skipIf(model() != 'Desktop',
1149 + "datepicker does not work correctly on device")
1150 + def test_add_single_type_alarm_must_add_to_alarm_list(self):
1151 + """Test to check if a single type alarm is saved properly

Here can you add a TODO comment explaining that due to bug #https://bugs.launchpad.net/ubuntu-calendar-app/+bug/1328600 the test cannot be run on device. Once the bug is fixed, remove the skip. This way we will remember in the future :)

review: Needs Fixing
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

1006 + """A common test case class that provides several useful methods for
1007 + calendar-app tests.

This should be clock-app tests

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Carla Sella (carla-sella) wrote :

Nik, hope eveything is ok now.

Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

lgtm! Nice work!

review: Approve
Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

Carla, in the readme I would mention running things with autopilot3, instead of autopilot. If you haven't run autopilot3 vis, you might be in for a surprise as it has search and some other niceties that autopilot vis doesn't have.

Also, for autopkg this line can be simplified:

adt-run ubuntu-clock-app --click=com.ubuntu.clock.devel --- ssh -s /usr/share/autopkgtest/ssh-setup/adb

to

adt-run ubuntu-clock-app --click=com.ubuntu.clock.devel --- ssh -s adb

Revision history for this message
Carla Sella (carla-sella) wrote :

Nicholas, I made the changes to README.autopilot as you asked but I left out autopiolot3 vis.
If I run:

autopilot3 vis

I get:

usage: autopilot3 [-h] [-v] {run,list,launch} ...
autopilot3: error: argument mode: invalid choice: 'vis' (choose from 'run', 'list', 'launch')

Am I missing something ?

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Carla Sella (carla-sella) wrote :

Got it! and fixed it :-).
I was missing python3-autopilot-vis.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nekhelesh Ramananthan (nik90) wrote :

A small nitpick but could you add python3-autopilot-vis to the readme.Autopilot pls :P ?

Revision history for this message
Carla Sella (carla-sella) wrote :

Said and done :P.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Nicholas Skaggs (nskaggs) wrote :

> Nicholas, I made the changes to README.autopilot as you asked but I left out
> autopiolot3 vis.
> If I run:
>
> autopilot3 vis
>
> I get:
>
> usage: autopilot3 [-h] [-v] {run,list,launch} ...
> autopilot3: error: argument mode: invalid choice: 'vis' (choose from 'run',
> 'list', 'launch')
>
>
> Am I missing something ?

Carla, yes python3-autopilot-vis package. You have to install it by hand.

Revision history for this message
Ubuntu Phone Apps Jenkins Bot (ubuntu-phone-apps-jenkins-bot) wrote :
review: Needs Fixing (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added file 'README.autopilot'
2--- README.autopilot 1970-01-01 00:00:00 +0000
3+++ README.autopilot 2014-08-04 19:00:38 +0000
4@@ -0,0 +1,45 @@
5+# Running Autopilot tests
6+
7+Ubuntu Clock App follows a test driven development where autopilot tests are run before every merge into trunk. If you are submitting your bugfix/patch to the clock app, please follow the following steps below to ensure that all tests pass before proposing a merge request.
8+
9+If you are looking for more info about Autopilot or writing AP tests for the clock app, here are some useful links to help you,
10+
11+- http://developer.ubuntu.com/api/devel/ubuntu-14.10/python/autopilot/
12+- http://developer.ubuntu.com/api/devel/ubuntu-14.10/python/autopilot-emulator/
13+
14+## Prerequisites
15+
16+Install the following autopilot packages required to run the tests,
17+$ sudo apt-get install python-autopilot libautopilot-qt ubuntu-ui-toolkit-autopilot python3-autopilot-vis
18+
19+
20+#### Running tests on the desktop
21+
22+Using terminal:
23+
24+1. Branch the clock app code,
25+ $ bzr branch lp:ubuntu-clock-app/reboot
26+
27+2. Navigate to the tests/autopilot directory.
28+ $ cd ubuntu-clock-app/reboot/tests/autopilot
29+
30+3. run all tests.
31+ $ autopilot3 run -vv ubuntu_clock_app
32+
33+ to list all tests:
34+ $ autopilot3 list ubuntu_clock_app
35+
36+ To run only one test (for instance: test_add_single_type_alarm_must_add_to_alarm_list in TestAlarm.py):
37+ $ autopilot3 run -vv ubuntu_clock_app.tests.test_alarm.TestAlarm.test_add_single_type_alarm_must_add_to_alarm_list
38+
39+ Debugging tests using autopilot vis
40+ $ autopilot3 launch -i Qt qmlscene ../../app/ubuntu-clock-app.qml -I ../../builddir/backend/
41+ $ autopilot3 vis
42+
43+
44+#### Running tests on device or emulator:
45+
46+Using autopkg:
47+
48+1. navigate to the directory where the ubuntu-clock-app branch is and run:
49+ $ adt-run ubuntu-clock-app --click=com.ubuntu.clock.devel --- ssh -s adb
50
51=== modified file 'app/alarm/AlarmLabel.qml'
52--- app/alarm/AlarmLabel.qml 2014-07-17 12:21:45 +0000
53+++ app/alarm/AlarmLabel.qml 2014-08-04 19:00:38 +0000
54@@ -21,6 +21,7 @@
55
56 Page {
57 id: _alarmLabelPage
58+ objectName: "alarmLabelPage"
59
60 visible: false
61 title: i18n.tr("Label")
62@@ -44,6 +45,7 @@
63
64 TextField {
65 id: _labelEntry
66+ objectName: "labelEntry"
67 text: alarm.message
68 width: parent.width
69 }
70
71=== modified file 'app/alarm/AlarmList.qml'
72--- app/alarm/AlarmList.qml 2014-07-17 12:21:45 +0000
73+++ app/alarm/AlarmList.qml 2014-08-04 19:00:38 +0000
74@@ -58,14 +58,18 @@
75
76 Column {
77 id: alarmList
78+ objectName: 'alarmList'
79 anchors.fill: parent
80
81 Repeater {
82 model: alarmListFlickable.model
83+ objectName: "alarmListRepeater"
84 ListItem.Base {
85+ objectName: "alarm" + index
86
87 Label {
88 id: alarmTime
89+ objectName: "listAlarmTime" + index
90
91 anchors {
92 top: alarmDetailsColumn.top
93@@ -89,6 +93,7 @@
94
95 Label {
96 id: alarmLabel
97+ objectName: "listAlarmLabel" + index
98
99 text: message
100 fontSize: "medium"
101@@ -98,6 +103,7 @@
102
103 Label {
104 id: alarmSubtitle
105+ objectName: "listAlarmSubtitle" + index
106
107 fontSize: "xx-small"
108 width: parent.width
109@@ -108,6 +114,7 @@
110
111 Switch {
112 id: alarmStatus
113+ objectName: "listAlarmStatus" + index
114
115 anchors {
116 right: parent.right
117
118=== modified file 'app/alarm/AlarmPage.qml'
119--- app/alarm/AlarmPage.qml 2014-07-17 12:21:45 +0000
120+++ app/alarm/AlarmPage.qml 2014-08-04 19:00:38 +0000
121@@ -22,10 +22,12 @@
122
123 Page {
124 title: "Alarms"
125+ objectName: 'AlarmPage'
126
127 flickable: null
128
129 head.actions: Action {
130+ objectName: "addAlarmAction"
131 iconName: "add"
132 text: i18n.tr("Alarm")
133 onTriggered: {
134
135=== modified file 'app/alarm/AlarmRepeat.qml'
136--- app/alarm/AlarmRepeat.qml 2014-07-17 12:21:45 +0000
137+++ app/alarm/AlarmRepeat.qml 2014-08-04 19:00:38 +0000
138@@ -22,6 +22,7 @@
139
140 Page {
141 id: _alarmRepeatPage
142+ objectName: "alarmRepeatPage"
143
144 visible: false
145 title: i18n.tr("Repeat")
146@@ -75,12 +76,14 @@
147
148 Repeater {
149 id: _alarmDays
150+ objectName: 'alarmDays'
151
152 model: daysModel
153
154 ListItem.Standard {
155 Label {
156 id: _alarmDay
157+ objectName: 'alarmDay' + index
158
159 anchors {
160 left: parent.left
161@@ -93,6 +96,7 @@
162 }
163
164 control: Switch {
165+ objectName: 'daySwitch' + index
166 checked: (alarm.daysOfWeek & flag) == flag
167 onCheckedChanged: {
168 if (checked) {
169
170=== modified file 'app/alarm/AlarmSound.qml'
171--- app/alarm/AlarmSound.qml 2014-07-17 12:21:45 +0000
172+++ app/alarm/AlarmSound.qml 2014-08-04 19:00:38 +0000
173@@ -52,6 +52,7 @@
174
175 Repeater {
176 id: _alarmSounds
177+ objectName: "alarmSounds"
178
179 model: _soundModel
180
181@@ -64,6 +65,7 @@
182
183 Label {
184 id: _soundName
185+ objectName: "soundName" + index
186
187 anchors {
188 left: parent.left
189@@ -77,6 +79,7 @@
190
191 CheckBox {
192 id: _soundStatus
193+ objectName: "soundStatus" + index
194
195 anchors {
196 right: parent.right
197
198=== modified file 'app/alarm/EditAlarmPage.qml'
199--- app/alarm/EditAlarmPage.qml 2014-07-28 14:25:00 +0000
200+++ app/alarm/EditAlarmPage.qml 2014-08-04 19:00:38 +0000
201@@ -25,6 +25,7 @@
202
203 Page {
204 id: _addAlarmPage
205+ objectName: "AddAlarmPage"
206
207 // Property to determine if this is a new/saved alarm
208 property bool isNewAlarm: true
209@@ -47,6 +48,7 @@
210
211 actions: Action {
212 iconName: "ok"
213+ objectName: "saveAlarmAction"
214 text: i18n.tr("Alarm")
215 onTriggered: {
216 if(isNewAlarm) {
217@@ -182,6 +184,7 @@
218
219 SubtitledListItem {
220 id: _alarmRepeat
221+ objectName: "alarmRepeat"
222
223 text: i18n.tr("Repeat")
224 subText: alarmUtils.format_day_string(_alarm.daysOfWeek)
225@@ -191,6 +194,7 @@
226
227 SubtitledListItem {
228 id: _alarmLabel
229+ objectName: "alarmLabel"
230
231 text: i18n.tr("Label")
232 subText: _alarm.message
233@@ -200,6 +204,7 @@
234
235 SubtitledListItem {
236 id: _alarmSound
237+ objectName: "alarmSound"
238 /*
239 #TODO: Add support for choosing new alarm sound when indicator-
240 datetime supports custom alarm sounds
241
242=== removed directory 'app/tests'
243=== removed directory 'app/tests/autopilot'
244=== removed file 'app/tests/autopilot/run'
245--- app/tests/autopilot/run 2014-06-06 18:45:49 +0000
246+++ app/tests/autopilot/run 1970-01-01 00:00:00 +0000
247@@ -1,11 +0,0 @@
248-#!/bin/bash
249-
250-if [[ -z `which autopilot` ]]; then
251- echo "Autopilot is not installed. Skip"
252- exit
253-fi
254-
255-SCRIPTPATH=`dirname $0`
256-pushd ${SCRIPTPATH}
257-autopilot run ubuntu-clock-app
258-popd
259
260=== removed directory 'app/tests/autopilot/ubuntu-clock-app'
261=== removed file 'app/tests/autopilot/ubuntu-clock-app/__init__.py'
262--- app/tests/autopilot/ubuntu-clock-app/__init__.py 2014-06-06 18:45:49 +0000
263+++ app/tests/autopilot/ubuntu-clock-app/__init__.py 1970-01-01 00:00:00 +0000
264@@ -1,132 +0,0 @@
265-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
266-
267-"""Ubuntu Touch App autopilot tests."""
268-
269-from os import remove
270-import os.path
271-from tempfile import mktemp
272-import subprocess
273-
274-from autopilot.input import Mouse, Touch, Pointer
275-from autopilot.matchers import Eventually
276-from autopilot.platform import model
277-from testtools.matchers import Is, Not, Equals
278-from autopilot.testcase import AutopilotTestCase
279-
280-def get_module_include_path():
281- return os.path.abspath(
282- os.path.join(
283- os.path.dirname(__file__),
284- '..',
285- '..',
286- '..',
287- '..',
288- 'backend',
289- 'modules')
290- )
291-
292-
293-class UbuntuTouchAppTestCase(AutopilotTestCase):
294- """A common test case class that provides several useful methods for the tests."""
295-
296- if model() == 'Desktop':
297- scenarios = [
298- ('with mouse', dict(input_device_class=Mouse))
299- ]
300- else:
301- scenarios = [
302- ('with touch', dict(input_device_class=Touch))
303- ]
304-
305- @property
306- def main_window(self):
307- return MainWindow(self.app)
308-
309-
310- def setUp(self):
311- self.pointing_device = Pointer(self.input_device_class.create())
312- super(UbuntuTouchAppTestCase, self).setUp()
313- self.launch_test_qml()
314-
315-
316- def launch_test_qml(self):
317- # If the test class has defined a 'test_qml' class attribute then we
318- # write it to disk and launch it inside the QML Scene. If not, then we
319- # silently do nothing (presumably the test has something else planned).
320- arch = subprocess.check_output(["dpkg-architecture",
321- "-qDEB_HOST_MULTIARCH"]).strip()
322- if hasattr(self, 'test_qml') and isinstance(self.test_qml, basestring):
323- qml_path = mktemp(suffix='.qml')
324- open(qml_path, 'w').write(self.test_qml)
325- self.addCleanup(remove, qml_path)
326-
327- self.app = self.launch_test_application(
328- "/usr/lib/" + arch + "/qt5/bin/qmlscene",
329- "-I", get_module_include_path(),
330- qml_path,
331- app_type='qt')
332-
333- if hasattr(self, 'test_qml_file') and isinstance(self.test_qml_file, basestring):
334- qml_path = self.test_qml_file
335- self.app = self.launch_test_application(
336- "/usr/lib/" + arch + "/qt5/bin/qmlscene",
337- "-I", get_module_include_path(),
338- qml_path,
339- app_type='qt')
340-
341- self.assertThat(self.get_qml_view().visible, Eventually(Equals(True)))
342-
343-
344- def get_qml_view(self):
345- """Get the main QML view"""
346-
347- return self.app.select_single("QQuickView")
348-
349- def get_mainview(self):
350- """Get the QML MainView"""
351-
352- mainView = self.app.select_single("MainView")
353- self.assertThat(mainView, Not(Is(None)))
354- return mainView
355-
356-
357- def get_object(self,objectName):
358- """Get a object based on the objectName"""
359-
360- obj = self.app.select_single(objectName=objectName)
361- self.assertThat(obj, Not(Is(None)))
362- return obj
363-
364-
365- def mouse_click(self,objectName):
366- """Move mouse on top of the object and click on it"""
367-
368- obj = self.get_object(objectName)
369- self.pointing_device.move_to_object(obj)
370- self.pointing_device.click()
371-
372-
373- def mouse_press(self,objectName):
374- """Move mouse on top of the object and press mouse button (without releasing it)"""
375-
376- obj = self.get_object(objectName)
377- self.pointing_device.move_to_object(obj)
378- self.pointing_device.press()
379-
380-
381- def mouse_release(self):
382- """Release mouse button"""
383-
384- self.pointing_device.release()
385-
386-
387- def type_string(self, string):
388- """Type a string with keyboard"""
389-
390- self.keyboard.type(string)
391-
392-
393- def type_key(self, key):
394- """Type a single key with keyboard"""
395-
396- self.keyboard.key(key)
397
398=== removed directory 'app/tests/autopilot/ubuntu-clock-app/main'
399=== removed file 'app/tests/autopilot/ubuntu-clock-app/main/__init__.py'
400--- app/tests/autopilot/ubuntu-clock-app/main/__init__.py 2014-06-06 18:45:49 +0000
401+++ app/tests/autopilot/ubuntu-clock-app/main/__init__.py 1970-01-01 00:00:00 +0000
402@@ -1,1 +0,0 @@
403-""" A main.qml test suite """
404
405=== removed file 'app/tests/autopilot/ubuntu-clock-app/main/test_main.py'
406--- app/tests/autopilot/ubuntu-clock-app/main/test_main.py 2014-06-06 18:45:49 +0000
407+++ app/tests/autopilot/ubuntu-clock-app/main/test_main.py 1970-01-01 00:00:00 +0000
408@@ -1,23 +0,0 @@
409-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
410-
411-"""Tests for the Hello World"""
412-
413-from autopilot.matchers import Eventually
414-from textwrap import dedent
415-from testtools.matchers import Is, Not, Equals
416-from testtools import skip
417-import os
418-from ubuntu-clock-app import UbuntuTouchAppTestCase
419-
420-
421-class MainTests(UbuntuTouchAppTestCase):
422- """Generic tests for the Hello World"""
423-
424- test_qml_file = "%s/%s.qml" % (os.path.dirname(os.path.realpath(__file__)),"../../../../ubuntu-clock-app")
425-
426- def test_0_can_select_mainView(self):
427- """Must be able to select the mainview."""
428-
429- mainView = self.get_mainview()
430- self.assertThat(mainView.visible,Eventually(Equals(True)))
431-
432
433=== removed directory 'app/tests/unit'
434=== removed file 'app/tests/unit/tst_hellocomponent.qml'
435--- app/tests/unit/tst_hellocomponent.qml 2014-06-06 18:45:49 +0000
436+++ app/tests/unit/tst_hellocomponent.qml 1970-01-01 00:00:00 +0000
437@@ -1,49 +0,0 @@
438-import QtQuick 2.0
439-import QtTest 1.0
440-import Ubuntu.Components 0.1
441-import "../../components"
442-
443-// See more details @ http://qt-project.org/doc/qt-5.0/qtquick/qml-testcase.html
444-
445-// Execute tests with:
446-// qmltestrunner
447-
448-Item {
449- // The objects
450- HelloComponent {
451- id: objectUnderTest
452- }
453-
454- TestCase {
455- name: "HelloComponent"
456-
457- function init() {
458- console.debug(">> init");
459- compare("",objectUnderTest.text,"text was not empty on init");
460- console.debug("<< init");
461- }
462-
463- function cleanup() {
464- console.debug(">> cleanup");
465- console.debug("<< cleanup");
466- }
467-
468- function initTestCase() {
469- console.debug(">> initTestCase");
470- console.debug("<< initTestCase");
471- }
472-
473- function cleanupTestCase() {
474- console.debug(">> cleanupTestCase");
475- console.debug("<< cleanupTestCase");
476- }
477-
478- function test_canReadAndWriteText() {
479- var expected = "Hello World";
480-
481- objectUnderTest.text = expected;
482-
483- compare(expected,objectUnderTest.text,"expected did not equal result");
484- }
485- }
486-}
487
488=== modified file 'manifest.json'
489--- manifest.json 2014-07-08 10:52:02 +0000
490+++ manifest.json 2014-08-04 19:00:38 +0000
491@@ -11,5 +11,8 @@
492 }
493 },
494 "version": "0.1",
495- "maintainer": "Ubuntu App Cats <ubuntu-touch-coreapps@lists.launchpad.net>"
496-}
497\ No newline at end of file
498+ "maintainer": "Ubuntu App Cats <ubuntu-touch-coreapps@lists.launchpad.net>",
499+ "x-test": {
500+ "autopilot": "ubuntu_clock_app"
501+ }
502+}
503
504=== added directory 'tests'
505=== added directory 'tests/autopilot'
506=== added file 'tests/autopilot/run'
507--- tests/autopilot/run 1970-01-01 00:00:00 +0000
508+++ tests/autopilot/run 2014-08-04 19:00:38 +0000
509@@ -0,0 +1,11 @@
510+#!/bin/bash
511+
512+if [[ -z `which autopilot` ]]; then
513+ echo "Autopilot is not installed. Skip"
514+ exit
515+fi
516+
517+SCRIPTPATH=`dirname $0`
518+pushd ${SCRIPTPATH}
519+autopilot run ubuntu-clock-app
520+popd
521
522=== added directory 'tests/autopilot/ubuntu_clock_app'
523=== added file 'tests/autopilot/ubuntu_clock_app/__init__.py'
524--- tests/autopilot/ubuntu_clock_app/__init__.py 1970-01-01 00:00:00 +0000
525+++ tests/autopilot/ubuntu_clock_app/__init__.py 2014-08-04 19:00:38 +0000
526@@ -0,0 +1,18 @@
527+# Copyright (C) 2014 Canonical Ltd
528+#
529+# This file is part of Ubuntu Clock App
530+#
531+# Ubuntu Clock App is free software: you can redistribute it and/or modify
532+# it under the terms of the GNU General Public License version 3 as
533+# published by the Free Software Foundation.
534+#
535+# Ubuntu Clock App is distributed in the hope that it will be useful,
536+# but WITHOUT ANY WARRANTY; without even the implied warranty of
537+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
538+# GNU General Public License for more details.
539+#
540+# You should have received a copy of the GNU General Public License
541+# along with this program. If not, see <http://www.gnu.org/licenses/>.
542+
543+
544+"""clock-app autopilot tests and emulators - top level package."""
545
546=== added file 'tests/autopilot/ubuntu_clock_app/emulators.py'
547--- tests/autopilot/ubuntu_clock_app/emulators.py 1970-01-01 00:00:00 +0000
548+++ tests/autopilot/ubuntu_clock_app/emulators.py 2014-08-04 19:00:38 +0000
549@@ -0,0 +1,395 @@
550+# Copyright (C) 2014 Canonical Ltd
551+#
552+# This file is part of Ubuntu Clock App
553+#
554+# Ubuntu Clock App is free software: you can redistribute it and/or modify
555+# it under the terms of the GNU General Public License version 3 as
556+# published by the Free Software Foundation.
557+#
558+# Ubuntu Clock App is distributed in the hope that it will be useful,
559+# but WITHOUT ANY WARRANTY; without even the implied warranty of
560+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
561+# GNU General Public License for more details.
562+#
563+# You should have received a copy of the GNU General Public License
564+# along with this program. If not, see <http://www.gnu.org/licenses/>.
565+
566+import logging
567+
568+from autopilot import logging as autopilot_logging
569+
570+from ubuntuuitoolkit import pickers
571+import ubuntuuitoolkit
572+
573+logger = logging.getLogger(__name__)
574+
575+
576+class ClockEmulatorException(ubuntuuitoolkit.ToolkitException):
577+
578+ """Exception raised when there is an error with the emulator."""
579+
580+
581+class MainView(ubuntuuitoolkit.MainView):
582+
583+ @autopilot_logging.log_action(logger.info)
584+ def open_clock(self):
585+ """Open the Clock Page.
586+
587+ :return the Clock Page
588+
589+ """
590+ return self.wait_select_single(ClockPage)
591+
592+ @autopilot_logging.log_action(logger.info)
593+ def open_alarm(self):
594+ """Open the Alarm Page.
595+
596+ :return: the Alarm Page.
597+
598+ """
599+ clockPage = self.wait_select_single(ClockPage)
600+ clockPage.drag_bottomEdge_up()
601+ self.get_header().visible.wait_for(True)
602+ return self.wait_select_single(Page11)
603+
604+ def get_AlarmList(self):
605+ """ Get the AlarmList object. """
606+ return AlarmList.select(self)
607+
608+
609+class Page(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
610+
611+ """Autopilot helper for Pages."""
612+
613+ def __init__(self, *args):
614+ super(Page, self).__init__(*args)
615+ # XXX we need a better way to keep reference to the main view.
616+ # --elopio - 2014-01-31
617+ self.main_view = self.get_root_instance().select_single(MainView)
618+
619+
620+class ClockPage(Page):
621+
622+ """Autopilot helper for the Clock page."""
623+
624+ @autopilot_logging.log_action(logger.info)
625+ def drag_bottomEdge_up(self):
626+ """Function to drag the bottom edge up."""
627+ self._click_bottomEdge()
628+
629+ x, y, w, h = self.globalRect
630+ start_x = stop_x = x + (w / 2)
631+ start_y = y + (h - 1)
632+
633+ stop_y = start_y - h
634+ self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
635+
636+ self._wait_for_ClockPage_to_close()
637+
638+ def _click_bottomEdge(self):
639+ """Function to click on the bottom edge."""
640+ bottomEdge = self.wait_select_single(
641+ 'QQuickItem', objectName='bottomEdgeTip')
642+ self.pointing_device.click_object(bottomEdge)
643+
644+ def _wait_for_ClockPage_to_close(self):
645+ self.isCollapsed.wait_for(False)
646+
647+
648+class Page11(Page):
649+
650+ """Autopilot helper for the Alarm page."""
651+
652+ @autopilot_logging.log_action(logger.info)
653+ def add_single_alarm(self, name, day, time_to_set, test_sound_name):
654+ """Add a single type alarm
655+
656+ :param name: name of alarm
657+ :param day: day on which the alarm should be triggered
658+ :param time_to_set: time to set alarm to
659+ :param test_sound_name: sound to set in alarm
660+
661+ """
662+ alarmListPage = AlarmList.select(self.main_view)
663+ old_alarm_count = alarmListPage.get_num_of_alarms()
664+
665+ edit_alarm_page = self._click_add_alarm_button()
666+ edit_alarm_page.set_alarm_time(time_to_set)
667+
668+ alarm_repeat_page = edit_alarm_page.open_alarmRepeat_page()
669+ alarm_repeat_page.set_single_alarm_day(day)
670+ self._click_header_backButton()
671+
672+ alarm_label_page = edit_alarm_page.open_alarmLabel_page()
673+ alarm_label_page.set_alarm_label(name)
674+ self._click_header_customBackButton()
675+
676+ alarm_sound_page = edit_alarm_page.open_alarmSound_page()
677+ alarm_sound_page.set_alarm_sound(test_sound_name)
678+ self._click_header_customBackButton()
679+ edit_alarm_page._check_sound_changed(test_sound_name)
680+
681+ self._click_save()
682+ self._confirm_alarm_creation(old_alarm_count)
683+
684+ def _click_add_alarm_button(self):
685+ """Click the add alarm header button."""
686+ header = self.main_view.get_header()
687+ header.click_action_button('addAlarmAction')
688+ return self.main_view.wait_select_single(EditAlarmPage)
689+
690+ def _click_header_customBackButton(self):
691+ """Click the header button: 'customBackButton' """
692+ header = self.main_view.get_header()
693+ header.click_custom_back_button()
694+
695+ def _click_header_backButton(self):
696+ """Click the header button: 'backButton' """
697+ header = self.main_view.get_header()
698+ header.click_back_button()
699+
700+ def _click_save(self):
701+ """Click the save timer header button"""
702+ header = self.main_view.get_header()
703+ header.click_action_button('saveAlarmAction')
704+
705+ def _confirm_alarm_creation(self, count):
706+ """Confirm creation of alarm
707+
708+ :param count: alarm count before alarm creation
709+
710+ """
711+ try:
712+ AlarmList.select(self.main_view)._get_saved_alarms_list().\
713+ count.wait_for(count + 1)
714+ except AssertionError:
715+ raise ClockEmulatorException('Error creating alarm.')
716+
717+
718+class EditAlarmPage(Page):
719+
720+ """Autopilot helper for the Add Alarm page."""
721+
722+ @autopilot_logging.log_action(logger.info)
723+ def set_alarm_time(self, time_to_set):
724+ """Set alarm time on datepicker.
725+
726+ :param time_to_set: time to set on datepicker
727+
728+ """
729+ PickerRow_HoursPicker = self.wait_select_single(
730+ "Picker", objectName="PickerRow_HoursPicker")
731+ self._set_picker(PickerRow_HoursPicker, 'time', time_to_set)
732+
733+ def _set_picker(self, field, mode, value):
734+ # open picker
735+ self.pointing_device.click_object(field)
736+ # valid options are date or time; assume date if invalid/no option
737+ mode_value = 'Hours|Minutes'
738+ picker = self.wait_select_single(
739+ pickers.DatePicker, mode=mode_value, visible=True)
740+ picker.pick_time(value)
741+ # close picker
742+ self.pointing_device.click_object(field)
743+
744+ @autopilot_logging.log_action(logger.info)
745+ def open_alarmRepeat_page(self):
746+ """ Open the alarmRepeat page """
747+
748+ alarmRepeatItem = self.wait_select_single(
749+ "SubtitledListItem", objectName="alarmRepeat")
750+ self.pointing_device.click_object(alarmRepeatItem)
751+ return self.main_view.wait_select_single(AlarmRepeat)
752+
753+ @autopilot_logging.log_action(logger.info)
754+ def open_alarmLabel_page(self):
755+ """ Open the alarmLabel page """
756+
757+ alarmLabelItem = self.wait_select_single(
758+ "SubtitledListItem", objectName="alarmLabel")
759+ self.pointing_device.click_object(alarmLabelItem)
760+ return AlarmLable.select(self.main_view)
761+
762+ @autopilot_logging.log_action(logger.info)
763+ def open_alarmSound_page(self):
764+ """ Open the alarmSound page """
765+
766+ alarmSoundItem = self.wait_select_single(
767+ "SubtitledListItem", objectName="alarmSound")
768+ self.pointing_device.click_object(alarmSoundItem)
769+ return self.main_view.wait_select_single(AlarmSound)
770+
771+ def _check_sound_changed(self, test_sound_name):
772+ """ function to check that sound has changed.
773+
774+ :param test_sound_name = new sound name
775+
776+ """
777+ self.wait_select_single("SubtitledListItem", objectName="alarmSound")\
778+ .subText == test_sound_name
779+
780+
781+class AlarmRepeat(Page):
782+
783+ """Autopilot helper for the AlarmRepeat page."""
784+
785+ @autopilot_logging.log_action(logger.info)
786+ def set_single_alarm_day(self, day):
787+ """Set the alarm day of a single type alarm.
788+
789+ :param day: single day on which alarm is triggered
790+
791+ """
792+ self.unselect_selected_days()
793+ index = 0
794+ for index in range(self._get_num_of_days()):
795+ if self.wait_select_single(
796+ 'Label', objectName='alarmDay{}'.format(index))\
797+ .text == day:
798+ self._select_single_alarm_day(index)
799+ break
800+
801+ def _get_num_of_days(self):
802+ return int(self.wait_select_single(
803+ 'QQuickRepeater', objectName='alarmDays').count)
804+
805+ def _select_single_alarm_day(self, index):
806+ """ function for selecting the day passed to the function.
807+
808+ :param index: the day to be selected
809+
810+ """
811+ dayCheckbox = self.wait_select_single(
812+ 'CheckBox', objectName='daySwitch{}'.format(index))
813+ dayCheckbox.check()
814+
815+ @autopilot_logging.log_action(logger.info)
816+ def unselect_selected_days(self):
817+ """ function for unselecting already selected days. """
818+ for index in range(self._get_num_of_days()):
819+ dayCheckbox = self.wait_select_single(
820+ 'CheckBox', objectName='daySwitch{}'.format(index))
821+ dayCheckbox.uncheck()
822+
823+
824+class AlarmSound(Page):
825+
826+ """Autopilot helper for the AlarmSound page."""
827+
828+ @autopilot_logging.log_action(logger.info)
829+ def set_alarm_sound(self, test_sound_name):
830+ """Set alarm sound.
831+
832+ :param test_sound_name: sound to set for alarm
833+
834+ """
835+ for index in range(self._get_num_of_sounds()):
836+ if self.wait_select_single(
837+ 'Label', objectName='soundName{}'.format(index)).\
838+ text == test_sound_name:
839+ self._select_alarm_sound(index)
840+ break
841+
842+ def _get_num_of_sounds(self):
843+ return int(self.wait_select_single(
844+ 'QQuickRepeater', objectName='alarmSounds').count)
845+
846+ def _select_alarm_sound(self, index):
847+ """ function for selecting the sound passed to the function.
848+
849+ :param index: the sound to be selected
850+
851+ """
852+ soundCheckbox = self.wait_select_single(
853+ 'CheckBox', objectName='soundStatus{}'.format(index))
854+ soundCheckbox.check()
855+
856+
857+class AlarmLable(object):
858+
859+ """Autopilot helper for the AlarmLabel page."""
860+
861+ def __init__(self, proxy_object):
862+ super(AlarmLable, self).__init__()
863+ self.proxy_object = proxy_object
864+
865+ @classmethod
866+ def select(cls, main_view):
867+ proxy_object = main_view.wait_select_single(
868+ objectName='alarmLabelPage')
869+ proxy_object.visible.wait_for(True)
870+ return cls(proxy_object)
871+
872+ @autopilot_logging.log_action(logger.info)
873+ def set_alarm_label(self, name):
874+ """Set alarm label.
875+
876+ :param name: label for alarm to set
877+
878+ """
879+ alarmTextfield = self.proxy_object.wait_select_single(
880+ "TextField", objectName='labelEntry')
881+ # TODO: This wait to ensure that the textfield is visible before
882+ # entering text should be part of the SDK emulator. Until then, it has
883+ # been added here. http://pad.lv/1289616 --nik90 2014-03-06
884+ alarmTextfield.visible.wait_for(True)
885+ alarmTextfield.write(name)
886+
887+
888+class AlarmList(object):
889+
890+ """Autopilot helper for the AlarmList."""
891+
892+ def __init__(self, proxy_object):
893+ super(AlarmList, self).__init__()
894+ self.proxy_object = proxy_object
895+
896+ @classmethod
897+ def select(cls, main_view):
898+ proxy_object = main_view.wait_select_single(
899+ objectName='alarmListFlickable')
900+ proxy_object.visible.wait_for(True)
901+ return cls(proxy_object)
902+
903+ def get_num_of_alarms(self):
904+ """Return the number of saved alarms."""
905+ return int(self._get_saved_alarms_list().count)
906+
907+ def _get_saved_alarms_list(self):
908+ """Return the saved alarm list"""
909+ return self.proxy_object.wait_select_single(
910+ 'QQuickRepeater', objectName='alarmListRepeater')
911+
912+ def get_saved_alarms(self):
913+ """Return a list with the information of the saved alarms.
914+
915+ Each item of the returned list is a tuple of
916+ (name, recurrence, time, enabled).
917+
918+ """
919+ alarms = []
920+ for index in range(self.get_num_of_alarms()):
921+ name = self.proxy_object.wait_select_single(
922+ 'Label', objectName='listAlarmLabel{}'.format(index)).text
923+ recurrence = self.proxy_object.wait_select_single(
924+ 'Label', objectName='listAlarmSubtitle{}'.format(index)).text
925+ time = self.proxy_object.wait_select_single(
926+ 'Label', objectName='listAlarmTime{}'.format(index)).text
927+ enabled = self.proxy_object.wait_select_single(
928+ ubuntuuitoolkit.CheckBox,
929+ objectName='listAlarmStatus{}'.format(index)).checked
930+ alarms.append((name, recurrence, enabled, time))
931+ return alarms
932+
933+ @autopilot_logging.log_action(logger.info)
934+ def delete_alarm(self, index):
935+ """Delete an alarm at the specified index."""
936+ old_alarm_count = self.get_num_of_alarms()
937+ alarm = self.proxy_object.wait_select_single(
938+ 'Base', objectName='alarm{}'.format(index))
939+ alarm.swipe_to_delete()
940+ alarm.confirm_removal()
941+ try:
942+ self._get_saved_alarms_list().count.wait_for(old_alarm_count - 1)
943+ except AssertionError:
944+ raise ClockEmulatorException('Error deleting alarm.')
945
946=== added directory 'tests/autopilot/ubuntu_clock_app/tests'
947=== added file 'tests/autopilot/ubuntu_clock_app/tests/__init__.py'
948--- tests/autopilot/ubuntu_clock_app/tests/__init__.py 1970-01-01 00:00:00 +0000
949+++ tests/autopilot/ubuntu_clock_app/tests/__init__.py 2014-08-04 19:00:38 +0000
950@@ -0,0 +1,125 @@
951+# Copyright (C) 2014 Canonical Ltd
952+#
953+# This file is part of Ubuntu Clock App
954+#
955+# Ubuntu Clock App is free software: you can redistribute it and/or modify
956+# it under the terms of the GNU General Public License version 3 as
957+# published by the Free Software Foundation.
958+#
959+# Ubuntu Clock App is distributed in the hope that it will be useful,
960+# but WITHOUT ANY WARRANTY; without even the implied warranty of
961+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
962+# GNU General Public License for more details.
963+#
964+# You should have received a copy of the GNU General Public License
965+# along with this program. If not, see <http://www.gnu.org/licenses/>.
966+
967+"""clock-app autopilot tests."""
968+
969+import os.path
970+import os
971+import shutil
972+import logging
973+import fixtures
974+
975+from autopilot import input
976+from autopilot.platform import model
977+from ubuntuuitoolkit import (
978+ base,
979+ emulators as toolkit_emulators
980+)
981+
982+from ubuntu_clock_app import emulators
983+
984+logger = logging.getLogger(__name__)
985+
986+
987+class ClockAppTestCase(base.UbuntuUIToolkitAppTestCase):
988+
989+ """A common test case class that provides several useful methods for
990+ clock-app tests.
991+
992+ """
993+ local_location = "../../app/ubuntu-clock-app.qml"
994+ local_backend_dir = "../../builddir/backend/"
995+ installed_location = "/usr/share/ubuntu-clock-app/app/ubuntu-clock-app.qml"
996+ installed_backend_dir = "/usr/share/ubuntu-clock-app/builddir/backend/"
997+ sqlite_dir = os.path.expanduser(
998+ "~/.local/share/com.ubuntu.clock")
999+ backup_dir = sqlite_dir + ".backup"
1000+
1001+ def setUp(self):
1002+ super(ClockAppTestCase, self).setUp()
1003+ self.pointing_device = input.Pointer(self.input_device_class.create())
1004+
1005+ self.useFixture(fixtures.EnvironmentVariable('LC_ALL', newvalue='C'))
1006+
1007+ # backup and wipe db's before testing
1008+ self.temp_move_sqlite_db()
1009+ self.addCleanup(self.restore_sqlite_db)
1010+
1011+ # turn off the OSK so it doesn't block screen elements
1012+ if model() != 'Desktop':
1013+ os.system("stop maliit-server")
1014+ self.addCleanup(os.system, "start maliit-server")
1015+
1016+ if os.path.exists(self.local_location):
1017+ self.launch_test_local()
1018+ elif os.path.exists(self.installed_location):
1019+ self.launch_test_installed()
1020+ else:
1021+ self.launch_test_click()
1022+
1023+ def launch_test_local(self):
1024+ self.app = self.launch_test_application(
1025+ base.get_qmlscene_launch_command(),
1026+ self.local_location,
1027+ "-I", self.local_backend_dir,
1028+ app_type='qt',
1029+ emulator_base=toolkit_emulators.UbuntuUIToolkitEmulatorBase)
1030+
1031+ def launch_test_installed(self):
1032+ self.app = self.launch_test_application(
1033+ base.get_qmlscene_launch_command(),
1034+ self.installed_location,
1035+ "-I", self.installed_backend_dir,
1036+ app_type='qt',
1037+ emulator_base=toolkit_emulators.UbuntuUIToolkitEmulatorBase)
1038+
1039+ def launch_test_click(self):
1040+ self.app = self.launch_click_package(
1041+ "com.ubuntu.clock.devel",
1042+ emulator_base=toolkit_emulators.UbuntuUIToolkitEmulatorBase)
1043+
1044+ def temp_move_sqlite_db(self):
1045+ try:
1046+ shutil.rmtree(self.backup_dir)
1047+ except:
1048+ pass
1049+ else:
1050+ logger.warning("Prexisting backup database found and removed")
1051+
1052+ try:
1053+ shutil.move(self.sqlite_dir, self.backup_dir)
1054+ except:
1055+ logger.warning("No current database found")
1056+ else:
1057+ logger.debug("Backed up database")
1058+
1059+ def restore_sqlite_db(self):
1060+ if os.path.exists(self.backup_dir):
1061+ if os.path.exists(self.sqlite_dir):
1062+ try:
1063+ shutil.rmtree(self.sqlite_dir)
1064+ except:
1065+ logger.error("Failed to remove test database and restore" /
1066+ "database")
1067+ return
1068+ try:
1069+ shutil.move(self.backup_dir, self.sqlite_dir)
1070+ except:
1071+ logger.error("Failed to restore database")
1072+
1073+ @property
1074+ def main_view(self):
1075+ return self.app.wait_select_single(emulators.MainView)
1076
1077=== added file 'tests/autopilot/ubuntu_clock_app/tests/test_alarm.py'
1078--- tests/autopilot/ubuntu_clock_app/tests/test_alarm.py 1970-01-01 00:00:00 +0000
1079+++ tests/autopilot/ubuntu_clock_app/tests/test_alarm.py 2014-08-04 19:00:38 +0000
1080@@ -0,0 +1,84 @@
1081+# Copyright (C) 2014 Canonical Ltd
1082+#
1083+# This file is part of Ubuntu Clock App
1084+#
1085+# Ubuntu Clock App is free software: you can redistribute it and/or modify
1086+# it under the terms of the GNU General Public License version 3 as
1087+# published by the Free Software Foundation.
1088+#
1089+# Ubuntu Clock App is distributed in the hope that it will be useful,
1090+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1091+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1092+# GNU General Public License for more details.
1093+#
1094+# You should have received a copy of the GNU General Public License
1095+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1096+
1097+"""Tests for the Clock App - Alarm"""
1098+
1099+from __future__ import absolute_import
1100+
1101+import datetime
1102+import unittest
1103+
1104+from autopilot.matchers import Eventually
1105+from testtools.matchers import Equals
1106+from ubuntu_clock_app.tests import ClockAppTestCase
1107+from autopilot.platform import model
1108+
1109+
1110+class TestAlarm(ClockAppTestCase):
1111+
1112+ """Tests the alarm page features"""
1113+
1114+ def setUp(self):
1115+ """ This is needed to wait for the application to start.
1116+
1117+ In the testfarm, the application may take some time to show up.
1118+
1119+ """
1120+ super(TestAlarm, self).setUp()
1121+ self.assertThat(
1122+ self.main_view.visible, Eventually(Equals(True)))
1123+
1124+ self.page = self.main_view.open_alarm()
1125+
1126+ # TODO
1127+ # Due to bug https://bugs.launchpad.net/ubuntu-calendar-app/+bug/1328600
1128+ # this test cannot be run on device, so until the bug is not fixed we are
1129+ # skipping the test if model not Desktop.
1130+ @unittest.skipIf(model() != 'Desktop',
1131+ "datepicker does not work correctly on device")
1132+ def test_add_recurring_type_alarm_must_add_to_alarm_list(self):
1133+ """Test to check if a single type alarm is saved properly
1134+
1135+ This test saves a single type alarm and verifies if it is added to the
1136+ alarm list in the alarm page.
1137+
1138+ """
1139+ tomorrow = datetime.datetime.now() + datetime.timedelta(days=1)
1140+ time_to_set = datetime.time(6, 10, 0)
1141+ test_alarm_name = 'Single Test'
1142+ # TODO this will be affected by the locale. --elopio - 2014-02-27
1143+ expected_alarm_name = test_alarm_name
1144+ expected_recurrence = tomorrow.strftime('%A')
1145+ expected_enabled_value = True
1146+ expected_time = "06:10:00"
1147+ test_sound_name = "Bliss"
1148+ expected_alarm_info = (
1149+ expected_alarm_name, expected_recurrence, expected_enabled_value,
1150+ expected_time)
1151+
1152+ tomorrow_day = tomorrow.strftime('%A')
1153+ self.page.add_single_alarm(
1154+ test_alarm_name, tomorrow_day, time_to_set, test_sound_name)
1155+
1156+ alarmlistPage = self.main_view.get_AlarmList()
1157+ saved_alarms = alarmlistPage.get_saved_alarms()
1158+ self.assertIn(expected_alarm_info, saved_alarms)
1159+
1160+ # TODO: Remove this statement once proper support for cleaning the
1161+ # test alarm environment is added. Until then remove the alarm
1162+ # created during the test at the end of the test.
1163+ # -- nik90 - 2014-03-03
1164+ alarmlistPage.delete_alarm(index=0)
1165
1166=== added file 'tests/autopilot/ubuntu_clock_app/tests/test_clock.py'
1167--- tests/autopilot/ubuntu_clock_app/tests/test_clock.py 1970-01-01 00:00:00 +0000
1168+++ tests/autopilot/ubuntu_clock_app/tests/test_clock.py 2014-08-04 19:00:38 +0000
1169@@ -0,0 +1,44 @@
1170+# Copyright (C) 2014 Canonical Ltd
1171+#
1172+# This file is part of Ubuntu Clock App
1173+#
1174+# Ubuntu Clock App is free software: you can redistribute it and/or modify
1175+# it under the terms of the GNU General Public License version 3 as
1176+# published by the Free Software Foundation.
1177+#
1178+# Ubuntu Clock App is distributed in the hope that it will be useful,
1179+# but WITHOUT ANY WARRANTY; without even the implied warranty of
1180+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1181+# GNU General Public License for more details.
1182+#
1183+# You should have received a copy of the GNU General Public License
1184+# along with this program. If not, see <http://www.gnu.org/licenses/>.
1185+
1186+"""
1187+Tests for the Clock App, main window.
1188+"""
1189+
1190+from __future__ import absolute_import
1191+
1192+from testtools.matchers import Equals
1193+from autopilot.matchers import Eventually
1194+
1195+from ubuntu_clock_app.tests import ClockAppTestCase
1196+
1197+
1198+class TestClock(ClockAppTestCase):
1199+
1200+ """Test the clock page features."""
1201+
1202+ def setUp(self):
1203+ """This is needed to wait for the application to start.
1204+
1205+ In the testfarm, the application may take some time to show up.
1206+
1207+ """
1208+
1209+ super(TestClock, self).setUp()
1210+ self.assertThat(
1211+ self.main_view.visible, Eventually(Equals(True)))
1212+
1213+ self.page = self.main_view.open_clock()
1214
1215=== added directory 'tests/unit'
1216=== added file 'tests/unit/tst_hellocomponent.qml'
1217--- tests/unit/tst_hellocomponent.qml 1970-01-01 00:00:00 +0000
1218+++ tests/unit/tst_hellocomponent.qml 2014-08-04 19:00:38 +0000
1219@@ -0,0 +1,49 @@
1220+import QtQuick 2.0
1221+import QtTest 1.0
1222+import Ubuntu.Components 0.1
1223+import "../../components"
1224+
1225+// See more details @ http://qt-project.org/doc/qt-5.0/qtquick/qml-testcase.html
1226+
1227+// Execute tests with:
1228+// qmltestrunner
1229+
1230+Item {
1231+ // The objects
1232+ HelloComponent {
1233+ id: objectUnderTest
1234+ }
1235+
1236+ TestCase {
1237+ name: "HelloComponent"
1238+
1239+ function init() {
1240+ console.debug(">> init");
1241+ compare("",objectUnderTest.text,"text was not empty on init");
1242+ console.debug("<< init");
1243+ }
1244+
1245+ function cleanup() {
1246+ console.debug(">> cleanup");
1247+ console.debug("<< cleanup");
1248+ }
1249+
1250+ function initTestCase() {
1251+ console.debug(">> initTestCase");
1252+ console.debug("<< initTestCase");
1253+ }
1254+
1255+ function cleanupTestCase() {
1256+ console.debug(">> cleanupTestCase");
1257+ console.debug("<< cleanupTestCase");
1258+ }
1259+
1260+ function test_canReadAndWriteText() {
1261+ var expected = "Hello World";
1262+
1263+ objectUnderTest.text = expected;
1264+
1265+ compare(expected,objectUnderTest.text,"expected did not equal result");
1266+ }
1267+ }
1268+}

Subscribers

People subscribed via source and target branches