Merge lp:~allanlesage/address-book-app/abook_navigation_favorites into lp:address-book-app

Proposed by Allan LeSage
Status: Superseded
Proposed branch: lp:~allanlesage/address-book-app/abook_navigation_favorites
Merge into: lp:address-book-app
Prerequisite: lp:~jibel/address-book-app/abook_delete_contact_pickmode
Diff against target: 908 lines (+712/-11)
16 files modified
debian/control (+1/-0)
tests/autopilot/address_book_app/emulators/__init__.py (+12/-0)
tests/autopilot/address_book_app/emulators/address_book.py (+73/-0)
tests/autopilot/address_book_app/emulators/contact_list_page.py (+201/-0)
tests/autopilot/address_book_app/emulators/contact_view.py (+97/-0)
tests/autopilot/address_book_app/emulators/main_window.py (+3/-5)
tests/autopilot/address_book_app/emulators/toolbar.py (+38/-0)
tests/autopilot/address_book_app/helpers.py (+55/-0)
tests/autopilot/address_book_app/tests/__init__.py (+25/-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 (+72/-0)
tests/autopilot/address_book_app/tests/test_edit_contact.py (+4/-0)
tests/autopilot/address_book_app/tests/test_favorites.py (+121/-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:~allanlesage/address-book-app/abook_navigation_favorites
Reviewer Review Type Date Requested Status
Leo Arias (community) code review Approve
PS Jenkins bot continuous-integration Needs Fixing
Jean-Baptiste Lallement (community) Needs Fixing
Chris Gagnon (community) Needs Fixing
Review via email: mp+205264@code.launchpad.net

This proposal has been superseded by a proposal from 2014-03-11.

Commit message

Add favoriting tests.

Description of the change

Add some favoriting tests; meanwhile move the existing contacts db out of the way during tests--this was necessary because favoriting appears broken at the moment using the in-memory QTCONTACTS override (don't know if this is a bug or not). So bounce two services (address-book-service and evolution-addressbook-factory) and preserve the existing contacts.db by moving it aside temporarily. Also make in-memory database override optional.

Note that the new address_book emulator comes mostly from iahmad and om26er but I've modified their method to use a templated vCard using jinja2--I'm open to a better method of generating these cards; a python-vobject module exists but ChrisGagnon notes that it's not Python3 so we'd like not to adopt.

To post a comment you must log in.
132. By Allan LeSage

Merged trunk.

133. By Allan LeSage

PEP8 and pyflakes corrections.

134. By Allan LeSage

Add a python-psutil dependency.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:132
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://code.launchpad.net/~allanlesage/address-book-app/abook_navigation_favorites/+merge/205264/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/address-book-app-ci/377/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/87
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/87
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/87/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/87
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/2990/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2723/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2626/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/2992
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/2992/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2724
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2724/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5143/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3722

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/377/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Chris Gagnon (chris.gagnon) wrote :

The emulators all functions all need docstrings lp #137 is good example of how it should be done, but it's missing the raises.

134 + def get_contact_by_name(self,
135 + contact_name,
136 + parent_delegate_type='ContactDelegate'):
137 + """Find a label with text matching contact name.
138 +
139 + :param contact_name: Name of the contact, e.g. 'Fulano de Tal'
140 + :param parent_delegate_type: 'ContactDelegate' or 'FavoriteDelegate'
141 + :raises StateNotFoundError: if contact_name and parent_delegate_type is not found

I get this error on all the favorites tests

Traceback (most recent call last):
  File "/home/phablet/abook_navigation_favorites/tests/autopilot/address_book_app/tests/test_favorites.py", line 85, in test_switch_between_favorites
    list_page.click_contact_by_name('Beth Whittard')
  File "/usr/lib/python2.7/dist-packages/autopilot/introspection/dbus.py", line 523, in __getattr__
    (self.__class__.__name__, name))
AttributeError: Class 'ContactListPage' has no attribute 'click_contact_by_name'

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:134
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://code.launchpad.net/~allanlesage/address-book-app/abook_navigation_favorites/+merge/205264/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/address-book-app-ci/379/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/89
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/89
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/89/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/89
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/2998/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2730/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2634/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3000
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3000/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2731
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2731/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5150/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3730

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/379/rebuild

review: Needs Fixing (continuous-integration)
135. By Allan LeSage

Resolve env prob which failed some favorites tests on transition from in-memory to faked db.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:135
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://code.launchpad.net/~allanlesage/address-book-app/abook_navigation_favorites/+merge/205264/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/address-book-app-ci/380/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/90
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/90
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/90/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/90
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3000/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2732/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2636/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3002
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3002/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2733
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2733/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5152/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3736

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/380/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Chris Gagnon (chris.gagnon) wrote :

There are a lot of pep8 issues in these tests, the ones that should be fixed in this MP are

test_favorites.py:94:80: E501 line too long (103 > 79 characters)
test_favorites.py:110:33: E203 whitespace before ':'
test_favorites.py:110:80: E501 line too long (82 > 79 characters)

review: Needs Fixing
Revision history for this message
Jean-Baptiste Lallement (jibel) wrote :

On an LXC container with all updates applied, I get the following error, maybe because a service is not running:
0:45:55.249 INFO globals:57 - ************************************************************
10:45:55.249 INFO globals:58 - Starting test address_book_app.tests.test_favorites.TestFavorite.test_save_multiple_favorites
10:45:55.249 ERROR content:49 - Could not add content object 'None' due to IO Error: [Errno 13] Permission denied: '/var/log/syslog'
10:45:55.333 INFO _launcher:152 - Launching process: ['/usr/bin/address-book-app', '-testability', '--desktop_file_hint=/usr/share/applications/address-book-app.desktop']
10:45:56.409 DEBUG dbus:431 - Selecting objects of type MainWindow with attributes: {}
10:45:56.630 DEBUG dbus:431 - Selecting objects of type MainWindow with attributes: {}
10:45:56.645 DEBUG dbus:431 - Selecting objects of type ContactListPage with attributes: {'objectName': 'contactListPage'}
10:45:56.679 DEBUG dbus:431 - Selecting objects of type Label with attributes: {'text': 'Beth Whittard'}
10:45:56.704 ERROR contact_list_page:114 - Contact Beth Whittard not found.
10:45:56.720 INFO _launcher:340 - waiting for process to exit.
10:45:56.720 INFO _launcher:266 - Killing process 9593
}}}

Traceback (most recent call last):
  File "/home/ubuntu/Touch/GapCoverage/src/abook_navigation_favorites/tests/autopilot/address_book_app/tests/test_favorites.py", line 70, in test_save_multiple_favorites
    list_page.click_contact_by_name('Beth Whittard')
  File "/home/ubuntu/Touch/GapCoverage/src/abook_navigation_favorites/tests/autopilot/address_book_app/emulators/contact_list_page.py", line 127, in click_contact_by_name
    contact_name, parent_delegate_type)
  File "/home/ubuntu/Touch/GapCoverage/src/abook_navigation_favorites/tests/autopilot/address_book_app/emulators/contact_list_page.py", line 112, in get_contact_by_name
    raise StateNotFoundError('Label')
StateNotFoundError: State not found for class 'Label'.

======================================

About jinja2, I'd remove the dependency on jinja2 because it forces the installation of a new package on the device and the logic is simple enough to be implemented with str.format() and standard string functions.

======================================

Data sample: Would it be possible to pre-load vcards instead of creating/updating contacts. contacts.db backup/restore and services restart adds a lot of complexity to the test and also requires an additional dependency on psutil.

review: Needs Fixing
136. By Allan LeSage

A fix for importing ContactList which broke individually-running tests.

137. By Allan LeSage

Added delete favorite test.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:136
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://code.launchpad.net/~allanlesage/address-book-app/abook_navigation_favorites/+merge/205264/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/address-book-app-ci/381/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/91
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/91
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/91/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/91
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3081/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2793/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2706/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3083
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3083/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2795
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2795/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5207/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3812

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/381/rebuild

review: Needs Fixing (continuous-integration)
138. By Allan LeSage

Add assertion for deleted contact not in contacts.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:138
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://code.launchpad.net/~allanlesage/address-book-app/abook_navigation_favorites/+merge/205264/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/address-book-app-ci/382/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/92
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/92
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/92/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/92
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3084/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2795/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2709/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3086
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3086/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2797
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2797/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5209/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3814

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/382/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:138
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://code.launchpad.net/~allanlesage/address-book-app/abook_navigation_favorites/+merge/205264/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/address-book-app-ci/383/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/93
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/93
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/93/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/93
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3088/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2798/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2714/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3090
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3090/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2800
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2800/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5212/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3817

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/383/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Chris Gagnon (chris.gagnon) wrote :

The following should be moved into an emulator, maybe the 2 star is illuminated could moved in to one star_is_illuminated_for_number function that returns true or false depending on if the star is illuminated?

(tests/autopilot/address_book_app/tests/test_favorites.py)
+ def get_contact_detail_phone_number_view(self, phone_number):
+ phone_number_label = self.main_window.select_single('Label',
+ text=phone_number)
+ return get_nearest_parent_matching_type(
+ phone_number_label,
+ 'ContactDetailPhoneNumberView')
+
+ def star_is_illuminated_for_phone_number(self, phone_number):
+ contact_detail = self.get_contact_detail_phone_number_view(
+ phone_number)
+ return contact_detail.iconSource == 'artwork:/favorite-selected.svg'
+
+ def star_is_unilluminated_for_phone_number(self, phone_number):
+ contact_detail = self.get_contact_detail_phone_number_view(
+ phone_number)
+ return contact_detail.iconSource == 'artwork:/favorite-unselected.svg'
+
+ def click_phone_number(self, phone_number):
+ # TODO select_many and raise if > 1?
+ phone_number_label = self.main_window.wait_select_single(
+ 'Label',
+ text=phone_number)
+ self.pointing_device.click_object(phone_number_label)

review: Needs Fixing
139. By Allan LeSage

Some pep8 and docstring fixes.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:139
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://code.launchpad.net/~allanlesage/address-book-app/abook_navigation_favorites/+merge/205264/+edit-commit-message

http://jenkins.qa.ubuntu.com/job/address-book-app-ci/384/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/94
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/94
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/94/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/94
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3131/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2820/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2750/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3133
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3133/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2822
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2822/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5232/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3843

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/384/rebuild

review: Needs Fixing (continuous-integration)
140. By Allan LeSage

Establish contact_view emulator, some massaging.

Revision history for this message
Chris Gagnon (chris.gagnon) wrote :

tests/autopilot/address_book_app/emulators/address_book.py needs docstrings like the contact list page emulator.

review: Needs Fixing
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:140
http://jenkins.qa.ubuntu.com/job/address-book-app-ci/385/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/95
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/95
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/95/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/95
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3140/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2827/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2757/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3142
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3142/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2829
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2829/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5237/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3850

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/385/rebuild

review: Needs Fixing (continuous-integration)
141. By Allan LeSage

Add missing contact_view emulator.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:141
http://jenkins.qa.ubuntu.com/job/address-book-app-ci/387/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/97
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/97
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/97/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/97
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3144/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2829/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2762/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3146
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3146/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2831
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2831/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5239/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3854

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/387/rebuild

review: Needs Fixing (continuous-integration)
142. By Allan LeSage

Remove dependency on psutil.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:142
http://jenkins.qa.ubuntu.com/job/address-book-app-ci/389/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/99
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/99
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/99/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/99
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3146/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2831/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2764/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3148
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3148/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2833
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2833/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5241/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3856

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/389/rebuild

review: Needs Fixing (continuous-integration)
143. By Allan LeSage

Remove jinja2 dependency, transform vcard template to string.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:143
http://jenkins.qa.ubuntu.com/job/address-book-app-ci/393/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/103
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/103
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/103/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/103
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3172/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2856/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2789/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3174
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3174/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2858
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2858/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5265/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3883

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/393/rebuild

review: Needs Fixing (continuous-integration)
144. By Allan LeSage

Add proper docstrings to address_book emulator.

145. By Allan LeSage

Temp commit of contacts-db-wiping for ChrisGagnon's perusal.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:144
http://jenkins.qa.ubuntu.com/job/address-book-app-ci/394/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/104
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/104
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/104/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/104
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3178/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2861/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2795/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3180
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3180/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2863
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2863/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5271/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3890

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/394/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:144
http://jenkins.qa.ubuntu.com/job/address-book-app-ci/395/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/105
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/105
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/105/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/105
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3181/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2862/console
    FAILURE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2797/console
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3183
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3183/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2864
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2864/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5272/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/3891

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/395/rebuild

review: Needs Fixing (continuous-integration)
146. By Allan LeSage

New helper uses syncevolution to manipulate contacts db.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Jean-Baptiste Lallement (jibel) wrote :

1. You need to add syncevolution as a dependency of address-book-app-autopilot otherwise the test will fail on desktop. syncevolution is only a dependency ubuntu-touch which is not installed on desktop.

2. On desktop I always get this failure
11:53:00.053 INFO globals:58 - Starting test address_book_app.tests.test_favorites.TestFavorite.test_save_multiple_favorites
11:53:00.054 ERROR content:49 - Could not add content object 'None' due to IO Error: [Errno 13] Permission denied: '/var/log/syslog'
11:53:00.240 INFO _launcher:152 - Launching process: ['/usr/bin/address-book-app', '-testability', '--desktop_file_hint=/usr/share/applications/address-book-app.desktop']
11:53:01.314 DEBUG dbus:431 - Selecting objects of type MainWindow with attributes: {}
11:53:01.533 DEBUG dbus:431 - Selecting objects of type MainWindow with attributes: {}
11:53:01.548 DEBUG dbus:431 - Selecting objects of type ContactListPage with attributes: {'objectName': 'contactListPage'}
11:53:01.576 DEBUG dbus:431 - Selecting objects of type Label with attributes: {'text': 'Beth Whittard'}
11:53:01.593 ERROR contact_list_page:114 - Contact Beth Whittard not found.
11:53:02.893 INFO _launcher:340 - waiting for process to exit.
11:53:02.893 INFO _launcher:266 - Killing process 7151
}}}

Traceback (most recent call last):
  File "/home/ubuntu/Touch/GapCoverage/src/abook/ale.abook_navigation_favorites.205264/tests/autopilot/address_book_app/tests/test_favorites.py", line 50, in test_save_multiple_favorites
    contact_list_page.click_contact_by_name('Beth Whittard')
  File "/home/ubuntu/Touch/GapCoverage/src/abook/ale.abook_navigation_favorites.205264/tests/autopilot/address_book_app/emulators/contact_list_page.py", line 137, in click_contact_by_name
    contact_name, parent_delegate_type)
  File "/home/ubuntu/Touch/GapCoverage/src/abook/ale.abook_navigation_favorites.205264/tests/autopilot/address_book_app/emulators/contact_list_page.py", line 112, in get_contact_by_name
    raise StateNotFoundError('Label')
StateNotFoundError: State not found for class 'Label'.

review: Needs Fixing
Revision history for this message
Jean-Baptiste Lallement (jibel) wrote :

For the StateNotFoundError, I tried this patch and it seems to be working.

'=== modified file 'tests/autopilot/address_book_app/emulators/contact_list_page.py'
'--- tests/autopilot/address_book_app/emulators/contact_list_page.py 2014-02-11 21:15:02 +0000
'+++ tests/autopilot/address_book_app/emulators/contact_list_page.py 2014-02-13 12:11:56 +0000
'@@ -100,9 +100,18 @@
' :raises StateNotFoundError: if contact_name is not found
' """
' try:
'- contact_name_labels = self.select_many(
'- "Label",
'- text=contact_name)
'+ # Note:
'+ # There is no wait_select_many, this loop simulates it and retries
'+ # 3 times or until the list is populated. If the list is still
'+ # empty after the loop, the exception StateNotFoundError('Label')
'+ # will be raised
'+ for i in range(3):
'+ contact_name_labels = self.select_many(
'+ "Label",
'+ text=contact_name)
'+ if contact_name_labels != []:
'+ break
'+ sleep(.5)
' for contact_name_label in contact_name_labels:
' # we could have a contact or a favorite
' if get_nearest_parent_matching_type(

Revision history for this message
Jean-Baptiste Lallement (jibel) wrote :
147. By Allan LeSage

Use Eventually matcher to assert contacts are returned by name.

Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

I do not think this is the right approach, you should populate the vcard contact with some favorite contacts, this will allow you to test the functionality without touch on EDS.

Revision history for this message
Leo Arias (elopio) wrote :
Download full text (4.1 KiB)

55 +# Borrowed the following helper class from
56 +# lp:address-book-service/examples/contacts.py

Wouldn't it be better if this is packaged and made available as address-book-services test helpers? That way the code is on the same project that provides the service and we don't have to duplicate it. Is that possible?
This is not a blocker for this branch, just part of my ranting about developers not writing anything for testability, and we covering for their faults.

=== added file 'tests/autopilot/address_book_app/emulators/address_book.py'

I'd say this file needs unit test. With the query method we have all we need to check that the other methods are working correctly.

258 + # TODO select_many and raise if > 1?

wait_select_single will raise an exception if there's more than one item matching, so I think that's already covered. Unless I didn't get the comment.

299 + try:
300 + buttons = self.select_many("Button",
301 + objectName=objectname)
302 + for button in buttons:
303 + if button.visible:
304 + self.pointing_device.click_object(button)
305 + except StateNotFoundError:
306 + LOGGER.error(
307 + 'Button with objectName "{0}" not found.'.format(objectname)
308 + )
309 + raise

Please note that you are not breaking out of the for loop, so if there are many visible buttons, all of them will be clicked. That doesn't sound like the goal of this method.

I find this weird, as the purpose of the object name is to identify things uniquely. So if there are many buttons with the same name, we need to change the name.
This code could be simplified like this:
self.select_single('Button', objectName=object_name, visible=True)

That will raise an exception if there's no button with that name, if the button with that name is not visible, and if there are many buttons matching the query.

332 + def star_is_illuminated_for_phone_number(self, phone_number):

I think we should keep a higher language, closer to the design user stories. From a user perspective, a illuminated starts means that the phone number is favorite, so I would do this:

def is_phone_favorite(self, phone_number):
    self._is_star_illuminated_for_phone_number(phone_number)

That way we keep as private the implementation detail, and on the tests we call the public higher level method that is more likely to remain stable. If in the future design decides to change the widget of a favorite number from a start to a drop down list, we don't have to change any tests, just the method we call inside is_phone_favorite.

576 + contact_list_page.click_contact_by_name('Fulano de Tal')
577 + contact_view = self.main_window.get_contact_view_page()

Here again, clicking a contact is actually an implementation details and it would be better as a private method in the emulator.
I prefer when the test reads like this:

contact_view = contact_list_page.open_contact_details(name='Fulano de Tal')

There's a nice selenium pattern called the page object: https://code.google.com/p/selenium/wiki/PageObjects
You might find it interesting to read. Not everything in there applies to the desktop, but some things do and I always try to follow them.

I find this as the most concise guide to avoid future pains with...

Read more...

review: Needs Fixing (code review)
148. By Allan LeSage

Merged trunk, resolving conflicts (test passing).

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

Instead of adding contacts on the address-book-service. We should fix the in-memory backend to support favorite contacts.

We will go back to this MR, as soon as this bug get fixed: https://bugs.launchpad.net/bugs/1279916

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Chris Gagnon (chris.gagnon) wrote :

holding back on this MP until a bug is fixed is blocking other apps from landing tests. like the dialer and the messaging-app. When the in-memory backend is fixed we can change the helper to use it instead of using the address-book-service.

We want one place to add and remove contacts, so we don't have to update every project when there is a change. the address-book-app is the most logical place to keep the helper.

The tests are working currently, there is no reason to block landing the tests from landing.

149. By Allan LeSage

Add some unit tests for our address_book emulator, removing any speculative functionality ;) .

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
150. By Allan LeSage

After discussing with thomi and elopio, in the interest of landing, remove unit tests for autopilot emulators.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:150
http://jenkins.qa.ubuntu.com/job/address-book-app-ci/409/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/119
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/119
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/119/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/119
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3309
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/2975/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/2915
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3311
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3311/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2977
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/2977/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5379/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/4077

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/409/rebuild

review: Needs Fixing (continuous-integration)
151. By Allan LeSage

Restore address_book emulator, some important quotation-mark changes per elopio.

152. By Allan LeSage

Actually restore address_book emulator :/ , remove emulators tests to expedite landing.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

Could you guys try to use this service branch: https://code.launchpad.net/~renatofilho/address-book-service/dummy-mode/+merge/208459, to test this functionality?

And instead of adding the contacts direct in the server could you add it using vcard files? this will make the test more flexible in case of we change the server API.

Revision history for this message
Renato Araujo Oliveira Filho (renatofilho) wrote :

A MR to refactory the contact and favorite list is in progress to get merged, we should adapt the test to this new layout.

https://code.launchpad.net/~renatofilho/address-book-app/new-favorite-list/+merge/208223

153. By Allan LeSage

Merge trunk.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
154. By Allan LeSage

Docstring improvements and add autopilot action logger to emulators.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
155. By Allan LeSage

Adopt page pattern per elopio's suggestion.

156. By Allan LeSage

Simplify emulators' click_button per elopio's request.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :

FAILED: Continuous integration, rev:156
http://jenkins.qa.ubuntu.com/job/address-book-app-ci/432/
Executed test runs:
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-amd64-ci/142
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/142
        deb: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-armhf-ci/142/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/address-book-app-trusty-i386-ci/142
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty/3577
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-trusty-touch/3190/console
    UNSTABLE: http://jenkins.qa.ubuntu.com/job/autopilot-testrunner-otto-trusty/3149
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3581
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-amd64/3581/artifact/work/output/*zip*/output.zip
    SUCCESS: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/3192
        deb: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-builder-trusty-armhf/3192/artifact/work/output/*zip*/output.zip
    FAILURE: http://jenkins.qa.ubuntu.com/job/generic-mediumtests-runner-mako/5575/console
    SUCCESS: http://s-jenkins.ubuntu-ci:8080/job/touch-flash-device/4364

Click here to trigger a rebuild:
http://s-jenkins.ubuntu-ci:8080/job/address-book-app-ci/432/rebuild

review: Needs Fixing (continuous-integration)
Revision history for this message
Allan LeSage (allanlesage) wrote :

Ready for review again, ubuntu-qa.

Concerning quotation marks for strings, I've straightened out for this commit (leaving triple-double-quotation-marks docstrings as-is), also added the log-action decorators.

Implemented the page pattern as elopio describes, thanks for that advice--formerly I've tried to keep the test-descriptions as stupid as possible, i.e. responding to visual stimulus, however I see the utility of separating the intention of the user from the visual implementation. Stashed the 'concise guide' for future reference :) .

Adjusted the simple selection singled out, removed an obsolete TODO.

elopio and I discussed adding unit tests with Thomi in Oakland, agreed that it'll be a good thing but exempted this MP (if we've changed our minds I can recover the tests I wrote for this emulator).

Lastly I've moved some of the emulator goodness to a 'helpers.py' file (although the packaging of this is opaque to me).

Revision history for this message
Leo Arias (elopio) wrote :

37 +#!/usr/bin/env python

I think you don't need this, as this file will never be executed as a script.

190 + @autopilot_logging.log_action(logger.info)

This log is unnecessary, as you you are already logging the action when calling cancel or delete.
What I would do is turn this:

191 + def click_button(self, objectname):

into _click_button, so we know it shouldn't be used outside the class. If we need to click another button, we will need to create a method for it.

214 + def get_contact_by_name(self,

I would rename this to _get_contact_label_by_name.
With the current name, it sounds like something that a test would call to get the text inside the label showing the contact name.

238 + raise StateNotFoundError('Label')
239 + except StateNotFoundError:
240 + logger.error('...')
241 + raise

I would prefer here to return our own exception, to differentiate it from something that autopilot throws.

Something like:
raise AddressBookError('Contact {} not found.'.format(contact_name))

I don't want to delay your branch anymore. It's already really nice. I have some comments that I think would make it a little more readable, but I'll make a note to discuss with you about them next week.

Thanks a lot, nice work.

review: Approve (code review)
Revision history for this message
Allan LeSage (allanlesage) wrote :

Thanks elopio for your review; I'll adapt some of your further suggestions after I've sorted renato's new address-book method, stay tuned. . . .

Unmerged revisions

156. By Allan LeSage

Simplify emulators' click_button per elopio's request.

155. By Allan LeSage

Adopt page pattern per elopio's suggestion.

154. By Allan LeSage

Docstring improvements and add autopilot action logger to emulators.

153. By Allan LeSage

Merge trunk.

152. By Allan LeSage

Actually restore address_book emulator :/ , remove emulators tests to expedite landing.

151. By Allan LeSage

Restore address_book emulator, some important quotation-mark changes per elopio.

150. By Allan LeSage

After discussing with thomi and elopio, in the interest of landing, remove unit tests for autopilot emulators.

149. By Allan LeSage

Add some unit tests for our address_book emulator, removing any speculative functionality ;) .

148. By Allan LeSage

Merged trunk, resolving conflicts (test passing).

147. By Allan LeSage

Use Eventually matcher to assert contacts are returned by name.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2013-12-11 15:03:32 +0000
3+++ debian/control 2014-02-27 22:11:08 +0000
4@@ -68,6 +68,7 @@
5 libqt5test5,
6 libqt5widgets5,
7 ubuntu-ui-toolkit-autopilot,
8+ syncevolution,
9 address-book-app (>= ${binary:Version}),
10 Description: Test package for address-book-app
11 Autopilot tests for the address-book-app package
12
13=== modified file 'tests/autopilot/address_book_app/emulators/__init__.py'
14--- tests/autopilot/address_book_app/emulators/__init__.py 2013-07-09 18:42:30 +0000
15+++ tests/autopilot/address_book_app/emulators/__init__.py 2014-02-27 22:11:08 +0000
16@@ -4,3 +4,15 @@
17 # This program is free software: you can redistribute it and/or modify it
18 # under the terms of the GNU General Public License version 3, as published
19 # by the Free Software Foundation.
20+
21+
22+def get_nearest_parent_matching_type(child, desired_type):
23+ """Climb down the widget tree, return first instance of desired_type"""
24+ while type(child).__name__ != desired_type:
25+ parent = child.get_parent()
26+ if type(child).__name__ == 'AddressBookApp':
27+ # we reached the root and found nothing
28+ return None
29+ else:
30+ child = parent
31+ return child
32
33=== added file 'tests/autopilot/address_book_app/emulators/address_book.py'
34--- tests/autopilot/address_book_app/emulators/address_book.py 1970-01-01 00:00:00 +0000
35+++ tests/autopilot/address_book_app/emulators/address_book.py 2014-02-27 22:11:08 +0000
36@@ -0,0 +1,73 @@
37+#!/usr/bin/env python
38+# -*- encoding: utf-8 -*-
39+#
40+# Copyright 2014 Canonical Ltd.
41+#
42+# This program is free software; you can redistribute it and/or modify
43+# it under the terms of the GNU Lesser General Public License as published by
44+# the Free Software Foundation; version 3.
45+#
46+# This program is distributed in the hope that it will be useful,
47+# but WITHOUT ANY WARRANTY; without even the implied warranty of
48+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
49+# GNU Lesser General Public License for more details.
50+#
51+# You should have received a copy of the GNU Lesser General Public License
52+# along with this program. If not, see <http://www.gnu.org/licenses/>.
53+#
54+
55+# Borrowed the following helper class from
56+# lp:address-book-service/examples/contacts.py
57+
58+import dbus
59+
60+DBUS_IFACE_ADD_BOOK = 'com.canonical.pim.AddressBook'
61+DBUS_IFACE_ADD_BOOKVIEW = 'com.canonical.pim.AddressBookView'
62+
63+TEL_WORK_TEMPLATE = """
64+TEL;TYPE=WORK,VOICE;PID=1.1:{tel_work}"""
65+
66+VCARD_TEMPLATE = """BEGIN:VCARD
67+VERSION:3.0
68+N:{name}
69+FN:{f_name}
70+TEL;TYPE=HOME,VOICE;PID=1.1:{tel_home}{tel_work}
71+END:VCARD
72+"""
73+
74+
75+class AddressBook(object):
76+
77+ def __init__(self):
78+ self.bus = dbus.SessionBus()
79+ self.addr = self.bus.get_object('com.canonical.pim',
80+ '/com/canonical/pim/AddressBook')
81+ self.addr_iface = dbus.Interface(self.addr,
82+ dbus_interface=DBUS_IFACE_ADD_BOOK)
83+
84+ def create_contact(self,
85+ name,
86+ f_name=None,
87+ tel_home=None,
88+ tel_work=None,
89+ email=None):
90+ """Create a contact in address-book via dbus interface.
91+
92+ NOTE that if only one phone number is specified, it must be tel_home.
93+
94+ :param name: name of the contact, e.g. 'Lincoln;Abraham'
95+ :param f_name: formatted name of the contact, e.g. 'Abraham Lincoln'
96+ :param tel_home: telephone number string, e.g. '92340981'
97+ :param tel_work: telephone number string, e.g. '23984719'
98+ :param email: e-mail address string, e.g. 'abe@whitehouse.gov'
99+ """
100+ contact_dict = {
101+ 'name': name,
102+ 'f_name': f_name if f_name else '',
103+ 'tel_home': tel_home if tel_home else '',
104+ 'tel_work': TEL_WORK_TEMPLATE.format(
105+ tel_work=tel_work) if tel_work else '',
106+ 'email': email if email else ''
107+ }
108+ vcard = VCARD_TEMPLATE.format(**contact_dict)
109+ return self.addr_iface.createContact(vcard, "")
110
111=== added file 'tests/autopilot/address_book_app/emulators/contact_list_page.py'
112--- tests/autopilot/address_book_app/emulators/contact_list_page.py 1970-01-01 00:00:00 +0000
113+++ tests/autopilot/address_book_app/emulators/contact_list_page.py 2014-02-27 22:11:08 +0000
114@@ -0,0 +1,201 @@
115+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
116+# Copyright 2014 Canonical
117+#
118+# This program is free software: you can redistribute it and/or modify it
119+# under the terms of the GNU General Public License version 3, as published
120+# by the Free Software Foundation.
121+
122+""" ContactListPage emulator for Addressbook App tests """
123+
124+import logging
125+from time import sleep
126+
127+from autopilot import logging as autopilot_logging
128+from autopilot.introspection.dbus import StateNotFoundError
129+from autopilot.matchers import Eventually
130+from testtools.matchers import GreaterThan
131+from ubuntuuitoolkit import emulators as uitk
132+
133+from address_book_app.emulators import get_nearest_parent_matching_type
134+
135+logger = logging.getLogger(__name__)
136+
137+
138+class ContactListPage(uitk.UbuntuUIToolkitEmulatorBase):
139+ """ ContactListPage emulator class """
140+
141+ def __init__(self, *args):
142+ self.contacts = None
143+ self.selection_marks = []
144+ self.selected_marks = []
145+ super(ContactListPage, self).__init__(*args)
146+
147+ def get_contacts(self):
148+ """Returns a list of ContactDelegate objects.
149+
150+ Also populate self.selection_marks.
151+
152+ :return: The list of ContactDelegate objects.
153+
154+ """
155+ sleep(1)
156+ self.contacts = self.select_many("ContactDelegate")
157+ self.selection_marks = []
158+ for contact in self.contacts:
159+ if contact.visible:
160+ mark = contact.select_single("QQuickRectangle",
161+ objectName="selectionMark")
162+ self.selection_marks.append(mark)
163+ return self.contacts
164+
165+ @autopilot_logging.log_action(logger.info)
166+ def select_contacts_by_index(self, indices):
167+ """Select contacts corresponding to the list of index in indices.
168+
169+ :param indices: List of integer indices of contacts to select.
170+
171+ """
172+ self.deselect_all()
173+
174+ # Select matching indices
175+ for idx in indices:
176+ self.selected_marks.append(self.selection_marks[idx])
177+ self.pointing_device.click_object(self.selection_marks[idx])
178+
179+ @autopilot_logging.log_action(logger.info)
180+ def deselect_all(self):
181+ """Deselect every contact."""
182+ contacts = self.select_many("ContactDelegate")
183+ self.selected_marks = []
184+ for contact in contacts:
185+ if contact.selected:
186+ mark = contact.select_single("QQuickRectangle",
187+ objectName="selectionMark")
188+ self.pointing_device.click_object(mark)
189+
190+ @autopilot_logging.log_action(logger.info)
191+ def click_button(self, objectname):
192+ """Press a button that matches objectname
193+
194+ :param objectname: The name of the object.
195+ :raise StateNotFoundError: When a matching button is not found.
196+
197+ """
198+ buttons = self.select_single("Button",
199+ objectName=objectname,
200+ visible=True)
201+ self.pointing_device.click_object(button)
202+
203+ @autopilot_logging.log_action(logger.info)
204+ def cancel(self):
205+ """Press the cancel button displayed when pick mode is enabled."""
206+ self.click_button("DialogButtons.rejectButton")
207+
208+ @autopilot_logging.log_action(logger.info)
209+ def delete(self):
210+ """Press the delete button displayed when pick mode is enabled."""
211+ self.click_button("DialogButtons.acceptButton")
212+ self.get_contacts()
213+
214+ def get_contact_by_name(self,
215+ contact_name,
216+ parent_delegate_type='ContactDelegate'):
217+ """Find a label with text matching contact name.
218+
219+ :param contact_name: The name of the contact, e.g. 'Fulano de Tal'.
220+ :param parent_delegate_type: 'ContactDelegate' or 'FavoriteDelegate'.
221+ :return: The label for a matching contact.
222+ :raises StateNotFoundError: If the contact_name is not found.
223+
224+ """
225+ try:
226+ assert(lambda: len(self.select_many("Label",
227+ text=contact_name)),
228+ Eventually(GreaterThan(0)))
229+ contact_name_labels = self.select_many(
230+ "Label",
231+ text=contact_name)
232+ for contact_name_label in contact_name_labels:
233+ # we could have a contact or a favorite
234+ if get_nearest_parent_matching_type(
235+ contact_name_label,
236+ parent_delegate_type):
237+ return contact_name_label
238+ raise StateNotFoundError('Label')
239+ except StateNotFoundError:
240+ logger.error("Contact {} not found.".format(contact_name))
241+ raise
242+
243+ def get_favorite_by_name(self, contact_name):
244+ """Find a label with text matching contact name under Favorites.
245+
246+ :param contact_name: Name of the contact, e.g. 'Fulano de Tal'.
247+ :return: The label for the metching favorite.
248+ :raises StateNotFoundError: If the contact_name is not found.
249+
250+ """
251+ return self.get_contact_by_name(
252+ contact_name,
253+ parent_delegate_type='FavoriteDelegate')
254+
255+ @autopilot_logging.log_action(logger.info)
256+ def click_contact_by_name(self,
257+ contact_name,
258+ parent_delegate_type='ContactDelegate'):
259+ """Click a contact with label matching the given contact name.
260+
261+ :param contact_name: Name of a contact, e.g. 'Fulano de Tal'.
262+ :param parent_delegate_type: 'ContactDelegate' or 'FavoriteDelegate'.
263+ :raises StateNotFoundError: If the contact_name is not found.
264+
265+ """
266+ contact_name_label = self.get_contact_by_name(
267+ contact_name, parent_delegate_type)
268+ self.pointing_device.click_object(contact_name_label)
269+
270+ @autopilot_logging.log_action(logger.info)
271+ def open_contact_view_by_contact_name(self, contact_name):
272+ """Open the contact view page for a contact with the given name.
273+
274+ :param contact_name: The name of the contact, e.g. 'Abe Lincoln'.
275+ :return: The ContactView for the contact.
276+ :raises StateNotFoundError: If the name is not found.
277+
278+ """
279+ self.click_contact_by_name(contact_name)
280+
281+ @autopilot_logging.log_action(logger.info)
282+ def click_favorite_by_name(self,
283+ contact_name):
284+ """Click a favorite with label matching the given contact name.
285+
286+ :param contact_name: Name of a contact, e.g. 'Fulano de Tal'
287+ :raises StateNotFoundError: If the contact_name is not found.
288+
289+ """
290+ contact_name_label = self.get_favorite_by_name(
291+ contact_name)
292+ self.pointing_device.click_object(contact_name_label)
293+
294+ @autopilot_logging.log_action(logger.info)
295+ def open_contact_view_by_favorite_name(self, favorite_name):
296+ """Open the contact view page for a favorite with the given name.
297+
298+ :param favorite_name: The name of the favorite, e.g. 'Abe Lincoln'.
299+ :return: The ContactView for the contact.
300+ :raises StateNotFoundError: If the name is not found.
301+
302+ """
303+ self.click_favorite_by_name(favorite_name)
304+
305+ @autopilot_logging.log_action(logger.info)
306+ def click_phone_number(self, phone_number):
307+ """Click a label matching the given phone number.
308+
309+ :param phone_number: A phone number, e.g. '3321 1232'.
310+ :raises StateNotFoundError: If the phone_number is not found.
311+
312+ """
313+ phone_number_label = self.wait_select_single('Label',
314+ text=phone_number)
315+ self.pointing_device.click_object(phone_number_label)
316
317=== added file 'tests/autopilot/address_book_app/emulators/contact_view.py'
318--- tests/autopilot/address_book_app/emulators/contact_view.py 1970-01-01 00:00:00 +0000
319+++ tests/autopilot/address_book_app/emulators/contact_view.py 2014-02-27 22:11:08 +0000
320@@ -0,0 +1,97 @@
321+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
322+# Copyright 2014 Canonical
323+#
324+# This program is free software: you can redistribute it and/or modify it
325+# under the terms of the GNU General Public License version 3, as published
326+# by the Free Software Foundation.
327+
328+""" ContactView emulator for Addressbook App tests """
329+
330+import logging
331+
332+from autopilot import logging as autopilot_logging
333+from autopilot.introspection.dbus import StateNotFoundError
334+from ubuntuuitoolkit import emulators as uitk
335+
336+from address_book_app.emulators import get_nearest_parent_matching_type
337+
338+logger = logging.getLogger(__name__)
339+
340+
341+class ContactView(uitk.UbuntuUIToolkitEmulatorBase):
342+ """ContactView emulator class"""
343+
344+ def __init__(self, *args):
345+ super(ContactView, self).__init__(*args)
346+
347+ @autopilot_logging.log_action(logger.info)
348+ def click_button(self, objectname):
349+ """Press a button that matches objectname.
350+
351+ :param objectname: The name of the object.
352+ :raises StateNotFoundError: If the matching object is not found.
353+
354+ """
355+ buttons = self.select_single("Button",
356+ objectName=objectname,
357+ visible=True)
358+ self.pointing_device.click_object(button)
359+
360+ @autopilot_logging.log_action(logger.info)
361+ def cancel(self):
362+ """Press the cancel button displayed when pick mode is enabled."""
363+ self.click_button("DialogButtons.rejectButton")
364+
365+ @autopilot_logging.log_action(logger.info)
366+ def delete(self):
367+ """Press the delete button displayed when pick mode is enabled."""
368+ self.click_button("DialogButtons.acceptButton")
369+ self.get_contacts()
370+
371+ def get_contact_detail_phone_number_view(self, phone_number):
372+ """Returns the View associated with the given phone number.
373+
374+ :param phone_number: The number listed for contact, e.g. '8675309'.
375+ :return: The matching view.
376+ :raises StateNotFoundError: If the phone_number is not found.
377+
378+ """
379+ phone_number_label = self.select_single('Label',
380+ text=phone_number)
381+ return get_nearest_parent_matching_type(
382+ phone_number_label,
383+ 'ContactDetailPhoneNumberView')
384+
385+ def _star_is_illuminated_for_phone_number(self, phone_number):
386+ """Is the star associated with the given phone number illuminated?
387+
388+ :param phone_number: The number listed for contact, e.g. '8675309'.
389+ :return: A Boolean.
390+ :raises StateNotFoundError: If the phone_number is not found.
391+
392+ """
393+ contact_detail = self.get_contact_detail_phone_number_view(
394+ phone_number)
395+ return contact_detail.iconSource == 'artwork:/favorite-selected.svg'
396+
397+ @autopilot_logging.log_action(logger.info)
398+ def click_phone_number(self, phone_number):
399+ """Tap/click the label with text matching the given phone number.
400+
401+ :param phone_number: The number listed for contact, e.g. '8675309'.
402+ :raises StateNotFoundError: If the phone_number is not found.
403+
404+ """
405+ phone_number_label = self.wait_select_single('Label',
406+ text=phone_number)
407+ self.pointing_device.click_object(phone_number_label)
408+
409+ def phone_number_is_favorite(self, phone_number):
410+ """Is the given phone number a favorite?
411+
412+ :param phone_number: A phone number, e.g. '8675309'.
413+ :raises StateNotFoundError: If the phone number is not found.
414+ :returns: Boolean.
415+
416+ """
417+ return self._star_is_illuminated_for_phone_number(phone_number)
418
419=== modified file 'tests/autopilot/address_book_app/emulators/main_window.py'
420--- tests/autopilot/address_book_app/emulators/main_window.py 2014-01-28 10:20:07 +0000
421+++ tests/autopilot/address_book_app/emulators/main_window.py 2014-02-27 22:11:08 +0000
422@@ -1,5 +1,5 @@
423 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
424-# Copyright 2013 Canonical
425+# Copyright 2014 Canonical
426 #
427 # This program is free software: you can redistribute it and/or modify it
428 # under the terms of the GNU General Public License version 3, as published
429@@ -13,7 +13,7 @@
430
431 def get_contact_list_page(self):
432 return self. wait_select_single("ContactListPage",
433- objectName="contactListPage")
434+ objectName="contactListPage")
435
436 def get_contact_edit_page(self):
437 return self.wait_select_single("ContactEditor",
438@@ -35,7 +35,7 @@
439 """
440 Returns a ContactListView iobject for the current window
441 """
442- return self.wait_select_single( "ContactListView",
443+ return self.wait_select_single("ContactListView",
444 objectName="contactListView")
445
446 def get_button(self, name):
447@@ -58,5 +58,3 @@
448 Press the 'Save' button
449 """
450 self.pointing_device.click_object(self.get_button("accept"))
451-
452-
453
454=== added file 'tests/autopilot/address_book_app/emulators/toolbar.py'
455--- tests/autopilot/address_book_app/emulators/toolbar.py 1970-01-01 00:00:00 +0000
456+++ tests/autopilot/address_book_app/emulators/toolbar.py 2014-02-27 22:11:08 +0000
457@@ -0,0 +1,38 @@
458+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
459+
460+""" Toolbar emulator for Addressbook App tests """
461+
462+# Copyright 2013 Canonical
463+#
464+# This program is free software: you can redistribute it and/or modify it
465+# under the terms of the GNU General Public License version 3, as published
466+# by the Free Software Foundation.
467+from autopilot.introspection.dbus import StateNotFoundError
468+import logging
469+from ubuntuuitoolkit import emulators as toolkit_emulators
470+
471+logger = logging.getLogger(__name__)
472+
473+
474+class Toolbar(toolkit_emulators.Toolbar):
475+ """An emulator class that makes it easy to interact with the tool bar"""
476+ def __init__(self, *args):
477+ super(Toolbar, self).__init__(*args)
478+
479+ def click_action_item_by_text(self, text):
480+ """Click an action item in the tool labelled 'text'
481+
482+ :param text: label of the ActionItem
483+ """
484+ try:
485+ action_item = self.select_single('ActionItem', text=text)
486+ self.pointing_device.click_object(action_item)
487+ except StateNotFoundError:
488+ logger.error(
489+ 'ActionItem with text "{0}" not found.'.format(text)
490+ )
491+ raise
492+
493+ def click_select(self):
494+ """Press 'Select' button on the toolbar"""
495+ self.click_action_item_by_text("Select")
496
497=== added file 'tests/autopilot/address_book_app/helpers.py'
498--- tests/autopilot/address_book_app/helpers.py 1970-01-01 00:00:00 +0000
499+++ tests/autopilot/address_book_app/helpers.py 2014-02-27 22:11:08 +0000
500@@ -0,0 +1,55 @@
501+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
502+# Copyright 2014 Canonical
503+#
504+# This program is free software: you can redistribute it and/or modify it
505+# under the terms of the GNU General Public License version 3, as published
506+# by the Free Software Foundation.
507+
508+"""Utilities for the evolution contacts db."""
509+
510+import os
511+import subprocess
512+import tempfile
513+
514+
515+def backup_evolution_contacts_db(backup_filepath=None):
516+ """Back up the existing evolution contacts db to a file.
517+
518+ :param backup_filepath: file to which to write, if None make tmpfile.
519+ :returns: backup filepath used.
520+ """
521+ if backup_filepath is None:
522+ backup_filepath = tempfile.mktemp(suffix=".syncevolution")
523+ subprocess.call([
524+ 'syncevolution',
525+ '--export',
526+ backup_filepath,
527+ 'backend=evolution-contacts',
528+ ])
529+ return backup_filepath
530+
531+
532+def restore_evolution_contacts_db(backup_filepath):
533+ """Restore the evolution contacts db from the backup.
534+
535+ :param backup_filepath: file from which to restore.
536+ """
537+ # NOTE restoring from empty file creates a phantom contact
538+ if os.path.getsize(backup_filepath) > 0:
539+ subprocess.call([
540+ 'syncevolution',
541+ '--import',
542+ backup_filepath,
543+ 'backend=evolution-contacts'
544+ ])
545+
546+
547+def wipe_evolution_contacts_db():
548+ """Wipe the existing evolution contacts db clean of contacts."""
549+ subprocess.call([
550+ 'syncevolution',
551+ '--delete-items',
552+ 'backend=evolution-contacts',
553+ '--luids',
554+ '*',
555+ ])
556
557=== modified file 'tests/autopilot/address_book_app/tests/__init__.py'
558--- tests/autopilot/address_book_app/tests/__init__.py 2014-01-30 08:35:04 +0000
559+++ tests/autopilot/address_book_app/tests/__init__.py 2014-02-27 22:11:08 +0000
560@@ -18,6 +18,9 @@
561 from testtools.matchers import Equals
562
563 from address_book_app.emulators.main_window import MainWindow
564+from address_book_app.helpers import (backup_evolution_contacts_db,
565+ restore_evolution_contacts_db,
566+ wipe_evolution_contacts_db)
567 from ubuntuuitoolkit import emulators as toolkit_emulators
568
569
570@@ -31,6 +34,7 @@
571 VCARD_PATH_DEV = os.path.abspath("../data/vcard.vcf")
572 ARGS = []
573 PRELOAD_VCARD = False
574+ QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True
575
576 def setUp(self):
577 self.pointing_device = toolkit_emulators.get_pointing_device()
578@@ -40,13 +44,25 @@
579 if model() != "Desktop":
580 subprocess.check_call(["/sbin/initctl", "stop", "maliit-server"])
581
582+ self.backup_filepath = backup_evolution_contacts_db()
583+ wipe_evolution_contacts_db()
584+
585 if 'AUTOPILOT_APP' in os.environ:
586 self.app_bin = os.environ['AUTOPILOT_APP']
587 else:
588 self.app_bin = AddressBookAppTestCase.DEFAULT_DEV_LOCATION
589
590- os.environ['QTCONTACTS_MANAGER_OVERRIDE'] = 'memory'
591+ print "Running from: %s" % (self.app_bin)
592+ # NOTE defeats favoriting: contacts don't show up in "Favorites" header
593+ if AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY:
594+ os.environ['QTCONTACTS_MANAGER_OVERRIDE'] = 'memory'
595+ else:
596+ try:
597+ del(os.environ['QTCONTACTS_MANAGER_OVERRIDE'])
598+ except KeyError:
599+ pass
600 vcard_data = ""
601+
602 if AddressBookAppTestCase.PRELOAD_VCARD:
603 # Use vcard from source tree and fallback on installed vcard (from
604 # address-book-app-autopilot package)
605@@ -55,16 +71,16 @@
606 else:
607 vcard_data = AddressBookAppTestCase.VCARD_PATH_BIN
608
609- os.environ["ADDRESS_BOOK_TEST_DATA"] = vcard_data
610- if vcard_data != "": print "Using vcard %s" % vcard_data
611+ os.environ['ADDRESS_BOOK_TEST_DATA'] = vcard_data
612+ if vcard_data != '': print 'Using vcard %s' % vcard_data
613 if os.path.exists(self.app_bin):
614- print "Running from: %s" % (self.app_bin)
615+ print 'Running from: %s' % (self.app_bin)
616 self.launch_test_local()
617 elif os.path.exists(self.DEB_LOCALTION):
618- print "Running from: %s" % (self.DEB_LOCALTION)
619+ print 'Running from: %s' % (self.DEB_LOCALTION)
620 self.launch_test_installed()
621 else:
622- print "Running from click package: address-book-app"
623+ print 'Running from click package: address-book-app'
624 self.launch_click_installed()
625
626 AddressBookAppTestCase.ARGS = []
627@@ -73,6 +89,9 @@
628
629 def tearDown(self):
630 super(AddressBookAppTestCase, self).tearDown()
631+ wipe_evolution_contacts_db()
632+ restore_evolution_contacts_db(self.backup_filepath)
633+ os.remove(self.backup_filepath)
634
635 # start the vkb
636 if model() != "Desktop":
637
638=== modified file 'tests/autopilot/address_book_app/tests/test_add_contact.py'
639--- tests/autopilot/address_book_app/tests/test_add_contact.py 2014-01-28 10:20:07 +0000
640+++ tests/autopilot/address_book_app/tests/test_add_contact.py 2014-02-27 22:11:08 +0000
641@@ -18,6 +18,10 @@
642 class TestAddContact(AddressBookAppTestCase):
643 """ Tests the Add contact """
644
645+ def setUp(self):
646+ AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True
647+ super(TestAddContact, self).setUp()
648+
649 def test_add_and_cancel_contact(self):
650 list_page = self.main_window.get_contact_list_page()
651
652
653=== modified file 'tests/autopilot/address_book_app/tests/test_contactlist.py'
654--- tests/autopilot/address_book_app/tests/test_contactlist.py 2013-11-21 18:53:19 +0000
655+++ tests/autopilot/address_book_app/tests/test_contactlist.py 2014-02-27 22:11:08 +0000
656@@ -18,6 +18,10 @@
657 class TestContactList(AddressBookAppTestCase):
658 """Tests the contact list features"""
659
660+ def setUp(self):
661+ AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True
662+ super(TestContactList, self).setUp()
663+
664 def test_contact_list(self):
665 contact_list = self.main_window.get_contact_list_page()
666 self.assertThat(contact_list.visible, Eventually(Equals(True)))
667
668=== added file 'tests/autopilot/address_book_app/tests/test_delete_contact.py'
669--- tests/autopilot/address_book_app/tests/test_delete_contact.py 1970-01-01 00:00:00 +0000
670+++ tests/autopilot/address_book_app/tests/test_delete_contact.py 2014-02-27 22:11:08 +0000
671@@ -0,0 +1,72 @@
672+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
673+
674+"""Tests for the Addressbook App"""
675+
676+# Copyright 2014 Canonical
677+#
678+# This program is free software: you can redistribute it and/or modify it
679+# under the terms of the GNU General Public License version 3, as published
680+# by the Free Software Foundation.
681+from __future__ import absolute_import
682+
683+from testtools.matchers import Equals
684+
685+from address_book_app.tests import AddressBookAppTestCase
686+from address_book_app.emulators.contact_list_page import ContactListPage
687+from address_book_app.emulators.toolbar import Toolbar
688+
689+
690+class TestDeleteSelectContact(AddressBookAppTestCase):
691+ """
692+ Delete a contact using pick mode and verify the behavior of Cancel and
693+ Delete actions
694+ """
695+ scenarios = [
696+ ("single_cancel", {
697+ "select": [1],
698+ "action": "cancel"}),
699+ ("multiple_cancel", {
700+ "select": [1, 2],
701+ "action": "cancel"}),
702+ ("none_delete", {
703+ "select": [],
704+ "action": "delete"}),
705+ ("single_delete", {
706+ "select": [1],
707+ "action": "delete"}),
708+ ("multiple_delete", {
709+ "select": [1, 2],
710+ "action": "delete"}),
711+ ]
712+
713+ def setUp(self):
714+ AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True
715+ AddressBookAppTestCase.PRELOAD_VCARD = True
716+ super(TestDeleteSelectContact, self).setUp()
717+
718+ def test_select(self):
719+ """
720+ Delete a contact in pick mode
721+
722+ This test switch the contact list view to pick mode and validate the
723+ behavior of Cancel and delete actions by comparing the numbers of
724+ contact in the list before and after the action.
725+ Note that it doesn't check which contact has been deleted.
726+ """
727+ self.main_window.open_toolbar().click_select()
728+ listpage = self.main_window.get_contact_list_page()
729+ contacts_before = listpage.get_contacts()
730+
731+ listpage.select_contacts_by_index(self.select)
732+ deleted = []
733+ if self.action == "cancel":
734+ listpage.cancel()
735+ elif self.action == "delete":
736+ listpage.delete()
737+ deleted = self.select
738+
739+ contacts_after = listpage.get_contacts()
740+ # TODO:
741+ # - Verify which contact have been deleted
742+ self.assertThat(len(contacts_after), Equals(len(contacts_before) -
743+ len(deleted)))
744
745=== modified file 'tests/autopilot/address_book_app/tests/test_edit_contact.py'
746--- tests/autopilot/address_book_app/tests/test_edit_contact.py 2014-01-28 10:20:07 +0000
747+++ tests/autopilot/address_book_app/tests/test_edit_contact.py 2014-02-27 22:11:08 +0000
748@@ -17,6 +17,10 @@
749 class TestEditContact(AddressBookAppTestCase):
750 """Tests edit a contact"""
751
752+ def setUp(self):
753+ AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True
754+ super(TestEditContact, self).setUp()
755+
756 def test_add_new_phone(self):
757 self.add_contact("Fulano", "de Tal", ["3321 2300"])
758 edit_page = self.edit_contact(0)
759
760=== added file 'tests/autopilot/address_book_app/tests/test_favorites.py'
761--- tests/autopilot/address_book_app/tests/test_favorites.py 1970-01-01 00:00:00 +0000
762+++ tests/autopilot/address_book_app/tests/test_favorites.py 2014-02-27 22:11:08 +0000
763@@ -0,0 +1,121 @@
764+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
765+# Copyright 2014 Canonical
766+#
767+# This program is free software: you can redistribute it and/or modify it
768+# under the terms of the GNU General Public License version 3, as published
769+# by the Free Software Foundation.
770+
771+"""Tests of favoriting contacts for the Addressbook App"""
772+
773+from __future__ import absolute_import
774+
775+from autopilot.introspection.dbus import StateNotFoundError
776+
777+from address_book_app.tests import AddressBookAppTestCase
778+from address_book_app.emulators import get_nearest_parent_matching_type
779+from address_book_app.emulators.contact_list_page import ContactListPage
780+from address_book_app.emulators.contact_view import ContactView
781+from address_book_app.emulators.address_book import AddressBook
782+
783+
784+class TestFavorite(AddressBookAppTestCase):
785+ """Test for favoriting contacts"""
786+
787+ def setUp(self):
788+ AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = False
789+ super(TestFavorite, self).setUp()
790+ self.address_book = AddressBook()
791+
792+ def test_add_favorite(self):
793+ self.address_book.create_contact(
794+ name='de Tal;Fulano',
795+ tel_home='3321 2300')
796+ contact_list_page = self.main_window.get_contact_list_page()
797+ contact_list_page.open_contact_view_by_contact_name('Fulano de Tal')
798+ contact_view = self.main_window.get_contact_view_page()
799+ contact_view.click_phone_number('3321 2300')
800+ self.assertTrue(
801+ contact_view.phone_number_is_favorite('3321 2300'))
802+ self.main_window.go_back()
803+ self.assertTrue(contact_list_page.get_favorite_by_name('Fulano de Tal'))
804+
805+ def test_save_multiple_favorites(self):
806+ self.address_book.create_contact(
807+ name=';Andrew',
808+ tel_home='3321 2300')
809+ self.address_book.create_contact(
810+ name='Whittard;Beth',
811+ tel_home='8675309')
812+ contact_list_page = self.main_window.get_contact_list_page()
813+ contact_list_page.click_contact_by_name('Beth Whittard')
814+ contact_view = self.main_window.get_contact_view_page()
815+ contact_view.click_phone_number('8675309')
816+ self.main_window.go_back()
817+ self.assertIsNotNone(contact_list_page.get_favorite_by_name('Beth Whittard'))
818+ contact_list_page.click_contact_by_name('Andrew')
819+ contact_view = self.main_window.get_contact_view_page()
820+ contact_view.click_phone_number('3321 2300')
821+ self.main_window.go_back()
822+ self.assertIsNotNone(contact_list_page.get_favorite_by_name('Andrew'))
823+
824+ def test_switch_between_favorites(self):
825+ self.address_book.create_contact(
826+ name='Whittard;Beth',
827+ tel_home='8675309',
828+ tel_work='5551212')
829+ contact_list_page = self.main_window.get_contact_list_page()
830+ contact_list_page.click_contact_by_name('Beth Whittard')
831+ contact_view = self.main_window.get_contact_view_page()
832+ contact_view.click_phone_number('8675309')
833+ self.assertTrue(contact_view.phone_number_is_favorite('8675309'))
834+ self.assertFalse(contact_view.phone_number_is_favorite('5551212'))
835+ contact_view.click_phone_number('5551212')
836+ self.assertFalse(contact_view.phone_number_is_favorite('8675309'))
837+ self.assertTrue(contact_view.phone_number_is_favorite('5551212'))
838+ self.main_window.go_back()
839+ contact_list_page.click_contact_by_name('Beth Whittard')
840+ contact_view = self.main_window.get_contact_view_page()
841+ # NOTE phones not visible from contact list favorites view
842+ self.assertTrue(contact_view.phone_number_is_favorite('5551212'))
843+ self.assertFalse(contact_view.phone_number_is_favorite('8675309'))
844+
845+ def test_remove_favorite(self):
846+ self.address_book.create_contact(
847+ name='Whittard;Beth',
848+ tel_home='8675309')
849+ contact_list_page = self.main_window.get_contact_list_page()
850+ contact_list_page.click_contact_by_name('Beth Whittard')
851+ contact_view = self.main_window.get_contact_view_page()
852+ contact_view.click_phone_number('8675309')
853+ self.assertTrue(contact_view.phone_number_is_favorite('8675309'))
854+ self.main_window.go_back()
855+ contact_list_page.click_contact_by_name('Beth Whittard')
856+ contact_view = self.main_window.get_contact_view_page()
857+ contact_view.click_phone_number('8675309')
858+ self.assertFalse(contact_view.phone_number_is_favorite('8675309'))
859+ self.main_window.go_back()
860+ self.assertRaises(
861+ StateNotFoundError,
862+ lambda: contact_list_page.get_favorite_by_name('Beth Wittard'))
863+ # FIXME: this passes but appears broken ATM--screen refresh?
864+
865+ def test_delete_favorite(self):
866+ self.address_book.create_contact(
867+ name='Whittard;Beth',
868+ tel_home='8675309')
869+ contact_list_page = self.main_window.get_contact_list_page()
870+ contact_list_page.click_contact_by_name('Beth Whittard')
871+ contact_view = self.main_window.get_contact_view_page()
872+ contact_view.click_phone_number('8675309')
873+ self.assertTrue(contact_view.phone_number_is_favorite('8675309'))
874+ self.main_window.go_back()
875+ contact_list_page.click_favorite_by_name('Beth Whittard')
876+ toolbar = self.main_window.open_toolbar()
877+ toolbar.click_button('delete')
878+ self.main_window.go_back()
879+ self.assertRaises(
880+ StateNotFoundError,
881+ lambda: contact_list_page.get_favorite_by_name('Beth Wittard'))
882+ self.assertRaises(
883+ StateNotFoundError,
884+ lambda: contact_list_page.get_contact_by_name('Beth Wittard'))
885
886=== modified file 'tests/autopilot/address_book_app/tests/test_multiple_pick_mode.py'
887--- tests/autopilot/address_book_app/tests/test_multiple_pick_mode.py 2013-12-13 19:31:33 +0000
888+++ tests/autopilot/address_book_app/tests/test_multiple_pick_mode.py 2014-02-27 22:11:08 +0000
889@@ -20,6 +20,7 @@
890
891 def setUp(self):
892 self.ARGS.append("addressbook:///pick?single=false")
893+ AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True
894 AddressBookAppTestCase.PRELOAD_VCARD = True
895 super(TestMultiplePickerMode, self).setUp()
896
897
898=== modified file 'tests/autopilot/address_book_app/tests/test_single_pick_mode.py'
899--- tests/autopilot/address_book_app/tests/test_single_pick_mode.py 2013-12-13 19:31:33 +0000
900+++ tests/autopilot/address_book_app/tests/test_single_pick_mode.py 2014-02-27 22:11:08 +0000
901@@ -21,6 +21,7 @@
902 def setUp(self):
903 AddressBookAppTestCase.ARGS.append("addressbook:///pick?single=true")
904 AddressBookAppTestCase.PRELOAD_VCARD = True
905+ AddressBookAppTestCase.QTCONTACTS_MANAGER_OVERRIDE_MEMORY = True
906 super(TestSinglePickerMode, self).setUp()
907
908 def test_select_single_contact(self):

Subscribers

People subscribed via source and target branches