~ubuntu-clock-dev/ubuntu-clock-app/reboot-packaging

« back to all changes in this revision

Viewing changes to tests/autopilot/ubuntu_clock_app/emulators.py

  • Committer: carla-sella
  • Date: 2014-07-31 16:58:56 UTC
  • mto: (37.1.1 reboot)
  • mto: This revision was merged to the branch mainline in revision 50.
  • Revision ID: carla.sella@gmail.com-20140731165856-o2g4v4z7ivk9864v
Implemented locale.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
 
2
#
 
3
# Copyright (C) 2013, 2014 Canonical Ltd.
 
4
#
 
5
# This program is free software; you can redistribute it and/or modify
 
6
# it under the terms of the GNU Lesser General Public License as published by
 
7
# the Free Software Foundation; version 3.
 
8
#
 
9
# This program is distributed in the hope that it will be useful,
 
10
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 
12
# GNU Lesser General Public License for more details.
 
13
#
 
14
# You should have received a copy of the GNU Lesser General Public License
 
15
# along with this program. If not, see <http://www.gnu.org/licenses/>.
 
16
#
 
17
# Authored by: Nekhelesh Ramananthan <krnekhelesh@gmail.com>
 
18
#              Nicholas Skaggs <nicholas.skaggs@canonical.com>
 
19
 
 
20
import logging
 
21
 
 
22
from autopilot import logging as autopilot_logging
 
23
 
 
24
from ubuntuuitoolkit import emulators as toolkit_emulators, pickers
 
25
 
 
26
logger = logging.getLogger(__name__)
 
27
 
 
28
 
 
29
class ClockEmulatorException(toolkit_emulators.ToolkitEmulatorException):
 
30
 
 
31
    """Exception raised when there is an error with the emulator."""
 
32
 
 
33
 
 
34
class MainView(toolkit_emulators.MainView):
 
35
 
 
36
    @autopilot_logging.log_action(logger.info)
 
37
    def open_clock(self):
 
38
        """Open the Clock Page.
 
39
 
 
40
        :return the Clock Page
 
41
 
 
42
        """
 
43
        return self.wait_select_single(ClockPage)
 
44
 
 
45
    @autopilot_logging.log_action(logger.info)
 
46
    def open_alarm(self):
 
47
        """Open the Alarm Page.
 
48
 
 
49
        :return: the Alarm Page.
 
50
 
 
51
        """
 
52
        clockPage = self.wait_select_single(ClockPage)
 
53
        clockPage.drag_bottomEdge_up()
 
54
        self.get_header().visible.wait_for(True)
 
55
        return self.wait_select_single(Page11)
 
56
 
 
57
    def get_AlarmList(self):
 
58
        """ Get the AlarmList object. """
 
59
        return AlarmList.select(self)
 
60
 
 
61
 
 
62
class Page(toolkit_emulators.UbuntuUIToolkitEmulatorBase):
 
63
 
 
64
    """Autopilot helper for Pages."""
 
65
 
 
66
    def __init__(self, *args):
 
67
        super(Page, self).__init__(*args)
 
68
        # XXX we need a better way to keep reference to the main view.
 
69
        # --elopio - 2014-01-31
 
70
        self.main_view = self.get_root_instance().select_single(MainView)
 
71
 
 
72
 
 
73
class ClockPage(Page):
 
74
 
 
75
    """Autopilot helper for the Clock page."""
 
76
 
 
77
    @autopilot_logging.log_action(logger.info)
 
78
    def drag_bottomEdge_up(self):
 
79
        """Function to drag the bottom edge up."""
 
80
        self._click_bottomEdge()
 
81
 
 
82
        x, y, w, h = self.globalRect
 
83
        start_x = stop_x = x + (w / 2)
 
84
        start_y = y + (h - 1)
 
85
 
 
86
        stop_y = start_y - h
 
87
        self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
 
88
 
 
89
        self._wait_for_ClockPage_to_close()
 
90
 
 
91
    def _click_bottomEdge(self):
 
92
        """Function to click on the bottom edge."""
 
93
        bottomEdge = self.wait_select_single(
 
94
            'QQuickItem', objectName='bottomEdgeTip')
 
95
        self.pointing_device.click_object(bottomEdge)
 
96
 
 
97
    def _wait_for_ClockPage_to_close(self):
 
98
        self.isCollapsed.wait_for(False)
 
99
 
 
100
 
 
101
class Page11(Page):
 
102
 
 
103
    """Autopilot helper for the Alarm page."""
 
