Merge lp:~om26er/address-book-app/abook_navigation_favorites into lp:address-book-app
- abook_navigation_favorites
- Merge into trunk
Status: | Work in progress |
---|---|
Proposed branch: | lp:~om26er/address-book-app/abook_navigation_favorites |
Merge into: | lp:address-book-app |
Prerequisite: | lp:~renatofilho/address-book-app/new-favorite-list |
Diff against target: |
726 lines (+446/-35) 15 files modified
src/imports/ContactView/ContactDetailFavoriteView.qml (+1/-0) src/imports/Ubuntu/Contacts/ContactListView.qml (+2/-0) tests/autopilot/address_book_app/emulators/__init__.py (+12/-0) tests/autopilot/address_book_app/emulators/contact_list_page.py (+145/-26) tests/autopilot/address_book_app/emulators/contact_view.py (+57/-0) tests/autopilot/address_book_app/emulators/main_window.py (+27/-3) tests/autopilot/address_book_app/helpers.py (+74/-0) tests/autopilot/address_book_app/tests/__init__.py (+17/-6) tests/autopilot/address_book_app/tests/test_add_contact.py (+4/-0) tests/autopilot/address_book_app/tests/test_contactlist.py (+4/-0) tests/autopilot/address_book_app/tests/test_delete_contact.py (+1/-0) tests/autopilot/address_book_app/tests/test_edit_contact.py (+4/-0) tests/autopilot/address_book_app/tests/test_favorites.py (+96/-0) tests/autopilot/address_book_app/tests/test_multiple_pick_mode.py (+1/-0) tests/autopilot/address_book_app/tests/test_single_pick_mode.py (+1/-0) |
To merge this branch: | bzr merge lp:~om26er/address-book-app/abook_navigation_favorites |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Allan LeSage | Pending | ||
Ubuntu Phablet Team | Pending | ||
Review via email: mp+211431@code.launchpad.net |
This proposal supersedes a proposal from 2014-03-17.
Commit message
autopilot: add tests for favoriting contacts, using the new dummy backend service
Description of the change
Note: I only fixed the code to use the dummy backend service, no other changes are from me.
Depends on lp:~renatofilho/address-book-service/dummy-mode to be merged.
- 163. By Omer Akram
-
remove syncevolution dep
PS Jenkins bot (ps-jenkins) wrote : | # |
- 164. By Omer Akram
-
remove unused test code, fix things
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:164
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 165. By Omer Akram
-
make dummy backend code reusable by other test cases
- 166. By Omer Akram
-
add docstrings for new tests
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:165
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:166
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 167. By Omer Akram
-
make starting of dummy backend a reusable helper for other apps to consume
- 168. By Omer Akram
-
adapt autopilot tests to UI changes in trunk
- 169. By Omer Akram
-
merge trunk
Unmerged revisions
- 169. By Omer Akram
-
merge trunk
- 168. By Omer Akram
-
adapt autopilot tests to UI changes in trunk
- 167. By Omer Akram
-
make starting of dummy backend a reusable helper for other apps to consume
- 166. By Omer Akram
-
add docstrings for new tests
- 165. By Omer Akram
-
make dummy backend code reusable by other test cases
- 164. By Omer Akram
-
remove unused test code, fix things
- 163. By Omer Akram
-
remove syncevolution dep
- 162. By Omer Akram
-
fix pep8 and pyflakes warnings for test_favorite, did not touch other modules
- 161. By Omer Akram
-
remove unused test code
- 160. By Omer Akram
-
don't use memory backend for favorite tests, use the new dummy backend from the service
Preview Diff
1 | === modified file 'src/imports/ContactView/ContactDetailFavoriteView.qml' |
2 | --- src/imports/ContactView/ContactDetailFavoriteView.qml 2014-02-25 21:52:58 +0000 |
3 | +++ src/imports/ContactView/ContactDetailFavoriteView.qml 2014-03-26 22:14:30 +0000 |
4 | @@ -28,6 +28,7 @@ |
5 | |
6 | Icon { |
7 | id: icon |
8 | + objectName: 'favoriteIcon' |
9 | |
10 | anchors.fill: parent |
11 | name: root.detail && root.detail.favorite ? "favorite-selected" : "favorite-unselected" |
12 | |
13 | === modified file 'src/imports/Ubuntu/Contacts/ContactListView.qml' |
14 | --- src/imports/Ubuntu/Contacts/ContactListView.qml 2014-02-25 20:20:21 +0000 |
15 | +++ src/imports/Ubuntu/Contacts/ContactListView.qml 2014-03-26 22:14:30 +0000 |
16 | @@ -57,6 +57,7 @@ |
17 | anchors.fill: parent |
18 | Label { |
19 | id: lblAll |
20 | + objectName: "labelAll" |
21 | |
22 | anchors { |
23 | top: parent.top |
24 | @@ -84,6 +85,7 @@ |
25 | |
26 | Label { |
27 | id: lblFavourites |
28 | + objectName: "labelFavorite" |
29 | |
30 | anchors { |
31 | top: parent.top |
32 | |
33 | === modified file 'tests/autopilot/address_book_app/emulators/__init__.py' |
34 | --- tests/autopilot/address_book_app/emulators/__init__.py 2013-07-09 18:42:30 +0000 |
35 | +++ tests/autopilot/address_book_app/emulators/__init__.py 2014-03-26 22:14:30 +0000 |
36 | @@ -4,3 +4,15 @@ |
37 | # This program is free software: you can redistribute it and/or modify it |
38 | # under the terms of the GNU General Public License version 3, as published |
39 | # by the Free Software Foundation. |
40 | + |
41 | + |
42 | +def get_nearest_parent_matching_type(child, desired_type): |
43 | + """Climb down the widget tree, return first instance of desired_type""" |
44 | + while type(child).__name__ != desired_type: |
45 | + parent = child.get_parent() |
46 | + if type(child).__name__ == 'AddressBookApp': |
47 | + # we reached the root and found nothing |
48 | + return None |
49 | + else: |
50 | + child = parent |
51 | + return child |
52 | |
53 | === modified file 'tests/autopilot/address_book_app/emulators/contact_list_page.py' |
54 | --- tests/autopilot/address_book_app/emulators/contact_list_page.py 2014-02-13 16:44:12 +0000 |
55 | +++ tests/autopilot/address_book_app/emulators/contact_list_page.py 2014-03-26 22:14:30 +0000 |
56 | @@ -1,20 +1,24 @@ |
57 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
58 | - |
59 | -""" ContactListPage emulator for Addressbook App tests """ |
60 | - |
61 | # Copyright 2014 Canonical |
62 | # |
63 | # This program is free software: you can redistribute it and/or modify it |
64 | # under the terms of the GNU General Public License version 3, as published |
65 | # by the Free Software Foundation. |
66 | |
67 | +""" ContactListPage emulator for Addressbook App tests """ |
68 | + |
69 | import logging |
70 | +from time import sleep |
71 | |
72 | +from autopilot import logging as autopilot_logging |
73 | from autopilot.introspection.dbus import StateNotFoundError |
74 | +from autopilot.matchers import Eventually |
75 | +from testtools.matchers import GreaterThan |
76 | from ubuntuuitoolkit import emulators as uitk |
77 | |
78 | -LOGGER = logging.getLogger(__name__) |
79 | -from time import sleep |
80 | +from address_book_app.emulators import get_nearest_parent_matching_type |
81 | + |
82 | +logger = logging.getLogger(__name__) |
83 | |
84 | |
85 | class ContactListPage(uitk.UbuntuUIToolkitEmulatorBase): |
86 | @@ -27,9 +31,12 @@ |
87 | super(ContactListPage, self).__init__(*args) |
88 | |
89 | def get_contacts(self): |
90 | - """ |
91 | - Returns a list of ContactDelegate objects and populate |
92 | - self.selection_marks |
93 | + """Returns a list of ContactDelegate objects. |
94 | + |
95 | + Also populate self.selection_marks. |
96 | + |
97 | + :return: The list of ContactDelegate objects. |
98 | + |
99 | """ |
100 | sleep(1) |
101 | self.contacts = self.select_many("ContactDelegate") |
102 | @@ -41,10 +48,12 @@ |
103 | self.selection_marks.append(mark) |
104 | return self.contacts |
105 | |
106 | + @autopilot_logging.log_action(logger.info) |
107 | def select_contacts_by_index(self, indices): |
108 | - """ Select contacts corresponding to the list of index in indices |
109 | - |
110 | - :param indices: List of integers |
111 | + """Select contacts corresponding to the list of index in indices. |
112 | + |
113 | + :param indices: List of integer indices of contacts to select. |
114 | + |
115 | """ |
116 | self.deselect_all() |
117 | |
118 | @@ -53,8 +62,9 @@ |
119 | self.selected_marks.append(self.selection_marks[idx]) |
120 | self.pointing_device.click_object(self.selection_marks[idx]) |
121 | |
122 | + @autopilot_logging.log_action(logger.info) |
123 | def deselect_all(self): |
124 | - """Deselect every contacts""" |
125 | + """Deselect every contact.""" |
126 | contacts = self.select_many("ContactDelegate") |
127 | self.selected_marks = [] |
128 | for contact in contacts: |
129 | @@ -63,28 +73,137 @@ |
130 | objectName="selectionMark") |
131 | self.pointing_device.click_object(mark) |
132 | |
133 | + @autopilot_logging.log_action(logger.info) |
134 | def click_button(self, objectname): |
135 | """Press a button that matches objectname |
136 | |
137 | - :param objectname: Name of the object |
138 | + :param objectname: The name of the object. |
139 | + :raise StateNotFoundError: When a matching button is not found. |
140 | + |
141 | """ |
142 | - try: |
143 | - buttons = self.select_many("Button", |
144 | - objectName=objectname) |
145 | - for button in buttons: |
146 | - if button.visible: |
147 | - self.pointing_device.click_object(button) |
148 | - except StateNotFoundError: |
149 | - LOGGER.error( |
150 | - 'Button with objectName "{0}" not found.'.format(objectname) |
151 | - ) |
152 | - raise |
153 | + button = self.select_single("Button", |
154 | + objectName=objectname, |
155 | + visible=True) |
156 | + self.pointing_device.click_object(button) |
157 | |
158 | + @autopilot_logging.log_action(logger.info) |
159 | def cancel(self): |
160 | - """Press the cancel button displayed when pick mode is enabled""" |
161 | + """Press the cancel button displayed when pick mode is enabled.""" |
162 | self.click_button("DialogButtons.rejectButton") |
163 | |
164 | + @autopilot_logging.log_action(logger.info) |
165 | def delete(self): |
166 | - """Press the delete button displayed when pick mode is enabled""" |
167 | + """Press the delete button displayed when pick mode is enabled.""" |
168 | self.click_button("DialogButtons.acceptButton") |
169 | self.get_contacts() |
170 | + |
171 | + def get_contact_by_name(self, |
172 | + contact_name, |
173 | + parent_delegate_type='ContactDelegate'): |
174 | + """Find a label with text matching contact name. |
175 | + |
176 | + :param contact_name: The name of the contact, e.g. 'Fulano de Tal'. |
177 | + :param parent_delegate_type: 'ContactDelegate' or 'FavoriteDelegate'. |
178 | + :return: The label for a matching contact. |
179 | + :raises StateNotFoundError: If the contact_name is not found. |
180 | + |
181 | + """ |
182 | + try: |
183 | + assert(lambda: len(self.select_many("Label", |
184 | + text=contact_name)), |
185 | + Eventually(GreaterThan(0))) |
186 | + contact_name_labels = self.select_many( |
187 | + "Label", |
188 | + text=contact_name) |
189 | + for contact_name_label in contact_name_labels: |
190 | + # we could have a contact or a favorite |
191 | + if get_nearest_parent_matching_type( |
192 | + contact_name_label, |
193 | + parent_delegate_type): |
194 | + return contact_name_label |
195 | + raise StateNotFoundError('Label') |
196 | + except StateNotFoundError: |
197 | + logger.error("Contact {} not found.".format(contact_name)) |
198 | + raise |
199 | + |
200 | + def get_favorite_by_name(self, contact_name): |
201 | + """Find a label with text matching contact name under Favorites. |
202 | + |
203 | + :param contact_name: Name of the contact, e.g. 'Fulano de Tal'. |
204 | + :return: The label for the metching favorite. |
205 | + :raises StateNotFoundError: If the contact_name is not found. |
206 | + |
207 | + """ |
208 | + return self.get_contact_by_name(contact_name).visible |
209 | + |
210 | + @autopilot_logging.log_action(logger.info) |
211 | + def click_contact_by_name(self, |
212 | + contact_name, |
213 | + parent_delegate_type='ContactDelegate'): |
214 | + """Click a contact with label matching the given contact name. |
215 | + |
216 | + :param contact_name: Name of a contact, e.g. 'Fulano de Tal'. |
217 | + :param parent_delegate_type: 'ContactDelegate' or 'FavoriteDelegate'. |
218 | + :raises StateNotFoundError: If the contact_name is not found. |
219 | + |
220 | + """ |
221 | + contact_name_label = self.get_contact_by_name( |
222 | + contact_name, parent_delegate_type) |
223 | + self.pointing_device.click_object(contact_name_label) |
224 | + |
225 | + @autopilot_logging.log_action(logger.info) |
226 | + def open_contact_view_by_contact_name(self, contact_name): |
227 | + """Open the contact view page for a contact with the given name. |
228 | + |
229 | + :param contact_name: The name of the contact, e.g. 'Abe Lincoln'. |
230 | + :return: The ContactView for the contact. |
231 | + :raises StateNotFoundError: If the name is not found. |
232 | + |
233 | + """ |
234 | + self.click_contact_by_name(contact_name) |
235 | + |
236 | + @autopilot_logging.log_action(logger.info) |
237 | + def click_favorite_by_name(self, |
238 | + contact_name): |
239 | + """Click a favorite with label matching the given contact name. |
240 | + |
241 | + :param contact_name: Name of a contact, e.g. 'Fulano de Tal' |
242 | + :raises StateNotFoundError: If the contact_name is not found. |
243 | + |
244 | + """ |
245 | + contact_name_label = self.get_favorite_by_name( |
246 | + contact_name) |
247 | + self.pointing_device.click_object(contact_name_label) |
248 | + |
249 | + @autopilot_logging.log_action(logger.info) |
250 | + def open_contact_view_by_favorite_name(self, favorite_name): |
251 | + """Open the contact view page for a favorite with the given name. |
252 | + |
253 | + :param favorite_name: The name of the favorite, e.g. 'Abe Lincoln'. |
254 | + :return: The ContactView for the contact. |
255 | + :raises StateNotFoundError: If the name is not found. |
256 | + |
257 | + """ |
258 | + self.click_favorite_by_name(favorite_name) |
259 | + |
260 | + @autopilot_logging.log_action(logger.info) |
261 | + def click_phone_number(self, phone_number): |
262 | + """Click a label matching the given phone number. |
263 | + |
264 | + :param phone_number: A phone number, e.g. '3321 1232'. |
265 | + :raises StateNotFoundError: If the phone_number is not found. |
266 | + |
267 | + """ |
268 | + phone_number_label = self.wait_select_single('Label', |
269 | + text=phone_number) |
270 | + self.pointing_device.click_object(phone_number_label) |
271 | + |
272 | + def contact_is_favorite(self, name): |
273 | + """Is the given contact name a favorite? |
274 | + |
275 | + :param contact_name: The name of a contact e.g. John. |
276 | + :raises StateNotFoundError: If the contact name is not found. |
277 | + :returns: Boolean. |
278 | + |
279 | + """ |
280 | + self.open_contact_view_by_contact_name(name) |
281 | |
282 | === added file 'tests/autopilot/address_book_app/emulators/contact_view.py' |
283 | --- tests/autopilot/address_book_app/emulators/contact_view.py 1970-01-01 00:00:00 +0000 |
284 | +++ tests/autopilot/address_book_app/emulators/contact_view.py 2014-03-26 22:14:30 +0000 |
285 | @@ -0,0 +1,57 @@ |
286 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
287 | +# Copyright 2014 Canonical |
288 | +# |
289 | +# This program is free software: you can redistribute it and/or modify it |
290 | +# under the terms of the GNU General Public License version 3, as published |
291 | +# by the Free Software Foundation. |
292 | + |
293 | +""" ContactView emulator for Addressbook App tests """ |
294 | + |
295 | +import logging |
296 | + |
297 | +from autopilot import logging as autopilot_logging |
298 | +from autopilot.introspection.dbus import StateNotFoundError |
299 | +from ubuntuuitoolkit import emulators as uitk |
300 | + |
301 | +logger = logging.getLogger(__name__) |
302 | + |
303 | + |
304 | +class ContactView(uitk.UbuntuUIToolkitEmulatorBase): |
305 | + """ContactView emulator class""" |
306 | + |
307 | + def __init__(self, *args): |
308 | + super(ContactView, self).__init__(*args) |
309 | + |
310 | + @autopilot_logging.log_action(logger.info) |
311 | + def click_button(self, objectname): |
312 | + """Press a button that matches objectname. |
313 | + |
314 | + :param objectname: The name of the object. |
315 | + :raises StateNotFoundError: If the matching object is not found. |
316 | + |
317 | + """ |
318 | + buttons = self.select_single("Button", |
319 | + objectName=objectname, |
320 | + visible=True) |
321 | + self.pointing_device.click_object(button) |
322 | + |
323 | + @autopilot_logging.log_action(logger.info) |
324 | + def cancel(self): |
325 | + """Press the cancel button displayed when pick mode is enabled.""" |
326 | + self.click_button("DialogButtons.rejectButton") |
327 | + |
328 | + @autopilot_logging.log_action(logger.info) |
329 | + def delete(self): |
330 | + """Press the delete button displayed when pick mode is enabled.""" |
331 | + self.click_button("DialogButtons.acceptButton") |
332 | + self.get_contacts() |
333 | + |
334 | + def favorite_icon(self): |
335 | + return self.wait_select_single('Icon', objectName='favoriteIcon') |
336 | + |
337 | + @autopilot_logging.log_action(logger.info) |
338 | + def click_favorite_icon(self): |
339 | + """Tap/click on the favorite icon to make a contact favorite.""" |
340 | + favorite_icon = self.favorite_icon() |
341 | + |
342 | + self.pointing_device.click_object(favorite_icon) |
343 | |
344 | === modified file 'tests/autopilot/address_book_app/emulators/main_window.py' |
345 | --- tests/autopilot/address_book_app/emulators/main_window.py 2014-02-28 16:00:02 +0000 |
346 | +++ tests/autopilot/address_book_app/emulators/main_window.py 2014-03-26 22:14:30 +0000 |
347 | @@ -21,7 +21,7 @@ |
348 | |
349 | def get_contact_list_page(self): |
350 | return self. wait_select_single("ContactListPage", |
351 | - objectName="contactListPage") |
352 | + objectName="contactListPage") |
353 | |
354 | def get_contact_edit_page(self): |
355 | return self.wait_select_single(ContactEditor, |
356 | @@ -43,7 +43,7 @@ |
357 | """ |
358 | Returns a ContactListView iobject for the current window |
359 | """ |
360 | - return self.wait_select_single( "ContactListView", |
361 | + return self.wait_select_single("ContactListView", |
362 | objectName="contactListView") |
363 | |
364 | def get_button(self, name): |
365 | @@ -53,7 +53,7 @@ |
366 | Arguments: |
367 | name: Name of the button |
368 | """ |
369 | - return self.wait_select_single( "Button", objectName=name) |
370 | + return self.wait_select_single("Button", objectName=name) |
371 | |
372 | def cancel(self): |
373 | """ |
374 | @@ -67,6 +67,30 @@ |
375 | """ |
376 | self.pointing_device.click_object(self.get_button("accept")) |
377 | |
378 | + def _get_label(self, name): |
379 | + """ |
380 | + Returns a Label object matching 'name' |
381 | + |
382 | + Arguments: |
383 | + name: objectName of the label |
384 | + """ |
385 | + return self.wait_select_single('Label', objectName=name, visible=True) |
386 | + |
387 | + def switch_to_favorites(self): |
388 | + """ |
389 | + switch to the favorite contacts view |
390 | + """ |
391 | + self.pointing_device.click_object(self._get_label('labelFavorite')) |
392 | + |
393 | + def switch_to_all_contact(self): |
394 | + """ |
395 | + Switch to all contacts view |
396 | + """ |
397 | + self.pointing_device.click_object(self._get_label('labelAll')) |
398 | + |
399 | + def are_favorites_shown(self): |
400 | + return self.get_contact_list_view().showFavourites |
401 | + |
402 | @autopilot_logging.log_action(logger.info) |
403 | def go_to_add_contact(self): |
404 | """ |
405 | |
406 | === added file 'tests/autopilot/address_book_app/helpers.py' |
407 | --- tests/autopilot/address_book_app/helpers.py 1970-01-01 00:00:00 +0000 |
408 | +++ tests/autopilot/address_book_app/helpers.py 2014-03-26 22:14:30 +0000 |
409 | @@ -0,0 +1,74 @@ |
410 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
411 | +# Copyright 2014 Canonical |
412 | +# |
413 | +# This program is free software: you can redistribute it and/or modify it |
414 | +# under the terms of the GNU General Public License version 3, as published |
415 | +# by the Free Software Foundation. |
416 | + |
417 | +import subprocess |
418 | + |
419 | +from autopilot.testcase import AutopilotTestCase |
420 | +from autopilot.matchers import Eventually |
421 | +from testtools.matchers import Equals |
422 | + |
423 | +import dbus |
424 | + |
425 | +DUMMY_BACKEND_ADDRESS = 'com.canonical.test.pim' |
426 | + |
427 | + |
428 | +class DummyServiceBackendSetup(AutopilotTestCase): |
429 | + |
430 | + def _set_contact_service_dummy_backend_environment_variables(self): |
431 | + self.patch_environment( |
432 | + 'CANONICAL_PIN_SERVICE_NAME', DUMMY_BACKEND_ADDRESS |
433 | + ) |
434 | + self.patch_environment( |
435 | + 'FOLKS_BACKEND_PATH', self._get_dummy_backend_so_location() |
436 | + ) |
437 | + self.patch_environment('FOLKS_BACKENDS_ALLOWED', 'dummy') |
438 | + self.patch_environment('FOLKS_PRIMARY_STORE', 'dummy') |
439 | + |
440 | + def _get_dummy_backend_so_location(self): |
441 | + output = subprocess.check_output( |
442 | + ['locate', '/usr/lib', '--basename', 'dummy.so'] |
443 | + ).split() |
444 | + |
445 | + if len(output) is 1: |
446 | + return output[0] |
447 | + elif len(output) > 1: |
448 | + for path in output: |
449 | + if 'address-book-service' in path: |
450 | + return path |
451 | + else: |
452 | + raise RuntimeError( |
453 | + 'Dummy backend .so not found is address-book-service-dummy' |
454 | + 'installed ?' |
455 | + ) |
456 | + |
457 | + def _get_address_book_service_binary_location(self): |
458 | + output = subprocess.check_output( |
459 | + ['locate', '/usr/lib', '--basename', 'address-book-service'] |
460 | + ).split() |
461 | + |
462 | + for path in output: |
463 | + if 'address-book-service/address-book-service' in path: |
464 | + return path |
465 | + |
466 | + def _start_service_dummy_backend(self): |
467 | + self.service = subprocess.Popen( |
468 | + [self._get_address_book_service_binary_location()] |
469 | + ) |
470 | + self.addCleanup(self.service.kill) |
471 | + |
472 | + self.assertThat( |
473 | + lambda: self._is_dummy_backend_up(), Eventually(Equals(True)) |
474 | + ) |
475 | + |
476 | + def _is_dummy_backend_up(self): |
477 | + interfaces = dbus.SessionBus().list_names() |
478 | + |
479 | + return DUMMY_BACKEND_ADDRESS in interfaces |
480 | + |
481 | + def ensure_dummy_service_backend_running(self): |
482 | + self._set_contact_service_dummy_backend_environment_variables() |
483 | + self._start_service_dummy_backend() |
484 | |
485 | === modified file 'tests/autopilot/address_book_app/tests/__init__.py' |
486 | --- tests/autopilot/address_book_app/tests/__init__.py 2014-01-30 08:35:04 +0000 |
487 | +++ tests/autopilot/address_book_app/tests/__init__.py 2014-03-26 22:14:30 +0000 |
488 | @@ -18,6 +18,7 @@ |
489 | from testtools.matchers import Equals |
490 | |
491 | from address_book_app.emulators.main_window import MainWindow |
492 | + |
493 | from ubuntuuitoolkit import emulators as toolkit_emulators |
494 | |
495 | |
496 | @@ -31,6 +32,7 @@ |
497 | VCARD_PATH_DEV = os.path.abspath("../data/vcard.vcf") |
498 | ARGS = [] |
499 | PRELOAD_VCARD = False |
500 | + QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True |
501 | |
502 | def setUp(self): |
503 | self.pointing_device = toolkit_emulators.get_pointing_device() |
504 | @@ -45,8 +47,17 @@ |
505 | else: |
506 | self.app_bin = AddressBookAppTestCase.DEFAULT_DEV_LOCATION |
507 | |
508 | - os.environ['QTCONTACTS_MANAGER_OVERRIDE'] = 'memory' |
509 | + print "Running from: %s" % (self.app_bin) |
510 | + # NOTE defeats favoriting: contacts don't show up in "Favorites" header |
511 | + if AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY: |
512 | + os.environ['QTCONTACTS_MANAGER_OVERRIDE'] = 'memory' |
513 | + else: |
514 | + try: |
515 | + del(os.environ['QTCONTACTS_MANAGER_OVERRIDE']) |
516 | + except KeyError: |
517 | + pass |
518 | vcard_data = "" |
519 | + |
520 | if AddressBookAppTestCase.PRELOAD_VCARD: |
521 | # Use vcard from source tree and fallback on installed vcard (from |
522 | # address-book-app-autopilot package) |
523 | @@ -55,16 +66,16 @@ |
524 | else: |
525 | vcard_data = AddressBookAppTestCase.VCARD_PATH_BIN |
526 | |
527 | - os.environ["ADDRESS_BOOK_TEST_DATA"] = vcard_data |
528 | - if vcard_data != "": print "Using vcard %s" % vcard_data |
529 | + os.environ['ADDRESS_BOOK_TEST_DATA'] = vcard_data |
530 | + if vcard_data != '': print 'Using vcard %s' % vcard_data |
531 | if os.path.exists(self.app_bin): |
532 | - print "Running from: %s" % (self.app_bin) |
533 | + print 'Running from: %s' % (self.app_bin) |
534 | self.launch_test_local() |
535 | elif os.path.exists(self.DEB_LOCALTION): |
536 | - print "Running from: %s" % (self.DEB_LOCALTION) |
537 | + print 'Running from: %s' % (self.DEB_LOCALTION) |
538 | self.launch_test_installed() |
539 | else: |
540 | - print "Running from click package: address-book-app" |
541 | + print 'Running from click package: address-book-app' |
542 | self.launch_click_installed() |
543 | |
544 | AddressBookAppTestCase.ARGS = [] |
545 | |
546 | === modified file 'tests/autopilot/address_book_app/tests/test_add_contact.py' |
547 | --- tests/autopilot/address_book_app/tests/test_add_contact.py 2014-02-28 15:36:09 +0000 |
548 | +++ tests/autopilot/address_book_app/tests/test_add_contact.py 2014-03-26 22:14:30 +0000 |
549 | @@ -20,6 +20,10 @@ |
550 | class TestAddContact(AddressBookAppTestCase): |
551 | """ Tests the Add contact """ |
552 | |
553 | + def setUp(self): |
554 | + AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True |
555 | + super(TestAddContact, self).setUp() |
556 | + |
557 | def test_go_to_add_contact(self): |
558 | """Test to launch the add contact screen using emulator method""" |
559 | self.assertRaises( |
560 | |
561 | === modified file 'tests/autopilot/address_book_app/tests/test_contactlist.py' |
562 | --- tests/autopilot/address_book_app/tests/test_contactlist.py 2013-11-21 18:53:19 +0000 |
563 | +++ tests/autopilot/address_book_app/tests/test_contactlist.py 2014-03-26 22:14:30 +0000 |
564 | @@ -18,6 +18,10 @@ |
565 | class TestContactList(AddressBookAppTestCase): |
566 | """Tests the contact list features""" |
567 | |
568 | + def setUp(self): |
569 | + AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True |
570 | + super(TestContactList, self).setUp() |
571 | + |
572 | def test_contact_list(self): |
573 | contact_list = self.main_window.get_contact_list_page() |
574 | self.assertThat(contact_list.visible, Eventually(Equals(True))) |
575 | |
576 | === modified file 'tests/autopilot/address_book_app/tests/test_delete_contact.py' |
577 | --- tests/autopilot/address_book_app/tests/test_delete_contact.py 2014-02-13 16:44:12 +0000 |
578 | +++ tests/autopilot/address_book_app/tests/test_delete_contact.py 2014-03-26 22:14:30 +0000 |
579 | @@ -40,6 +40,7 @@ |
580 | ] |
581 | |
582 | def setUp(self): |
583 | + AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True |
584 | AddressBookAppTestCase.PRELOAD_VCARD = True |
585 | super(TestDeleteSelectContact, self).setUp() |
586 | |
587 | |
588 | === modified file 'tests/autopilot/address_book_app/tests/test_edit_contact.py' |
589 | --- tests/autopilot/address_book_app/tests/test_edit_contact.py 2014-03-18 21:13:04 +0000 |
590 | +++ tests/autopilot/address_book_app/tests/test_edit_contact.py 2014-03-26 22:14:30 +0000 |
591 | @@ -17,6 +17,10 @@ |
592 | class TestEditContact(AddressBookAppTestCase): |
593 | """Tests edit a contact""" |
594 | |
595 | + def setUp(self): |
596 | + AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True |
597 | + super(TestEditContact, self).setUp() |
598 | + |
599 | def test_add_new_phone(self): |
600 | self.add_contact("Fulano", "de Tal", ["3321 2300"]) |
601 | edit_page = self.edit_contact(0) |
602 | |
603 | === added file 'tests/autopilot/address_book_app/tests/test_favorites.py' |
604 | --- tests/autopilot/address_book_app/tests/test_favorites.py 1970-01-01 00:00:00 +0000 |
605 | +++ tests/autopilot/address_book_app/tests/test_favorites.py 2014-03-26 22:14:30 +0000 |
606 | @@ -0,0 +1,96 @@ |
607 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
608 | +# Copyright 2014 Canonical |
609 | +# |
610 | +# This program is free software: you can redistribute it and/or modify it |
611 | +# under the terms of the GNU General Public License version 3, as published |
612 | +# by the Free Software Foundation. |
613 | + |
614 | +"""Tests of favoriting contacts for the Addressbook App""" |
615 | + |
616 | +from __future__ import absolute_import |
617 | + |
618 | +import subprocess |
619 | + |
620 | +from autopilot.introspection.dbus import StateNotFoundError |
621 | +from autopilot.matchers import Eventually |
622 | +from testtools.matchers import Equals |
623 | + |
624 | +from address_book_app.helpers import DummyServiceBackendSetup |
625 | +from address_book_app.tests import AddressBookAppTestCase |
626 | +from address_book_app.emulators.contact_list_page import ContactListPage |
627 | +from address_book_app.emulators.contact_view import ContactView |
628 | + |
629 | + |
630 | +class TestFavorite(AddressBookAppTestCase, DummyServiceBackendSetup): |
631 | + """Test for favoriting contacts""" |
632 | + |
633 | + def setUp(self): |
634 | + AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = False |
635 | + AddressBookAppTestCase.PRELOAD_VCARD = True |
636 | + self.ensure_dummy_service_backend_running() |
637 | + super(TestFavorite, self).setUp() |
638 | + |
639 | + def _add_contact_as_favorite(self, name): |
640 | + contact_list_page = self.main_window.get_contact_list_page() |
641 | + contact_list_page.open_contact_view_by_contact_name(name) |
642 | + contact_view = self.main_window.get_contact_view_page() |
643 | + contact_view.click_favorite_icon() |
644 | + self.main_window.go_back() |
645 | + self._ensure_favorites_shown() |
646 | + |
647 | + return contact_list_page |
648 | + |
649 | + def _ensure_favorites_shown(self): |
650 | + if not self.main_window.are_favorites_shown(): |
651 | + self.main_window.switch_to_favorites() |
652 | + self.main_window.are_favorites_shown().wait_for(True) |
653 | + |
654 | + def is_contact_favorite(self, name): |
655 | + contact_list_page = self.main_window.get_contact_list_page() |
656 | + contact_list_page.open_contact_view_by_contact_name(name) |
657 | + |
658 | + contact_view = self.main_window.get_contact_view_page() |
659 | + favorite_icon = contact_view.favorite_icon() |
660 | + |
661 | + if favorite_icon.name == 'favorite-selected': |
662 | + return True |
663 | + else: |
664 | + return False |
665 | + |
666 | + def test_add_favorite(self): |
667 | + """Ensure a contact can be made a favorite.""" |
668 | + self._add_contact_as_favorite('teste test34') |
669 | + |
670 | + self.assertTrue(self.is_contact_favorite('teste test34')) |
671 | + |
672 | + def test_save_multiple_favorites(self): |
673 | + """Ensure multiple contacts can be made favorites.""" |
674 | + self._add_contact_as_favorite('teste test34') |
675 | + self.assertTrue(self.is_contact_favorite('teste test34')) |
676 | + |
677 | + self.main_window.go_back() |
678 | + self.main_window.switch_to_all_contact() |
679 | + |
680 | + contact_list_page = self._add_contact_as_favorite('teste teste2') |
681 | + self.assertTrue(self.is_contact_favorite('teste teste2')) |
682 | + |
683 | + def test_remove_favorite(self): |
684 | + """Ensure an already favorite contact can be un-favorited.""" |
685 | + contact_list_page = self._add_contact_as_favorite('teste test34') |
686 | + contact_list_page.open_contact_view_by_contact_name('teste test34') |
687 | + contact_view = self.main_window.get_contact_view_page() |
688 | + contact_view.click_favorite_icon() |
689 | + |
690 | + self.assertFalse(contact_list_page.get_favorite_by_name('teste test34')) |
691 | + |
692 | + def test_delete_favorite(self): |
693 | + """Ensure deleting a favorite contact also removes it from favorite |
694 | + category.""" |
695 | + contact_list_page = self._add_contact_as_favorite('teste test34') |
696 | + contact_list_page.open_contact_view_by_contact_name('teste test34') |
697 | + toolbar = self.main_window.open_toolbar() |
698 | + toolbar.click_button('delete') |
699 | + |
700 | + self.assertRaises( |
701 | + StateNotFoundError, |
702 | + lambda: contact_list_page.get_favorite_by_name('teste test34')) |
703 | |
704 | === modified file 'tests/autopilot/address_book_app/tests/test_multiple_pick_mode.py' |
705 | --- tests/autopilot/address_book_app/tests/test_multiple_pick_mode.py 2013-12-13 19:31:33 +0000 |
706 | +++ tests/autopilot/address_book_app/tests/test_multiple_pick_mode.py 2014-03-26 22:14:30 +0000 |
707 | @@ -20,6 +20,7 @@ |
708 | |
709 | def setUp(self): |
710 | self.ARGS.append("addressbook:///pick?single=false") |
711 | + AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True |
712 | AddressBookAppTestCase.PRELOAD_VCARD = True |
713 | super(TestMultiplePickerMode, self).setUp() |
714 | |
715 | |
716 | === modified file 'tests/autopilot/address_book_app/tests/test_single_pick_mode.py' |
717 | --- tests/autopilot/address_book_app/tests/test_single_pick_mode.py 2013-12-13 19:31:33 +0000 |
718 | +++ tests/autopilot/address_book_app/tests/test_single_pick_mode.py 2014-03-26 22:14:30 +0000 |
719 | @@ -21,6 +21,7 @@ |
720 | def setUp(self): |
721 | AddressBookAppTestCase.ARGS.append("addressbook:///pick?single=true") |
722 | AddressBookAppTestCase.PRELOAD_VCARD = True |
723 | + AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True |
724 | super(TestSinglePickerMode, self).setUp() |
725 | |
726 | def test_select_single_contact(self): |
FAILED: Continuous integration, rev:163 jenkins. qa.ubuntu. com/job/ address- book-app- ci/455/ jenkins. qa.ubuntu. com/job/ address- book-app- trusty- amd64-ci/ 165 jenkins. qa.ubuntu. com/job/ address- book-app- trusty- armhf-ci/ 165 jenkins. qa.ubuntu. com/job/ address- book-app- trusty- armhf-ci/ 165/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ address- book-app- trusty- i386-ci/ 165 jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty/ 4001 jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty- touch/3586/ console jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-trusty/ 3493 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/4042 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/4042/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/3588 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/3588/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ generic- mediumtests- runner- mako/5918/ console s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 4891
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
FAILURE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/address- book-app- ci/455/ rebuild
http://