Merge lp:~zsombi/ubuntu-ui-toolkit/70-cpos into lp:ubuntu-ui-toolkit/staging

Proposed by Zsombor Egri
Status: Merged
Approved by: Tim Peeters
Approved revision: 1362
Merged at revision: 1367
Proposed branch: lp:~zsombi/ubuntu-ui-toolkit/70-cpos
Merge into: lp:ubuntu-ui-toolkit/staging
Prerequisite: lp:~zsombi/ubuntu-ui-toolkit/listitem-master
Diff against target: 329 lines (+250/-0)
7 files modified
modules/Ubuntu/Components/Themes/Ambiance/ListItemPanel.qml (+1/-0)
tests/autopilot/ubuntuuitoolkit/__init__.py (+2/-0)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/__init__.py (+4/-0)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_uclistitem.py (+87/-0)
tests/autopilot/ubuntuuitoolkit/emulators.py (+2/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.ListItemTestCase.qml (+68/-0)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.py (+86/-0)
To merge this branch: bzr merge lp:~zsombi/ubuntu-ui-toolkit/70-cpos
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Approve
Tim Peeters Approve
Leo Arias (community) Needs Fixing
Review via email: mp+243506@code.launchpad.net

Commit message

CPOs

To post a comment you must log in.
Revision history for this message
Tim Peeters (tpeeters) wrote :

 + def _click_on_panel_action(self, swipe_direction, action_object):
101 + self._swipe_content(swipe_direction)
102 + try:
103 + button_name = 'actionbutton_' + action_object
104 + action_button = self.select_single(objectName=button_name)
105 + except dbus.StateNotFound:
106 + raise _common.ToolkitException(
107 + 'The requested action not found on leading side')

the exception text is incorrect, swipe direction may be 'left', then you are looking for an action on trailing side.

review: Needs Fixing
Revision history for this message
Tim Peeters (tpeeters) wrote :

swipe_direction is ambiguous. Is it swipe TO this direction or swipe FROM? Perhaps rename the variable to "swipe_to_direction"?

Revision history for this message
Tim Peeters (tpeeters) wrote :

115 + def click_leading_action(self, action_objectName):
120 + def click_trailing_action(self, action_objectName):

Maybe trigger_{leading,trailing}_action(..) is better here. You click on a button to trigger the action.

Revision history for this message
Tim Peeters (tpeeters) wrote :

114 + @autopilot_logging.log_action(logger.info)
115 + def click_leading_action(self, action_objectName):
116 + """Swipe the item in from left to right to open leading actions."""
117 + self._click_on_panel_action('right', action_objectName)
118 +
119 + @autopilot_logging.log_action(logger.info)
120 + def click_trailing_action(self, action_objectName):
121 + """Swipe the item in from right to left to open trailing actions."""
122 + self._click_on_panel_action('left', action_objectName)

You do more than just swipe in these functions.
Add something similar to this to the descriptions: "and click on the button representing the requested action".

Revision history for this message
Tim Peeters (tpeeters) wrote :

244 + Label {
245 + id: triggeredAction
246 + height: paintedHeight
247 + objectName: "triggeredAction"
248 + }

It is better to anchor this somewhere. Who knows where it may end up now?

Revision history for this message
Tim Peeters (tpeeters) wrote :

237 +MainView {

I propose to use a MainView with a Page inside (then there is a header), or simply to use an Item in which you test the ListView with ListItems.

Revision history for this message
Tim Peeters (tpeeters) wrote :

244 + Label {
245 + id: triggeredAction
246 + height: paintedHeight
247 + objectName: "triggeredAction"
248 + }

I prefer an initial label of "no action triggered", and when an action is triggered label.text = objectName + " action triggered". Adds a little bit of clarity when watching the videos of a failed test.

Revision history for this message
Tim Peeters (tpeeters) wrote :

We should also test what happens when you self.test_listitem.click_leading_action('this_action_does_not_exist')

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 244 + Label {
> 245 + id: triggeredAction
> 246 + height: paintedHeight
> 247 + objectName: "triggeredAction"
> 248 + }
>
> It is better to anchor this somewhere. Who knows where it may end up now?

Any item unanchored is positioned to (0,0), you should know that. Everyone should know that.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> + def _click_on_panel_action(self, swipe_direction, action_object):
> 101 + self._swipe_content(swipe_direction)
> 102 + try:
> 103 + button_name = 'actionbutton_' + action_object
> 104 + action_button =
> self.select_single(objectName=button_name)
> 105 + except dbus.StateNotFound:
> 106 + raise _common.ToolkitException(
> 107 + 'The requested action not found on leading side')
>
>
> the exception text is incorrect, swipe direction may be 'left', then you are
> looking for an action on trailing side.

Aah, right, I forgot to adjust that message when moved the code in one function. Fix in the next revision.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> swipe_direction is ambiguous. Is it swipe TO this direction or swipe FROM?
> Perhaps rename the variable to "swipe_to_direction"?

Uhm... I think this naming is widely used and means always the destination direction. You specify "to" and "from" only if you have both parameters in a function.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 115 + def click_leading_action(self, action_objectName):
> 120 + def click_trailing_action(self, action_objectName):
>
> Maybe trigger_{leading,trailing}_action(..) is better here. You click on a
> button to trigger the action.

Ack, changed.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> > swipe_direction is ambiguous. Is it swipe TO this direction or swipe FROM?
> > Perhaps rename the variable to "swipe_to_direction"?
>
> Uhm... I think this naming is widely used and means always the destination
> direction. You specify "to" and "from" only if you have both parameters in a
> function.

Actually I reformatted that part so now it uses panel_item (leading/trailing) to identify which panel to be swiped in.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> 237 +MainView {
>
> I propose to use a MainView with a Page inside (then there is a header), or
> simply to use an Item in which you test the ListView with ListItems.

Ok, I'll do that. But then having a label in a view and under it the list view makes not much sense, we can use the app title to store the action triggered.

Revision history for this message
Zsombor Egri (zsombi) wrote :

> We should also test what happens when you
> self.test_listitem.click_leading_action('this_action_does_not_exist')

Done.

Revision history for this message
Tim Peeters (tpeeters) wrote :

> > 244 + Label {
> > 245 + id: triggeredAction
> > 246 + height: paintedHeight
> > 247 + objectName: "triggeredAction"
> > 248 + }
> >
> > It is better to anchor this somewhere. Who knows where it may end up now?
>
> Any item unanchored is positioned to (0,0), you should know that. Everyone
> should know that.

Do you have a reference for that?

Revision history for this message
Tim Peeters (tpeeters) wrote :

should we rename _click_on_panel_action() to _trigger_action() or _click_on_panel_button() ?

Revision history for this message
Tim Peeters (tpeeters) wrote :

good

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

Looks pretty good. Just, please change the last two tests to something like this:

def test_trigger_nonexistent_leading_action(self):
    error = self.assertRaises(
       ubuntuuitoolkit.ToolkitException,
       self.test_listitem.trigger_leading_action,
       'this_action_does_not_exist')
    self.assertEqual(
        str(error),
       'The requested action not found on leading side')

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

thanks

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

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'modules/Ubuntu/Components/Themes/Ambiance/ListItemPanel.qml'
2--- modules/Ubuntu/Components/Themes/Ambiance/ListItemPanel.qml 2014-12-01 14:50:13 +0000
3+++ modules/Ubuntu/Components/Themes/Ambiance/ListItemPanel.qml 2014-12-08 14:37:55 +0000
4@@ -157,6 +157,7 @@
5 // use action's objectName to identify the visualized action
6 if (item && item.objectName === "") {
7 item.objectName = modelData.objectName;
8+ actionButton.objectName = "actionbutton_" + modelData.objectName
9 }
10 }
11 }
12
13=== modified file 'tests/autopilot/ubuntuuitoolkit/__init__.py'
14--- tests/autopilot/ubuntuuitoolkit/__init__.py 2014-08-20 08:52:11 +0000
15+++ tests/autopilot/ubuntuuitoolkit/__init__.py 2014-12-08 14:37:55 +0000
16@@ -28,6 +28,7 @@
17 'get_pointing_device',
18 'Header',
19 'listitems',
20+ 'UCListItem',
21 'MainView',
22 'OptionSelector',
23 'pickers',
24@@ -63,6 +64,7 @@
25 get_pointing_device,
26 Header,
27 listitems,
28+ UCListItem,
29 MainView,
30 OptionSelector,
31 pickers,
32
33=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/__init__.py'
34--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/__init__.py 2014-08-03 02:50:45 +0000
35+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/__init__.py 2014-12-08 14:37:55 +0000
36@@ -25,6 +25,7 @@
37 'get_pointing_device',
38 'Header',
39 'listitems',
40+ 'UCListItem',
41 'MainView',
42 'OptionSelector',
43 'pickers',
44@@ -56,6 +57,9 @@
45 Header,
46 )
47 from ubuntuuitoolkit._custom_proxy_objects import listitems
48+from ubuntuuitoolkit._custom_proxy_objects._uclistitem import (
49+ UCListItem
50+)
51 from ubuntuuitoolkit._custom_proxy_objects._mainview import MainView
52 from ubuntuuitoolkit._custom_proxy_objects._optionselector import (
53 OptionSelector
54
55=== added file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_uclistitem.py'
56--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_uclistitem.py 1970-01-01 00:00:00 +0000
57+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_uclistitem.py 2014-12-08 14:37:55 +0000
58@@ -0,0 +1,87 @@
59+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
60+#
61+# Copyright (C) 2012, 2013, 2014 Canonical Ltd.
62+#
63+# This program is free software; you can redistribute it and/or modify
64+# it under the terms of the GNU Lesser General Public License as published by
65+# the Free Software Foundation; version 3.
66+#
67+# This program is distributed in the hope that it will be useful,
68+# but WITHOUT ANY WARRANTY; without even the implied warranty of
69+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
70+# GNU Lesser General Public License for more details.
71+#
72+# You should have received a copy of the GNU Lesser General Public License
73+# along with this program. If not, see <http://www.gnu.org/licenses/>.
74+
75+import logging
76+
77+from autopilot import logging as autopilot_logging
78+from ubuntuuitoolkit._custom_proxy_objects import _common
79+
80+
81+logger = logging.getLogger(__name__)
82+
83+
84+class UCListItem(_common.UbuntuUIToolkitCustomProxyObjectBase):
85+ """Base class to emulate swipe for leading and trailing actions."""
86+
87+ @autopilot_logging.log_action(logger.info)
88+ def _swipe_in_panel(self, panel_item):
89+ """ Swipe in panel (leading/trailing)"""
90+ x, y, width, height = self.globalRect
91+ if panel_item == 'leading':
92+ start_x = x + (width * 0.2)
93+ stop_x = x + (width * 0.8)
94+ elif panel_item == 'trailing':
95+ start_x = x + (width * 0.8)
96+ stop_x = x + (width * 0.2)
97+ else:
98+ raise _common.ToolkitException(
99+ 'No {0} panel found in a ListItem'.format(panel_item))
100+ start_y = stop_y = y + (height // 2)
101+ self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
102+
103+ def _click_on_panel_action(self, panel_item, action_object, wait_function):
104+ self._swipe_in_panel(panel_item)
105+ try:
106+ button_name = 'actionbutton_' + action_object
107+ action_button = self.select_single(objectName=button_name)
108+ except:
109+ raise _common.ToolkitException(
110+ 'The requested action not found on {0} side'.
111+ format(panel_item))
112+
113+ self.pointing_device.click_object(action_button)
114+ if wait_function is None:
115+ # wait for the animation to finish
116+ contentItem = self.select_single(objectName='ListItemHolder')
117+ contentItem.x.wait_for(0)
118+ else:
119+ wait_function()
120+
121+ @autopilot_logging.log_action(logger.info)
122+ def trigger_leading_action(self, action_objectName, wait_function=None):
123+ """Swipe the item in from left to right to open leading actions
124+ and click on the button representing the requested action.
125+
126+ parameters: action_objectName - object name of the action to be
127+ triggered.
128+ wait_function - a custom wait function to wait till the
129+ action is triggered
130+ """
131+ self._click_on_panel_action('leading', action_objectName,
132+ wait_function)
133+
134+ @autopilot_logging.log_action(logger.info)
135+ def trigger_trailing_action(self, action_objectName, wait_function=None):
136+ """Swipe the item in from right to left to open trailing actions
137+ and click on the button representing the requested action.
138+
139+ parameters: action_objectName - object name of the action to be
140+ triggered.
141+ wait_function - a custom wait function to wait till the
142+ action is triggered
143+ """
144+ self._click_on_panel_action('trailing', action_objectName,
145+ wait_function)
146
147=== modified file 'tests/autopilot/ubuntuuitoolkit/emulators.py'
148--- tests/autopilot/ubuntuuitoolkit/emulators.py 2014-08-20 06:45:28 +0000
149+++ tests/autopilot/ubuntuuitoolkit/emulators.py 2014-12-08 14:37:55 +0000
150@@ -37,6 +37,7 @@
151 'CheckBox',
152 'ComposerSheet',
153 'Empty',
154+ 'UCListItem',
155 'Header',
156 'ItemSelector',
157 'MainView',
158@@ -63,6 +64,7 @@
159 get_pointing_device,
160 CheckBox,
161 Header,
162+ UCListItem,
163 MainView,
164 OptionSelector,
165 QQuickFlickable,
166
167=== added file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.ListItemTestCase.qml'
168--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.ListItemTestCase.qml 1970-01-01 00:00:00 +0000
169+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.ListItemTestCase.qml 2014-12-08 14:37:55 +0000
170@@ -0,0 +1,68 @@
171+/*
172+ * Copyright 2014 Canonical Ltd.
173+ *
174+ * This program is free software; you can redistribute it and/or modify
175+ * it under the terms of the GNU Lesser General Public License as published by
176+ * the Free Software Foundation; version 3.
177+ *
178+ * This program is distributed in the hope that it will be useful,
179+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
180+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
181+ * GNU Lesser General Public License for more details.
182+ *
183+ * You should have received a copy of the GNU Lesser General Public License
184+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
185+ */
186+
187+import QtQuick 2.0
188+import Ubuntu.Components 1.2
189+
190+MainView {
191+ width: units.gu(48)
192+ height: units.gu(60)
193+
194+ // make sure we're not messed up by the deprecated toolbar
195+ useDeprecatedToolbar: false
196+
197+ Page {
198+ id: testPage
199+ objectName: "test_page"
200+ title: "No action triggered"
201+ ListView {
202+ id: listView
203+ anchors.fill: parent
204+ model: 25
205+ delegate: ListItem {
206+ objectName: "listitem" + index
207+ leadingActions: ListItemActions {
208+ actions: [
209+ Action {
210+ iconName: "delete"
211+ objectName: 'delete_action'
212+ onTriggered: testPage.title = objectName + " action triggered";
213+ }
214+ ]
215+ }
216+ trailingActions: ListItemActions {
217+ actions: [
218+ Action {
219+ iconName: "search"
220+ objectName: 'search_action'
221+ onTriggered: testPage.title = objectName + " action triggered";
222+ },
223+ Action {
224+ iconName: "edit"
225+ objectName: 'edit_action'
226+ onTriggered: testPage.title = objectName + " action triggered";
227+ },
228+ Action {
229+ iconName: "email"
230+ objectName: 'email_action'
231+ onTriggered: testPage.title = objectName + " action triggered";
232+ }
233+ ]
234+ }
235+ }
236+ }
237+ }
238+}
239
240=== added file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.py'
241--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.py 1970-01-01 00:00:00 +0000
242+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_listitem.py 2014-12-08 14:37:55 +0000
243@@ -0,0 +1,86 @@
244+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
245+#
246+# Copyright (C) 2013, 2014 Canonical Ltd.
247+#
248+# This program is free software; you can redistribute it and/or modify
249+# it under the terms of the GNU Lesser General Public License as published by
250+# the Free Software Foundation; version 3.
251+#
252+# This program is distributed in the hope that it will be useful,
253+# but WITHOUT ANY WARRANTY; without even the implied warranty of
254+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
255+# GNU Lesser General Public License for more details.
256+#
257+# You should have received a copy of the GNU Lesser General Public License
258+# along with this program. If not, see <http://www.gnu.org/licenses/>.
259+
260+import os
261+
262+import ubuntuuitoolkit
263+from ubuntuuitoolkit import tests
264+
265+
266+class ListItemTestCase(tests.QMLFileAppTestCase):
267+ path = os.path.abspath(__file__)
268+ dir_path = os.path.dirname(path)
269+ test_qml_file_path = os.path.join(
270+ dir_path, 'test_listitem.ListItemTestCase.qml')
271+
272+ def setUp(self):
273+ super(ListItemTestCase, self).setUp()
274+ self.test_listitem = self.main_view.select_single(
275+ 'UCListItem', objectName='listitem0')
276+ self.test_page = self.main_view.select_single(
277+ objectName='test_page')
278+ self.assertEqual(self.test_page.title, 'No action triggered')
279+
280+ def test_trigger_delete(self):
281+ self.test_listitem.trigger_leading_action('delete_action')
282+ self.assertEqual(self.test_page.title,
283+ 'delete_action action triggered')
284+
285+ def test_trigger_search(self):
286+ self.test_listitem.trigger_trailing_action('search_action')
287+ self.assertEqual(self.test_page.title,
288+ 'search_action action triggered')
289+
290+ def test_trigger_edit(self):
291+ self.test_listitem.trigger_trailing_action('edit_action')
292+ self.assertEqual(self.test_page.title,
293+ 'edit_action action triggered')
294+
295+ def test_trigger_email(self):
296+ self.test_listitem.trigger_trailing_action('email_action')
297+ self.assertEqual(self.test_page.title,
298+ 'email_action action triggered')
299+
300+ def test_trigger_all_actions(self):
301+ self.test_listitem.trigger_leading_action('delete_action')
302+ self.assertEqual(self.test_page.title,
303+ 'delete_action action triggered')
304+
305+ self.test_listitem.trigger_trailing_action('search_action')
306+ self.assertEqual(self.test_page.title,
307+ 'search_action action triggered')
308+
309+ self.test_listitem.trigger_trailing_action('edit_action')
310+ self.assertEqual(self.test_page.title,
311+ 'edit_action action triggered')
312+
313+ self.test_listitem.trigger_trailing_action('email_action')
314+ self.assertEqual(self.test_page.title,
315+ 'email_action action triggered')
316+
317+ def test_trigger_nonexistent_leading_action(self):
318+ error = self.assertRaises(ubuntuuitoolkit.ToolkitException,
319+ self.test_listitem.trigger_leading_action,
320+ ('this_action_does_not_exist'))
321+ self.assertEqual(str(error),
322+ 'The requested action not found on leading side')
323+
324+ def test_trigger_nonexistent_trailing_action(self):
325+ error = self.assertRaises(ubuntuuitoolkit.ToolkitException,
326+ self.test_listitem.trigger_trailing_action,
327+ 'this_action_does_not_exist')
328+ self.assertEqual(str(error),
329+ 'The requested action not found on trailing side')

Subscribers

People subscribed via source and target branches