104
 
 
105
    @autopilot_logging.log_action(logger.info)
 
106
    def add_single_alarm(self, name, day, time_to_set, test_sound_name):
 
107
        """Add a single type alarm
 
108
 
 
109
        :param name: name of alarm
 
110
        :param day: day on which the alarm should be triggered
 
111
        :param time_to_set: time to set alarm to
 
112
        :param test_sound_name: sound to set in alarm
 
113
 
 
114
        """
 
115
        alarmListPage = AlarmList.select(self.main_view)
 
116
        old_alarm_count = alarmListPage.get_num_of_alarms()
 
117
 
 
118
        edit_alarm_page = self._click_add_alarm_button()
 
119
        edit_alarm_page.set_alarm_time(time_to_set)
 
120
 
 
121
        alarm_repeat_page = edit_alarm_page.open_alarmRepeat_page()
 
122
        alarm_repeat_page.set_single_alarm_day(day)
 
123
        self._click_header_backButton()
 
124
 
 
125
        alarm_label_page = edit_alarm_page.open_alarmLabel_page()
 
126
        alarm_label_page.set_alarm_label(name)
 
127
        self._click_header_customBackButton()
 
128
 
 
129
        alarm_sound_page = edit_alarm_page.open_alarmSound_page()
 
130
        alarm_sound_page.set_alarm_sound(test_sound_name)
 
131
        self._click_header_customBackButton()
 
132
        edit_alarm_page._check_sound_changed(test_sound_name)
 
133
 
 
134
        self._click_save()
 
135
        self._confirm_alarm_creation(old_alarm_count)
 
136
 
 
137
    def _click_add_alarm_button(self):
 
138
        """Click the add alarm header button."""
 
139
        header = self.main_view.get_header()
 
140
        header.click_action_button('addAlarmAction')
 
141
        return self.main_view.wait_select_single(EditAlarmPage)
 
142
 
 
143
    def _click_header_customBackButton(self):
 
144
        """Click the  header button:  'customBackButton' """
 
145
        header = self.main_view.get_header()
 
146
        header.click_custom_back_button()
 
147
 
 
148
    def _click_header_backButton(self):
 
149
        """Click the  header button:  'backButton' """
 
150
        header = self.main_view.get_header()
 
151
        header.click_back_button()
 
152
 
 
153
    def _click_save(self):
 
154
        """Click the save timer header button"""
 
155
        header = self.main_view.get_header()
 
156
        header.click_action_button('saveAlarmAction')
 
157
 
 
158
    def _confirm_alarm_creation(self, count):
 
159
        """Confirm creation of alarm
 
160
 
 
161
        :param count: alarm count before alarm creation
 
162
 
 
163
        """
 
164
        try:
 
165
            AlarmList.select(self.main_view)._get_saved_alarms_list().\
 
166
                count.wait_for(count + 1)
 
167
        except AssertionError:
 
168
            raise ClockEmulatorException('Error creating alarm.')
 
169
 
 
170
 
 
171
class EditAlarmPage(Page):
 
172
 
 
173
    """Autopilot helper for the Add Alarm page."""
 
174
 
 
175
    @autopilot_logging.log_action(logger.info)
 
176
    def set_alarm_time(self, time_to_set):
 
177
        """Set alarm time on datepicker.
 
178
 
 
179
        :param time_to_set: time to set on datepicker
 
180
 
 
181
        """
 
182
        PickerRow_HoursPicker = self.wait_select_single(
 
183
            "Picker", objectName="PickerRow_HoursPicker")
 
184
        self._set_picker(PickerRow_HoursPicker, 'time', time_to_set)
 
185
 
 
186
    def _set_picker(self, field, mode, value):
 
187
        # open picker
 
188
        self.pointing_device.click_object(field)
 
189
        # valid options are date or time; assume date if invalid/no option
 
190
        if mode == 'time':
 
191
            mode_value = 'Hours|Minutes'
 
192
        else:
 
193
            mode_value = 'Years|Months|Days'
 
194
        picker = self.wait_select_single(
 
195
            pickers.DatePicker, mode=mode_value, visible=True)
 
196
        if mode_value == 'Hours|Minutes':
 
197
            picker.pick_time(value)
 
198
        else:
 
199
            picker.pick_date(value)
 
200
        # close picker
 
201
        self.pointing_device.click_object(field)
 
202
 
 
203
    @autopilot_logging.log_action(logger.info)
 
204
    def open_alarmRepeat_page(self):
 
