Merge lp:~canonical-platform-qa/address-book-app/ux-call-msg-helpers into lp:address-book-app
- ux-call-msg-helpers
- Merge into trunk
Status: | Work in progress |
---|---|
Proposed branch: | lp:~canonical-platform-qa/address-book-app/ux-call-msg-helpers |
Merge into: | lp:address-book-app |
Diff against target: |
218 lines (+165/-0) 4 files modified
debian/control (+1/-0) tests/autopilot/address_book_app/pages/_contact_list_page.py (+33/-0) tests/autopilot/address_book_app/pages/_contact_view.py (+69/-0) tests/autopilot/address_book_app/tests/test_contactlist.py (+62/-0) |
To merge this branch: | bzr merge lp:~canonical-platform-qa/address-book-app/ux-call-msg-helpers |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Leo Arias (community) | Needs Fixing | ||
PS Jenkins bot | continuous-integration | Needs Fixing | |
Canonical Platform QA Team | Pending | ||
Ubuntu Phablet Team | Pending | ||
Review via email:
|
This proposal supersedes a proposal from 2014-07-11.
Commit message
New autopilot helper methods to press the telephone and message icons for a specific phone number in contacts view
Description of the change
New autopilot helper methods to press the telephone and message icons for a specific phone number in contacts view
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:239
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:240
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Leo Arias (elopio) wrote : Posted in a previous version of this proposal | # |
Thanks Richard. This is nice.
125 + def get_contact_
This needs some love, but feel free to leave it for the future because it's not your fault. Many things would be a lot easier if we had a method called get_contacts_info on the contacts list page. That method should return a list of contact tuples composed of all the visible information, ordered by the y coordinate. Reminders has a good example of this.
Then you could look for the contact index on that list, instead of in the QML tree.
I'm just saying it would be nice :)
174 + def _get_contact(self, index, phone_number):
This would be clearer as two methods: _get_contact_
203 + def call_contact(self, index=0, phone_number=None):
215 + def message_
Just like this, I would make two methods. And for a high level helper, I think index might not be a good parameter. I would be inclined to make a call_contact_
231 + def get_call_
234 + def get_message_
Please make these two private method. And make two additional methods click_call_button and click_message_
273 + self.add_
This is the old helper, it needs to be removed but I didn't have time to refactor all the tests.
This is the new way:
test_contact = data.Contact(
first_
phones=
contact_editor = self.app.
contact_
self.app.
You can wrap that in an add_contact method. Please don't use the other one, so it's easier to remove it once we have time.
277 + def convert_
There's a phone object on the data.py module. This sounds like a good method to have in that object.
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:241
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : Posted in a previous version of this proposal | # |
FAILED: Continuous integration, rev:243
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:243
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:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:244
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:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:244
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:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:244
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:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:248
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:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild:
http://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:244
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://
![](/+icing/build/overlay/assets/skins/sam/images/close.gif)
Leo Arias (elopio) wrote : | # |
Needs to be updated.
We will need this soon when automating the telephony stuff from the sanity suite.
- 249. By Richard Huddie
-
merge from trunk
Unmerged revisions
- 249. By Richard Huddie
-
merge from trunk
- 248. By Richard Huddie
-
remove un-needed dependencies
- 247. By Richard Huddie
-
fix tests
- 246. By Richard Huddie
-
merge trunk
- 245. By Richard Huddie
-
use url-dispatcher-
testability - 244. By Richard Huddie
-
merge trunk
- 243. By Richard Huddie
-
fix review comments
- 242. By Richard Huddie
-
merge trunk
- 241. By Richard Huddie
-
review updates
- 240. By Richard Huddie
-
add dependencies
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2015-02-09 15:02:11 +0000 |
3 | +++ debian/control 2015-02-24 15:29:58 +0000 |
4 | @@ -92,5 +92,6 @@ |
5 | ubuntu-ui-toolkit-autopilot (>= 0.1.46+14.10.20140527), |
6 | address-book-app (>= ${binary:Version}), |
7 | ubuntu-mobile-icons, |
8 | + url-dispatcher-testability, |
9 | Description: Test package for address-book-app |
10 | Autopilot tests for the address-book-app package |
11 | |
12 | === modified file 'tests/autopilot/address_book_app/pages/_contact_list_page.py' |
13 | --- tests/autopilot/address_book_app/pages/_contact_list_page.py 2015-02-19 07:02:09 +0000 |
14 | +++ tests/autopilot/address_book_app/pages/_contact_list_page.py 2015-02-24 15:29:58 +0000 |
15 | @@ -126,6 +126,39 @@ |
16 | ] |
17 | return [label.text for label in name_labels] |
18 | |
19 | + def get_contact_index_by_name(self, display_name): |
20 | + """ |
21 | + Return the index of the contact with the specified name |
22 | + :param display_name: Display name of contact |
23 | + :return: Index of the required contact within the list |
24 | + None if not found |
25 | + """ |
26 | + counter = 0 |
27 | + match_index = None |
28 | + contact_list = self.get_contacts() |
29 | + for contact in contact_list: |
30 | + try: |
31 | + # try to find matching contact |
32 | + contact.select_single( |
33 | + 'ContactAvatar', displayName=display_name) |
34 | + except StateNotFoundError: |
35 | + # increase counter and carry on |
36 | + counter += 1 |
37 | + else: |
38 | + # found a match, record index and exit loop |
39 | + match_index = counter |
40 | + break |
41 | + return match_index |
42 | + |
43 | + def open_contact_by_name(self, display_name): |
44 | + """ |
45 | + Open the contact specified by display_name |
46 | + :param display_name: Name of contact to open |
47 | + :return: Page with contact information |
48 | + """ |
49 | + contact_index = self.get_contact_index_by_name(display_name) |
50 | + return self.open_contact(contact_index) |
51 | + |
52 | |
53 | class RemoveContactsDialog( |
54 | ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
55 | |
56 | === modified file 'tests/autopilot/address_book_app/pages/_contact_view.py' |
57 | --- tests/autopilot/address_book_app/pages/_contact_view.py 2014-06-13 15:05:40 +0000 |
58 | +++ tests/autopilot/address_book_app/pages/_contact_view.py 2015-02-24 15:29:58 +0000 |
59 | @@ -15,6 +15,7 @@ |
60 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
61 | |
62 | from address_book_app.pages import _common, _contact_editor |
63 | +from autopilot.introspection.dbus import StateNotFoundError |
64 | |
65 | |
66 | class ContactView(_common.PageWithHeader): |
67 | @@ -26,3 +27,71 @@ |
68 | _contact_editor.ContactEditor, |
69 | objectName='contactEditorPage', |
70 | active=True) |
71 | + |
72 | + def _get_contact_by_phone_number(self, phone_number): |
73 | + """ |
74 | + Find the contact using phone number |
75 | + :param phone_number: Phone number for required contact |
76 | + :return: ContactDetailPhoneNumberView matching search requirements |
77 | + None if match is not found |
78 | + """ |
79 | + required_contact = None |
80 | + contacts = self.select_many(ContactDetailPhoneNumberView) |
81 | + if phone_number: |
82 | + # search for a specific phone number |
83 | + for contact in contacts: |
84 | + try: |
85 | + # try to find matching phone number |
86 | + contact.select_single('Label', text=phone_number) |
87 | + except StateNotFoundError: |
88 | + # move onto the next one |
89 | + pass |
90 | + else: |
91 | + # found the required contact |
92 | + required_contact = contact |
93 | + break |
94 | + return required_contact |
95 | + |
96 | + def _get_contact_by_index(self, index): |
97 | + """ |
98 | + Find the contact using index |
99 | + :param index: Index offset for required contact |
100 | + :return: ContactDetailPhoneNumberView matching search requirements |
101 | + """ |
102 | + return self.select_many(ContactDetailPhoneNumberView)[index] |
103 | + |
104 | + def call_contact(self, phone_number): |
105 | + """ |
106 | + Press the call button for the required phone number |
107 | + :param phone_number: The specified phone number to search for |
108 | + """ |
109 | + contact_phone_number = self._get_contact_by_phone_number(phone_number) |
110 | + contact_phone_number.click_call_button() |
111 | + |
112 | + def message_contact(self, phone_number): |
113 | + """ |
114 | + Press the message button for the required phone number |
115 | + :param phone_number: The specified phone number to search for |
116 | + """ |
117 | + contact_phone_number = self._get_contact_by_phone_number(phone_number) |
118 | + contact_phone_number.click_message_button() |
119 | + |
120 | + |
121 | +class ContactDetailPhoneNumberView(ContactView): |
122 | + """Class to represent a phone number view with call and message buttons""" |
123 | + |
124 | + def _get_call_button(self): |
125 | + """Return the call button ActionButton object""" |
126 | + return self.select_single('ActionButton', iconName='call-start') |
127 | + |
128 | + def _get_message_button(self): |
129 | + """Return the message button ActionButton object""" |
130 | + return self.select_single('ActionButton', iconName='message') |
131 | + |
132 | + def click_call_button(self): |
133 | + """Click on the call button for this phone number""" |
134 | + self.pointing_device.click_object(self._get_call_button()) |
135 | + |
136 | + def click_message_button(self): |
137 | + """Click on the message button for this phone number""" |
138 | + self.pointing_device.click_object(self._get_message_button()) |
139 | |
140 | === modified file 'tests/autopilot/address_book_app/tests/test_contactlist.py' |
141 | --- tests/autopilot/address_book_app/tests/test_contactlist.py 2014-05-22 13:42:45 +0000 |
142 | +++ tests/autopilot/address_book_app/tests/test_contactlist.py 2015-02-24 15:29:58 +0000 |
143 | @@ -10,13 +10,75 @@ |
144 | from autopilot.matchers import Eventually |
145 | from testtools.matchers import Equals |
146 | |
147 | +from address_book_app import data |
148 | from address_book_app.tests import AddressBookAppTestCase |
149 | +from url_dispatcher_testability import fixture_setup, fake_dispatcher |
150 | |
151 | |
152 | class TestContactList(AddressBookAppTestCase): |
153 | """Tests the contact list features""" |
154 | |
155 | + TEST_MOBILE_NUMBER = '073331234567' |
156 | + |
157 | + def setUp(self): |
158 | + super(TestContactList, self).setUp() |
159 | + self.fake_url_dispatcher = fixture_setup.FakeURLDispatcher() |
160 | + self.useFixture(self.fake_url_dispatcher) |
161 | + self.phone_number = data.Phone( |
162 | + type_='Mobile', number=self.TEST_MOBILE_NUMBER) |
163 | + self.message_url = 'message:///{}'.format(self.phone_number.number) |
164 | + self.tel_url = 'tel:///{}'.format(self.phone_number.number) |
165 | + |
166 | + def add_test_contact(self): |
167 | + """ |
168 | + Create a contact for testing |
169 | + """ |
170 | + test_contact = data.Contact( |
171 | + first_name='Fulano', last_name='de Tal', |
172 | + phones=[self.phone_number]) |
173 | + contact_editor = self.app.main_window.go_to_add_contact() |
174 | + contact_editor.fill_form(test_contact) |
175 | + self.app.main_window.save() |
176 | + |
177 | + def create_and_open_test_contact(self): |
178 | + """ |
179 | + Create a contact for testing, return detail page for new contact |
180 | + :return: Contact detail page |
181 | + """ |
182 | + self.add_test_contact() |
183 | + contacts_list = self.app.main_window.get_contact_list_page() |
184 | + return contacts_list.open_contact(0) |
185 | + |
186 | + def assert_last_dispatch_url(self, expected_url): |
187 | + """ |
188 | + Assert that the last dispatch url matches the expected url |
189 | + :param expected_url: The expected url |
190 | + """ |
191 | + url_dispatcher = self.fake_url_dispatcher |
192 | + |
193 | + def get_last_dispatch_url_call_parameter(): |
194 | + # Workaround for http://pad.lv/1312384 |
195 | + try: |
196 | + return url_dispatcher.get_last_dispatch_url_call_parameter() |
197 | + except fake_dispatcher.FakeDispatcherException: |
198 | + return None |
199 | + self.assertThat( |
200 | + get_last_dispatch_url_call_parameter, |
201 | + Eventually(Equals(expected_url))) |
202 | + |
203 | def test_contact_list(self): |
204 | contact_list = self.app.main_window.get_contact_list_page() |
205 | self.assertThat(contact_list.visible, Eventually(Equals(True))) |
206 | pass |
207 | + |
208 | + def test_call_contact(self): |
209 | + """Press the call button on a contact's phone number""" |
210 | + contact_page = self.create_and_open_test_contact() |
211 | + contact_page.call_contact(self.TEST_MOBILE_NUMBER) |
212 | + self.assert_last_dispatch_url(self.tel_url) |
213 | + |
214 | + def test_message_contact(self): |
215 | + """Press the message button on a contact's phone number""" |
216 | + contact_page = self.create_and_open_test_contact() |
217 | + contact_page.message_contact(self.TEST_MOBILE_NUMBER) |
218 | + self.assert_last_dispatch_url(self.message_url) |
FAILED: Continuous integration, rev:238 jenkins. qa.ubuntu. com/job/ address- book-app- ci/601/ jenkins. qa.ubuntu. com/job/ address- book-app- utopic- amd64-ci/ 54 jenkins. qa.ubuntu. com/job/ address- book-app- utopic- armhf-ci/ 54 jenkins. qa.ubuntu. com/job/ address- book-app- utopic- armhf-ci/ 54/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ address- book-app- utopic- i386-ci/ 54 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- utopic- touch/1872 jenkins. qa.ubuntu. com/job/ generic- mediumtests- utopic/ 1566 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- mako/2129 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/2969 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- armhf/2969/ artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 9705 jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-utopic/ 1312 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/1756 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- utopic- amd64/1756/ artifact/ work/output/ *zip*/output. zip
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
UNSTABLE: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/address- book-app- ci/601/ rebuild
http://