Merge lp:~elopio/ubuntu-ui-toolkit/listview-scroll_to_bottom into lp:ubuntu-ui-toolkit
- listview-scroll_to_bottom
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Cris Dywan |
Approved revision: | 928 |
Merged at revision: | 957 |
Proposed branch: | lp:~elopio/ubuntu-ui-toolkit/listview-scroll_to_bottom |
Merge into: | lp:ubuntu-ui-toolkit |
Diff against target: |
254 lines (+98/-84) 2 files modified
tests/autopilot/ubuntuuitoolkit/emulators.py (+73/-31) tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py (+25/-53) |
To merge this branch: | bzr merge lp:~elopio/ubuntu-ui-toolkit/listview-scroll_to_bottom |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Florian Boucault (community) | Approve | ||
Cris Dywan | Approve | ||
PS Jenkins bot | continuous-integration | Approve | |
Javier Collado | Pending | ||
Richard Huddie | Pending | ||
VĂctor R. Ruiz | Pending | ||
Review via email: mp+202129@code.launchpad.net |
Commit message
On the autopilot listview emulator, scroll to the bottom to try to find elements not yet created.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
Leo Arias (elopio) wrote : | # |
We can't just scroll to the bottom, because then the items on the top will not exists.
On this version, we are scrolling one 'page' at a time.
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:923
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:924
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:926
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Javier Collado (javier.collado) wrote : | # |
The code looks good, but still I'm not familiar enough with it, so I have a
couple of questions:
- My understanding is that the statements in test_emulators.py in "delegate"
(line 193 in the MP) create the elements that were previously created
manually. Is that correct? How come that there isn't any loop counter or
anything? Does using just one number as in "%1" mean that only the elements
from 0 to 9 will be created?
- The _is_element_
the x coordinate. If the element is wide enough I guess it might happen that
its center in the y axis is visible, but not the center in the x axis. Maybe
there's some assumption or precondition that I'm missing?
Leo Arias (elopio) wrote : | # |
Thanks for reviewing Javier.
The changes on the delegate are pretty nice. I didn't know how to do that, but kalikiana gave me the code. You can do a loop by just using:
191 + model: 20
So elements from 0 to 19 are created.
About _is_element_
For now, going back to work in progress as the drag in the phone is still to fast and is taking us further than we need. I have solved the slow drag in https:/
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:927
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:928
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Cris Dywan (kalikiana) wrote : | # |
FAIL: ubuntu_
http://
Florian Boucault (fboucault) wrote : | # |
> FAIL: ubuntu_
> _feed_and_
> http://
After rerunning tests ubuntu_
CI@home OK http://
Leo Arias (elopio) wrote : | # |
I'm improving this test_add_
Preview Diff
1 | === modified file 'tests/autopilot/ubuntuuitoolkit/emulators.py' |
2 | --- tests/autopilot/ubuntuuitoolkit/emulators.py 2014-01-30 15:26:21 +0000 |
3 | +++ tests/autopilot/ubuntuuitoolkit/emulators.py 2014-02-22 00:04:26 +0000 |
4 | @@ -15,7 +15,6 @@ |
5 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
6 | |
7 | import logging |
8 | -import time |
9 | from distutils import version |
10 | |
11 | import autopilot |
12 | @@ -527,7 +526,7 @@ |
13 | def click_element(self, objectName): |
14 | """Click an element from the list. |
15 | |
16 | - It swipes the element into view if it's not fully visible. |
17 | + It swipes the element into view if it's center is not visible. |
18 | |
19 | :parameter objectName: The objectName property of the element to click. |
20 | |
21 | @@ -537,38 +536,81 @@ |
22 | self.pointing_device.click_object(element) |
23 | |
24 | def _swipe_element_into_view(self, objectName): |
25 | - element = self.select_single(objectName=objectName) |
26 | - x, y, width, height = self.globalRect |
27 | - start_x = x + (width / 2) |
28 | - start_y = y + (height / 2) |
29 | + element = self._select_element(objectName) |
30 | |
31 | - while not self._is_element_fully_visible(objectName): |
32 | - stop_x = start_x |
33 | + while not self._is_element_clickable(objectName): |
34 | if element.globalRect.y < self.globalRect.y: |
35 | - stop_y = start_y + element.implicitHeight |
36 | - else: |
37 | - stop_y = start_y - element.implicitHeight |
38 | - |
39 | - if platform.model() == 'Desktop': |
40 | - # The drag on the desktop is done two fast, so we are left at |
41 | - # the bottom or at the top of the list, sometimes missing the |
42 | - # element we are looking for. |
43 | - # TODO: use the slow drag once it's implemented: |
44 | - # https://bugs.launchpad.net/autopilot/+bug/1257055 |
45 | - # --elopio - 2014-01-09 |
46 | - self.pointing_device.move(start_x, start_y) |
47 | - self.pointing_device.press() |
48 | - self.pointing_device.move(stop_x, stop_y) |
49 | - time.sleep(0.3) |
50 | - self.pointing_device.release() |
51 | - else: |
52 | - self.pointing_device.drag(start_x, start_y, stop_x, stop_y) |
53 | - |
54 | - def _is_element_fully_visible(self, objectName): |
55 | + self._show_more_elements_above() |
56 | + else: |
57 | + self._show_more_elements_below() |
58 | + |
59 | + def _select_element(self, object_name): |
60 | + try: |
61 | + return self.select_single(objectName=object_name) |
62 | + except dbus.StateNotFoundError: |
63 | + # If the list is big, elements will only be created when we scroll |
64 | + # them into view. |
65 | + self._scroll_to_top() |
66 | + while not self.atYEnd: |
67 | + self._show_more_elements_below() |
68 | + try: |
69 | + return self.select_single(objectName=object_name) |
70 | + except dbus.StateNotFoundError: |
71 | + pass |
72 | + raise ToolkitEmulatorException( |
73 | + 'List element with objectName "{}" not found.'.format( |
74 | + object_name)) |
75 | + |
76 | + @autopilot_logging.log_action(logger.info) |
77 | + def _scroll_to_top(self): |
78 | + x, y, width, height = self.globalRect |
79 | + while not self.atYBeginning: |
80 | + self._show_more_elements_above() |
81 | + |
82 | + @autopilot_logging.log_action(logger.info) |
83 | + def _show_more_elements_below(self): |
84 | + if self.atYEnd: |
85 | + raise ToolkitEmulatorException('There are no more elements below.') |
86 | + else: |
87 | + self._show_more_elements('below') |
88 | + |
89 | + @autopilot_logging.log_action(logger.info) |
90 | + def _show_more_elements_above(self): |
91 | + if self.atYBeginning: |
92 | + raise ToolkitEmulatorException('There are no more elements above.') |
93 | + else: |
94 | + self._show_more_elements('above') |
95 | + |
96 | + def _show_more_elements(self, direction): |
97 | + x, y, width, height = self.globalRect |
98 | + start_x = stop_x = x + (width / 2) |
99 | + # Start and stop just a little under the top of the list. |
100 | + top = y + 5 |
101 | + bottom = y + height - 5 |
102 | + if direction == 'below': |
103 | + start_y = bottom |
104 | + stop_y = top |
105 | + elif direction == 'above': |
106 | + start_y = top |
107 | + stop_y = bottom |
108 | + else: |
109 | + raise ToolkitEmulatorException( |
110 | + 'Invalid direction {}.'.format(direction)) |
111 | + self._slow_drag(start_x, stop_x, start_y, stop_y) |
112 | + self.dragging.wait_for(False) |
113 | + self.moving.wait_for(False) |
114 | + |
115 | + def _slow_drag(self, start_x, stop_x, start_y, stop_y): |
116 | + # If we drag too fast, we end up scrolling more than what we |
117 | + # should, sometimes missing the element we are looking for. |
118 | + self.pointing_device.drag(start_x, start_y, stop_x, stop_y, rate=5) |
119 | + |
120 | + def _is_element_clickable(self, objectName): |
121 | + """Return True if the center of the element is visible.""" |
122 | element = self.select_single(objectName=objectName) |
123 | - return (element.globalRect.y >= self.globalRect.y and |
124 | - element.globalRect.y + element.globalRect.height <= |
125 | - self.globalRect.y + self.globalRect.height) |
126 | + element_center = element.globalRect.y + element.globalRect.height / 2 |
127 | + return (element_center >= self.globalRect.y and |
128 | + element_center <= self.globalRect.y + self.globalRect.height) |
129 | |
130 | |
131 | class Empty(UbuntuUIToolkitEmulatorBase): |
132 | |
133 | === modified file 'tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py' |
134 | --- tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py 2014-01-13 15:23:25 +0000 |
135 | +++ tests/autopilot/ubuntuuitoolkit/tests/test_emulators.py 2014-02-22 00:04:26 +0000 |
136 | @@ -574,47 +574,6 @@ |
137 | text: "No element clicked." |
138 | } |
139 | |
140 | - ListModel { |
141 | - id: testModel |
142 | - |
143 | - ListElement { |
144 | - objectName: "testListElement1" |
145 | - label: "test list element 1" |
146 | - } |
147 | - ListElement { |
148 | - objectName: "testListElement2" |
149 | - label: "test list element 2" |
150 | - } |
151 | - ListElement { |
152 | - objectName: "testListElement3" |
153 | - label: "test list element 3" |
154 | - } |
155 | - ListElement { |
156 | - objectName: "testListElement4" |
157 | - label: "test list element 4" |
158 | - } |
159 | - ListElement { |
160 | - objectName: "testListElement5" |
161 | - label: "test list element 5" |
162 | - } |
163 | - ListElement { |
164 | - objectName: "testListElement6" |
165 | - label: "test list element 6" |
166 | - } |
167 | - ListElement { |
168 | - objectName: "testListElement7" |
169 | - label: "test list element 7" |
170 | - } |
171 | - ListElement { |
172 | - objectName: "testListElement8" |
173 | - label: "test list element 8" |
174 | - } |
175 | - ListElement { |
176 | - objectName: "testListElement9" |
177 | - label: "test list element 9" |
178 | - } |
179 | - } |
180 | - |
181 | ListView { |
182 | id: testListView |
183 | objectName: "testListView" |
184 | @@ -622,13 +581,13 @@ |
185 | anchors.right: parent.right |
186 | height: column.height - clickedLabel.paintedHeight |
187 | clip: true |
188 | - model: testModel |
189 | + model: 20 |
190 | |
191 | delegate: ListItem.Standard { |
192 | - text: model.label |
193 | - objectName: model.objectName |
194 | - onClicked: clickedLabel.text = model.objectName |
195 | - height: units.gu(5) |
196 | + objectName: "testListElement%1".arg(index) |
197 | + text: "test list element %1".arg(index) |
198 | + onClicked: clickedLabel.text = objectName |
199 | + height: units.gu(5) |
200 | } |
201 | } |
202 | } |
203 | @@ -648,32 +607,45 @@ |
204 | self.assertIsInstance(self.list_view, emulators.QQuickListView) |
205 | |
206 | def test_click_element(self): |
207 | - self.list_view.click_element('testListElement1') |
208 | - self.assertEqual(self.label.text, 'testListElement1') |
209 | + self.list_view.click_element('testListElement0') |
210 | + self.assertEqual(self.label.text, 'testListElement0') |
211 | |
212 | def test_click_element_outside_view_below(self): |
213 | # Click the first element out of view to make sure we are not scrolling |
214 | # to the bottom at once. |
215 | self.assertFalse( |
216 | - self.list_view._is_element_fully_visible('testListElement5')) |
217 | + self.list_view._is_element_clickable('testListElement5')) |
218 | |
219 | self.list_view.click_element('testListElement5') |
220 | self.assertEqual(self.label.text, 'testListElement5') |
221 | |
222 | def test_click_element_outside_view_above(self): |
223 | - # First we need to scroll to the 8th element in order for the 9th to be |
224 | - # created. |
225 | - self.list_view.click_element('testListElement8') |
226 | self.list_view.click_element('testListElement9') |
227 | |
228 | # Click the first element out of view to make sure we are not scrolling |
229 | # to the top at once. |
230 | self.assertFalse( |
231 | - self.list_view._is_element_fully_visible('testListElement4')) |
232 | + self.list_view._is_element_clickable('testListElement4')) |
233 | |
234 | self.list_view.click_element('testListElement4') |
235 | self.assertEqual(self.label.text, 'testListElement4') |
236 | |
237 | + def test_click_element_not_created_at_start(self): |
238 | + objectName = 'testListElement19' |
239 | + self.assertRaises( |
240 | + dbus.StateNotFoundError, |
241 | + self.list_view.select_single, |
242 | + objectName=objectName) |
243 | + self.list_view.click_element(objectName) |
244 | + |
245 | + def test_click_unexisting_element(self): |
246 | + error = self.assertRaises( |
247 | + emulators.ToolkitEmulatorException, |
248 | + self.list_view.click_element, |
249 | + 'unexisting') |
250 | + self.assertEqual( |
251 | + str(error), 'List element with objectName "unexisting" not found.') |
252 | + |
253 | |
254 | class SwipeToDeleteTestCase(tests.QMLStringAppTestCase): |
255 |
FAILED: Continuous integration, rev:920 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- ci/1602/ jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty/ 2444 jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty- touch/2294/ console jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- trusty- amd64-ci/ 550 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- trusty- armhf-ci/ 550 jenkins. qa.ubuntu. com/job/ ubuntu- ui-toolkit- trusty- armhf-ci/ 550/artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ autopilot- testrunner- otto-trusty/ 2134 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/2446 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/2446/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/2294 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- armhf/2294/ artifact/ work/output/ *zip*/output. zip jenkins. qa.ubuntu. com/job/ generic- mediumtests- runner- mako/4740/ console s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 3178
http://
Executed test runs:
SUCCESS: http://
FAILURE: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
deb: http://
FAILURE: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/ubuntu- ui-toolkit- ci/1602/ rebuild
http://