205
        """ Open the alarmRepeat page """
 
206
 
 
207
        alarmRepeatItem = self.wait_select_single(
 
208
            "SubtitledListItem", objectName="alarmRepeat")
 
209
        self.pointing_device.click_object(alarmRepeatItem)
 
210
        return self.main_view.wait_select_single(AlarmRepeat)
 
211
 
 
212
    @autopilot_logging.log_action(logger.info)
 
213
    def open_alarmLabel_page(self):
 
214
        """ Open the alarmLabel page """
 
215
 
 
216
        alarmLabelItem = self.wait_select_single(
 
217
            "SubtitledListItem", objectName="alarmLabel")
 
218
        self.pointing_device.click_object(alarmLabelItem)
 
219
        return AlarmLable.select(self.main_view)
 
220
 
 
221
    @autopilot_logging.log_action(logger.info)
 
222
    def open_alarmSound_page(self):
 
223
        """ Open the alarmSound page """
 
224
 
 
225
        alarmSoundItem = self.wait_select_single(
 
226
            "SubtitledListItem", objectName="alarmSound")
 
227
        self.pointing_device.click_object(alarmSoundItem)
 
228
        return self.main_view.wait_select_single(AlarmSound)
 
229
 
 
230
    def _check_sound_changed(self, test_sound_name):
 
231
        """ function to check that sound has changed.
 
232
 
 
233
        :param test_sound_name = new sound name
 
234
 
 
235
        """
 
236
        self.wait_select_single("SubtitledListItem", objectName="alarmSound")\
 
237
            .subText == test_sound_name
 
238
 
 
239
 
 
240
class AlarmRepeat(Page):
 
241
 
 
242
    """Autopilot helper for the  AlarmRepeat page."""
 
243
 
 
244
    @autopilot_logging.log_action(logger.info)
 
245
    def set_single_alarm_day(self, day):
 
246
        """Set the alarm day of a single type alarm.
 
247
 
 
248
        :param day: single day on which alarm is triggered
 
249
 
 
250
        """
 
251
        self.unselect_selected_days()
 
252
        index = 0
 
253
        for index in range(self._get_num_of_days()):
 
254
            if self.wait_select_single(
 
255
                    'Label', objectName='alarmDay{}'.format(index))\
 
256
                    .text == day:
 
257
                self._select_single_alarm_day(index)
 
258
                break
 
259
 
 
260
    def _get_num_of_days(self):
 
261
        return int(self.wait_select_single(
 
262
            'QQuickRepeater', objectName='alarmDays').count)
 
263
 
 
264
    def _select_single_alarm_day(self, index):
 
265
        """ function for selecting the day passed to the function.
 
266
 
 
267
        :param index: the day to be selected
 
268
 
 
269
        """
 
270
        dayCheckbox = self.wait_select_single(
 
271
            'CheckBox', objectName='daySwitch{}'.format(index))
 
272
        if not dayCheckbox.checked:
 
273
            self.pointing_device.click_object(dayCheckbox)
 
274
 
 
275
    @autopilot_logging.log_action(logger.info)
 
276
    def unselect_selected_days(self):
 
277
        """ function for unselecting already selected days.   """
 
278
        for index in range(self._get_num_of_days()):
 
279
            if self.wait_select_single(
 
280
                    'CheckBox', objectName='daySwitch{}'.format(index))\
 
281
                    .checked:
 
282
                self.pointing_device.click_object(self.wait_select_single(
 
283
                    'CheckBox', objectName='daySwitch{}'.format(index)))
 
284
                break
 
285
 
 
286
 
 
287
class AlarmSound(Page):
 
288
 
 
289
    """Autopilot helper for the  AlarmSound page."""
 
290
 
 
291
    @autopilot_logging.log_action(logger.info)
 
292
    def set_alarm_sound(self, test_sound_name):
 
293
        """Set alarm sound.
 
294
 
 
295
        :param test_sound_name: sound to set for alarm
 
296
 
 
297
        """
 
298
        for index in range(self._get_num_of_sounds()):
 
299
            if self.wait_select_single(
 
300
                    'Label', objectName='soundName{}'.format(index)).\
 
301
                    text == test_sound_name:
 
302
                self._select_alarm_sound(index)
 
303
                break
 
304
 
 
305
    def _get_num_of_sounds(self):
 
306
        return int(self.wait_select_single(
 
307
            'QQuickRepeater', objectName='alarmSounds').count)
 
308
 
 
309
    def _select_alarm_sound(self, index):
 
310
        """ function for selecting the sound passed to the function.
 
311
 
 
312
        :param index: the sound to be selected
 
313
 
 
314
        """
 
315
        soundCheckbox = self.wait_select_single(
 
316
            'CheckBox', objectName='soundStatus{}'.format(index))
 
317
        if not soundCheckbox.checked:
 
318
            self.pointing_device.click_object(soundCheckbox)
 
319
 
 
320
 
 
321
class AlarmLable(object):
 
322
 
 
323
    """Autopilot helper for the  AlarmLabel page."""
 
324
 
 
325
    def __init__(self, proxy_object):
 
326
        super(AlarmLable, self).__init__()
 
327
        self.proxy_object = proxy_object
 
328
 
 
329
    @classmethod
 
330
    def select(cls, main_view):
 
331
        proxy_object = main_view.wait_select_single(
 
332
            objectName='alarmLabelPage')
 
333
        proxy_object.visible.wait_for(True)
 
334
        return cls(proxy_object)
 
335
 
 
336
    @autopilot_logging.log_action(logger.info)
 
337
    def set_alarm_label(self, name):
 
338
        """Set alarm label.
 
339
 
 
340
        :param name: label for alarm to set
 
341
 
 
342
        """
 
343
        alarmTextfield = self.proxy_object.wait_select_single(
 
344
            "TextField", objectName='labelEntry')
 
345
        # TODO: This wait to ensure that the textfield is visible before
 
346
        # entering text should be part of the SDK emulator. Until then, it has
 
347
        # been added here. http://pad.lv/1289616  --nik90 2014-03-06
 
348
        alarmTextfield.visible.wait_for(True)
 
349
        alarmTextfield.write(name)
 
350
 
 
351
 
 
352
class AlarmList(object):
 
353
 
 
354
    """Autopilot helper for the  AlarmList."""
 
355
 
 
356
    def __init__(self, proxy_object):
 
357
        super(AlarmList, self).__init__()
 
358
        self.proxy_object = proxy_object
 
359
 
 
360
    @classmethod
 
361
    def select(cls, main_view):
 
362
        proxy_object = main_view.wait_select_single(
 
363
            objectName='alarmListFlickable')
 
364
        proxy_object.visible.wait_for(True)
 
365
        return cls(proxy_object)
 
366
 
 
367
    def get_num_of_alarms(self):
 
368
        """Return the number of saved alarms."""
 
369
        return int(self._get_saved_alarms_list().count)
 
370
 
 
371
    def _get_saved_alarms_list(self):
 
372
        """Return the saved alarm list"""
 
373
        return self.proxy_object.wait_select_single(
 
374
            'QQuickRepeater', objectName='alarmListRepeater')
 
375
 
 
376
    def get_saved_alarms(self):
 
377
        """Return a list with the information of the saved alarms.
 
378
 
 
379
        Each item of the returned list is a tuple of
 
380
        (name, recurrence, time, enabled).
 
381
 
 
382
        """
 
383
        alarms = []
 
384
        for index in range(self.get_num_of_alarms()):
 
385
            name = self.proxy_object.wait_select_single(
 
386
                'Label', objectName='listAlarmLabel{}'.format(index)).text
 
387
            recurrence = self.proxy_object.wait_select_single(
 
388
                'Label', objectName='listAlarmSubtitle{}'.format(index)).text
 
389
            time = self.proxy_object.wait_select_single(
 
390
                'Label', objectName='listAlarmTime{}'.format(index)).text
 
391
            enabled = self.proxy_object.wait_select_single(
 
392
                toolkit_emulators.CheckBox,
 
393
                objectName='listAlarmStatus{}'.format(index)).checked
 
394
            alarms.append((name, recurrence, enabled, time))
 
395
        return alarms
 
396
 
 
397
    @autopilot_logging.log_action(logger.info)
 
398
    def delete_alarm(self, index):
 
399
        """Delete an alarm at the specified index."""
 
400
        old_alarm_count = self.get_num_of_alarms()
 
401
        alarm = self.proxy_object.wait_select_single(
 
402
            toolkit_emulators.Base, objectName='alarm{}'.format(index))
 
403
        alarm.swipe_to_delete()
 
404
        alarm.confirm_removal()
 
405
        try:
 
406
            self._get_saved_alarms_list().count.wait_for(old_alarm_count - 1)
 
407
        except AssertionError:
 
408
            raise ClockEmulatorException('Error deleting alarm.')