Merge lp:~elopio/address-book-app/refactoring_tests1 into lp:address-book-app
- refactoring_tests1
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~elopio/address-book-app/refactoring_tests1 |
Merge into: | lp:address-book-app |
Prerequisite: | lp:~renatofilho/address-book-app/new-header |
Diff against target: |
1505 lines (+527/-519) (has conflicts) 19 files modified
tests/autopilot/address_book_app/__init__.py (+0/-8) tests/autopilot/address_book_app/_errors.py (+21/-0) tests/autopilot/address_book_app/emulators/__init__.py (+0/-6) tests/autopilot/address_book_app/emulators/main_window.py (+0/-376) tests/autopilot/address_book_app/emulators/page_with_bottom_edge.py (+0/-40) tests/autopilot/address_book_app/pages/__init__.py (+25/-0) tests/autopilot/address_book_app/pages/_common.py (+53/-0) tests/autopilot/address_book_app/pages/_contact_editor.py (+272/-0) tests/autopilot/address_book_app/pages/_contact_list_page.py (+35/-14) tests/autopilot/address_book_app/pages/_contact_view.py (+28/-0) tests/autopilot/address_book_app/tests/__init__.py (+7/-5) tests/autopilot/address_book_app/tests/test_add_contact.py (+38/-36) tests/autopilot/address_book_app/tests/test_contactlist.py (+1/-1) tests/autopilot/address_book_app/tests/test_create_new_from_uri.py (+9/-9) tests/autopilot/address_book_app/tests/test_custom_proxy_objects.py (+1/-3) tests/autopilot/address_book_app/tests/test_delete_contact.py (+4/-4) tests/autopilot/address_book_app/tests/test_edit_contact.py (+31/-15) tests/autopilot/address_book_app/tests/test_multiple_pick_mode.py (+1/-1) tests/autopilot/address_book_app/tests/test_single_pick_mode.py (+1/-1) Text conflict in src/imports/ContactEdit/ContactDetailSyncTargetEditor.qml Text conflict in src/imports/ContactEdit/TextInputDetail.qml Text conflict in src/imports/Ubuntu/Contacts/ContactSimpleListView.qml |
To merge this branch: | bzr merge lp:~elopio/address-book-app/refactoring_tests1 |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Ubuntu Phablet Team | Pending | ||
Review via email: mp+220654@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-05-23.
Commit message
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:230
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
Renato Araujo Oliveira Filho (renatofilho) wrote : | # |
could you resubmit this proposal against the lp:~phablet-team/address-book-app/staging
Unmerged revisions
Preview Diff
1 | === removed file 'tests/autopilot/address_book_app/__init__.py' |
2 | --- tests/autopilot/address_book_app/__init__.py 2013-07-09 18:42:30 +0000 |
3 | +++ tests/autopilot/address_book_app/__init__.py 1970-01-01 00:00:00 +0000 |
4 | @@ -1,8 +0,0 @@ |
5 | -# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
6 | -# Copyright 2013 Canonical |
7 | -# |
8 | -# This program is free software: you can redistribute it and/or modify it |
9 | -# under the terms of the GNU General Public License version 3, as published |
10 | -# by the Free Software Foundation. |
11 | - |
12 | -"""address-book-app autopilot tests and emulators - top level package.""" |
13 | |
14 | === added file 'tests/autopilot/address_book_app/_errors.py' |
15 | --- tests/autopilot/address_book_app/_errors.py 1970-01-01 00:00:00 +0000 |
16 | +++ tests/autopilot/address_book_app/_errors.py 2014-05-22 14:40:49 +0000 |
17 | @@ -0,0 +1,21 @@ |
18 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
19 | +# |
20 | +# Copyright (C) 2014 Canonical Ltd. |
21 | +# |
22 | +# This program is free software; you can redistribute it and/or modify |
23 | +# it under the terms of the GNU General Public License version 3, as published |
24 | +# by the Free Software Foundation. |
25 | +# |
26 | +# This program is distributed in the hope that it will be useful, |
27 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
28 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
29 | +# GNU General Public License for more details. |
30 | +# |
31 | +# You should have received a copy of the GNU General Public License |
32 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
33 | + |
34 | +import ubuntuuitoolkit |
35 | + |
36 | + |
37 | +class AddressBookAppError(ubuntuuitoolkit.ToolkitException): |
38 | + """Exception raised when there is an error with the emulator.""" |
39 | |
40 | === removed directory 'tests/autopilot/address_book_app/emulators' |
41 | === removed file 'tests/autopilot/address_book_app/emulators/__init__.py' |
42 | --- tests/autopilot/address_book_app/emulators/__init__.py 2013-07-09 18:42:30 +0000 |
43 | +++ tests/autopilot/address_book_app/emulators/__init__.py 1970-01-01 00:00:00 +0000 |
44 | @@ -1,6 +0,0 @@ |
45 | -# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
46 | -# Copyright 2013 Canonical |
47 | -# |
48 | -# This program is free software: you can redistribute it and/or modify it |
49 | -# under the terms of the GNU General Public License version 3, as published |
50 | -# by the Free Software Foundation. |
51 | |
52 | === removed file 'tests/autopilot/address_book_app/emulators/main_window.py' |
53 | --- tests/autopilot/address_book_app/emulators/main_window.py 2014-05-22 14:40:49 +0000 |
54 | +++ tests/autopilot/address_book_app/emulators/main_window.py 1970-01-01 00:00:00 +0000 |
55 | @@ -1,376 +0,0 @@ |
56 | -# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
57 | -# Copyright 2013, 2014 Canonical |
58 | -# |
59 | -# This program is free software: you can redistribute it and/or modify it |
60 | -# under the terms of the GNU General Public License version 3, as published |
61 | -# by the Free Software Foundation. |
62 | - |
63 | -import collections |
64 | -import logging |
65 | -import time |
66 | - |
67 | -from autopilot import logging as autopilot_logging |
68 | -from autopilot.introspection.dbus import StateNotFoundError |
69 | -from ubuntuuitoolkit import emulators as uitk |
70 | -from address_book_app import data |
71 | -from address_book_app.emulators.page_with_bottom_edge import ContactListPage |
72 | - |
73 | - |
74 | -logger = logging.getLogger(__name__) |
75 | - |
76 | - |
77 | -_TEXT_FIELD_OBJECT_NAMES = { |
78 | - 'first_name': 'firstName', |
79 | - 'last_name': 'lastName', |
80 | - 'street': 'streetAddress_{}', |
81 | - 'locality': 'localityAddress_{}', |
82 | - 'region': 'regionAddress_{}', |
83 | - 'postal_code': 'postcodeAddress_{}', |
84 | - 'country': 'countryAddress_{}' |
85 | -} |
86 | - |
87 | - |
88 | -def _get_text_field(parent, field, index=None): |
89 | - if field not in _TEXT_FIELD_OBJECT_NAMES: |
90 | - raise AddressBookAppError('Unknown field: {}.'.format(field)) |
91 | - |
92 | - object_name = _TEXT_FIELD_OBJECT_NAMES[field] |
93 | - if index is not None: |
94 | - object_name = object_name.format(index) |
95 | - return parent.select_single(TextInputDetail, objectName=object_name) |
96 | - |
97 | - |
98 | -class AddressBookAppError(uitk.ToolkitEmulatorException): |
99 | - """Exception raised when there is an error with the emulator.""" |
100 | - |
101 | - |
102 | -class MainWindow(uitk.MainView): |
103 | - """An emulator class that makes it easy to interact with the app.""" |
104 | - |
105 | - def get_contact_list_page(self): |
106 | - # ContactListPage is the only page that can appears multiple times |
107 | - # Ex.: During the pick mode we alway push a new contactListPage, to |
108 | - # preserve the current application status. |
109 | - pages = self.select_many(ContactListPage, |
110 | - objectName="contactListPage") |
111 | - |
112 | - # alway return the page without pickMode |
113 | - for p in pages: |
114 | - if not p.pickMode: |
115 | - return p |
116 | - return None |
117 | - |
118 | - def get_contact_edit_page(self): |
119 | - # We can have two contact editor page because of bottom edge page |
120 | - # but we will return only the actived one |
121 | - list_page = self.get_contact_list_page() |
122 | - list_page.bottomEdgePageLoaded.wait_for(True) |
123 | - pages = self.select_many(ContactEditor, |
124 | - objectName="contactEditorPage") |
125 | - for p in pages: |
126 | - if p.active: |
127 | - return p |
128 | - raise StateNotFoundError('contactEditorPage not found') |
129 | - return None |
130 | - |
131 | - |
132 | - def get_contact_view_page(self): |
133 | - return self.wait_select_single("ContactView", |
134 | - objectName="contactViewPage") |
135 | - |
136 | - def get_contact_list_pick_page(self): |
137 | - pages = self.select_many("ContactListPage", |
138 | - objectName="contactListPage") |
139 | - for p in pages: |
140 | - if p.pickMode: |
141 | - return p |
142 | - return None |
143 | - |
144 | - def get_contact_list_view(self): |
145 | - """ |
146 | - Returns a ContactListView iobject for the current window |
147 | - """ |
148 | - return self.wait_select_single("ContactListView", |
149 | - objectName="contactListView") |
150 | - |
151 | - def get_button(self, buttonName): |
152 | - return self.get_header()._get_action_button(buttonName) |
153 | - |
154 | - def open_header(self): |
155 | - header = self.get_header() |
156 | - if (header.y != 0): |
157 | - edit_page = self.get_contact_edit_page() |
158 | - flickable = edit_page.wait_select_single( |
159 | - "QQuickFlickable", |
160 | - objectName="scrollArea") |
161 | - |
162 | - while (header.y != 0): |
163 | - globalRect = flickable.globalRect |
164 | - start_x = globalRect.x + (globalRect.width * 0.5) |
165 | - start_y = globalRect.y + (flickable.height * 0.1) |
166 | - stop_y = start_y + (flickable.height * 0.1) |
167 | - |
168 | - self.pointing_device.drag(start_x, start_y, start_x, stop_y, rate=5) |
169 | - # wait flicking stops to move to the next field |
170 | - flickable.flicking.wait_for(False) |
171 | - |
172 | - return header |
173 | - |
174 | - def cancel(self): |
175 | - """ |
176 | - Press the 'Cancel' button |
177 | - """ |
178 | - header = self.open_header() |
179 | - header.click_custom_back_button() |
180 | - |
181 | - def save(self): |
182 | - """ |
183 | - Press the 'Save' button |
184 | - """ |
185 | - bottom_swipe_page = self.get_contact_list_page() |
186 | - self.click_action_button("save") |
187 | - bottom_swipe_page.isCollapsed.wait_for(True) |
188 | - |
189 | - def done_selection(self): |
190 | - """ |
191 | - Press the 'doneSelection' button |
192 | - """ |
193 | - bottom_swipe_page = self.get_contact_list_page() |
194 | - self.click_action_button("doneSelection") |
195 | - bottom_swipe_page.isCollapsed.wait_for(True) |
196 | - |
197 | - def get_toolbar(self): |
198 | - """Override base class so we get our expected Toolbar subclass.""" |
199 | - return self.select_single(Toolbar) |
200 | - |
201 | - @autopilot_logging.log_action(logger.info) |
202 | - def go_to_add_contact(self): |
203 | - """ |
204 | - Press the 'Add' button and return the contact editor page |
205 | - """ |
206 | - bottom_swipe_page = self.get_contact_list_page() |
207 | - bottom_swipe_page.revel_bottom_edge_page() |
208 | - return self.get_contact_edit_page() |
209 | - |
210 | - |
211 | -class ContactEditor(uitk.UbuntuUIToolkitEmulatorBase): |
212 | - """Custom proxy object for the Contact Editor.""" |
213 | - |
214 | - @autopilot_logging.log_action(logger.info) |
215 | - def fill_form(self, contact_information): |
216 | - """Fill the edit contact form. |
217 | - |
218 | - :param contact_information: Values of the contact to fill the form. |
219 | - :type contact_information: data object with the attributes first_name, |
220 | - last_name, phones, emails, social_aliases, addresses and |
221 | - professional_details |
222 | - |
223 | - """ |
224 | - if contact_information.first_name is not None: |
225 | - self._fill_first_name(contact_information.first_name) |
226 | - if contact_information.last_name is not None: |
227 | - self._fill_last_name(contact_information.last_name) |
228 | - |
229 | - groups = collections.OrderedDict() |
230 | - groups['phones'] = contact_information.phones |
231 | - groups['emails'] = contact_information.emails |
232 | - groups['ims'] = contact_information.social_aliases |
233 | - groups['addresses'] = contact_information.addresses |
234 | - groups['professionalDetails'] = ( |
235 | - contact_information.professional_details) |
236 | - |
237 | - for key, information in groups.items(): |
238 | - if information: |
239 | - self._fill_detail_group( |
240 | - object_name=key, details=information) |
241 | - |
242 | - def _fill_first_name(self, first_name): |
243 | - text_field = _get_text_field(self, 'first_name') |
244 | - text_field.write(first_name) |
245 | - |
246 | - def _fill_last_name(self, last_name): |
247 | - text_field = _get_text_field(self, 'last_name') |
248 | - text_field.write(last_name) |
249 | - |
250 | - def _fill_detail_group(self, object_name, details): |
251 | - editor = self.select_single( |
252 | - ContactDetailGroupWithTypeEditor, objectName=object_name) |
253 | - editor.fill(details) |
254 | - |
255 | - def _get_form_values(self): |
256 | - first_name = _get_text_field(self, 'first_name').text |
257 | - last_name = _get_text_field(self, 'last_name').text |
258 | - phones = self._get_values_from_detail_group(object_name='phones') |
259 | - emails = self._get_values_from_detail_group(object_name='emails') |
260 | - social_aliases = self._get_values_from_detail_group(object_name='ims') |
261 | - addresses = self._get_values_from_detail_group(object_name='addresses') |
262 | - professional_details = self._get_values_from_detail_group( |
263 | - object_name='professionalDetails') |
264 | - |
265 | - return data.Contact( |
266 | - first_name=first_name, last_name=last_name, phones=phones, |
267 | - emails=emails, social_aliases=social_aliases, addresses=addresses, |
268 | - professional_details=professional_details) |
269 | - |
270 | - def _get_values_from_detail_group(self, object_name): |
271 | - editor = self.select_single( |
272 | - ContactDetailGroupWithTypeEditor, objectName=object_name) |
273 | - return editor.get_values(object_name) |
274 | - |
275 | - def wait_to_stop_moving(self): |
276 | - flickable = self.select_single( |
277 | - 'QQuickFlickable', objectName='scrollArea') |
278 | - flickable.flicking.wait_for(False) |
279 | - |
280 | - |
281 | -class TextInputDetail(uitk.TextField): |
282 | - """Custom proxy object for the Text Input Detail field.""" |
283 | - |
284 | - |
285 | -class ContactDetailGroupWithTypeEditor(uitk.UbuntuUIToolkitEmulatorBase): |
286 | - """Custom proxy object for the ContactDetailGroupWithTypeEditor widget.""" |
287 | - |
288 | - _DETAIL_EDITORS = { |
289 | - 'phones': 'base_phoneNumber_{}', |
290 | - 'emails': 'base_email_{}', |
291 | - 'ims': 'base_onlineAccount_{}', |
292 | - 'addresses': 'base_address_{}', |
293 | - # FIXME fix the unknown. --elopio - 2014-03-01 |
294 | - 'professionalDetails': 'base_unknown_{}' |
295 | - } |
296 | - |
297 | - def fill(self, details): |
298 | - """Fill a contact detail group.""" |
299 | - for index, detail in enumerate(details[:-1]): |
300 | - self._fill_detail(index, detail) |
301 | - self._add_detail() |
302 | - self._fill_detail(len(details) - 1, details[-1]) |
303 | - |
304 | - def _fill_detail(self, index, detail): |
305 | - detail_editor = self._get_detail_editor_by_index(index) |
306 | - detail_editor.fill(field=self.objectName, index=index, detail=detail) |
307 | - |
308 | - def _get_detail_editor_by_index(self, index): |
309 | - object_name = self._get_contact_detail_editor_object_name(index) |
310 | - return self.select_single( |
311 | - ContactDetailWithTypeEditor, objectName=object_name) |
312 | - |
313 | - def _get_contact_detail_editor_object_name(self, index): |
314 | - return self._DETAIL_EDITORS[self.objectName].format(index) |
315 | - |
316 | - def _add_detail(self): |
317 | - # TODO --elopio - 2014-03-01 |
318 | - raise NotImplementedError('Add extra details not yet implemented.') |
319 | - |
320 | - def get_values(self, object_name): |
321 | - """Return the values of a contact detail group.""" |
322 | - values = [] |
323 | - for index in range(self.detailsCount): |
324 | - detail_editor = self._get_detail_editor_by_index(index) |
325 | - value = detail_editor.get_values(field=object_name, index=index) |
326 | - if (value): |
327 | - values.append(value) |
328 | - |
329 | - return values |
330 | - |
331 | - |
332 | -class ContactDetailWithTypeEditor(uitk.UbuntuUIToolkitEmulatorBase): |
333 | - """Custom proxy object for the ContactDetailWithTypeEditor widget.""" |
334 | - |
335 | - def __init__(self, *args): |
336 | - super(ContactDetailWithTypeEditor, self).__init__(*args) |
337 | - self.main_view = self.get_root_instance().select_single(MainWindow) |
338 | - |
339 | - def fill(self, field, index, detail): |
340 | - self._select_type(detail) |
341 | - self._fill_value(field, index, detail) |
342 | - |
343 | - def _select_type(self, detail): |
344 | - type_index = detail.TYPES.index(detail.type) |
345 | - selected_type_index = self._get_selected_type_index() |
346 | - if type_index != selected_type_index: |
347 | - # TODO --elopio - 2014-03-01 |
348 | - raise NotImplementedError('Type selection not yet implemented.') |
349 | - |
350 | - def _get_selected_type_index(self): |
351 | - value_selector = self.select_single('ValueSelector') |
352 | - return value_selector.currentIndex |
353 | - |
354 | - def _fill_value(self, field, index, detail): |
355 | - single_values = { |
356 | - 'phones': 'number', |
357 | - 'emails': 'address', |
358 | - 'ims': 'alias' |
359 | - } |
360 | - if field in single_values: |
361 | - self._fill_single_field(getattr(detail, single_values[field])) |
362 | - elif field == 'addresses': |
363 | - self._fill_address(index, detail) |
364 | - elif field == 'professionalDetails': |
365 | - self._fill_professional_details(index, detail) |
366 | - else: |
367 | - raise AddressBookAppError('Unknown field: {}.'.format(field)) |
368 | - |
369 | - def _fill_single_field(self, value): |
370 | - text_field = self.select_single(TextInputDetail) |
371 | - self._make_field_visible_and_write(text_field, value) |
372 | - |
373 | - def _make_field_visible_and_write(self, text_field, value): |
374 | - while not text_field.activeFocus: |
375 | - # XXX We should just swipe the text field into view. |
376 | - # Update this once bug http://pad.lv/1286479 is implemented. |
377 | - # --elopio - 2014-03-01 |
378 | - text_field.keyboard.press_and_release('Tab') |
379 | - time.sleep(0.1) |
380 | - self.main_view.get_contact_edit_page().wait_to_stop_moving() |
381 | - |
382 | - text_field.write(value) |
383 | - |
384 | - def _fill_address(self, index, address): |
385 | - fields = collections.OrderedDict() |
386 | - fields['street'] = address.street |
387 | - fields['locality'] = address.locality |
388 | - fields['region'] = address.region |
389 | - fields['postal_code'] = address.postal_code |
390 | - fields['country'] = address.country |
391 | - for key, value in fields.items(): |
392 | - text_field = _get_text_field(self, key, index) |
393 | - self._make_field_visible_and_write(text_field, value) |
394 | - |
395 | - def _fill_professional_details(self, index, address): |
396 | - # TODO --elopio - 2014-03-01 |
397 | - raise NotImplementedError('Not yet implemented.') |
398 | - |
399 | - def get_values(self, field, index): |
400 | - if field == 'phones': |
401 | - return data.Phone( |
402 | - type_=data.Phone.TYPES[self._get_selected_type_index()], |
403 | - number=self._get_single_field_value()) |
404 | - if field == 'emails': |
405 | - return data.Email( |
406 | - type_=data.Email.TYPES[self._get_selected_type_index()], |
407 | - address=self._get_single_field_value()) |
408 | - if field == 'ims': |
409 | - return data.SocialAlias( |
410 | - type_=data.SocialAlias.TYPES[self._get_selected_type_index()], |
411 | - alias=self._get_single_field_value()) |
412 | - if field == 'addresses': |
413 | - return self._get_address_value(index) |
414 | - if field == 'professionalDetails': |
415 | - # TODO --elopio - 2014-03-01 |
416 | - return None |
417 | - raise AddressBookAppError('Unknown field: {}.'.format(field)) |
418 | - |
419 | - def _get_single_field_value(self): |
420 | - return self.select_single(TextInputDetail).text |
421 | - |
422 | - def _get_address_value(self, index): |
423 | - street = _get_text_field(self, 'street', index).text |
424 | - locality = _get_text_field(self, 'locality', index).text |
425 | - region = _get_text_field(self, 'region', index).text |
426 | - postal_code = _get_text_field(self, 'postal_code', index).text |
427 | - country = _get_text_field(self, 'country', index).text |
428 | - return data.Address( |
429 | - type_=data.Address.TYPES[self._get_selected_type_index()], |
430 | - street=street, locality=locality, region=region, |
431 | - postal_code=postal_code, country=country) |
432 | |
433 | === removed file 'tests/autopilot/address_book_app/emulators/page_with_bottom_edge.py' |
434 | --- tests/autopilot/address_book_app/emulators/page_with_bottom_edge.py 2014-05-22 14:40:49 +0000 |
435 | +++ tests/autopilot/address_book_app/emulators/page_with_bottom_edge.py 1970-01-01 00:00:00 +0000 |
436 | @@ -1,40 +0,0 @@ |
437 | -# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
438 | - |
439 | -""" PageWithBottomEdge emulator """ |
440 | - |
441 | -# Copyright 2014 Canonical |
442 | -# |
443 | -# This program is free software: you can redistribute it and/or modify it |
444 | -# under the terms of the GNU General Public License version 3, as published |
445 | -# by the Free Software Foundation. |
446 | - |
447 | -import logging |
448 | -from address_book_app.emulators.contact_list_page import ContactListPage |
449 | -from autopilot.introspection.dbus import StateNotFoundError |
450 | -from ubuntuuitoolkit import emulators as toolkit_emulators |
451 | - |
452 | -logger = logging.getLogger(__name__) |
453 | - |
454 | -class PageWithBottomEdge(ContactListPage): |
455 | - """An emulator class that makes it easy to interact with the bottom edge |
456 | - swipe page""" |
457 | - def __init__(self, *args): |
458 | - super(PageWithBottomEdge, self).__init__(*args) |
459 | - |
460 | - def revel_bottom_edge_page(self): |
461 | - """Bring the bottom edge page to the screen""" |
462 | - self.bottomEdgePageLoaded.wait_for(True) |
463 | - try: |
464 | - action_item = self.wait_select_single('QQuickItem', objectName='bottomEdgeTip') |
465 | - start_x = action_item.globalRect.x + (action_item.globalRect.width * 0.5) |
466 | - start_y = action_item.globalRect.y + (action_item.height * 0.5) |
467 | - stop_y = start_y - (self.height * 0.7) |
468 | - self.pointing_device.drag(start_x, start_y, start_x, stop_y, rate=2) |
469 | - self.isReady.wait_for(True) |
470 | - except StateNotFoundError: |
471 | - logger.error('ButtomEdge element not found.') |
472 | - raise |
473 | - |
474 | -class ContactListPage(PageWithBottomEdge): |
475 | - pass |
476 | - |
477 | |
478 | === added directory 'tests/autopilot/address_book_app/pages' |
479 | === added file 'tests/autopilot/address_book_app/pages/__init__.py' |
480 | --- tests/autopilot/address_book_app/pages/__init__.py 1970-01-01 00:00:00 +0000 |
481 | +++ tests/autopilot/address_book_app/pages/__init__.py 2014-05-22 14:40:49 +0000 |
482 | @@ -0,0 +1,25 @@ |
483 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
484 | +# |
485 | +# Copyright (C) 2014 Canonical Ltd. |
486 | +# |
487 | +# This program is free software; you can redistribute it and/or modify |
488 | +# it under the terms of the GNU General Public License version 3, as published |
489 | +# by the Free Software Foundation. |
490 | +# |
491 | +# This program is distributed in the hope that it will be useful, |
492 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
493 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
494 | +# GNU General Public License for more details. |
495 | +# |
496 | +# You should have received a copy of the GNU General Public License |
497 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
498 | + |
499 | +__all__ = [ |
500 | + 'ContactEditor', |
501 | + 'ContactListPage', |
502 | + 'ContactView', |
503 | +] |
504 | + |
505 | +from address_book_app.pages._contact_editor import ContactEditor |
506 | +from address_book_app.pages._contact_list_page import ContactListPage |
507 | +from address_book_app.pages._contact_view import ContactView |
508 | |
509 | === added file 'tests/autopilot/address_book_app/pages/_common.py' |
510 | --- tests/autopilot/address_book_app/pages/_common.py 1970-01-01 00:00:00 +0000 |
511 | +++ tests/autopilot/address_book_app/pages/_common.py 2014-05-22 14:40:49 +0000 |
512 | @@ -0,0 +1,53 @@ |
513 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
514 | +# |
515 | +# Copyright (C) 2014 Canonical Ltd. |
516 | +# |
517 | +# This program is free software; you can redistribute it and/or modify |
518 | +# it under the terms of the GNU General Public License version 3, as published |
519 | +# by the Free Software Foundation. |
520 | +# |
521 | +# This program is distributed in the hope that it will be useful, |
522 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
523 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
524 | +# GNU General Public License for more details. |
525 | +# |
526 | +# You should have received a copy of the GNU General Public License |
527 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
528 | + |
529 | +import logging |
530 | + |
531 | +import ubuntuuitoolkit |
532 | +from autopilot.introspection import dbus |
533 | + |
534 | + |
535 | +logger = logging.getLogger(__name__) |
536 | + |
537 | + |
538 | +class PageWithHeader(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
539 | + |
540 | + def get_header(self): |
541 | + """Return the Header custom proxy object of the Page.""" |
542 | + return self.get_root_instance().select_single( |
543 | + 'Header', objectName='MainView_Header') |
544 | + |
545 | + |
546 | +class PageWithBottomEdge(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
547 | + """An emulator class that makes it easy to interact with the bottom edge |
548 | + swipe page""" |
549 | + |
550 | + def revel_bottom_edge_page(self): |
551 | + """Bring the bottom edge page to the screen""" |
552 | + self.bottomEdgePageLoaded.wait_for(True) |
553 | + try: |
554 | + action_item = self.wait_select_single( |
555 | + 'QQuickItem', objectName='bottomEdgeTip') |
556 | + start_x = (action_item.globalRect.x + |
557 | + (action_item.globalRect.width * 0.5)) |
558 | + start_y = action_item.globalRect.y + (action_item.height * 0.5) |
559 | + stop_y = start_y - (self.height * 0.7) |
560 | + self.pointing_device.drag( |
561 | + start_x, start_y, start_x, stop_y, rate=2) |
562 | + self.isReady.wait_for(True) |
563 | + except dbus.StateNotFoundError: |
564 | + logger.error('ButtomEdge element not found.') |
565 | + raise |
566 | |
567 | === added file 'tests/autopilot/address_book_app/pages/_contact_editor.py' |
568 | --- tests/autopilot/address_book_app/pages/_contact_editor.py 1970-01-01 00:00:00 +0000 |
569 | +++ tests/autopilot/address_book_app/pages/_contact_editor.py 2014-05-22 14:40:49 +0000 |
570 | @@ -0,0 +1,272 @@ |
571 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
572 | +# |
573 | +# Copyright (C) 2014 Canonical Ltd. |
574 | +# |
575 | +# This program is free software; you can redistribute it and/or modify |
576 | +# it under the terms of the GNU General Public License version 3, as published |
577 | +# by the Free Software Foundation. |
578 | +# |
579 | +# This program is distributed in the hope that it will be useful, |
580 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
581 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
582 | +# GNU General Public License for more details. |
583 | +# |
584 | +# You should have received a copy of the GNU General Public License |
585 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
586 | + |
587 | +import collections |
588 | +import logging |
589 | +import time |
590 | + |
591 | +import autopilot.logging |
592 | +import ubuntuuitoolkit |
593 | +from address_book_app import data, _errors |
594 | +from address_book_app.pages import _common |
595 | + |
596 | + |
597 | +logger = logging.getLogger(__name__) |
598 | + |
599 | + |
600 | +_TEXT_FIELD_OBJECT_NAMES = { |
601 | + 'first_name': 'firstName', |
602 | + 'last_name': 'lastName', |
603 | + 'street': 'streetAddress_{}', |
604 | + 'locality': 'localityAddress_{}', |
605 | + 'region': 'regionAddress_{}', |
606 | + 'postal_code': 'postcodeAddress_{}', |
607 | + 'country': 'countryAddress_{}' |
608 | +} |
609 | + |
610 | + |
611 | +def _get_text_field(parent, field, index=None): |
612 | + if field not in _TEXT_FIELD_OBJECT_NAMES: |
613 | + raise _errors.AddressBookAppError('Unknown field: {}.'.format(field)) |
614 | + |
615 | + object_name = _TEXT_FIELD_OBJECT_NAMES[field] |
616 | + if index is not None: |
617 | + object_name = object_name.format(index) |
618 | + return parent.select_single(TextInputDetail, objectName=object_name) |
619 | + |
620 | + |
621 | +class ContactEditor(_common.PageWithHeader): |
622 | + """Custom proxy object for the Contact Editor.""" |
623 | + |
624 | + @autopilot.logging.log_action(logger.info) |
625 | + def fill_form(self, contact_information): |
626 | + """Fill the edit contact form. |
627 | + |
628 | + :param contact_information: Values of the contact to fill the form. |
629 | + :type contact_information: data object with the attributes first_name, |
630 | + last_name, phones, emails, social_aliases, addresses and |
631 | + professional_details |
632 | + |
633 | + """ |
634 | + if contact_information.first_name is not None: |
635 | + self._fill_first_name(contact_information.first_name) |
636 | + if contact_information.last_name is not None: |
637 | + self._fill_last_name(contact_information.last_name) |
638 | + |
639 | + groups = collections.OrderedDict() |
640 | + groups['phones'] = contact_information.phones |
641 | + groups['emails'] = contact_information.emails |
642 | + groups['ims'] = contact_information.social_aliases |
643 | + groups['addresses'] = contact_information.addresses |
644 | + groups['professionalDetails'] = ( |
645 | + contact_information.professional_details) |
646 | + |
647 | + for key, information in groups.items(): |
648 | + if information: |
649 | + self._fill_detail_group( |
650 | + object_name=key, details=information) |
651 | + |
652 | + def _fill_first_name(self, first_name): |
653 | + text_field = _get_text_field(self, 'first_name') |
654 | + text_field.write(first_name) |
655 | + |
656 | + def _fill_last_name(self, last_name): |
657 | + text_field = _get_text_field(self, 'last_name') |
658 | + text_field.write(last_name) |
659 | + |
660 | + def _fill_detail_group(self, object_name, details): |
661 | + editor = self.select_single( |
662 | + ContactDetailGroupWithTypeEditor, objectName=object_name) |
663 | + editor.fill(details) |
664 | + |
665 | + def _get_form_values(self): |
666 | + first_name = _get_text_field(self, 'first_name').text |
667 | + last_name = _get_text_field(self, 'last_name').text |
668 | + phones = self._get_values_from_detail_group(object_name='phones') |
669 | + emails = self._get_values_from_detail_group(object_name='emails') |
670 | + social_aliases = self._get_values_from_detail_group(object_name='ims') |
671 | + addresses = self._get_values_from_detail_group(object_name='addresses') |
672 | + professional_details = self._get_values_from_detail_group( |
673 | + object_name='professionalDetails') |
674 | + |
675 | + return data.Contact( |
676 | + first_name=first_name, last_name=last_name, phones=phones, |
677 | + emails=emails, social_aliases=social_aliases, addresses=addresses, |
678 | + professional_details=professional_details) |
679 | + |
680 | + def _get_values_from_detail_group(self, object_name): |
681 | + editor = self.select_single( |
682 | + ContactDetailGroupWithTypeEditor, objectName=object_name) |
683 | + return editor.get_values(object_name) |
684 | + |
685 | + def wait_to_stop_moving(self): |
686 | + flickable = self.select_single( |
687 | + 'QQuickFlickable', objectName='scrollArea') |
688 | + flickable.flicking.wait_for(False) |
689 | + |
690 | + |
691 | +class TextInputDetail(ubuntuuitoolkit.TextField): |
692 | + """Custom proxy object for the Text Input Detail field.""" |
693 | + |
694 | + |
695 | +class ContactDetailGroupWithTypeEditor( |
696 | + ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
697 | + """Custom proxy object for the ContactDetailGroupWithTypeEditor widget.""" |
698 | + |
699 | + _DETAIL_EDITORS = { |
700 | + 'phones': 'base_phoneNumber_{}', |
701 | + 'emails': 'base_email_{}', |
702 | + 'ims': 'base_onlineAccount_{}', |
703 | + 'addresses': 'base_address_{}', |
704 | + # FIXME fix the unknown. --elopio - 2014-03-01 |
705 | + 'professionalDetails': 'base_unknown_{}' |
706 | + } |
707 | + |
708 | + def fill(self, details): |
709 | + """Fill a contact detail group.""" |
710 | + for index, detail in enumerate(details[:-1]): |
711 | + self._fill_detail(index, detail) |
712 | + self._add_detail() |
713 | + self._fill_detail(len(details) - 1, details[-1]) |
714 | + |
715 | + def _fill_detail(self, index, detail): |
716 | + detail_editor = self._get_detail_editor_by_index(index) |
717 | + detail_editor.fill(field=self.objectName, index=index, detail=detail) |
718 | + |
719 | + def _get_detail_editor_by_index(self, index): |
720 | + object_name = self._get_contact_detail_editor_object_name(index) |
721 | + return self.select_single( |
722 | + ContactDetailWithTypeEditor, objectName=object_name) |
723 | + |
724 | + def _get_contact_detail_editor_object_name(self, index): |
725 | + return self._DETAIL_EDITORS[self.objectName].format(index) |
726 | + |
727 | + def _add_detail(self): |
728 | + # TODO --elopio - 2014-03-01 |
729 | + raise NotImplementedError('Add extra details not yet implemented.') |
730 | + |
731 | + def get_values(self, object_name): |
732 | + """Return the values of a contact detail group.""" |
733 | + values = [] |
734 | + for index in range(self.detailsCount): |
735 | + detail_editor = self._get_detail_editor_by_index(index) |
736 | + value = detail_editor.get_values(field=object_name, index=index) |
737 | + if (value): |
738 | + values.append(value) |
739 | + |
740 | + return values |
741 | + |
742 | + |
743 | +class ContactDetailWithTypeEditor( |
744 | + ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
745 | + """Custom proxy object for the ContactDetailWithTypeEditor widget.""" |
746 | + |
747 | + def fill(self, field, index, detail): |
748 | + self._select_type(detail) |
749 | + self._fill_value(field, index, detail) |
750 | + |
751 | + def _select_type(self, detail): |
752 | + type_index = detail.TYPES.index(detail.type) |
753 | + selected_type_index = self._get_selected_type_index() |
754 | + if type_index != selected_type_index: |
755 | + # TODO --elopio - 2014-03-01 |
756 | + raise NotImplementedError('Type selection not yet implemented.') |
757 | + |
758 | + def _get_selected_type_index(self): |
759 | + value_selector = self.select_single('ValueSelector') |
760 | + return value_selector.currentIndex |
761 | + |
762 | + def _fill_value(self, field, index, detail): |
763 | + single_values = { |
764 | + 'phones': 'number', |
765 | + 'emails': 'address', |
766 | + 'ims': 'alias' |
767 | + } |
768 | + if field in single_values: |
769 | + self._fill_single_field(getattr(detail, single_values[field])) |
770 | + elif field == 'addresses': |
771 | + self._fill_address(index, detail) |
772 | + elif field == 'professionalDetails': |
773 | + self._fill_professional_details(index, detail) |
774 | + else: |
775 | + raise _errors.AddressBookAppError( |
776 | + 'Unknown field: {}.'.format(field)) |
777 | + |
778 | + def _fill_single_field(self, value): |
779 | + text_field = self.select_single(TextInputDetail) |
780 | + self._make_field_visible_and_write(text_field, value) |
781 | + |
782 | + def _make_field_visible_and_write(self, text_field, value): |
783 | + while not text_field.activeFocus: |
784 | + # XXX We should just swipe the text field into view. |
785 | + # Update this once bug http://pad.lv/1286479 is implemented. |
786 | + # --elopio - 2014-03-01 |
787 | + text_field.keyboard.press_and_release('Tab') |
788 | + time.sleep(0.1) |
789 | + contact_editor = self.get_root_instance().select_single( |
790 | + ContactEditor, objectName='contactEditorPage', active=True) |
791 | + contact_editor.wait_to_stop_moving() |
792 | + |
793 | + text_field.write(value) |
794 | + |
795 | + def _fill_address(self, index, address): |
796 | + fields = collections.OrderedDict() |
797 | + fields['street'] = address.street |
798 | + fields['locality'] = address.locality |
799 | + fields['region'] = address.region |
800 | + fields['postal_code'] = address.postal_code |
801 | + fields['country'] = address.country |
802 | + for key, value in fields.items(): |
803 | + text_field = _get_text_field(self, key, index) |
804 | + self._make_field_visible_and_write(text_field, value) |
805 | + |
806 | + def _fill_professional_details(self, index, address): |
807 | + # TODO --elopio - 2014-03-01 |
808 | + raise NotImplementedError('Not yet implemented.') |
809 | + |
810 | + def get_values(self, field, index): |
811 | + if field == 'phones': |
812 | + return data.Phone( |
813 | + type_=data.Phone.TYPES[self._get_selected_type_index()], |
814 | + number=self._get_single_field_value()) |
815 | + if field == 'emails': |
816 | + return data.Email( |
817 | + type_=data.Email.TYPES[self._get_selected_type_index()], |
818 | + address=self._get_single_field_value()) |
819 | + if field == 'ims': |
820 | + return data.SocialAlias( |
821 | + type_=data.SocialAlias.TYPES[self._get_selected_type_index()], |
822 | + alias=self._get_single_field_value()) |
823 | + if field == 'addresses': |
824 | + return self._get_address_value(index) |
825 | + if field == 'professionalDetails': |
826 | + # TODO --elopio - 2014-03-01 |
827 | + return None |
828 | + raise _errors.AddressBookAppError('Unknown field: {}.'.format(field)) |
829 | + |
830 | + def _get_single_field_value(self): |
831 | + return self.select_single(TextInputDetail).text |
832 | + |
833 | + def _get_address_value(self, index): |
834 | + street = _get_text_field(self, 'street', index).text |
835 | + locality = _get_text_field(self, 'locality', index).text |
836 | + region = _get_text_field(self, 'region', index).text |
837 | + postal_code = _get_text_field(self, 'postal_code', index).text |
838 | + country = _get_text_field(self, 'country', index).text |
839 | + return data.Address( |
840 | + type_=data.Address.TYPES[self._get_selected_type_index()], |
841 | + street=street, locality=locality, region=region, |
842 | + postal_code=postal_code, country=country) |
843 | |
844 | === renamed file 'tests/autopilot/address_book_app/emulators/contact_list_page.py' => 'tests/autopilot/address_book_app/pages/_contact_list_page.py' |
845 | --- tests/autopilot/address_book_app/emulators/contact_list_page.py 2014-05-22 14:40:49 +0000 |
846 | +++ tests/autopilot/address_book_app/pages/_contact_list_page.py 2014-05-22 14:40:49 +0000 |
847 | @@ -1,23 +1,33 @@ |
848 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
849 | +# |
850 | +# Copyright (C) 2014 Canonical Ltd. |
851 | +# |
852 | +# This program is free software; you can redistribute it and/or modify |
853 | +# it under the terms of the GNU General Public License version 3, as published |
854 | +# by the Free Software Foundation. |
855 | +# |
856 | +# This program is distributed in the hope that it will be useful, |
857 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
858 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
859 | +# GNU General Public License for more details. |
860 | +# |
861 | +# You should have received a copy of the GNU General Public License |
862 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
863 | |
864 | """ ContactListPage emulator for Addressbook App tests """ |
865 | |
866 | -# Copyright 2014 Canonical |
867 | -# |
868 | -# This program is free software: you can redistribute it and/or modify it |
869 | -# under the terms of the GNU General Public License version 3, as published |
870 | -# by the Free Software Foundation. |
871 | - |
872 | import logging |
873 | +import time |
874 | |
875 | from autopilot.introspection.dbus import StateNotFoundError |
876 | -from ubuntuuitoolkit import emulators as uitk |
877 | + |
878 | +from address_book_app.pages import _common, _contact_view |
879 | + |
880 | |
881 | LOGGER = logging.getLogger(__name__) |
882 | -from time import sleep |
883 | - |
884 | - |
885 | -class ContactListPage(uitk.UbuntuUIToolkitEmulatorBase): |
886 | + |
887 | + |
888 | +class ContactListPage(_common.PageWithHeader, _common.PageWithBottomEdge): |
889 | """ ContactListPage emulator class """ |
890 | |
891 | def __init__(self, *args): |
892 | @@ -26,6 +36,18 @@ |
893 | self.selected_marks = [] |
894 | super(ContactListPage, self).__init__(*args) |
895 | |
896 | + def open_contact(self, index): |
897 | + """Open the page with the contact information. |
898 | + |
899 | + :param index: The index of the contact to open. |
900 | + :return: The page with the contact information. |
901 | + |
902 | + """ |
903 | + contacts = self.get_contacts() |
904 | + self.pointing_device.click_object(contacts[index]) |
905 | + return self.get_root_instance().select_single( |
906 | + _contact_view.ContactView, objectName='contactViewPage') |
907 | + |
908 | def _get_list_view(self): |
909 | return self.wait_select_single("ContactListView", |
910 | objectName="contactListView") |
911 | @@ -35,7 +57,7 @@ |
912 | Returns a list of ContactDelegate objects and populate |
913 | self.selection_marks |
914 | """ |
915 | - sleep(1) |
916 | + time.sleep(1) |
917 | self.contacts = self.select_many("ContactDelegate") |
918 | self.selection_marks = [] |
919 | for contact in self.contacts: |
920 | @@ -52,7 +74,7 @@ |
921 | self.selected_marks.append(self.selection_marks[idx]) |
922 | self.pointing_device.move_to_object(self.contacts[idx]) |
923 | self.pointing_device.press() |
924 | - sleep(2.0) |
925 | + time.sleep(2.0) |
926 | self.pointing_device.release() |
927 | view.isInSelectionMode.wait_for(True) |
928 | else: |
929 | @@ -110,4 +132,3 @@ |
930 | dialog = main_window.wait_select_single("RemoveContactsDialog", |
931 | objectName="removeContactsDialog") |
932 | self.click_button(main_window, "removeContactsDialog.Yes") |
933 | - |
934 | |
935 | === added file 'tests/autopilot/address_book_app/pages/_contact_view.py' |
936 | --- tests/autopilot/address_book_app/pages/_contact_view.py 1970-01-01 00:00:00 +0000 |
937 | +++ tests/autopilot/address_book_app/pages/_contact_view.py 2014-05-22 14:40:49 +0000 |
938 | @@ -0,0 +1,28 @@ |
939 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
940 | +# |
941 | +# Copyright (C) 2014 Canonical Ltd. |
942 | +# |
943 | +# This program is free software; you can redistribute it and/or modify |
944 | +# it under the terms of the GNU General Public License version 3, as published |
945 | +# by the Free Software Foundation. |
946 | +# |
947 | +# This program is distributed in the hope that it will be useful, |
948 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
949 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
950 | +# GNU General Public License for more details. |
951 | +# |
952 | +# You should have received a copy of the GNU General Public License |
953 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
954 | + |
955 | +from address_book_app.pages import _common, _contact_editor |
956 | + |
957 | + |
958 | +class ContactView(_common.PageWithHeader): |
959 | + """Autopilot helper for the ContactView page.""" |
960 | + |
961 | + def go_to_edit_contact(self): |
962 | + self.get_header().click_action_button('edit') |
963 | + return self.get_root_instance().select_single( |
964 | + _contact_editor.ContactEditor, |
965 | + objectName='contactEditorPage', |
966 | + active=True) |
967 | |
968 | === modified file 'tests/autopilot/address_book_app/tests/__init__.py' |
969 | --- tests/autopilot/address_book_app/tests/__init__.py 2014-05-22 14:40:49 +0000 |
970 | +++ tests/autopilot/address_book_app/tests/__init__.py 2014-05-22 14:40:49 +0000 |
971 | @@ -16,7 +16,8 @@ |
972 | from autopilot.platform import model |
973 | from testtools.matchers import Equals |
974 | |
975 | -from address_book_app.emulators.main_window import MainWindow |
976 | +import address_book_app |
977 | +from address_book_app import MainWindow |
978 | from ubuntuuitoolkit import emulators as toolkit_emulators |
979 | |
980 | |
981 | @@ -71,6 +72,7 @@ |
982 | AddressBookAppTestCase.ARGS = [] |
983 | AddressBookAppTestCase.PRELOAD_VCARD = False |
984 | self.main_window.visible.wait_for(True) |
985 | + self.app = address_book_app.AddressBookApp(self.app_proxy) |
986 | |
987 | def tearDown(self): |
988 | super(AddressBookAppTestCase, self).tearDown() |
989 | @@ -80,7 +82,7 @@ |
990 | subprocess.check_call(["/sbin/initctl", "start", "maliit-server"]) |
991 | |
992 | def launch_test_local(self): |
993 | - self.app = self.launch_test_application( |
994 | + self.app_proxy = self.launch_test_application( |
995 | self.app_bin, |
996 | *AddressBookAppTestCase.ARGS, |
997 | app_type='qt', |
998 | @@ -89,19 +91,19 @@ |
999 | def launch_test_installed(self): |
1000 | df = "/usr/share/applications/address-book-app.desktop" |
1001 | self.ARGS.append("--desktop_file_hint=" + df) |
1002 | - self.app = self.launch_test_application( |
1003 | + self.app_proxy = self.launch_test_application( |
1004 | "address-book-app", |
1005 | *AddressBookAppTestCase.ARGS, |
1006 | app_type='qt', |
1007 | emulator_base=toolkit_emulators.UbuntuUIToolkitEmulatorBase) |
1008 | |
1009 | def launch_click_installed(self): |
1010 | - self.app = self.launch_click_package( |
1011 | + self.app_proxy = self.launch_click_package( |
1012 | "com.ubuntu.address-book") |
1013 | |
1014 | @property |
1015 | def main_window(self): |
1016 | - return self.app.select_single(MainWindow) |
1017 | + return self.app_proxy.select_single(MainWindow) |
1018 | |
1019 | def select_a_value(self, field, value_selector, value): |
1020 | # Make sure the field has focus |
1021 | |
1022 | === modified file 'tests/autopilot/address_book_app/tests/test_add_contact.py' |
1023 | --- tests/autopilot/address_book_app/tests/test_add_contact.py 2014-05-22 14:40:49 +0000 |
1024 | +++ tests/autopilot/address_book_app/tests/test_add_contact.py 2014-05-22 14:40:49 +0000 |
1025 | @@ -11,9 +11,9 @@ |
1026 | from autopilot.matchers import Eventually |
1027 | from autopilot.introspection import dbus |
1028 | |
1029 | +import address_book_app |
1030 | from address_book_app import data |
1031 | from address_book_app.tests import AddressBookAppTestCase |
1032 | -from address_book_app.emulators import main_window |
1033 | |
1034 | |
1035 | class TestAddContact(AddressBookAppTestCase): |
1036 | @@ -22,37 +22,39 @@ |
1037 | def test_go_to_add_contact(self): |
1038 | """Test to launch the add contact screen using emulator method""" |
1039 | self.assertRaises( |
1040 | - dbus.StateNotFoundError, self.main_window.get_contact_edit_page) |
1041 | - contact_editor = self.main_window.go_to_add_contact() |
1042 | + dbus.StateNotFoundError, |
1043 | + self.app.main_window.get_contact_edit_page) |
1044 | + contact_editor = self.app.main_window.go_to_add_contact() |
1045 | self.assertTrue(contact_editor.visible) |
1046 | - self.assertIsInstance(contact_editor, main_window.ContactEditor) |
1047 | + self.assertIsInstance( |
1048 | + contact_editor, address_book_app.pages.ContactEditor) |
1049 | |
1050 | def test_add_and_cancel_contact(self): |
1051 | - list_page = self.main_window.get_contact_list_page() |
1052 | + list_page = self.app.main_window.get_contact_list_page() |
1053 | |
1054 | # execute add new contact |
1055 | - contact_editor = self.main_window.go_to_add_contact() |
1056 | + contact_editor = self.app.main_window.go_to_add_contact() |
1057 | |
1058 | # Check if the contact list disapear and contact editor appears |
1059 | self.assertThat(list_page.visible, Eventually(Equals(False))) |
1060 | self.assertThat(contact_editor.visible, Eventually(Equals(True))) |
1061 | |
1062 | # cancel new contact without save |
1063 | - self.main_window.cancel() |
1064 | + self.app.main_window.cancel() |
1065 | |
1066 | # Check if the contact list is visible again |
1067 | self.assertThat(list_page.visible, Eventually(Equals(True))) |
1068 | |
1069 | # Check if the contact list still empty |
1070 | - list_view = self.main_window.get_contact_list_view() |
1071 | + list_view = self.app.main_window.get_contact_list_view() |
1072 | self.assertThat(list_view.count, Eventually(Equals(0))) |
1073 | |
1074 | def test_add_contact_without_name(self): |
1075 | # execute add new contact |
1076 | - contact_editor = self.main_window.go_to_add_contact() |
1077 | + contact_editor = self.app.main_window.go_to_add_contact() |
1078 | |
1079 | # Try to save a empty contact |
1080 | - acceptButton = self.main_window.get_button("save") |
1081 | + acceptButton = self.app.main_window.get_button("save") |
1082 | |
1083 | # Save button must be disabled |
1084 | self.assertThat(acceptButton.enabled, Eventually(Equals(False))) |
1085 | @@ -82,59 +84,59 @@ |
1086 | self.pointing_device.click_object(acceptButton) |
1087 | |
1088 | # Check if the contact editor still visbile |
1089 | - list_page = self.main_window.get_contact_list_page() |
1090 | + list_page = self.app.main_window.get_contact_list_page() |
1091 | |
1092 | self.assertThat(list_page.visible, Eventually(Equals(False))) |
1093 | self.assertThat(contact_editor.visible, Eventually(Equals(True))) |
1094 | |
1095 | # Check if the contact list still empty |
1096 | - list_view = self.main_window.get_contact_list_view() |
1097 | + list_view = self.app.main_window.get_contact_list_view() |
1098 | self.assertThat(list_view.count, Eventually(Equals(0))) |
1099 | |
1100 | def test_add_contact_with_full_name(self): |
1101 | test_contact = data.Contact(first_name='Fulano', last_name='de Tal') |
1102 | |
1103 | # execute add new contact |
1104 | - contact_editor = self.main_window.go_to_add_contact() |
1105 | + contact_editor = self.app.main_window.go_to_add_contact() |
1106 | contact_editor.fill_form(test_contact) |
1107 | |
1108 | # Save contact |
1109 | - self.main_window.save() |
1110 | + self.app.main_window.save() |
1111 | |
1112 | # Check if the contact list is visible again |
1113 | - list_page = self.main_window.get_contact_list_page() |
1114 | + list_page = self.app.main_window.get_contact_list_page() |
1115 | self.assertThat(list_page.visible, Eventually(Equals(True))) |
1116 | |
1117 | # Check if contact was added |
1118 | - list_view = self.main_window.get_contact_list_view() |
1119 | + list_view = self.app.main_window.get_contact_list_view() |
1120 | self.assertThat(list_view.count, Eventually(Equals(1))) |
1121 | |
1122 | def test_add_contact_with_first_name(self): |
1123 | test_contact = data.Contact(first_name='Fulano') |
1124 | |
1125 | # execute add new contact |
1126 | - contact_editor = self.main_window.go_to_add_contact() |
1127 | + contact_editor = self.app.main_window.go_to_add_contact() |
1128 | contact_editor.fill_form(test_contact) |
1129 | |
1130 | # Save contact |
1131 | - self.main_window.save() |
1132 | + self.app.main_window.save() |
1133 | |
1134 | # Check if contact was added |
1135 | - list_view = self.main_window.get_contact_list_view() |
1136 | + list_view = self.app.main_window.get_contact_list_view() |
1137 | self.assertThat(list_view.count, Eventually(Equals(1))) |
1138 | |
1139 | def test_add_contact_with_last_name(self): |
1140 | test_contact = data.Contact(last_name='de Tal') |
1141 | |
1142 | # execute add new contact |
1143 | - contact_editor = self.main_window.go_to_add_contact() |
1144 | + contact_editor = self.app.main_window.go_to_add_contact() |
1145 | contact_editor.fill_form(test_contact) |
1146 | |
1147 | # Save contact |
1148 | - self.main_window.save() |
1149 | + self.app.main_window.save() |
1150 | |
1151 | # Check if contact was added |
1152 | - list_view = self.main_window.get_contact_list_view() |
1153 | + list_view = self.app.main_window.get_contact_list_view() |
1154 | self.assertThat(list_view.count, Eventually(Equals(1))) |
1155 | |
1156 | def test_add_contact_with_name_and_phone(self): |
1157 | @@ -143,14 +145,14 @@ |
1158 | phones=[data.Phone.make()]) |
1159 | |
1160 | # execute add new contact |
1161 | - contact_editor = self.main_window.go_to_add_contact() |
1162 | + contact_editor = self.app.main_window.go_to_add_contact() |
1163 | contact_editor.fill_form(test_contact) |
1164 | |
1165 | # Save contact |
1166 | - self.main_window.save() |
1167 | + self.app.main_window.save() |
1168 | |
1169 | # Check if contact was added |
1170 | - list_view = self.main_window.get_contact_list_view() |
1171 | + list_view = self.app.main_window.get_contact_list_view() |
1172 | self.assertThat(list_view.count, Eventually(Equals(1))) |
1173 | |
1174 | def test_add_full_contact(self): |
1175 | @@ -160,19 +162,19 @@ |
1176 | test_contact.professional_details = [] |
1177 | |
1178 | # execute add new contact |
1179 | - contact_editor = self.main_window.go_to_add_contact() |
1180 | + contact_editor = self.app.main_window.go_to_add_contact() |
1181 | contact_editor.fill_form(test_contact) |
1182 | |
1183 | # Save contact |
1184 | - self.main_window.save() |
1185 | + self.app.main_window.save() |
1186 | |
1187 | # Check if contact was added |
1188 | - list_view = self.main_window.get_contact_list_view() |
1189 | + list_view = self.app.main_window.get_contact_list_view() |
1190 | self.assertThat(list_view.count, Eventually(Equals(1))) |
1191 | |
1192 | def test_email_label_save(self): |
1193 | # execute add new contact |
1194 | - contact_editor = self.main_window.go_to_add_contact() |
1195 | + contact_editor = self.app.main_window.go_to_add_contact() |
1196 | |
1197 | # fill name |
1198 | contact_editor.fill_form( |
1199 | @@ -186,13 +188,13 @@ |
1200 | self.set_email_address(2, "other@email.com", 2) |
1201 | |
1202 | # Save contact |
1203 | - self.main_window.save() |
1204 | + self.app.main_window.save() |
1205 | |
1206 | - contacts = self.main_window.select_many("ContactDelegate") |
1207 | + contacts = self.app.main_window.select_many("ContactDelegate") |
1208 | self.pointing_device.click_object(contacts[0]) |
1209 | |
1210 | # check if contacts was saved with the correct labels |
1211 | - view_page = self.main_window.get_contact_view_page() |
1212 | + view_page = self.app.main_window.get_contact_view_page() |
1213 | self.assertThat(view_page.visible, Eventually(Equals(True))) |
1214 | |
1215 | # check if we have 3 emails""" |
1216 | @@ -222,7 +224,7 @@ |
1217 | |
1218 | def test_phone_label_save(self): |
1219 | # execute add new contact |
1220 | - contact_editor = self.main_window.go_to_add_contact() |
1221 | + contact_editor = self.app.main_window.go_to_add_contact() |
1222 | |
1223 | # fill name |
1224 | contact_editor.fill_form( |
1225 | @@ -240,13 +242,13 @@ |
1226 | self.set_phone_number(4, "(000) 000-0004", 4) |
1227 | |
1228 | # Save contact |
1229 | - self.main_window.save() |
1230 | + self.app.main_window.save() |
1231 | |
1232 | - contacts = self.main_window.select_many("ContactDelegate") |
1233 | + contacts = self.app.main_window.select_many("ContactDelegate") |
1234 | self.pointing_device.click_object(contacts[0]) |
1235 | |
1236 | # check if contacts was saved with the correct labels |
1237 | - view_page = self.main_window.get_contact_view_page() |
1238 | + view_page = self.app.main_window.get_contact_view_page() |
1239 | self.assertThat(view_page.visible, Eventually(Equals(True))) |
1240 | |
1241 | # check if we have five phones""" |
1242 | |
1243 | === modified file 'tests/autopilot/address_book_app/tests/test_contactlist.py' |
1244 | --- tests/autopilot/address_book_app/tests/test_contactlist.py 2014-03-12 20:35:16 +0000 |
1245 | +++ tests/autopilot/address_book_app/tests/test_contactlist.py 2014-05-22 14:40:49 +0000 |
1246 | @@ -17,6 +17,6 @@ |
1247 | """Tests the contact list features""" |
1248 | |
1249 | def test_contact_list(self): |
1250 | - contact_list = self.main_window.get_contact_list_page() |
1251 | + contact_list = self.app.main_window.get_contact_list_page() |
1252 | self.assertThat(contact_list.visible, Eventually(Equals(True))) |
1253 | pass |
1254 | |
1255 | === modified file 'tests/autopilot/address_book_app/tests/test_create_new_from_uri.py' |
1256 | --- tests/autopilot/address_book_app/tests/test_create_new_from_uri.py 2014-05-22 14:40:49 +0000 |
1257 | +++ tests/autopilot/address_book_app/tests/test_create_new_from_uri.py 2014-05-22 14:40:49 +0000 |
1258 | @@ -23,17 +23,17 @@ |
1259 | super(TestCreateNewContactFromURI, self).setUp() |
1260 | |
1261 | def test_save_new_contact(self): |
1262 | - list_page = self.main_window.get_contact_list_page() |
1263 | + list_page = self.app.main_window.get_contact_list_page() |
1264 | list_page.isReady.wait_for(True) |
1265 | - |
1266 | - edit_page = self.main_window.get_contact_edit_page() |
1267 | + |
1268 | + edit_page = self.app.main_window.get_contact_edit_page() |
1269 | self.assertThat(edit_page.visible, Eventually(Equals(True))) |
1270 | |
1271 | # add name to the contact |
1272 | - firstNameField = self.main_window.wait_select_single( |
1273 | + firstNameField = self.app.main_window.wait_select_single( |
1274 | "TextInputDetail", |
1275 | objectName="firstName") |
1276 | - lastNameField = self.main_window.wait_select_single( |
1277 | + lastNameField = self.app.main_window.wait_select_single( |
1278 | "TextInputDetail", |
1279 | objectName="lastName") |
1280 | |
1281 | @@ -41,14 +41,14 @@ |
1282 | self.type_on_field(lastNameField, "de Tal") |
1283 | |
1284 | # save the contact |
1285 | - acceptButton = self.main_window.save() |
1286 | + self.app.main_window.save() |
1287 | |
1288 | # open contact view |
1289 | - contacts = self.main_window.select_many("ContactDelegate") |
1290 | + contacts = self.app.main_window.select_many("ContactDelegate") |
1291 | self.pointing_device.click_object(contacts[0]) |
1292 | - view_page = self.main_window.get_contact_view_page() |
1293 | + view_page = self.app.main_window.get_contact_view_page() |
1294 | self.assertThat(view_page.visible, Eventually(Equals(True))) |
1295 | - |
1296 | + |
1297 | |
1298 | # check if we have the new phone""" |
1299 | phone_group = view_page.select_single( |
1300 | |
1301 | === renamed file 'tests/autopilot/address_book_app/tests/test_emulators.py' => 'tests/autopilot/address_book_app/tests/test_custom_proxy_objects.py' |
1302 | --- tests/autopilot/address_book_app/tests/test_emulators.py 2014-03-01 11:03:45 +0000 |
1303 | +++ tests/autopilot/address_book_app/tests/test_custom_proxy_objects.py 2014-05-22 14:40:49 +0000 |
1304 | @@ -17,8 +17,6 @@ |
1305 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
1306 | |
1307 | from address_book_app import data, tests |
1308 | -from address_book_app.emulators import main_window |
1309 | - |
1310 | |
1311 | class ContactEditorTestCase(tests.AddressBookAppTestCase): |
1312 | |
1313 | @@ -29,7 +27,7 @@ |
1314 | # --elopio - 2014-03-01 |
1315 | test_contact.professional_details = [] |
1316 | |
1317 | - contact_editor = self.main_window.go_to_add_contact() |
1318 | + contact_editor = self.app.main_window.go_to_add_contact() |
1319 | |
1320 | contact_editor.fill_form(test_contact) |
1321 | |
1322 | |
1323 | === modified file 'tests/autopilot/address_book_app/tests/test_delete_contact.py' |
1324 | --- tests/autopilot/address_book_app/tests/test_delete_contact.py 2014-05-22 14:40:49 +0000 |
1325 | +++ tests/autopilot/address_book_app/tests/test_delete_contact.py 2014-05-22 14:40:49 +0000 |
1326 | @@ -35,7 +35,7 @@ |
1327 | def setUp(self): |
1328 | AddressBookAppTestCase.PRELOAD_VCARD = True |
1329 | super(TestDeleteSelectContact, self).setUp() |
1330 | - |
1331 | + |
1332 | def test_select(self): |
1333 | """ |
1334 | Delete a contact in pick mode |
1335 | @@ -45,15 +45,15 @@ |
1336 | contact in the list before and after the action. |
1337 | Note that it doesn't check which contact has been deleted. |
1338 | """ |
1339 | - listpage = self.main_window.get_contact_list_page() |
1340 | + listpage = self.app.main_window.get_contact_list_page() |
1341 | contacts_before = listpage.get_contacts() |
1342 | |
1343 | listpage.select_contacts_by_index(self.select) |
1344 | deleted = [] |
1345 | if self.action == "cancel": |
1346 | - self.main_window.cancel() |
1347 | + self.app.main_window.cancel() |
1348 | elif self.action == "delete": |
1349 | - listpage.delete(self.main_window) |
1350 | + listpage.delete(self.app.main_window) |
1351 | deleted = self.select |
1352 | |
1353 | contacts_after = listpage.get_contacts() |
1354 | |
1355 | === modified file 'tests/autopilot/address_book_app/tests/test_edit_contact.py' |
1356 | --- tests/autopilot/address_book_app/tests/test_edit_contact.py 2014-05-22 14:40:49 +0000 |
1357 | +++ tests/autopilot/address_book_app/tests/test_edit_contact.py 2014-05-22 14:40:49 +0000 |
1358 | @@ -10,6 +10,7 @@ |
1359 | from testtools.matchers import Equals |
1360 | from autopilot.matchers import Eventually |
1361 | |
1362 | +from address_book_app import data |
1363 | from address_book_app.tests import AddressBookAppTestCase |
1364 | |
1365 | |
1366 | @@ -17,6 +18,21 @@ |
1367 | """Tests edit a contact""" |
1368 | PHONE_NUMBERS = ['(333) 123-4567', '(333) 123-4568', '(222) 222-2222'] |
1369 | |
1370 | + PHONE_NUMBERS = ['(333) 123-4567', '(333) 123-4568', '(222) 222-2222'] |
1371 | + |
1372 | + def add_test_contact(self): |
1373 | + test_contact = data.Contact('test', 'test') |
1374 | + # TODO implement the filling of professional details. |
1375 | + # --elopio - 2014-03-01 |
1376 | + test_contact.professional_details = [] |
1377 | + |
1378 | + # execute add new contact |
1379 | + contact_editor = self.main_window.go_to_add_contact() |
1380 | + contact_editor.fill_form(test_contact) |
1381 | + |
1382 | + # Save contact |
1383 | + self.main_window.save() |
1384 | + |
1385 | def test_add_new_phone(self): |
1386 | self.add_contact("Fulano", "de Tal", [self.PHONE_NUMBERS[0]]) |
1387 | edit_page = self.edit_contact(0) |
1388 | @@ -28,15 +44,15 @@ |
1389 | self.create_new_detail(phoneGroup) |
1390 | |
1391 | # fill phone number |
1392 | - phone_number_1 = self.main_window.select_single( |
1393 | + phone_number_1 = self.app.main_window.select_single( |
1394 | "TextInputDetail", |
1395 | objectName="phoneNumber_1") |
1396 | self.type_on_field(phone_number_1, self.PHONE_NUMBERS[1]) |
1397 | |
1398 | - self.main_window.save() |
1399 | + self.app.main_window.save() |
1400 | |
1401 | # go back to view page |
1402 | - view_page = self.main_window.get_contact_view_page() |
1403 | + view_page = self.app.main_window.get_contact_view_page() |
1404 | self.assertThat(view_page.visible, Eventually(Equals(True))) |
1405 | |
1406 | # check if we have two phones""" |
1407 | @@ -62,10 +78,10 @@ |
1408 | self.clear_text_on_field(phone_number_1) |
1409 | |
1410 | # Save contact |
1411 | - self.main_window.save() |
1412 | + self.app.main_window.save() |
1413 | |
1414 | # check if we have onlye one phone |
1415 | - view_page = self.main_window.get_contact_view_page() |
1416 | + view_page = self.app.main_window.get_contact_view_page() |
1417 | phone_group = view_page.select_single( |
1418 | "ContactDetailGroupWithTypeView", |
1419 | objectName="phones") |
1420 | @@ -92,10 +108,10 @@ |
1421 | objectName="emailAddress_0") |
1422 | self.type_on_field(email_field, "fulano@internet.com.br") |
1423 | |
1424 | - self.main_window.save() |
1425 | + self.app.main_window.save() |
1426 | |
1427 | # go back to view page |
1428 | - view_page = self.main_window.get_contact_view_page() |
1429 | + view_page = self.app.main_window.get_contact_view_page() |
1430 | self.assertThat(view_page.visible, Eventually(Equals(True))) |
1431 | |
1432 | # check if we have a new email |
1433 | @@ -122,10 +138,10 @@ |
1434 | self.clear_text_on_field(email_address_0) |
1435 | |
1436 | # Save contact |
1437 | - self.main_window.save() |
1438 | + self.app.main_window.save() |
1439 | |
1440 | # check if the email list is empty |
1441 | - view_page = self.main_window.get_contact_view_page() |
1442 | + view_page = self.app.main_window.get_contact_view_page() |
1443 | emails_group = view_page.select_single( |
1444 | "ContactDetailGroupWithTypeView", |
1445 | objectName="emails") |
1446 | @@ -147,15 +163,15 @@ |
1447 | self.clear_text_on_field(last_name_field) |
1448 | |
1449 | # check if is possible to save a contact without name |
1450 | - self.main_window.save() |
1451 | - accept_button = self.main_window.get_button("save") |
1452 | + self.app.main_window.save() |
1453 | + accept_button = self.app.main_window.get_button("save") |
1454 | self.assertThat(accept_button.enabled, Eventually(Equals(False))) |
1455 | |
1456 | # Cancel edit |
1457 | - self.main_window.cancel() |
1458 | + self.app.main_window.cancel() |
1459 | |
1460 | # Check if the names still there |
1461 | - view_page = self.main_window.get_contact_view_page() |
1462 | + view_page = self.app.main_window.get_contact_view_page() |
1463 | self.assertThat(view_page.title, Eventually(Equals("Fulano de Tal"))) |
1464 | |
1465 | def test_im_type(self): |
1466 | @@ -177,9 +193,9 @@ |
1467 | self.select_a_value(im_address_0, im_value_selector, 0) |
1468 | |
1469 | # save contact |
1470 | - self.main_window.save() |
1471 | + self.app.main_window.save() |
1472 | |
1473 | - view_page = self.main_window.get_contact_view_page() |
1474 | + view_page = self.app.main_window.get_contact_view_page() |
1475 | |
1476 | # check if the type was saved correct |
1477 | im_type = view_page.select_single( |
1478 | |
1479 | === modified file 'tests/autopilot/address_book_app/tests/test_multiple_pick_mode.py' |
1480 | --- tests/autopilot/address_book_app/tests/test_multiple_pick_mode.py 2014-03-12 20:35:16 +0000 |
1481 | +++ tests/autopilot/address_book_app/tests/test_multiple_pick_mode.py 2014-05-22 14:40:49 +0000 |
1482 | @@ -22,7 +22,7 @@ |
1483 | super(TestMultiplePickerMode, self).setUp() |
1484 | |
1485 | def test_select_contacts(self): |
1486 | - pick_page = self.main_window.get_contact_list_pick_page() |
1487 | + pick_page = self.app.main_window.get_contact_list_pick_page() |
1488 | contacts = pick_page.select_many("ContactDelegate") |
1489 | # all selection marks should be visible |
1490 | selection_marks = [] |
1491 | |
1492 | === modified file 'tests/autopilot/address_book_app/tests/test_single_pick_mode.py' |
1493 | --- tests/autopilot/address_book_app/tests/test_single_pick_mode.py 2014-03-12 20:35:16 +0000 |
1494 | +++ tests/autopilot/address_book_app/tests/test_single_pick_mode.py 2014-05-22 14:40:49 +0000 |
1495 | @@ -22,7 +22,7 @@ |
1496 | super(TestSinglePickerMode, self).setUp() |
1497 | |
1498 | def test_select_single_contact(self): |
1499 | - pick_page = self.main_window.get_contact_list_pick_page() |
1500 | + pick_page = self.app.main_window.get_contact_list_pick_page() |
1501 | contacts = pick_page.select_many("ContactDelegate") |
1502 | # all selection marks should be visible |
1503 | selection_marks = [] |
1504 | |
1505 | === renamed file 'tests/autopilot/address_book_app/emulators/toolbar.py' => 'tests/autopilot/address_book_app/toolbar.py' |
FAILED: Continuous integration, rev:228 /code.launchpad .net/~elopio/ address- book-app/ refactoring_ tests1/ +merge/ 220654/ +edit-commit- message
No commit message was specified in the merge proposal. Click on the following link and set the commit message (if you want a jenkins rebuild you need to trigger it yourself):
https:/
http:// jenkins. qa.ubuntu. com/job/ address- book-app- ci/582/ jenkins. qa.ubuntu. com/job/ address- book-app- utopic- amd64-ci/ 35/console jenkins. qa.ubuntu. com/job/ address- book-app- utopic- armhf-ci/ 35/console jenkins. qa.ubuntu. com/job/ address- book-app- utopic- i386-ci/ 35/console jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/415/ console jenkins. qa.ubuntu. com/job/ generic- mediumtests- utopic/ 364/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/816/ console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/478/ console
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/address- book-app- ci/582/ rebuild
http://