Merge lp:~nskaggs/ubuntu-calendar-app/fix-1359167 into lp:ubuntu-calendar-app

Proposed by Nicholas Skaggs
Status: Merged
Approved by: Nicholas Skaggs
Approved revision: 456
Merged at revision: 425
Proposed branch: lp:~nskaggs/ubuntu-calendar-app/fix-1359167
Merge into: lp:ubuntu-calendar-app
Diff against target: 2194 lines (+797/-970)
21 files modified
click/manifest.json.in (+1/-1)
debian/calendar-app-autopilot.install (+0/-1)
debian/control (+4/-3)
tests/autopilot/CMakeLists.txt (+3/-6)
tests/autopilot/address_book_service_testability/__init__.py (+0/-18)
tests/autopilot/address_book_service_testability/data/backend-store-key-file-data.ini (+0/-12)
tests/autopilot/address_book_service_testability/data/vcard.vcf (+0/-7)
tests/autopilot/address_book_service_testability/fixture_setup.py (+0/-133)
tests/autopilot/address_book_service_testability/helpers.py (+0/-42)
tests/autopilot/calendar_app/CMakeLists.txt (+8/-0)
tests/autopilot/calendar_app/__init__.py (+637/-1)
tests/autopilot/calendar_app/emulators.py (+0/-621)
tests/autopilot/calendar_app/tests/CMakeLists.txt (+6/-0)
tests/autopilot/calendar_app/tests/__init__.py (+37/-17)
tests/autopilot/calendar_app/tests/test_custom_proxy_objects.py (+4/-13)
tests/autopilot/calendar_app/tests/test_dayview.py (+10/-12)
tests/autopilot/calendar_app/tests/test_monthview.py (+10/-12)
tests/autopilot/calendar_app/tests/test_new_event.py (+42/-39)
tests/autopilot/calendar_app/tests/test_weekview.py (+16/-17)
tests/autopilot/calendar_app/tests/test_yearview.py (+13/-15)
tests/autopilot/calendar_app/vcard.vcf (+6/-0)
To merge this branch: bzr merge lp:~nskaggs/ubuntu-calendar-app/fix-1359167
Reviewer Review Type Date Requested Status
Ubuntu Phone Apps Jenkins Bot continuous-integration Approve
Mihir Soni Approve
Review via email: mp+233387@code.launchpad.net

Commit message

Update launching, fix bug 1359167, remove packing address_book_service_testability modules, fix _get_selected_day_event_bubbles, add test_new_event_must_start_with_default_values

Description of the change

Update launching, fix bug 1359167, remove packing address_book_service_testability modules, fix _get_selected_day_event_bubbles, add test_new_event_must_start_with_default_values

To post a comment you must log in.
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
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
Mihir Soni (mihirsoni) wrote :

There is something wrong with a new test you've added,
rest works fine on my machine.

Traceback (most recent call last):
  File "/home/mihir/Documents/reviews/fix-1359167/tests/autopilot/calendar_app/tests/test_new_event.py", line 99, in test_new_event_must_start_with_default_values
    self.assertThat(new_event_page.get_calendar(), Equals('Personal'))
  File "/usr/lib/python3/dist-packages/testtools/testcase.py", line 406, in assertThat
    raise mismatch_error
testtools.matchers._impl.MismatchError: !=:
reference = 'Personal'
actual = <ubuntuuitoolkit._custom_proxy_objects._optionselector.OptionSelector object at 0x7f72853b27f0>

Ran 25 tests in 530.692s
FAILED (failures=1)

review: Needs Fixing
Revision history for this message
Mihir Soni (mihirsoni) wrote :

Balloons , thanks for the quick fix.
All test pass on my machine.
Thanks a lot for your time :)

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
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
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
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) :
review: Approve (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: Approve (continuous-integration)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'click/manifest.json.in'
2--- click/manifest.json.in 2014-08-07 18:02:06 +0000
3+++ click/manifest.json.in 2014-09-05 01:20:41 +0000
4@@ -20,7 +20,7 @@
5 "x-test": {
6 "autopilot": {
7 "autopilot_module": "@AUTOPILOT_DIR@",
8- "depends": ["python3-dateutil", "address-book-service-dummy"]
9+ "depends": ["python3-dateutil", "address-book-service-dummy", "address-book-service-testability"]
10 }
11 }
12 }
13
14=== modified file 'debian/calendar-app-autopilot.install'
15--- debian/calendar-app-autopilot.install 2014-07-31 16:42:45 +0000
16+++ debian/calendar-app-autopilot.install 2014-09-05 01:20:41 +0000
17@@ -1,3 +1,2 @@
18 usr/lib/*/dist-packages/calendar_app/*
19-usr/lib/*/dist-packages/address_book_service_testability/*
20
21
22=== modified file 'debian/control'
23--- debian/control 2014-07-30 21:40:03 +0000
24+++ debian/control 2014-09-05 01:20:41 +0000
25@@ -4,7 +4,7 @@
26 Build-Depends: cmake,
27 debhelper (>= 9),
28 intltool,
29- python,
30+ python3,
31 qtdeclarative5-dev-tools,
32 qt5-default,
33 qtdeclarative5-qtquick2-plugin,
34@@ -43,9 +43,10 @@
35 Depends: libautopilot-qt (>= 1.4),
36 libqt5test5,
37 calendar-app (= ${source:Version}),
38- python-dateutil,
39+ python3-dateutil,
40 ubuntu-ui-toolkit-autopilot,
41- address-book-service-dummy
42+ address-book-service-dummy,
43+ address-book-service-testability
44 Description: Autopilot tests for Ubuntu Calendar Application
45 This package contains autopilot tests for the Ubuntu Calendar application.
46
47
48=== modified file 'tests/autopilot/CMakeLists.txt'
49--- tests/autopilot/CMakeLists.txt 2014-07-31 16:42:45 +0000
50+++ tests/autopilot/CMakeLists.txt 2014-09-05 01:20:41 +0000
51@@ -1,13 +1,10 @@
52 if(INSTALL_TESTS)
53-execute_process(COMMAND python -c "from distutils.sysconfig import get_python_lib; print get_python_lib()"
54+execute_process(COMMAND python3 -c "from distutils.sysconfig import get_python_lib; print(get_python_lib())"
55 OUTPUT_VARIABLE PYTHON_PACKAGE_DIR OUTPUT_STRIP_TRAILING_WHITESPACE)
56
57 install(DIRECTORY ${AUTOPILOT_DIR}
58 DESTINATION ${PYTHON_PACKAGE_DIR}
59 )
60-
61-#add depends
62-install(DIRECTORY address_book_service_testability
63- DESTINATION ${PYTHON_PACKAGE_DIR}
64- )
65 endif(INSTALL_TESTS)
66+
67+add_subdirectory(calendar_app)
68
69=== removed directory 'tests/autopilot/address_book_service_testability'
70=== removed file 'tests/autopilot/address_book_service_testability/__init__.py'
71--- tests/autopilot/address_book_service_testability/__init__.py 2014-07-30 21:40:03 +0000
72+++ tests/autopilot/address_book_service_testability/__init__.py 1970-01-01 00:00:00 +0000
73@@ -1,18 +0,0 @@
74-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
75-#
76-# Copyright (C) 2014 Canonical
77-# Author: Omer Akram <omer.akram@canonical.com>
78-#
79-# This program is free software: you can redistribute it and/or modify
80-# it under the terms of the GNU General Public License as published by
81-# the Free Software Foundation, either version 3 of the License, or
82-# (at your option) any later version.
83-#
84-# This program is distributed in the hope that it will be useful,
85-# but WITHOUT ANY WARRANTY; without even the implied warranty of
86-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
87-# GNU General Public License for more details.
88-#
89-# You should have received a copy of the GNU General Public License
90-# along with this program. If not, see <http://www.gnu.org/licenses/>.
91-#
92
93=== removed directory 'tests/autopilot/address_book_service_testability/data'
94=== removed file 'tests/autopilot/address_book_service_testability/data/backend-store-key-file-data.ini'
95--- tests/autopilot/address_book_service_testability/data/backend-store-key-file-data.ini 2014-07-30 21:40:03 +0000
96+++ tests/autopilot/address_book_service_testability/data/backend-store-key-file-data.ini 1970-01-01 00:00:00 +0000
97@@ -1,12 +0,0 @@
98-#export FOLKS_BACKEND_KEY_FILE_PATH
99-[0]
100-__alias=Renato Araujo
101-msn=renato@msn.com
102-
103-[1]
104-__alias=Rodrigo Almeida
105-msn=kiko@msn.com
106-
107-[2]
108-__alias=Raphael Almeida
109-msn=rafa@msn.com
110
111=== removed file 'tests/autopilot/address_book_service_testability/data/vcard.vcf'
112--- tests/autopilot/address_book_service_testability/data/vcard.vcf 2014-07-30 21:40:03 +0000
113+++ tests/autopilot/address_book_service_testability/data/vcard.vcf 1970-01-01 00:00:00 +0000
114@@ -1,7 +0,0 @@
115-BEGIN:VCARD
116-VERSION:3.0
117-N:User;UX;
118-FN:UX User
119-TEL:3333333
120-END:VCARD
121-
122
123=== removed file 'tests/autopilot/address_book_service_testability/fixture_setup.py'
124--- tests/autopilot/address_book_service_testability/fixture_setup.py 2014-07-31 19:53:11 +0000
125+++ tests/autopilot/address_book_service_testability/fixture_setup.py 1970-01-01 00:00:00 +0000
126@@ -1,133 +0,0 @@
127-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
128-#
129-# Copyright (C) 2014 Canonical
130-# Author: Omer Akram <omer.akram@canonical.com>
131-#
132-# This program is free software: you can redistribute it and/or modify
133-# it under the terms of the GNU General Public License as published by
134-# the Free Software Foundation, either version 3 of the License, or
135-# (at your option) any later version.
136-#
137-# This program is distributed in the hope that it will be useful,
138-# but WITHOUT ANY WARRANTY; without even the implied warranty of
139-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
140-# GNU General Public License for more details.
141-#
142-# You should have received a copy of the GNU General Public License
143-# along with this program. If not, see <http://www.gnu.org/licenses/>.
144-#
145-
146-import os
147-import subprocess
148-import sysconfig
149-import time
150-
151-from fixtures import EnvironmentVariable, Fixture
152-
153-
154-def get_service_library_path():
155- """Return path of address-book-service binary directory."""
156- architecture = sysconfig.get_config_var('MULTIARCH')
157-
158- return os.path.join(
159- '/usr/lib/',
160- architecture,
161- 'address-book-service/')
162-
163-
164-class AddressBookServiceDummyBackend(Fixture):
165- """Fixture to load test vcard for client applications
166-
167- Call the fixture without any paramter to load a default vcard
168-
169- :parameter vcard: call the fixture with a vcard to be used by
170- test application.
171-
172- """
173- def __init__(self, vcard=None):
174- self.contact_data = vcard
175-
176- def setUp(self):
177- super(AddressBookServiceDummyBackend, self).setUp()
178- self.useFixture(SetupEnvironmentVariables(self.contact_data))
179- self.useFixture(RestartService())
180-
181-
182-class SetupEnvironmentVariables(Fixture):
183-
184- def __init__(self, vcard):
185- self.vcard = vcard
186-
187- def setUp(self):
188- super(SetupEnvironmentVariables, self).setUp()
189- self._setup_environment()
190-
191- def _setup_environment(self):
192- self.useFixture(EnvironmentVariable(
193- 'ALTERNATIVE_CPIM_SERVICE_NAME', 'com.canonical.test.pim'))
194- self.useFixture(EnvironmentVariable(
195- 'FOLKS_BACKEND_PATH',
196- os.path.join(get_service_library_path(), 'dummy.so')))
197- self.useFixture(EnvironmentVariable('FOLKS_BACKENDS_ALLOWED', 'dummy'))
198- self.useFixture(EnvironmentVariable('FOLKS_PRIMARY_STORE', 'dummy'))
199- self.useFixture(EnvironmentVariable(
200- 'ADDRESS_BOOK_SERVICE_DEMO_DATA',
201- self._get_vcard_location()))
202-
203- def _get_vcard_location(self):
204- if self.vcard:
205- return self.vcard
206-
207- local_location = os.path.dirname(os.path.dirname(os.getcwd()))
208- local_location = os.path.join(
209- local_location,
210- 'tests/autopilot/address_book_service_testability/data/vcard.vcf')
211- phablet_location = 'address_book_service_testability/data/vcard.vcf'
212- bin_location = '/usr/share/address-book-service/data/vcard.vcf'
213- cal_location = os.path.join('/usr/lib/python2.7/dist-packages/',
214- 'address_book_service_testability/data/',
215- 'vcard.vcf')
216- if os.path.exists(local_location):
217- print('Using %s for vcard' % local_location)
218- return local_location
219- elif os.path.exists(phablet_location):
220- print('Using %s for vcard' % phablet_location)
221- return phablet_location
222- elif os.path.exists(cal_location):
223- print('Using %s for vcard' % cal_location)
224- return cal_location
225- elif os.path.exists(bin_location):
226- print('Using %s for vcard' % bin_location)
227- return bin_location
228- else:
229- raise RuntimeError('No VCARD found in %s or %s or %s or %s' %
230- (local_location, bin_location,
231- cal_location, phablet_location))
232-
233-
234-class RestartService(Fixture):
235-
236- def setUp(self):
237- super(RestartService, self).setUp()
238- self.addCleanup(self._kill_address_book_service)
239- self._restart_address_book_service()
240-
241- def _kill_address_book_service(self):
242- try:
243- pid = subprocess.check_output(
244- ['pidof', 'address-book-service']).strip()
245- subprocess.call(['kill', '-3', pid])
246- except subprocess.CalledProcessError:
247- # Service not running, so do nothing.
248- pass
249-
250- def _restart_address_book_service(self):
251- self._kill_address_book_service()
252- path = os.path.join(
253- get_service_library_path(), 'address-book-service')
254-
255- subprocess.Popen([path])
256- # FIXME: Wait for 5 seconds before proceeding so that the
257- # service starts,doing this because the dbus interface is
258- # not reliable enough it seems. --om26er 23-07-2014
259- time.sleep(5)
260
261=== removed file 'tests/autopilot/address_book_service_testability/helpers.py'
262--- tests/autopilot/address_book_service_testability/helpers.py 2014-07-30 21:40:03 +0000
263+++ tests/autopilot/address_book_service_testability/helpers.py 1970-01-01 00:00:00 +0000
264@@ -1,42 +0,0 @@
265-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
266-#
267-# Copyright 2014 Canonical Ltd.
268-#
269-# This file is part of address-book-service tests.
270-#
271-# This program is free software; you can redistribute it and/or modify
272-# it under the terms of the GNU General Public License version 3, as published
273-# by the Free Software Foundation.
274-#
275-# This program is distributed in the hope that it will be useful,
276-# but WITHOUT ANY WARRANTY; without even the implied warranty of
277-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
278-# GNU General Public License for more details.
279-#
280-# You should have received a copy of the GNU General Public License
281-# along with this program. If not, see <http://www.gnu.org/licenses/>
282-
283-import dbus
284-
285-DBUS_IFACE_ADD_BOOK = 'com.canonical.pim.AddressBook'
286-DBUS_IFACE_ADD_BOOKVIEW = 'com.canonical.pim.AddressBookView'
287-
288-bus = dbus.SessionBus()
289-
290-
291-def query_contacts(fields='', query='', sources=[]):
292- iface = _get_contacts_dbus_service_iface()
293- view_path = iface.query(fields, query, [])
294- view = bus.get_object(
295- 'com.canonical.pim', view_path)
296- view_iface = dbus.Interface(
297- view, dbus_interface=DBUS_IFACE_ADD_BOOKVIEW)
298- contacts = view_iface.contactsDetails([], 0, -1)
299- view.close()
300- return contacts
301-
302-
303-def _get_contacts_dbus_service_iface():
304- proxy = bus.get_object(
305- 'com.canonical.pim', '/com/canonical/pim/AddressBook')
306- return dbus.Interface(proxy, 'com.canonical.pim.AddressBook')
307
308=== added file 'tests/autopilot/calendar_app/CMakeLists.txt'
309--- tests/autopilot/calendar_app/CMakeLists.txt 1970-01-01 00:00:00 +0000
310+++ tests/autopilot/calendar_app/CMakeLists.txt 2014-09-05 01:20:41 +0000
311@@ -0,0 +1,8 @@
312+add_subdirectory(tests)
313+
314+# make the emulator files visible on qtcreator
315+file(GLOB PYTHON_EMULATOR_FILES
316+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
317+ *.py)
318+
319+add_custom_target(com_ubuntu_calendar_PYTHONEMULATORFiles ALL SOURCES ${PYTHON_EMULATOR_FILES})
320
321=== modified file 'tests/autopilot/calendar_app/__init__.py'
322--- tests/autopilot/calendar_app/__init__.py 2014-06-26 18:10:28 +0000
323+++ tests/autopilot/calendar_app/__init__.py 2014-09-05 01:20:41 +0000
324@@ -14,4 +14,640 @@
325 # You should have received a copy of the GNU General Public License
326 # along with this program. If not, see <http://www.gnu.org/licenses/>.
327
328-"""calendar-app tests and emulators - top level package."""
329+"""Calendar app autopilot helpers."""
330+
331+import logging
332+from time import sleep
333+
334+import autopilot.logging
335+from dateutil import tz
336+
337+import ubuntuuitoolkit
338+
339+from calendar_app import data
340+
341+
342+logger = logging.getLogger(__name__)
343+
344+
345+class CalendarException(ubuntuuitoolkit.ToolkitException):
346+
347+ """Exception raised when there are problems with the Calendar."""
348+
349+
350+class CalendarApp(object):
351+
352+ """Autopilot helper object for the terminal application."""
353+
354+ def __init__(self, app_proxy, test_type):
355+ self.app = app_proxy
356+ self.test_type = test_type
357+ self.main_view = self.app.select_single(MainView)
358+
359+ @property
360+ def pointing_device(self):
361+ return self.app.pointing_device
362+
363+
364+class MainView(ubuntuuitoolkit.MainView):
365+
366+ """A helper that makes it easy to interact with the calendar-app."""
367+
368+ def __init__(self, *args):
369+ super(MainView, self).__init__(*args)
370+ self.visible.wait_for(True)
371+
372+ @autopilot.logging.log_action(logger.info)
373+ def go_to_month_view(self):
374+ """Open the month view.
375+
376+ :return: The Month View page.
377+
378+ """
379+ month_tab = self.select_single('Tab', objectName='monthTab')
380+ if not month_tab.visible:
381+ self.switch_to_tab('monthTab')
382+ else:
383+ logger.debug('The month View page is already opened.')
384+ return self.get_month_view(month_tab)
385+
386+ @autopilot.logging.log_action(logger.info)
387+ def go_to_week_view(self):
388+ """Open the week view.
389+
390+ :return: The Week View page.
391+
392+ """
393+ week_tab = self.select_single('Tab', objectName='weekTab')
394+ if not week_tab.visible:
395+ self.switch_to_tab('weekTab')
396+ else:
397+ logger.debug('The week View page is already opened.')
398+ return self.get_week_view(week_tab)
399+
400+ @autopilot.logging.log_action(logger.info)
401+ def go_to_year_view(self):
402+ """Open the year view.
403+
404+ :return: The Year View page.
405+
406+ """
407+ year_tab = self.select_single('Tab', objectName='yearTab')
408+ if not year_tab.visible:
409+ self.switch_to_tab('yearTab')
410+ else:
411+ logger.debug('The Year View page is already opened.')
412+ return self.get_year_view(year_tab)
413+
414+ @autopilot.logging.log_action(logger.info)
415+ def go_to_day_view(self):
416+ """Open the day view.
417+
418+ :return: The Day View page.
419+
420+ """
421+ day_tab = self.select_single('Tab', objectName='dayTab')
422+ if not day_tab.visible:
423+ self.switch_to_tab('dayTab')
424+ else:
425+ logger.debug('The Day View page is already opened.')
426+ return self.get_day_view(day_tab)
427+
428+ @autopilot.logging.log_action(logger.info)
429+ def go_to_new_event(self):
430+ """Open the page to add a new event.
431+
432+ :return: The New Event page.
433+
434+ """
435+ header = self.get_header()
436+ header.click_action_button('neweventbutton')
437+ return self.select_single(NewEvent, objectName='newEventPage')
438+
439+ def set_picker(self, field, mode, value):
440+ # open picker
441+ self.pointing_device.click_object(field)
442+ # valid options are date or time; assume date if invalid/no option
443+ if mode == 'time':
444+ mode_value = 'Hours|Minutes'
445+ else:
446+ mode_value = 'Years|Months|Days'
447+ picker = self.wait_select_single(
448+ ubuntuuitoolkit.pickers.DatePicker, mode=mode_value, visible=True)
449+ if mode_value == 'Hours|Minutes':
450+ picker.pick_time(value)
451+ else:
452+ picker.pick_date(value)
453+ # close picker
454+ self.pointing_device.click_object(field)
455+
456+ def get_event_view(self, parent_object=None):
457+ if parent_object is None:
458+ parent_object = self
459+ return parent_object.select_single("EventView")
460+
461+ def get_event_details(self, parent_object=None):
462+ if parent_object is None:
463+ parent_object = self
464+ return parent_object.select_single(EventDetails,
465+ objectName='eventDetails')
466+
467+ def get_month_view(self, parent_object=None):
468+ if parent_object is None:
469+ parent_object = self
470+ return parent_object.select_single(MonthView,
471+ objectName='monthViewPage')
472+
473+ def get_year_view(self, parent_object=None):
474+ if parent_object is None:
475+ parent_object = self
476+ return parent_object.select_single(YearView, objectName='yearViewPage')
477+
478+ def get_day_view(self, parent_object=None):
479+ if parent_object is None:
480+ parent_object = self
481+ return parent_object.select_single(DayView, objectName='dayViewPage')
482+
483+ def get_week_view(self, parent_object=None):
484+ if parent_object is None:
485+ parent_object = self
486+ return parent_object.select_single(WeekView, objectName='weekViewPage')
487+
488+ def get_label_with_text(self, text, root=None):
489+ if root is None:
490+ root = self
491+ labels = root.select_many("Label", text=text)
492+ if (len(labels) > 0):
493+ return labels[0]
494+ else:
495+ return None
496+
497+ def get_year(self, component):
498+ return int(component.wait_select_single(
499+ "Label", objectName="yearLabel").text)
500+
501+ def get_month_name(self, component):
502+ return component.wait_select_single(
503+ "Label", objectName="monthLabel").text
504+
505+ def safe_swipe_view(self, direction, view, date):
506+ """
507+ direction: direction to swip
508+ view: the view you are swiping against
509+ date: a function object of the view
510+ """
511+ timeout = 0
512+ before = date
513+ # try up to 3 times to swipe
514+ while timeout < 3 and date == before:
515+ self._swipe(direction, view)
516+ # check for up to 3 seconds after swipe for view
517+ # to have changed before trying again
518+ for x in range(0, 3):
519+ if date != before:
520+ break
521+ sleep(1)
522+ timeout += 1
523+
524+ def swipe_view(self, direction, view, x_pad=0.15):
525+ """Swipe the given view to left or right.
526+
527+ Args:
528+ direction: if 1 it swipes from right to left, if -1 from
529+ left right.
530+
531+ """
532+
533+ start = (-direction * x_pad) % 1
534+ stop = (direction * x_pad) % 1
535+
536+ y_line = view.globalRect[1] + view.globalRect[3] / 2
537+ x_start = view.globalRect[0] + view.globalRect[2] * start
538+ x_stop = view.globalRect[0] + view.globalRect[2] * stop
539+
540+ self.pointing_device.drag(x_start, y_line, x_stop, y_line)
541+
542+ def to_local_date(self, date):
543+ utc = date.replace(tzinfo=tz.tzutc())
544+ local = utc.astimezone(tz.tzlocal())
545+ return local
546+
547+
548+class YearView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
549+
550+ """Autopilot helper for the Year View page."""
551+
552+
553+class WeekView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
554+
555+ """Autopilot helper for the Week View page."""
556+
557+
558+class MonthView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
559+
560+ """Autopilot helper for the Year View page."""
561+
562+
563+class DayView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
564+
565+ """Autopilot helper for the Day View page."""
566+
567+ @autopilot.logging.log_action(logger.info)
568+ def get_events(self, visible=True):
569+ """Return the events for this day.
570+
571+ :param visible: toggles filtering for only visible events
572+ :return: A list with the events. Each event is a tuple with name, start
573+ time and end time.
574+
575+ """
576+ event_bubbles = self._get_selected_day_event_bubbles()
577+
578+ # sort by y, x
579+ event_bubbles = sorted(
580+ event_bubbles,
581+ key=lambda bubble: (bubble.globalRect.y, bubble.globalRect.x))
582+
583+ events = []
584+ for event in event_bubbles:
585+ # Event-bubbles objects are recycled, only show visible ones.
586+ if visible:
587+ if event.visible:
588+ events.append(event.get_information())
589+ else:
590+ events.append(event.get_information())
591+
592+ return events
593+
594+ @autopilot.logging.log_action(logger.info)
595+ def get_event(self, event_name, visible=True):
596+ """Return a specific event from current day.
597+
598+ :param visible: toggles filtering for only visible events
599+ :param event_name: the name of the event.
600+ If more than one name matches, return the first matching event
601+ :return: The event object
602+ """
603+ event_bubbles = self._get_selected_day_event_bubbles()
604+
605+ # sort by y, x
606+ event_bubbles = sorted(
607+ event_bubbles,
608+ key=lambda bubble: (bubble.globalRect.y, bubble.globalRect.x))
609+
610+ for event in event_bubbles:
611+ # Event-bubbles objects are recycled, only show visible ones.
612+ if event.get_name() == event_name:
613+ if (visible and event.visible) or not visible:
614+ matched_event = event
615+ return matched_event
616+
617+ raise CalendarException('No event found for %s' % event_name)
618+
619+ def _get_day_component(self, day='selected'):
620+ """Get the selected day component.
621+ This method considers 'yesterday' to be the selected day - 1
622+ and 'tomorrow' to be the selected day + 1
623+ """
624+ if day == 'yesterday':
625+ return self.select_single('TimeLineBaseComponent',
626+ objectName='DayComponent-2')
627+ elif day == 'tomorrow':
628+ return self.select_single('TimeLineBaseComponent',
629+ objectName='DayComponent-1')
630+ else:
631+ return self.select_single('TimeLineBaseComponent',
632+ objectName='DayComponent-0')
633+
634+ def _get_selected_day_event_bubbles(self):
635+ selected_day = self._get_day_component()
636+ return self._get_event_bubbles(selected_day)
637+
638+ def _get_event_bubbles(self, selected_day):
639+ try:
640+ loading_spinner = selected_day.select_single("ActivityIndicator")
641+ loading_spinner.running.wait_for(False)
642+ except:
643+ pass
644+ event_bubbles = selected_day.select_many(EventBubble)
645+ return event_bubbles
646+
647+ def _remove_duplicate_events(self, separator_id, event_bubbles):
648+ events = []
649+ for bubble in event_bubbles:
650+ if bubble.id > separator_id:
651+ events.append(bubble)
652+
653+ return events
654+
655+ @autopilot.logging.log_action(logger.info)
656+ def open_event(self, name):
657+ """Open an event.
658+
659+ :param name: The name of the event to open.
660+ :return: The Event Details page.
661+
662+ """
663+ return self.get_event(name).open_event()
664+
665+ @autopilot.logging.log_action(logger.info)
666+ def delete_event(self, name):
667+ """Delete an event.
668+
669+ :param name: The name of the event to delete.
670+ :return: The Day View page.
671+
672+ """
673+ event_details_page = self.open_event(name)
674+ return event_details_page.delete()
675+
676+ @autopilot.logging.log_action(logger.info)
677+ def edit_event(self, name):
678+ """Edit an event.
679+ :param name:The name of event to edit
680+ :return : event details page. """
681+ event_details_page = self.open_event(name)
682+ return event_details_page.edit()
683+
684+ @autopilot.logging.log_action(logger.info)
685+ def get_day_header(self, day=None):
686+ """Return the dayheader for a given day. If no day is given,
687+ return the current day.
688+
689+ :param day: A datetime object matching the header
690+ :return: The day header object
691+ """
692+ if day:
693+ headers = self.select_many('TimeLineHeaderComponent')
694+ for header in headers:
695+ if header.startDay.datetime == day:
696+ day_header = header
697+ break
698+ else:
699+ # just grab the current day
700+ day_header = self.wait_select_single(
701+ 'TimeLineHeaderComponent', isCurrentItem=True)
702+
703+ if not(day_header):
704+ raise CalendarException('Day Header not found for %s' % day)
705+ return day_header
706+
707+
708+class EventBubble(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
709+
710+ """Autopiot helper for the Event Bubble items."""
711+
712+ def get_information(self):
713+ """Return a tuple with the name, start time and end time."""
714+ name = self.get_name()
715+ start_time, end_time = self._get_start_and_end_time()
716+ return name, start_time, end_time
717+
718+ def _get_start_and_end_time(self):
719+ """Return a tuple with the start time and end time."""
720+ time_label = self.select_single('Label', objectName='timeLabel')
721+ start_time, end_time = time_label.text.split(' - ')
722+ return start_time, end_time
723+
724+ def get_name(self):
725+ """Return the event name."""
726+ title_label = self.select_single('Label', objectName='titleLabel')
727+ return title_label.text
728+
729+ @autopilot.logging.log_action(logger.info)
730+ def open_event(self):
731+ """Open the event.
732+
733+ :return: The Event Details page.
734+
735+ """
736+ # If there are too many events, the center of the bubble
737+ # might be hidden by another event. Click the left side of the
738+ # bubble.
739+ left = self.globalRect.x + 5
740+ center_y = self.globalRect.y + self.globalRect.height // 2
741+ self.pointing_device.move(left, center_y)
742+ self.pointing_device.click()
743+ return self.get_root_instance().select_single(
744+ EventDetails, objectName='eventDetails')
745+
746+
747+# override toolkit helper to
748+# workaround bug https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1343916
749+class QQuickFlickable(ubuntuuitoolkit.QQuickFlickable):
750+
751+ def _slow_drag(self, start_x, stop_x, start_y, stop_y):
752+ rate = (self.flickDeceleration + 250) / 350
753+ self.pointing_device.drag(start_x, start_y, stop_x, stop_y, rate=rate)
754+ self.pointing_device.click()
755+
756+
757+class NewEvent(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
758+
759+ """Autopilot helper for the New Event page."""
760+
761+ @autopilot.logging.log_action(logger.info)
762+ def add_event(self, event_information):
763+ """Add a new event.
764+
765+ :param event_information: Values of the event to fill the form.
766+ :type event_information: data object with the attributes name,
767+ description, location and guests.
768+
769+ """
770+ self._fill_form(event_information)
771+ self._save()
772+
773+ @autopilot.logging.log_action(logger.debug)
774+ def _fill_form(self, event_information):
775+ """Fill the add event form.
776+
777+ :param event_information: Values of the event to fill the form.
778+ :type event_information: data object with the attributes
779+ calendar, name, description, location and guests.
780+
781+ """
782+ # TODO fill start date and end date, is all day event, recurrence and
783+ # reminders. --elopio - 2014-06-26
784+ if event_information.calendar is not None:
785+ self._select_calendar(event_information.calendar)
786+ if event_information.name is not None:
787+ self._fill_name(event_information.name)
788+ if event_information.description is not None:
789+ self._fill_description(event_information.description)
790+ if event_information.location is not None:
791+ self._fill_location(event_information.location)
792+ if event_information.guests is not None:
793+ self._fill_guests(event_information.guests)
794+
795+ def _fill_name(self, value):
796+ self._ensure_entry_field_visible_and_write('newEventName', value)
797+
798+ def _ensure_entry_field_visible_and_write(self, object_name, value):
799+ name_text_field = self._get_new_event_entry_field(object_name)
800+ self._ensure_visible_and_write(name_text_field, value)
801+
802+ def _get_new_event_entry_field(self, object_name):
803+ return self.select_single(NewEventEntryField, objectName=object_name)
804+
805+ def _ensure_visible_and_write(self, text_field, value):
806+ text_field.swipe_into_view()
807+ text_field.write(value)
808+
809+ def _fill_description(self, value):
810+ description_text_area = self._get_description_text_area()
811+ self._ensure_visible_and_write(description_text_area, value)
812+
813+ def _get_description_text_area(self):
814+ return self.select_single(
815+ ubuntuuitoolkit.TextArea, objectName='eventDescriptionInput')
816+
817+ def _fill_location(self, value):
818+ self._ensure_entry_field_visible_and_write('eventLocationInput', value)
819+
820+ def _fill_guests(self, guests):
821+ guests_btn = self.select_single('Button', objectName='addGuestButton')
822+ main_view = self.get_root_instance().select_single(MainView)
823+
824+ for guest in guests:
825+ self.pointing_device.click_object(guests_btn)
826+ guest_input = main_view.select_single(
827+ NewEventEntryField, objectName='contactPopoverInput')
828+ contacts = main_view.select_single(ubuntuuitoolkit.QQuickListView,
829+ objectName='contactPopoverList')
830+ guest_input.write(guest)
831+
832+ try:
833+ contacts.click_element('contactPopoverList0')
834+ except ubuntuuitoolkit.ToolkitException:
835+ raise CalendarException('No guest found with name %s' % guest)
836+
837+ def _select_calendar(self, calendar):
838+ self._get_calendar().select_option('Label', text=calendar)
839+
840+ def _get_calendar(self):
841+ return self.select_single(ubuntuuitoolkit.OptionSelector,
842+ objectName="calendarsOption")
843+
844+ def _get_guests(self):
845+ guestlist = self.select_single('QQuickColumn', objectName='guestList')
846+ guests = guestlist.select_many('Standard')
847+ guest_names = []
848+ for guest in guests:
849+ guest_names.append(guest.text)
850+ return guest_names
851+
852+ def get_calendar_name(self):
853+ return self._get_calendar().get_current_label().text
854+
855+ def get_event_name(self):
856+ return self._get_new_event_entry_field('newEventName').text
857+
858+ def get_description_text(self):
859+ return self._get_description_text_area().text
860+
861+ def get_location_name(self):
862+ return self._get_new_event_entry_field('eventLocationInput').text
863+
864+ def _get_form_values(self):
865+ # TODO get start date and end date, is all day event, recurrence and
866+ # reminders. --elopio - 2014-06-26
867+ calendar = self.get_calendar_name()
868+ name = self.get_event_name()
869+ description = self.get_description_text()
870+ location = self.get_location_name()
871+ guests = self._get_guests()
872+ return data.Event(calendar, name, description, location, guests)
873+
874+ @autopilot.logging.log_action(logger.info)
875+ def _save(self):
876+ """Save the new event."""
877+ root = self.get_root_instance()
878+ header = root.select_single(MainView).get_header()
879+ header.click_action_button('save')
880+
881+
882+class NewEventEntryField(ubuntuuitoolkit.TextField):
883+
884+ """Autopilot helper for the NewEventEntryField component."""
885+
886+
887+class EventDetails(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
888+
889+ """Autopilot helper for the Event Details page."""
890+
891+ @autopilot.logging.log_action(logger.debug)
892+ def delete(self):
893+ """Click the delete button.
894+
895+ :return: The Day View page.
896+
897+ """
898+ root = self.get_root_instance()
899+ header = root.select_single(MainView).get_header()
900+ header.click_action_button('delete')
901+
902+ delete_confirmation_dialog = root.select_single(
903+ DeleteConfirmationDialog, objectName='deleteConfirmationDialog')
904+ delete_confirmation_dialog.confirm_deletion()
905+
906+ return root.select_single(DayView, objectName='dayViewPage')
907+
908+ @autopilot.logging.log_action(logger.debug)
909+ def edit(self):
910+ """Click the Edit button.
911+
912+ :return: The Edit page.
913+
914+ """
915+ root = self.get_root_instance()
916+ header = root.select_single(MainView).get_header()
917+ header.click_action_button('edit')
918+ return root.select_single(NewEvent, objectName='newEventPage')
919+
920+ def get_event_information(self):
921+ """Return the information of the event."""
922+ calendar = self._get_calendar()
923+ name = self._get_name()
924+ description = self._get_description()
925+ location = self._get_location()
926+ guests = self._get_guests()
927+ return data.Event(calendar, name, description, location, guests)
928+
929+ def _get_calendar(self):
930+ return self._get_label_text('calendarName')
931+
932+ def _get_name(self):
933+ return self._get_label_text('titleLabel')
934+
935+ def _get_label_text(self, object_name):
936+ return self.select_single('Label', objectName=object_name).text
937+
938+ def _get_description(self):
939+ return self._get_label_text('descriptionLabel')
940+
941+ def _get_location(self):
942+ return self._get_label_text('locationLabel')
943+
944+ def _get_guests(self):
945+ guests = []
946+ contacts_list = self.select_single(
947+ 'QQuickColumn', objectName='contactList')
948+ guest_labels = contacts_list.select_many('Label')
949+ for label in guest_labels:
950+ guests.append(label.text)
951+
952+ return guests
953+
954+
955+class DeleteConfirmationDialog(
956+ ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
957+
958+ """Autopilot helper for the Delete Confirmation dialog."""
959+
960+ @autopilot.logging.log_action(logger.debug)
961+ def confirm_deletion(self):
962+ """Confirm the deletion of the event."""
963+ delete_button = self.select_single(
964+ 'Button', objectName='deleteEventButton')
965+ self.pointing_device.click_object(delete_button)
966
967=== removed file 'tests/autopilot/calendar_app/emulators.py'
968--- tests/autopilot/calendar_app/emulators.py 2014-08-22 11:41:06 +0000
969+++ tests/autopilot/calendar_app/emulators.py 1970-01-01 00:00:00 +0000
970@@ -1,621 +0,0 @@
971-# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
972-#
973-# Copyright (C) 2013, 2014 Canonical Ltd
974-#
975-# This program is free software: you can redistribute it and/or modify
976-# it under the terms of the GNU General Public License version 3 as
977-# published by the Free Software Foundation.
978-#
979-# This program is distributed in the hope that it will be useful,
980-# but WITHOUT ANY WARRANTY; without even the implied warranty of
981-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
982-# GNU General Public License for more details.
983-#
984-# You should have received a copy of the GNU General Public License
985-# along with this program. If not, see <http://www.gnu.org/licenses/>.
986-
987-"""Calendar app autopilot emulators."""
988-
989-import logging
990-from time import sleep
991-
992-import autopilot.logging
993-from dateutil import tz
994-
995-import ubuntuuitoolkit
996-
997-from calendar_app import data
998-
999-
1000-logger = logging.getLogger(__name__)
1001-
1002-
1003-class CalendarException(ubuntuuitoolkit.ToolkitException):
1004-
1005- """Exception raised when there are problems with the Calendar."""
1006-
1007-
1008-class MainView(ubuntuuitoolkit.MainView):
1009-
1010- """An emulator that makes it easy to interact with the calendar-app."""
1011-
1012- @autopilot.logging.log_action(logger.info)
1013- def go_to_month_view(self):
1014- """Open the month view.
1015-
1016- :return: The Month View page.
1017-
1018- """
1019- month_tab = self.select_single('Tab', objectName='monthTab')
1020- if not month_tab.visible:
1021- self.switch_to_tab('monthTab')
1022- else:
1023- logger.debug('The month View page is already opened.')
1024- return self.get_month_view(month_tab)
1025-
1026- @autopilot.logging.log_action(logger.info)
1027- def go_to_week_view(self):
1028- """Open the week view.
1029-
1030- :return: The Week View page.
1031-
1032- """
1033- week_tab = self.select_single('Tab', objectName='weekTab')
1034- if not week_tab.visible:
1035- self.switch_to_tab('weekTab')
1036- else:
1037- logger.debug('The week View page is already opened.')
1038- return self.get_week_view(week_tab)
1039-
1040- @autopilot.logging.log_action(logger.info)
1041- def go_to_year_view(self):
1042- """Open the year view.
1043-
1044- :return: The Year View page.
1045-
1046- """
1047- year_tab = self.select_single('Tab', objectName='yearTab')
1048- if not year_tab.visible:
1049- self.switch_to_tab('yearTab')
1050- else:
1051- logger.debug('The Year View page is already opened.')
1052- return self.get_year_view(year_tab)
1053-
1054- @autopilot.logging.log_action(logger.info)
1055- def go_to_day_view(self):
1056- """Open the day view.
1057-
1058- :return: The Day View page.
1059-
1060- """
1061- day_tab = self.select_single('Tab', objectName='dayTab')
1062- if not day_tab.visible:
1063- self.switch_to_tab('dayTab')
1064- else:
1065- logger.debug('The Day View page is already opened.')
1066- return self.get_day_view(day_tab)
1067-
1068- @autopilot.logging.log_action(logger.info)
1069- def go_to_new_event(self):
1070- """Open the page to add a new event.
1071-
1072- :return: The New Event page.
1073-
1074- """
1075- header = self.get_header()
1076- header.click_action_button('neweventbutton')
1077- return self.select_single(NewEvent, objectName='newEventPage')
1078-
1079- def set_picker(self, field, mode, value):
1080- # open picker
1081- self.pointing_device.click_object(field)
1082- # valid options are date or time; assume date if invalid/no option
1083- if mode == 'time':
1084- mode_value = 'Hours|Minutes'
1085- else:
1086- mode_value = 'Years|Months|Days'
1087- picker = self.wait_select_single(
1088- ubuntuuitoolkit.pickers.DatePicker, mode=mode_value, visible=True)
1089- if mode_value == 'Hours|Minutes':
1090- picker.pick_time(value)
1091- else:
1092- picker.pick_date(value)
1093- # close picker
1094- self.pointing_device.click_object(field)
1095-
1096- def get_event_view(self, parent_object=None):
1097- if parent_object is None:
1098- parent_object = self
1099- return parent_object.select_single("EventView")
1100-
1101- def get_event_details(self, parent_object=None):
1102- if parent_object is None:
1103- parent_object = self
1104- return parent_object.select_single(EventDetails,
1105- objectName='eventDetails')
1106-
1107- def get_month_view(self, parent_object=None):
1108- if parent_object is None:
1109- parent_object = self
1110- return parent_object.select_single(MonthView,
1111- objectName='monthViewPage')
1112-
1113- def get_year_view(self, parent_object=None):
1114- if parent_object is None:
1115- parent_object = self
1116- return parent_object.select_single(YearView, objectName='yearViewPage')
1117-
1118- def get_day_view(self, parent_object=None):
1119- if parent_object is None:
1120- parent_object = self
1121- return parent_object.select_single(DayView, objectName='dayViewPage')
1122-
1123- def get_week_view(self, parent_object=None):
1124- if parent_object is None:
1125- parent_object = self
1126- return parent_object.select_single(WeekView, objectName='weekViewPage')
1127-
1128- def get_label_with_text(self, text, root=None):
1129- if root is None:
1130- root = self
1131- labels = root.select_many("Label", text=text)
1132- if (len(labels) > 0):
1133- return labels[0]
1134- else:
1135- return None
1136-
1137- def get_year(self, component):
1138- return int(component.wait_select_single(
1139- "Label", objectName="yearLabel").text)
1140-
1141- def get_month_name(self, component):
1142- return component.wait_select_single(
1143- "Label", objectName="monthLabel").text
1144-
1145- def safe_swipe_view(self, direction, view, date):
1146- """
1147- direction: direction to swip
1148- view: the view you are swiping against
1149- date: a function object of the view
1150- """
1151- timeout = 0
1152- before = date
1153- # try up to 3 times to swipe
1154- while timeout < 3 and date == before:
1155- self._swipe(direction, view)
1156- # check for up to 3 seconds after swipe for view
1157- # to have changed before trying again
1158- for x in range(0, 3):
1159- if date != before:
1160- break
1161- sleep(1)
1162- timeout += 1
1163-
1164- def swipe_view(self, direction, view, x_pad=0.15):
1165- """Swipe the given view to left or right.
1166-
1167- Args:
1168- direction: if 1 it swipes from right to left, if -1 from
1169- left right.
1170-
1171- """
1172-
1173- start = (-direction * x_pad) % 1
1174- stop = (direction * x_pad) % 1
1175-
1176- y_line = view.globalRect[1] + view.globalRect[3] / 2
1177- x_start = view.globalRect[0] + view.globalRect[2] * start
1178- x_stop = view.globalRect[0] + view.globalRect[2] * stop
1179-
1180- self.pointing_device.drag(x_start, y_line, x_stop, y_line)
1181-
1182- def to_local_date(self, date):
1183- utc = date.replace(tzinfo=tz.tzutc())
1184- local = utc.astimezone(tz.tzlocal())
1185- return local
1186-
1187-
1188-class YearView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
1189-
1190- """Autopilot helper for the Year View page."""
1191-
1192-
1193-class WeekView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
1194-
1195- """Autopilot helper for the Week View page."""
1196-
1197-
1198-class MonthView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
1199-
1200- """Autopilot helper for the Year View page."""
1201-
1202-
1203-class DayView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
1204-
1205- """Autopilot helper for the Day View page."""
1206-
1207- @autopilot.logging.log_action(logger.info)
1208- def get_events(self, visible=True):
1209- """Return the events for this day.
1210-
1211- :param visible: toggles filtering for only visible events
1212- :return: A list with the events. Each event is a tuple with name, start
1213- time and end time.
1214-
1215- """
1216- event_bubbles = self._get_selected_day_event_bubbles()
1217-
1218- # sort by y, x
1219- event_bubbles = sorted(
1220- event_bubbles,
1221- key=lambda bubble: (bubble.globalRect.y, bubble.globalRect.x))
1222-
1223- events = []
1224- for event in event_bubbles:
1225- # Event-bubbles objects are recycled, only show visible ones.
1226- if visible:
1227- if event.visible:
1228- events.append(event.get_information())
1229- else:
1230- events.append(event.get_information())
1231-
1232- return events
1233-
1234- @autopilot.logging.log_action(logger.info)
1235- def get_event(self, event_name, visible=True):
1236- """Return a specific event from current day.
1237-
1238- :param visible: toggles filtering for only visible events
1239- :param event_name: the name of the event.
1240- If more than one name matches, return the first matching event
1241- :return: The event object
1242- """
1243- event_bubbles = self._get_selected_day_event_bubbles()
1244-
1245- # sort by y, x
1246- event_bubbles = sorted(
1247- event_bubbles,
1248- key=lambda bubble: (bubble.globalRect.y, bubble.globalRect.x))
1249-
1250- for event in event_bubbles:
1251- # Event-bubbles objects are recycled, only show visible ones.
1252- if event.get_name() == event_name:
1253- if (visible and event.visible) or not visible:
1254- matched_event = event
1255- return matched_event
1256-
1257- raise CalendarException('No event found for %s' % event_name)
1258-
1259- def _get_current_day_component(self):
1260- components = self.select_many('TimeLineBaseComponent')
1261- for component in components:
1262- if (self.currentDay.datetime.date() ==
1263- component.startDay.datetime.date()):
1264- return component
1265- else:
1266- raise CalendarException(
1267- 'Could not find the current day component.')
1268-
1269- def _get_selected_day_event_bubbles(self):
1270- selected_day = self._get_current_day_component()
1271- return self._get_event_bubbles(selected_day)
1272-
1273- def _get_event_bubbles(self, selected_day):
1274- try:
1275- loading_spinner = selected_day.select_single("ActivityIndicator")
1276- loading_spinner.running.wait_for(False)
1277- except:
1278- pass
1279- event_bubbles = selected_day.select_many(EventBubble)
1280- return event_bubbles
1281-
1282- def _remove_duplicate_events(self, separator_id, event_bubbles):
1283- events = []
1284- for bubble in event_bubbles:
1285- if bubble.id > separator_id:
1286- events.append(bubble)
1287-
1288- return events
1289-
1290- @autopilot.logging.log_action(logger.info)
1291- def open_event(self, name):
1292- """Open an event.
1293-
1294- :param name: The name of the event to open.
1295- :return: The Event Details page.
1296-
1297- """
1298- return self.get_event(name).open_event()
1299-
1300- @autopilot.logging.log_action(logger.info)
1301- def delete_event(self, name):
1302- """Delete an event.
1303-
1304- :param name: The name of the event to delete.
1305- :return: The Day View page.
1306-
1307- """
1308- event_details_page = self.open_event(name)
1309- return event_details_page.delete()
1310-
1311- @autopilot.logging.log_action(logger.info)
1312- def edit_event(self, name):
1313- """Edit an event.
1314- :param name:The name of event to edit
1315- :return : event details page. """
1316- event_details_page = self.open_event(name)
1317- return event_details_page.edit()
1318-
1319- @autopilot.logging.log_action(logger.info)
1320- def get_day_header(self, day=None):
1321- """Return the dayheader for a given day. If no day is given,
1322- return the current day.
1323-
1324- :param day: A datetime object matching the header
1325- :return: The day header object
1326- """
1327- if day:
1328- headers = self.select_many('TimeLineHeaderComponent')
1329- for header in headers:
1330- if header.startDay.datetime == day:
1331- day_header = header
1332- break
1333- else:
1334- # just grab the current day
1335- day_header = self.wait_select_single(
1336- 'TimeLineHeaderComponent', isCurrentItem=True)
1337-
1338- if not(day_header):
1339- raise CalendarException('Day Header not found for %s' % day)
1340- return day_header
1341-
1342-
1343-class EventBubble(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
1344-
1345- """Autopiot helper for the Event Bubble items."""
1346-
1347- def get_information(self):
1348- """Return a tuple with the name, start time and end time."""
1349- name = self.get_name()
1350- start_time, end_time = self._get_start_and_end_time()
1351- return name, start_time, end_time
1352-
1353- def _get_start_and_end_time(self):
1354- """Return a tuple with the start time and end time."""
1355- time_label = self.select_single('Label', objectName='timeLabel')
1356- start_time, end_time = time_label.text.split(' - ')
1357- return start_time, end_time
1358-
1359- def get_name(self):
1360- """Return the event name."""
1361- title_label = self.select_single('Label', objectName='titleLabel')
1362- return title_label.text
1363-
1364- @autopilot.logging.log_action(logger.info)
1365- def open_event(self):
1366- """Open the event.
1367-
1368- :return: The Event Details page.
1369-
1370- """
1371- # If there are too many events, the center of the bubble
1372- # might be hidden by another event. Click the left side of the
1373- # bubble.
1374- left = self.globalRect.x + 5
1375- center_y = self.globalRect.y + self.globalRect.height // 2
1376- self.pointing_device.move(left, center_y)
1377- self.pointing_device.click()
1378- return self.get_root_instance().select_single(
1379- EventDetails, objectName='eventDetails')
1380-
1381-
1382-# override toolkit helper to
1383-# workaround bug https://bugs.launchpad.net/ubuntu-ui-toolkit/+bug/1343916
1384-class QQuickFlickable(ubuntuuitoolkit.QQuickFlickable):
1385-
1386- def _slow_drag(self, start_x, stop_x, start_y, stop_y):
1387- rate = (self.flickDeceleration + 250) / 350
1388- self.pointing_device.drag(start_x, start_y, stop_x, stop_y, rate=rate)
1389- self.pointing_device.click()
1390-
1391-
1392-class NewEvent(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
1393-
1394- """Autopilot helper for the New Event page."""
1395-
1396- @autopilot.logging.log_action(logger.info)
1397- def add_event(self, event_information):
1398- """Add a new event.
1399-
1400- :param event_information: Values of the event to fill the form.
1401- :type event_information: data object with the attributes name,
1402- description, location and guests.
1403- :return: The Day View page.
1404-
1405- """
1406- self._fill_form(event_information)
1407- self._save()
1408- return self.get_root_instance().select_single(
1409- DayView, objectName='dayViewPage')
1410-
1411- @autopilot.logging.log_action(logger.debug)
1412- def _fill_form(self, event_information):
1413- """Fill the add event form.
1414-
1415- :param event_information: Values of the event to fill the form.
1416- :type event_information: data object with the attributes
1417- calendar, name, description, location and guests.
1418-
1419- """
1420- # TODO fill start date and end date, is all day event, recurrence and
1421- # reminders. --elopio - 2014-06-26
1422- if event_information.calendar is not None:
1423- self._select_calendar(event_information.calendar)
1424- if event_information.name is not None:
1425- self._fill_name(event_information.name)
1426- if event_information.description is not None:
1427- self._fill_description(event_information.description)
1428- if event_information.location is not None:
1429- self._fill_location(event_information.location)
1430- if event_information.guests is not None:
1431- self._fill_guests(event_information.guests)
1432-
1433- def _fill_name(self, value):
1434- self._ensure_entry_field_visible_and_write('newEventName', value)
1435-
1436- def _ensure_entry_field_visible_and_write(self, object_name, value):
1437- name_text_field = self._get_new_event_entry_field(object_name)
1438- self._ensure_visible_and_write(name_text_field, value)
1439-
1440- def _get_new_event_entry_field(self, object_name):
1441- return self.select_single(NewEventEntryField, objectName=object_name)
1442-
1443- def _ensure_visible_and_write(self, text_field, value):
1444- text_field.swipe_into_view()
1445- text_field.write(value)
1446-
1447- def _fill_description(self, value):
1448- description_text_area = self._get_description_text_area()
1449- self._ensure_visible_and_write(description_text_area, value)
1450-
1451- def _get_description_text_area(self):
1452- return self.select_single(
1453- ubuntuuitoolkit.TextArea, objectName='eventDescriptionInput')
1454-
1455- def _fill_location(self, value):
1456- self._ensure_entry_field_visible_and_write('eventLocationInput', value)
1457-
1458- def _fill_guests(self, guests):
1459- guests_btn = self.select_single('Button', objectName='addGuestButton')
1460- main_view = self.get_root_instance().select_single(MainView)
1461-
1462- for guest in guests:
1463- self.pointing_device.click_object(guests_btn)
1464- guest_input = main_view.select_single(
1465- NewEventEntryField, objectName='contactPopoverInput')
1466- contacts = main_view.select_single(ubuntuuitoolkit.QQuickListView,
1467- objectName='contactPopoverList')
1468- guest_input.write(guest)
1469-
1470- try:
1471- contacts.click_element('contactPopoverList0')
1472- except ubuntuuitoolkit.ToolkitException:
1473- raise CalendarException('No guest found with name %s' % guest)
1474-
1475- def _select_calendar(self, calendar):
1476- self._get_calendar().select_option('Label', text=calendar)
1477-
1478- def _get_calendar(self):
1479- return self.select_single(ubuntuuitoolkit.OptionSelector,
1480- objectName="calendarsOption")
1481-
1482- def _get_guests(self):
1483- guestlist = self.select_single('QQuickColumn', objectName='guestList')
1484- guests = guestlist.select_many('Standard')
1485- guest_names = []
1486- for guest in guests:
1487- guest_names.append(guest.text)
1488- return guest_names
1489-
1490- def _get_form_values(self):
1491- # TODO get start date and end date, is all day event, recurrence and
1492- # reminders. --elopio - 2014-06-26
1493- calendar = self._get_calendar().get_current_label().text
1494- name = self._get_new_event_entry_field('newEventName').text
1495- description = self._get_description_text_area().text
1496- location = self._get_new_event_entry_field('eventLocationInput').text
1497- guests = self._get_guests()
1498- return data.Event(calendar, name, description, location, guests)
1499-
1500- @autopilot.logging.log_action(logger.info)
1501- def _save(self):
1502- """Save the new event."""
1503- root = self.get_root_instance()
1504- header = root.select_single(MainView).get_header()
1505- header.click_action_button('save')
1506-
1507-
1508-class NewEventEntryField(ubuntuuitoolkit.TextField):
1509-
1510- """Autopilot helper for the NewEventEntryField component."""
1511-
1512-
1513-class EventDetails(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
1514-
1515- """Autopilot helper for the Event Details page."""
1516-
1517- @autopilot.logging.log_action(logger.debug)
1518- def delete(self):
1519- """Click the delete button.
1520-
1521- :return: The Day View page.
1522-
1523- """
1524- root = self.get_root_instance()
1525- header = root.select_single(MainView).get_header()
1526- header.click_action_button('delete')
1527-
1528- delete_confirmation_dialog = root.select_single(
1529- DeleteConfirmationDialog, objectName='deleteConfirmationDialog')
1530- delete_confirmation_dialog.confirm_deletion()
1531-
1532- return root.select_single(DayView, objectName='dayViewPage')
1533-
1534- @autopilot.logging.log_action(logger.debug)
1535- def edit(self):
1536- """Click the Edit button.
1537-
1538- :return: The Edit page.
1539-
1540- """
1541- root = self.get_root_instance()
1542- header = root.select_single(MainView).get_header()
1543- header.click_action_button('edit')
1544- return root.select_single(NewEvent, objectName='newEventPage')
1545-
1546- def get_event_information(self):
1547- """Return the information of the event."""
1548- calendar = self._get_calendar()
1549- name = self._get_name()
1550- description = self._get_description()
1551- location = self._get_location()
1552- guests = self._get_guests()
1553- return data.Event(calendar, name, description, location, guests)
1554-
1555- def _get_calendar(self):
1556- return self._get_label_text('calendarName')
1557-
1558- def _get_name(self):
1559- return self._get_label_text('titleLabel')
1560-
1561- def _get_label_text(self, object_name):
1562- return self.select_single('Label', objectName=object_name).text
1563-
1564- def _get_description(self):
1565- return self._get_label_text('descriptionLabel')
1566-
1567- def _get_location(self):
1568- return self._get_label_text('locationLabel')
1569-
1570- def _get_guests(self):
1571- guests = []
1572- contacts_list = self.select_single(
1573- 'QQuickColumn', objectName='contactList')
1574- guest_labels = contacts_list.select_many('Label')
1575- for label in guest_labels:
1576- guests.append(label.text)
1577-
1578- return guests
1579-
1580-
1581-class DeleteConfirmationDialog(
1582- ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase):
1583-
1584- """Autopilot helper for the Delete Confirmation dialog."""
1585-
1586- @autopilot.logging.log_action(logger.debug)
1587- def confirm_deletion(self):
1588- """Confirm the deletion of the event."""
1589- delete_button = self.select_single(
1590- 'Button', objectName='deleteEventButton')
1591- self.pointing_device.click_object(delete_button)
1592
1593=== added file 'tests/autopilot/calendar_app/tests/CMakeLists.txt'
1594--- tests/autopilot/calendar_app/tests/CMakeLists.txt 1970-01-01 00:00:00 +0000
1595+++ tests/autopilot/calendar_app/tests/CMakeLists.txt 2014-09-05 01:20:41 +0000
1596@@ -0,0 +1,6 @@
1597+# make the test files visible on qtcreator
1598+file(GLOB PYTHON_TEST_FILES
1599+ RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
1600+ *.py)
1601+
1602+add_custom_target(com_ubuntu_calendar_PYTHONTESTFiles ALL SOURCES ${PYTHON_TEST_FILES})
1603
1604=== modified file 'tests/autopilot/calendar_app/tests/__init__.py'
1605--- tests/autopilot/calendar_app/tests/__init__.py 2014-08-02 19:21:55 +0000
1606+++ tests/autopilot/calendar_app/tests/__init__.py 2014-09-05 01:20:41 +0000
1607@@ -21,10 +21,9 @@
1608 import logging
1609
1610 import fixtures
1611-from calendar_app import emulators
1612+import calendar_app
1613+from address_book_service_testability import fixture_setup
1614
1615-from autopilot.input import Mouse, Touch, Pointer
1616-from autopilot.platform import model
1617 from autopilot.testcase import AutopilotTestCase
1618 from autopilot import logging as autopilot_logging
1619
1620@@ -37,19 +36,15 @@
1621 logger = logging.getLogger(__name__)
1622
1623
1624-class CalendarTestCase(AutopilotTestCase):
1625+class BaseTestCaseWithPatchedHome(AutopilotTestCase):
1626
1627 """A common test case class that provides several useful methods for
1628 calendar-app tests.
1629
1630 """
1631- if model() == 'Desktop':
1632- scenarios = [('with mouse', dict(input_device_class=Mouse))]
1633- else:
1634- scenarios = [('with touch', dict(input_device_class=Touch))]
1635
1636 local_location = os.path.dirname(os.path.dirname(os.getcwd()))
1637- local_location_qml = local_location + "/calendar.qml"
1638+ local_location_qml = os.path.join(local_location, 'calendar.qml')
1639 installed_location_qml = "/usr/share/calendar-app/calendar.qml"
1640
1641 def get_launcher_and_type(self):
1642@@ -65,18 +60,15 @@
1643 return launcher, test_type
1644
1645 def setUp(self):
1646- launcher, self.test_type = self.get_launcher_and_type()
1647+ super(BaseTestCaseWithPatchedHome, self).setUp()
1648+ self.launcher, self.test_type = self.get_launcher_and_type()
1649 self.home_dir = self._patch_home()
1650- self.pointing_device = Pointer(self.input_device_class.create())
1651- super(CalendarTestCase, self).setUp()
1652
1653 # Unset the current locale to ensure locale-specific data
1654 # (day and month names, first day of the week, …) doesn’t get
1655 # in the way of test expectations.
1656 self.useFixture(fixtures.EnvironmentVariable('LC_ALL', newvalue='C'))
1657
1658- self.app = launcher()
1659-
1660 @autopilot_logging.log_action(logger.info)
1661 def launch_test_local(self):
1662 return self.launch_test_application(
1663@@ -182,6 +174,34 @@
1664 logger.debug("Patched home to fake home directory %s" % temp_dir)
1665 return temp_dir
1666
1667- @property
1668- def main_view(self):
1669- return self.app.wait_select_single(emulators.MainView)
1670+
1671+class CalendarAppTestCase(BaseTestCaseWithPatchedHome):
1672+
1673+ """Base test case that launches the calendar-app."""
1674+
1675+ def setUp(self):
1676+ super(CalendarAppTestCase, self).setUp()
1677+ self.app = calendar_app.CalendarApp(self.launcher(), self.test_type)
1678+
1679+
1680+class CalendarAppTestCaseWithVcard(BaseTestCaseWithPatchedHome):
1681+
1682+ def setup_vcard(self):
1683+ if self.test_type is 'deb':
1684+ location = '/usr/lib/python3/dist-packages/calendar_app'
1685+ elif self.test_type is 'click':
1686+ location = os.path.dirname(os.path.dirname(os.getcwd()))
1687+ else:
1688+ location = os.path.join(
1689+ os.path.dirname(os.path.dirname(os.getcwd())),
1690+ 'tests/autopilot/calendar_app')
1691+ vcard = os.path.join(location, 'vcard.vcf')
1692+ logger.debug('Using vcard from %s', vcard)
1693+ contacts_backend = fixture_setup.AddressBookServiceDummyBackend(
1694+ vcard=vcard)
1695+ self.useFixture(contacts_backend)
1696+
1697+ def setUp(self):
1698+ super(CalendarAppTestCaseWithVcard, self).setUp()
1699+ self.setup_vcard()
1700+ self.app = calendar_app.CalendarApp(self.launcher(), self.test_type)
1701
1702=== modified file 'tests/autopilot/calendar_app/tests/test_custom_proxy_objects.py'
1703--- tests/autopilot/calendar_app/tests/test_custom_proxy_objects.py 2014-07-30 21:45:13 +0000
1704+++ tests/autopilot/calendar_app/tests/test_custom_proxy_objects.py 2014-09-05 01:20:41 +0000
1705@@ -15,24 +15,15 @@
1706 # along with this program. If not, see <http://www.gnu.org/licenses/>.
1707
1708 from calendar_app import data, tests
1709-from address_book_service_testability import fixture_setup
1710-
1711-
1712-class NewEventFormTestCase(tests.CalendarTestCase):
1713-
1714- # TODO once address_book_service_testability is packaged, remove
1715- # packing the modules as part of testcase
1716-
1717- def setUp(self):
1718- contacts_backend = fixture_setup.AddressBookServiceDummyBackend()
1719- self.useFixture(contacts_backend)
1720- super(NewEventFormTestCase, self).setUp()
1721+
1722+
1723+class NewEventFormTestCase(tests.CalendarAppTestCaseWithVcard):
1724
1725 def test_fill_form(self):
1726 """Test that the form can be filled with event information."""
1727 test_event = data.Event.make_unique(unique_id='test uuid')
1728
1729- new_event_page = new_event_page = self.main_view.go_to_new_event()
1730+ new_event_page = self.app.main_view.go_to_new_event()
1731 new_event_page._fill_form(test_event)
1732
1733 form_values = new_event_page._get_form_values()
1734
1735=== modified file 'tests/autopilot/calendar_app/tests/test_dayview.py'
1736--- tests/autopilot/calendar_app/tests/test_dayview.py 2014-07-02 18:02:21 +0000
1737+++ tests/autopilot/calendar_app/tests/test_dayview.py 2014-09-05 01:20:41 +0000
1738@@ -29,16 +29,14 @@
1739 from autopilot.matchers import Eventually
1740 from testtools.matchers import Equals, NotEquals
1741
1742-from calendar_app.tests import CalendarTestCase
1743-
1744-
1745-class TestDayView(CalendarTestCase):
1746+from calendar_app.tests import CalendarAppTestCase
1747+
1748+
1749+class TestDayView(CalendarAppTestCase):
1750
1751 def setUp(self):
1752 super(TestDayView, self).setUp()
1753- self.assertThat(self.main_view.visible, Eventually(Equals(True)))
1754-
1755- self.day_view = self.main_view.go_to_day_view()
1756+ self.day_view = self.app.main_view.go_to_day_view()
1757
1758 def test_current_month_and_year_is_selected(self):
1759 """By default, the day view shows the current month and year."""
1760@@ -48,10 +46,10 @@
1761 expected_year = now.year
1762 expected_month_name = now.strftime("%B")
1763
1764- self.assertThat(self.main_view.get_year(self.day_view),
1765+ self.assertThat(self.app.main_view.get_year(self.day_view),
1766 Equals(expected_year))
1767
1768- self.assertThat(self.main_view.get_month_name(self.day_view),
1769+ self.assertThat(self.app.main_view.get_month_name(self.day_view),
1770 Equals(expected_month_name))
1771
1772 def test_show_current_days(self):
1773@@ -83,7 +81,7 @@
1774 yesterday_header = self.day_view.get_day_header(yesterday)
1775
1776 self.assertThat(yesterday_header.isCurrentItem, Equals(False))
1777- self.pointing_device.click_object(yesterday_header)
1778+ self.app.pointing_device.click_object(yesterday_header)
1779 self.assertThat(yesterday_header.isCurrentItem,
1780 Eventually(Equals(True)))
1781
1782@@ -92,7 +90,7 @@
1783 tomorrow_header = self.day_view.get_day_header(tomorrow)
1784
1785 self.assertThat(tomorrow_header.isCurrentItem, Equals(False))
1786- self.pointing_device.click_object(tomorrow_header)
1787+ self.app.pointing_device.click_object(tomorrow_header)
1788 self.assertThat(tomorrow_header.isCurrentItem,
1789 Eventually(Equals(True)))
1790
1791@@ -110,7 +108,7 @@
1792 for i in range(1, 5):
1793 # prevent timing issues with swiping
1794 old_day = self.day_view.currentDay.datetime
1795- self.main_view.swipe_view(direction, self.day_view)
1796+ self.app.main_view.swipe_view(direction, self.day_view)
1797 self.assertThat(lambda: self.day_view.currentDay.datetime,
1798 Eventually(NotEquals(old_day)))
1799
1800
1801=== modified file 'tests/autopilot/calendar_app/tests/test_monthview.py'
1802--- tests/autopilot/calendar_app/tests/test_monthview.py 2014-07-01 20:26:51 +0000
1803+++ tests/autopilot/calendar_app/tests/test_monthview.py 2014-09-05 01:20:41 +0000
1804@@ -23,35 +23,33 @@
1805
1806 import math
1807
1808-from calendar_app.tests import CalendarTestCase
1809+from calendar_app.tests import CalendarAppTestCase
1810
1811 from datetime import datetime
1812 from dateutil.relativedelta import relativedelta
1813
1814
1815-class TestMonthView(CalendarTestCase):
1816+class TestMonthView(CalendarAppTestCase):
1817
1818 def setUp(self):
1819 super(TestMonthView, self).setUp()
1820- self.assertThat(self.main_view.visible, Eventually(Equals(True)))
1821-
1822- self.month_view = self.main_view.go_to_month_view()
1823+ self.month_view = self.app.main_view.go_to_month_view()
1824
1825 def _change_month(self, delta):
1826- month_view = self.main_view.get_month_view()
1827+ month_view = self.app.main_view.get_month_view()
1828 direction = int(math.copysign(1, delta))
1829
1830 for _ in range(abs(delta)):
1831- before = self.main_view.to_local_date(
1832+ before = self.app.main_view.to_local_date(
1833 month_view.currentMonth.datetime)
1834
1835 # prevent timing issues with swiping
1836- old_month = self.main_view.to_local_date(
1837+ old_month = self.app.main_view.to_local_date(
1838 month_view.currentMonth.datetime)
1839
1840- self.main_view.swipe_view(direction, month_view)
1841+ self.app.main_view.swipe_view(direction, month_view)
1842
1843- month_after = self.main_view.to_local_date(
1844+ month_after = self.app.main_view.to_local_date(
1845 month_view.currentMonth.datetime)
1846
1847 self.assertThat(lambda: month_after,
1848@@ -67,7 +65,7 @@
1849 Eventually(Equals(after.year)))
1850
1851 def _assert_today(self):
1852- local = self.main_view.to_local_date(
1853+ local = self.app.main_view.to_local_date(
1854 self.month_view.currentMonth.datetime)
1855 today = datetime.now()
1856
1857@@ -82,7 +80,7 @@
1858 self._assert_today()
1859
1860 self._change_month(delta)
1861- header = self.main_view.get_header()
1862+ header = self.app.main_view.get_header()
1863 header.click_action_button('todaybutton')
1864
1865 self._assert_today()
1866
1867=== modified file 'tests/autopilot/calendar_app/tests/test_new_event.py'
1868--- tests/autopilot/calendar_app/tests/test_new_event.py 2014-08-23 02:31:49 +0000
1869+++ tests/autopilot/calendar_app/tests/test_new_event.py 2014-09-05 01:20:41 +0000
1870@@ -21,27 +21,15 @@
1871 import logging
1872
1873 from autopilot.matchers import Eventually
1874-from testtools.matchers import Equals, NotEquals
1875-from unittest import skipUnless
1876-from autopilot.platform import model
1877+from testtools.matchers import Equals
1878
1879 from calendar_app import data
1880-from calendar_app.tests import CalendarTestCase
1881-from address_book_service_testability import fixture_setup
1882-
1883+from calendar_app.tests import CalendarAppTestCaseWithVcard
1884
1885 logger = logging.getLogger(__name__)
1886
1887
1888-class NewEventTestCase(CalendarTestCase):
1889-
1890- # TODO once address_book_service_testability is packaged, remove
1891- # packing the modules as part of testcase
1892-
1893- def setUp(self):
1894- contacts_backend = fixture_setup.AddressBookServiceDummyBackend()
1895- self.useFixture(contacts_backend)
1896- super(NewEventTestCase, self).setUp()
1897+class NewEventTestCase(CalendarAppTestCaseWithVcard):
1898
1899 # TODO add tests for events in the future and in the past, all day event,
1900 # event with recurrence and event with reminders.
1901@@ -52,57 +40,72 @@
1902
1903 def _try_delete_event(self, event_name):
1904 try:
1905- day_view = self.main_view.go_to_day_view()
1906+ day_view = self.app.main_view.go_to_day_view()
1907 day_view.delete_event(event_name)
1908 except Exception as exception:
1909 logger.warn(str(exception))
1910
1911 def _add_event(self):
1912 test_event = data.Event.make_unique()
1913- day_view = self.main_view.go_to_day_view()
1914- start_num_events = len(day_view.get_events())
1915-
1916- new_event_page = self.main_view.go_to_new_event()
1917+ new_event_page = self.app.main_view.go_to_new_event()
1918 new_event_page.add_event(test_event)
1919
1920- day_view = self.main_view.get_day_view()
1921-
1922- # Wait a bit for the event to be added.
1923- self.assertThat(lambda: len(day_view.get_events()),
1924- Eventually(Equals(start_num_events + 1)))
1925-
1926- return day_view, test_event
1927+ self.assertThat(lambda: self._event_exists(test_event.name),
1928+ Eventually(Equals(True)))
1929+
1930+ return test_event
1931
1932 def _edit_event(self, event_name):
1933 test_event = data.Event.make_unique()
1934- day_view = self.main_view.go_to_day_view()
1935+ day_view = self.app.main_view.go_to_day_view()
1936
1937 new_event_page = day_view.edit_event(event_name)
1938
1939 new_event_page.add_event(test_event)
1940- return day_view, test_event
1941+ return test_event
1942
1943 def _event_exists(self, event_name):
1944 try:
1945- day_view = self.main_view.go_to_day_view()
1946+ day_view = self.app.main_view.go_to_day_view()
1947 day_view.get_event(event_name, True)
1948 except Exception:
1949 return False
1950 return True
1951
1952+ # TODO write helpers to check all of the default values
1953+ # then expand the asserts to ensure defaults are correct
1954+ def test_new_event_must_start_with_default_values(self):
1955+ """Test adding a new event default values
1956+
1957+ Start Date: today Start Time: next half hour increment
1958+ End Date: today End Time: 30 mins after start time
1959+ Calendar: Personal
1960+ All Day Event: unchecked
1961+ Event Name: blank, selected
1962+ Description: blank
1963+ Location: none
1964+ Guests: none
1965+ This happens: Once
1966+ Remind me: No Reminder
1967+ """
1968+
1969+ new_event_page = self.app.main_view.go_to_new_event()
1970+ self.assertThat(new_event_page.get_calendar_name(), Equals('Personal'))
1971+ self.assertThat(new_event_page.get_event_name(), Equals(''))
1972+ self.assertThat(new_event_page.get_description_text(), Equals(''))
1973+ self.assertThat(new_event_page.get_location_name(), Equals(''))
1974+
1975 def test_add_new_event_with_default_values(self):
1976 """Test adding a new event with the default values.
1977
1978 The event must be created on the currently selected date,
1979 with an end time, without recurrence and without reminders."""
1980
1981- day_view, test_event = self._add_event()
1982+ test_event = self._add_event()
1983
1984 self.addCleanup(self._try_delete_event, test_event.name)
1985
1986- event_bubble = lambda: day_view.get_event(test_event.name)
1987- self.assertThat(event_bubble, Eventually(NotEquals(None)))
1988-
1989+ day_view = self.app.main_view.go_to_day_view()
1990 event_details_page = day_view.open_event(test_event.name)
1991
1992 self.assertEqual(test_event,
1993@@ -110,22 +113,22 @@
1994
1995 def test_delete_event_must_remove_it_from_day_view(self):
1996 """Test deleting an event must no longer show it on the day view."""
1997- day_view, test_event = self._add_event()
1998+ test_event = self._add_event()
1999
2000+ day_view = self.app.main_view.go_to_day_view()
2001 day_view.delete_event(test_event.name)
2002
2003 self.assertThat(lambda: self._event_exists(test_event.name),
2004 Eventually(Equals(False)))
2005
2006- @skipUnless(model() == 'Desktop', 'skipping, bug 1359167')
2007 def test_edit_event_with_default_values(self):
2008 """Test editing an event change unique values of an event."""
2009
2010- day_view, original_event = self._add_event()
2011- day_view, edited_event = self._edit_event(original_event.name)
2012+ original_event = self._add_event()
2013+ edited_event = self._edit_event(original_event.name)
2014 self.addCleanup(self._try_delete_event, edited_event.name)
2015
2016- event_details_page = self.main_view.get_event_details()
2017+ event_details_page = self.app.main_view.get_event_details()
2018
2019 self.assertEqual(edited_event,
2020 event_details_page.get_event_information())
2021
2022=== modified file 'tests/autopilot/calendar_app/tests/test_weekview.py'
2023--- tests/autopilot/calendar_app/tests/test_weekview.py 2014-07-01 18:21:14 +0000
2024+++ tests/autopilot/calendar_app/tests/test_weekview.py 2014-09-05 01:20:41 +0000
2025@@ -28,33 +28,31 @@
2026 from autopilot.matchers import Eventually
2027 from testtools.matchers import Equals, NotEquals
2028
2029-from calendar_app.tests import CalendarTestCase
2030+from calendar_app.tests import CalendarAppTestCase
2031 import logging
2032
2033 logger = logging.getLogger(__name__)
2034
2035
2036-class TestWeekView(CalendarTestCase):
2037+class TestWeekView(CalendarAppTestCase):
2038
2039 def setUp(self):
2040 super(TestWeekView, self).setUp()
2041- self.assertThat(self.main_view.visible, Eventually(Equals(True)))
2042-
2043- self.week_view = self.main_view.go_to_week_view()
2044+ self.week_view = self.app.main_view.go_to_week_view()
2045
2046 def _change_week(self, direction):
2047 first_dow = self._get_first_day_of_week()
2048
2049 # prevent timing issues with swiping
2050- old_day = self.main_view.to_local_date(
2051+ old_day = self.app.main_view.to_local_date(
2052 self.week_view.dayStart.datetime)
2053- self.main_view.swipe_view(direction, self.week_view)
2054+ self.app.main_view.swipe_view(direction, self.week_view)
2055 self.assertThat(lambda:
2056- self.main_view.to_local_date(
2057+ self.app.main_view.to_local_date(
2058 self.week_view.dayStart.datetime),
2059 Eventually(NotEquals(old_day)))
2060
2061- new_day_start = self.main_view.to_local_date(
2062+ new_day_start = self.app.main_view.to_local_date(
2063 self.week_view.dayStart.datetime)
2064
2065 expected_day_start = first_dow + datetime.timedelta(
2066@@ -83,15 +81,16 @@
2067 return sorteddays
2068
2069 def _get_date_label_headers(self):
2070- header = self.main_view.select_single(objectName="weekHeader")
2071+ header = self.app.main_view.select_single(objectName="weekHeader")
2072 timeline = header.select_single("TimeLineHeaderComponent",
2073 isCurrentItem=True)
2074 dateLabels = timeline.select_many("Label", objectName="dateLabel")
2075 return dateLabels
2076
2077 def _get_first_day_of_week(self):
2078- date = self.main_view.to_local_date(self.week_view.dayStart.datetime)
2079- firstDay = self.main_view.to_local_date(
2080+ date = self.app.main_view.to_local_date(
2081+ self.week_view.dayStart.datetime)
2082+ firstDay = self.app.main_view.to_local_date(
2083 self.week_view.firstDay.datetime)
2084
2085 # sunday
2086@@ -127,10 +126,10 @@
2087 expected_year = now.year
2088 expected_month_name = now.strftime("%B")
2089
2090- self.assertThat(self.main_view.get_year(self.week_view),
2091+ self.assertThat(self.app.main_view.get_year(self.week_view),
2092 Equals(expected_year))
2093
2094- self.assertThat(self.main_view.get_month_name(self.week_view),
2095+ self.assertThat(self.app.main_view.get_month_name(self.week_view),
2096 Equals(expected_month_name))
2097
2098 def test_current_week_is_selected(self):
2099@@ -173,12 +172,12 @@
2100 expected_year = first_day_date.year
2101
2102 days = self._get_days_of_week()
2103- day_to_select = self.main_view.get_label_with_text(days[0])
2104+ day_to_select = self.app.main_view.get_label_with_text(days[0])
2105
2106- self.pointing_device.click_object(day_to_select)
2107+ self.app.pointing_device.click_object(day_to_select)
2108
2109 # Check that the view changed from 'Week' to 'Day'
2110- day_view = self.main_view.get_day_view()
2111+ day_view = self.app.main_view.get_day_view()
2112 self.assertThat(day_view.visible, Eventually(Equals(True)))
2113
2114 # Check that the 'Day' view is on the correct/selected day.
2115
2116=== modified file 'tests/autopilot/calendar_app/tests/test_yearview.py'
2117--- tests/autopilot/calendar_app/tests/test_yearview.py 2014-07-01 20:06:00 +0000
2118+++ tests/autopilot/calendar_app/tests/test_yearview.py 2014-09-05 01:20:41 +0000
2119@@ -28,16 +28,14 @@
2120 from autopilot.matchers import Eventually
2121 from testtools.matchers import Equals, NotEquals
2122
2123-from calendar_app.tests import CalendarTestCase
2124-
2125-
2126-class TestYearView(CalendarTestCase):
2127+from calendar_app.tests import CalendarAppTestCase
2128+
2129+
2130+class TestYearView(CalendarAppTestCase):
2131
2132 def setUp(self):
2133 super(TestYearView, self).setUp()
2134- self.assertThat(self.main_view.visible, Eventually(Equals(True)))
2135-
2136- self.year_view = self.main_view.go_to_year_view()
2137+ self.year_view = self.app.main_view.go_to_year_view()
2138
2139 def _get_year_grid(self):
2140 return self.year_view.wait_select_single("QQuickGridView",
2141@@ -51,7 +49,7 @@
2142 current_year = self.year_view.currentYear
2143
2144 for i in range(1, how_many):
2145- self.main_view.swipe_view(direction, self.year_view)
2146+ self.app.main_view.swipe_view(direction, self.year_view)
2147
2148 self.assertThat(
2149 lambda: self.year_view.currentYear,
2150@@ -87,15 +85,15 @@
2151 months.sort(key=lambda month: month.currentMonth)
2152
2153 february = months[1]
2154- expected_month_name = self.main_view.get_month_name(february)
2155- expected_year = self.main_view.get_year(february)
2156+ expected_month_name = self.app.main_view.get_month_name(february)
2157+ expected_year = self.app.main_view.get_year(february)
2158
2159- self.pointing_device.click_object(february)
2160+ self.app.pointing_device.click_object(february)
2161
2162 self.assertThat(
2163- self.main_view.get_month_view, Eventually(NotEquals(None)))
2164+ self.app.main_view.get_month_view, Eventually(NotEquals(None)))
2165
2166- month_view = self.main_view.get_month_view()
2167+ month_view = self.app.main_view.get_month_view()
2168 self.assertThat(month_view.visible, Eventually(Equals(True)))
2169
2170 selected_month = month_view.select_single("MonthComponent",
2171@@ -103,10 +101,10 @@
2172
2173 self.assertThat(selected_month, NotEquals(None))
2174
2175- self.assertThat(self.main_view.get_year(selected_month),
2176+ self.assertThat(self.app.main_view.get_year(selected_month),
2177 Equals(expected_year))
2178
2179- self.assertThat(self.main_view.get_month_name(selected_month),
2180+ self.assertThat(self.app.main_view.get_month_name(selected_month),
2181 Equals(expected_month_name))
2182
2183 def test_current_day_is_selected(self):
2184
2185=== added file 'tests/autopilot/calendar_app/vcard.vcf'
2186--- tests/autopilot/calendar_app/vcard.vcf 1970-01-01 00:00:00 +0000
2187+++ tests/autopilot/calendar_app/vcard.vcf 2014-09-05 01:20:41 +0000
2188@@ -0,0 +1,6 @@
2189+BEGIN:VCARD
2190+VERSION:3.0
2191+N:User;UX;
2192+FN:UX User
2193+TEL:3333333
2194+END:VCARD

Subscribers

People subscribed via source and target branches

to status/vote changes: