Merge lp:~elopio/autopilot/fix1266601-Pointer-pressed-move into lp:autopilot
- fix1266601-Pointer-pressed-move
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~elopio/autopilot/fix1266601-Pointer-pressed-move |
Merge into: | lp:autopilot |
Diff against target: |
418 lines (+270/-22) 4 files modified
autopilot/input/_X11.py (+3/-3) autopilot/input/__init__.py (+9/-4) autopilot/input/_uinput.py (+23/-13) autopilot/tests/unit/test_input.py (+235/-2) |
To merge this branch: | bzr merge lp:~elopio/autopilot/fix1266601-Pointer-pressed-move |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot | continuous-integration | Needs Fixing | |
Autopilot Hackers | Pending | ||
Review via email: mp+200617@code.launchpad.net |
This proposal has been superseded by a proposal from 2014-01-19.
Commit message
Do a touch move when the Pointer is pressed.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:409
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:410
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild:
http://
- 411. By Leo Arias
-
Merged with prerequisite branch.
- 412. By Leo Arias
-
Merged with prerequisite branch.
- 413. By Leo Arias
-
Merged with prerequisite branch.
- 414. By Leo Arias
-
Merged with prerequisite branch.
- 415. By Leo Arias
-
Use the mock touch so now real mouse events are used.
- 416. By Leo Arias
-
Merged with prerequisite.
- 417. By Leo Arias
-
Cleaned up the tests.
- 418. By Leo Arias
-
Cleaned up the tests.
- 419. By Leo Arias
-
Merged with prerequisite.
- 420. By Leo Arias
-
Updated prerequisite.
- 421. By Leo Arias
-
Use the device pressed property.
- 422. By Leo Arias
-
Fixed the tests backend.
- 423. By Leo Arias
-
Cleanup.
- 424. By Leo Arias
-
Finger move with transition.
- 425. By Leo Arias
-
Be consistent on the use of attributes.
- 426. By Leo Arias
-
Fixed pep8.
Unmerged revisions
- 426. By Leo Arias
-
Fixed pep8.
- 425. By Leo Arias
-
Be consistent on the use of attributes.
- 424. By Leo Arias
-
Finger move with transition.
- 423. By Leo Arias
-
Cleanup.
- 422. By Leo Arias
-
Fixed the tests backend.
- 421. By Leo Arias
-
Use the device pressed property.
- 420. By Leo Arias
-
Updated prerequisite.
- 419. By Leo Arias
-
Merged with prerequisite.
- 418. By Leo Arias
-
Cleaned up the tests.
- 417. By Leo Arias
-
Cleaned up the tests.
Preview Diff
1 | === modified file 'autopilot/input/_X11.py' | |||
2 | --- autopilot/input/_X11.py 2013-11-07 05:53:36 +0000 | |||
3 | +++ autopilot/input/_X11.py 2014-01-19 01:47:17 +0000 | |||
4 | @@ -1,7 +1,7 @@ | |||
5 | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
6 | 2 | # | 2 | # |
7 | 3 | # Autopilot Functional Test Tool | 3 | # Autopilot Functional Test Tool |
9 | 4 | # Copyright (C) 2012-2013 Canonical | 4 | # Copyright (C) 2012, 2013, 2014 Canonical |
10 | 5 | # | 5 | # |
11 | 6 | # This program is free software: you can redistribute it and/or modify | 6 | # This program is free software: you can redistribute it and/or modify |
12 | 7 | # it under the terms of the GNU General Public License as published by | 7 | # it under the terms of the GNU General Public License as published by |
13 | @@ -455,7 +455,7 @@ | |||
14 | 455 | x, y = coord["root_x"], coord["root_y"] | 455 | x, y = coord["root_x"], coord["root_y"] |
15 | 456 | return x, y | 456 | return x, y |
16 | 457 | 457 | ||
18 | 458 | def drag(self, x1, y1, x2, y2): | 458 | def drag(self, x1, y1, x2, y2, rate=10): |
19 | 459 | """Performs a press, move and release. | 459 | """Performs a press, move and release. |
20 | 460 | 460 | ||
21 | 461 | This is to keep a common API between Mouse and Finger as long as | 461 | This is to keep a common API between Mouse and Finger as long as |
22 | @@ -464,7 +464,7 @@ | |||
23 | 464 | """ | 464 | """ |
24 | 465 | self.move(x1, y1) | 465 | self.move(x1, y1) |
25 | 466 | self.press() | 466 | self.press() |
27 | 467 | self.move(x2, y2) | 467 | self.move(x2, y2, rate=rate) |
28 | 468 | self.release() | 468 | self.release() |
29 | 469 | 469 | ||
30 | 470 | @classmethod | 470 | @classmethod |
31 | 471 | 471 | ||
32 | === modified file 'autopilot/input/__init__.py' | |||
33 | --- autopilot/input/__init__.py 2013-09-20 19:01:27 +0000 | |||
34 | +++ autopilot/input/__init__.py 2014-01-19 01:47:17 +0000 | |||
35 | @@ -369,7 +369,7 @@ | |||
36 | 369 | """ | 369 | """ |
37 | 370 | raise NotImplementedError("You cannot use this class directly.") | 370 | raise NotImplementedError("You cannot use this class directly.") |
38 | 371 | 371 | ||
40 | 372 | def drag(self, x1, y1, x2, y2): | 372 | def drag(self, x1, y1, x2, y2, rate=10): |
41 | 373 | """Performs a press, move and release. | 373 | """Performs a press, move and release. |
42 | 374 | 374 | ||
43 | 375 | This is to keep a common API between Mouse and Finger as long as | 375 | This is to keep a common API between Mouse and Finger as long as |
44 | @@ -466,7 +466,7 @@ | |||
45 | 466 | """Release a previously pressed finger""" | 466 | """Release a previously pressed finger""" |
46 | 467 | raise NotImplementedError("You cannot use this class directly.") | 467 | raise NotImplementedError("You cannot use this class directly.") |
47 | 468 | 468 | ||
49 | 469 | def drag(self, x1, y1, x2, y2): | 469 | def drag(self, x1, y1, x2, y2, rate=10): |
50 | 470 | """Perform a drag gesture from (x1,y1) to (x2,y2)""" | 470 | """Perform a drag gesture from (x1,y1) to (x2,y2)""" |
51 | 471 | raise NotImplementedError("You cannot use this class directly.") | 471 | raise NotImplementedError("You cannot use this class directly.") |
52 | 472 | 472 | ||
53 | @@ -502,6 +502,7 @@ | |||
54 | 502 | self._device = device | 502 | self._device = device |
55 | 503 | self._x = 0 | 503 | self._x = 0 |
56 | 504 | self._y = 0 | 504 | self._y = 0 |
57 | 505 | self._pressed = False | ||
58 | 505 | 506 | ||
59 | 506 | @property | 507 | @property |
60 | 507 | def x(self): | 508 | def x(self): |
61 | @@ -544,6 +545,7 @@ | |||
62 | 544 | raise ValueError( | 545 | raise ValueError( |
63 | 545 | "Touch devices do not have button %d" % (button)) | 546 | "Touch devices do not have button %d" % (button)) |
64 | 546 | self._device.press(self._x, self._y) | 547 | self._device.press(self._x, self._y) |
65 | 548 | self._pressed = True | ||
66 | 547 | 549 | ||
67 | 548 | def release(self, button=1): | 550 | def release(self, button=1): |
68 | 549 | """Releases the pointer at it's current location. | 551 | """Releases the pointer at it's current location. |
69 | @@ -560,6 +562,7 @@ | |||
70 | 560 | raise ValueError( | 562 | raise ValueError( |
71 | 561 | "Touch devices do not have button %d" % (button)) | 563 | "Touch devices do not have button %d" % (button)) |
72 | 562 | self._device.release() | 564 | self._device.release() |
73 | 565 | self._pressed = False | ||
74 | 563 | 566 | ||
75 | 564 | def click(self, button=1, press_duration=0.10): | 567 | def click(self, button=1, press_duration=0.10): |
76 | 565 | """Press and release at the current pointer location. | 568 | """Press and release at the current pointer location. |
77 | @@ -589,6 +592,8 @@ | |||
78 | 589 | if isinstance(self._device, Mouse): | 592 | if isinstance(self._device, Mouse): |
79 | 590 | self._device.move(x, y) | 593 | self._device.move(x, y) |
80 | 591 | else: | 594 | else: |
81 | 595 | if self._pressed: | ||
82 | 596 | self._device.move(x, y) | ||
83 | 592 | self._x = x | 597 | self._x = x |
84 | 593 | self._y = y | 598 | self._y = y |
85 | 594 | 599 | ||
86 | @@ -641,9 +646,9 @@ | |||
87 | 641 | else: | 646 | else: |
88 | 642 | return (self._x, self._y) | 647 | return (self._x, self._y) |
89 | 643 | 648 | ||
91 | 644 | def drag(self, x1, y1, x2, y2): | 649 | def drag(self, x1, y1, x2, y2, rate=10): |
92 | 645 | """Performs a press, move and release.""" | 650 | """Performs a press, move and release.""" |
94 | 646 | self._device.drag(x1, y1, x2, y2) | 651 | self._device.drag(x1, y1, x2, y2, rate=rate) |
95 | 647 | if isinstance(self._device, Touch): | 652 | if isinstance(self._device, Touch): |
96 | 648 | self._x = x2 | 653 | self._x = x2 |
97 | 649 | self._y = y2 | 654 | self._y = y2 |
98 | 650 | 655 | ||
99 | === modified file 'autopilot/input/_uinput.py' | |||
100 | --- autopilot/input/_uinput.py 2013-11-07 05:53:36 +0000 | |||
101 | +++ autopilot/input/_uinput.py 2014-01-19 01:47:17 +0000 | |||
102 | @@ -1,7 +1,7 @@ | |||
103 | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
104 | 2 | # | 2 | # |
105 | 3 | # Autopilot Functional Test Tool | 3 | # Autopilot Functional Test Tool |
107 | 4 | # Copyright (C) 2012-2013 Canonical | 4 | # Copyright (C) 2012, 2013, 2014 Canonical |
108 | 5 | # | 5 | # |
109 | 6 | # This program is free software: you can redistribute it and/or modify | 6 | # This program is free software: you can redistribute it and/or modify |
110 | 7 | # it under the terms of the GNU General Public License as published by | 7 | # it under the terms of the GNU General Public License as published by |
111 | @@ -361,23 +361,33 @@ | |||
112 | 361 | raise RuntimeError("Attempting to move without finger being down.") | 361 | raise RuntimeError("Attempting to move without finger being down.") |
113 | 362 | self._finger_move(x, y) | 362 | self._finger_move(x, y) |
114 | 363 | 363 | ||
116 | 364 | def drag(self, x1, y1, x2, y2): | 364 | def drag(self, x1, y1, x2, y2, rate=10): |
117 | 365 | """Perform a drag gesture from (x1,y1) to (x2,y2)""" | 365 | """Perform a drag gesture from (x1,y1) to (x2,y2)""" |
118 | 366 | logger.debug("Dragging from %d,%d to %d,%d", x1, y1, x2, y2) | 366 | logger.debug("Dragging from %d,%d to %d,%d", x1, y1, x2, y2) |
119 | 367 | self._finger_down(x1, y1) | 367 | self._finger_down(x1, y1) |
120 | 368 | 368 | ||
128 | 369 | # Let's drag in 100 steps for now... | 369 | current_x, current_y = x1, y1 |
129 | 370 | dx = 1.0 * (x2 - x1) / 100 | 370 | while current_x != x2 or current_y != y2: |
130 | 371 | dy = 1.0 * (y2 - y1) / 100 | 371 | dx = abs(x2 - current_x) |
131 | 372 | cur_x = x1 + dx | 372 | dy = abs(y2 - current_y) |
132 | 373 | cur_y = y1 + dy | 373 | |
133 | 374 | for i in range(0, 100): | 374 | intx = float(dx) / max(dx, dy) |
134 | 375 | self._finger_move(int(cur_x), int(cur_y)) | 375 | inty = float(dy) / max(dx, dy) |
135 | 376 | |||
136 | 377 | step_x = min(rate * intx, dx) | ||
137 | 378 | step_y = min(rate * inty, dy) | ||
138 | 379 | |||
139 | 380 | if x2 < current_x: | ||
140 | 381 | step_x *= -1 | ||
141 | 382 | if y2 < current_y: | ||
142 | 383 | step_y *= -1 | ||
143 | 384 | |||
144 | 385 | current_x += step_x | ||
145 | 386 | current_y += step_y | ||
146 | 387 | self._finger_move(current_x, current_y) | ||
147 | 388 | |||
148 | 376 | sleep(0.002) | 389 | sleep(0.002) |
153 | 377 | cur_x += dx | 390 | |
150 | 378 | cur_y += dy | ||
151 | 379 | # Make sure we actually end up at target | ||
152 | 380 | self._finger_move(x2, y2) | ||
154 | 381 | self._finger_up() | 391 | self._finger_up() |
155 | 382 | 392 | ||
156 | 383 | def _finger_down(self, x, y): | 393 | def _finger_down(self, x, y): |
157 | 384 | 394 | ||
158 | === modified file 'autopilot/tests/unit/test_input.py' | |||
159 | --- autopilot/tests/unit/test_input.py 2013-12-10 03:10:11 +0000 | |||
160 | +++ autopilot/tests/unit/test_input.py 2014-01-19 01:47:17 +0000 | |||
161 | @@ -1,7 +1,7 @@ | |||
162 | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- | 1 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
163 | 2 | # | 2 | # |
164 | 3 | # Autopilot Functional Test Tool | 3 | # Autopilot Functional Test Tool |
166 | 4 | # Copyright (C) 2013 Canonical | 4 | # Copyright (C) 2013, 2014 Canonical |
167 | 5 | # | 5 | # |
168 | 6 | # This program is free software: you can redistribute it and/or modify | 6 | # This program is free software: you can redistribute it and/or modify |
169 | 7 | # it under the terms of the GNU General Public License as published by | 7 | # it under the terms of the GNU General Public License as published by |
170 | @@ -17,10 +17,14 @@ | |||
171 | 17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 17 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
172 | 18 | # | 18 | # |
173 | 19 | 19 | ||
175 | 20 | from mock import patch | 20 | import testscenarios |
176 | 21 | |||
177 | 22 | from mock import call, Mock, patch | ||
178 | 21 | from testtools import TestCase | 23 | from testtools import TestCase |
179 | 22 | from testtools.matchers import raises | 24 | from testtools.matchers import raises |
180 | 23 | 25 | ||
181 | 26 | import autopilot.input | ||
182 | 27 | from autopilot.input import _uinput, _X11 | ||
183 | 24 | from autopilot.input._common import get_center_point | 28 | from autopilot.input._common import get_center_point |
184 | 25 | 29 | ||
185 | 26 | 30 | ||
186 | @@ -151,3 +155,232 @@ | |||
187 | 151 | 155 | ||
188 | 152 | self.assertEqual(123, x) | 156 | self.assertEqual(123, x) |
189 | 153 | self.assertEqual(345, y) | 157 | self.assertEqual(345, y) |
190 | 158 | |||
191 | 159 | |||
192 | 160 | class PartialMock(object): | ||
193 | 161 | """Mock some of the methods of an object, and record their calls.""" | ||
194 | 162 | |||
195 | 163 | def __init__(self, real_object, *args): | ||
196 | 164 | super(PartialMock, self).__init__() | ||
197 | 165 | self._mock_manager = Mock() | ||
198 | 166 | self._real_object = real_object | ||
199 | 167 | self.patched_attributes = args | ||
200 | 168 | |||
201 | 169 | def __getattr__(self, name): | ||
202 | 170 | """Forward all the calls to the real object.""" | ||
203 | 171 | return self._real_object.__getattribute__(name) | ||
204 | 172 | |||
205 | 173 | @property | ||
206 | 174 | def mock_calls(self): | ||
207 | 175 | """Return the calls recorded for the mocked attributes.""" | ||
208 | 176 | return self._mock_manager.mock_calls | ||
209 | 177 | |||
210 | 178 | def __enter__(self): | ||
211 | 179 | self._start_patchers() | ||
212 | 180 | return self | ||
213 | 181 | |||
214 | 182 | def _start_patchers(self): | ||
215 | 183 | self._patchers = [] | ||
216 | 184 | for attribute in self.patched_attributes: | ||
217 | 185 | patcher = patch.object(self._real_object, attribute) | ||
218 | 186 | self._patchers.append(patcher) | ||
219 | 187 | |||
220 | 188 | self._mock_manager.attach_mock(patcher.start(), attribute) | ||
221 | 189 | |||
222 | 190 | def __exit__(self, exc_type, exc_val, exc_tb): | ||
223 | 191 | self._stop_patchers() | ||
224 | 192 | |||
225 | 193 | def _stop_patchers(self): | ||
226 | 194 | for patcher in self._patchers: | ||
227 | 195 | patcher.stop() | ||
228 | 196 | |||
229 | 197 | |||
230 | 198 | class MockX11Mouse(PartialMock): | ||
231 | 199 | """Mock for the X11 Mouse Touch. | ||
232 | 200 | |||
233 | 201 | It records the calls to press, release and move, but doesn't perform them. | ||
234 | 202 | |||
235 | 203 | """ | ||
236 | 204 | |||
237 | 205 | def __init__(self): | ||
238 | 206 | super(MockX11Mouse, self).__init__( | ||
239 | 207 | _X11.Mouse(), 'press', 'release', 'move') | ||
240 | 208 | |||
241 | 209 | def get_move_call_args_list(self): | ||
242 | 210 | return self._mock_manager.move.call_args_list | ||
243 | 211 | |||
244 | 212 | |||
245 | 213 | class X11MouseTestCase(TestCase): | ||
246 | 214 | |||
247 | 215 | def test_drag_should_call_move_with_rate(self): | ||
248 | 216 | expected_first_move_call = call(0, 0) | ||
249 | 217 | expected_second_move_call = call(100, 100, rate=1) | ||
250 | 218 | with MockX11Mouse() as mock_mouse: | ||
251 | 219 | mock_mouse.drag(0, 0, 100, 100, rate=1) | ||
252 | 220 | |||
253 | 221 | self.assertEqual( | ||
254 | 222 | [expected_first_move_call, expected_second_move_call], | ||
255 | 223 | mock_mouse.get_move_call_args_list()) | ||
256 | 224 | |||
257 | 225 | def test_drag_with_default_rate(self): | ||
258 | 226 | expected_first_move_call = call(0, 0) | ||
259 | 227 | expected_second_move_call = call(100, 100, rate=10) | ||
260 | 228 | with MockX11Mouse() as mock_mouse: | ||
261 | 229 | mock_mouse.drag(0, 0, 100, 100) | ||
262 | 230 | |||
263 | 231 | self.assertEqual( | ||
264 | 232 | [expected_first_move_call, expected_second_move_call], | ||
265 | 233 | mock_mouse.get_move_call_args_list()) | ||
266 | 234 | |||
267 | 235 | |||
268 | 236 | class MockUinputTouch(PartialMock): | ||
269 | 237 | """Mock for the uinput Touch. | ||
270 | 238 | |||
271 | 239 | It records the calls to _finger_down, _finger_up and _finger_move, but | ||
272 | 240 | doesn't perform them. | ||
273 | 241 | |||
274 | 242 | """ | ||
275 | 243 | |||
276 | 244 | def __init__(self): | ||
277 | 245 | super(MockUinputTouch, self).__init__( | ||
278 | 246 | _uinput.Touch(), '_finger_down', '_finger_up', '_finger_move') | ||
279 | 247 | |||
280 | 248 | def get_finger_move_call_args_list(self): | ||
281 | 249 | return self._mock_manager._finger_move.call_args_list | ||
282 | 250 | |||
283 | 251 | |||
284 | 252 | class UinputTouchTestCase(TestCase): | ||
285 | 253 | |||
286 | 254 | def test_drag_finger_actions(self): | ||
287 | 255 | expected_finger_calls = [ | ||
288 | 256 | call._finger_down(0, 0), | ||
289 | 257 | call._finger_move(10, 10), | ||
290 | 258 | call._finger_up() | ||
291 | 259 | ] | ||
292 | 260 | with MockUinputTouch() as mock_touch: | ||
293 | 261 | mock_touch.drag(0, 0, 10, 10) | ||
294 | 262 | self.assertEqual(mock_touch.mock_calls, expected_finger_calls) | ||
295 | 263 | |||
296 | 264 | def test_drag_should_call_move_with_rate(self): | ||
297 | 265 | expected_move_calls = [call(5, 5), call(10, 10), call(15, 15)] | ||
298 | 266 | with MockUinputTouch() as mock_touch: | ||
299 | 267 | mock_touch.drag(0, 0, 15, 15, rate=5) | ||
300 | 268 | |||
301 | 269 | self.assertEqual( | ||
302 | 270 | expected_move_calls, mock_touch.get_finger_move_call_args_list()) | ||
303 | 271 | |||
304 | 272 | def test_drag_with_default_rate(self): | ||
305 | 273 | expected_move_calls = [call(10, 10), call(20, 20)] | ||
306 | 274 | with MockUinputTouch() as mock_touch: | ||
307 | 275 | mock_touch.drag(0, 0, 20, 20) | ||
308 | 276 | |||
309 | 277 | self.assertEqual( | ||
310 | 278 | expected_move_calls, mock_touch.get_finger_move_call_args_list()) | ||
311 | 279 | |||
312 | 280 | def test_drag_to_same_place_should_not_move(self): | ||
313 | 281 | expected_finger_calls = [ | ||
314 | 282 | call._finger_down(0, 0), | ||
315 | 283 | call._finger_up() | ||
316 | 284 | ] | ||
317 | 285 | with MockUinputTouch() as mock_touch: | ||
318 | 286 | mock_touch.drag(0, 0, 0, 0) | ||
319 | 287 | self.assertEqual(mock_touch.mock_calls, expected_finger_calls) | ||
320 | 288 | |||
321 | 289 | |||
322 | 290 | class DragUinputTouchTestCase(testscenarios.TestWithScenarios, TestCase): | ||
323 | 291 | |||
324 | 292 | scenarios = [ | ||
325 | 293 | ('drag to top', dict( | ||
326 | 294 | start_x=50, start_y=50, stop_x=50, stop_y=30, | ||
327 | 295 | expected_moves=[call(50, 40), call(50, 30)])), | ||
328 | 296 | ('drag to bottom', dict( | ||
329 | 297 | start_x=50, start_y=50, stop_x=50, stop_y=70, | ||
330 | 298 | expected_moves=[call(50, 60), call(50, 70)])), | ||
331 | 299 | ('drag to left', dict( | ||
332 | 300 | start_x=50, start_y=50, stop_x=30, stop_y=50, | ||
333 | 301 | expected_moves=[call(40, 50), call(30, 50)])), | ||
334 | 302 | ('drag to right', dict( | ||
335 | 303 | start_x=50, start_y=50, stop_x=70, stop_y=50, | ||
336 | 304 | expected_moves=[call(60, 50), call(70, 50)])), | ||
337 | 305 | |||
338 | 306 | ('drag to top-left', dict( | ||
339 | 307 | start_x=50, start_y=50, stop_x=30, stop_y=30, | ||
340 | 308 | expected_moves=[call(40, 40), call(30, 30)])), | ||
341 | 309 | ('drag to top-right', dict( | ||
342 | 310 | start_x=50, start_y=50, stop_x=70, stop_y=30, | ||
343 | 311 | expected_moves=[call(60, 40), call(70, 30)])), | ||
344 | 312 | ('drag to bottom-left', dict( | ||
345 | 313 | start_x=50, start_y=50, stop_x=30, stop_y=70, | ||
346 | 314 | expected_moves=[call(40, 60), call(30, 70)])), | ||
347 | 315 | ('drag to bottom-right', dict( | ||
348 | 316 | start_x=50, start_y=50, stop_x=70, stop_y=70, | ||
349 | 317 | expected_moves=[call(60, 60), call(70, 70)])), | ||
350 | 318 | |||
351 | 319 | ('drag less than rate', dict( | ||
352 | 320 | start_x=50, start_y=50, stop_x=55, stop_y=55, | ||
353 | 321 | expected_moves=[call(55, 55)])), | ||
354 | 322 | |||
355 | 323 | ('drag with last move less than rate', dict( | ||
356 | 324 | start_x=50, start_y=50, stop_x=65, stop_y=65, | ||
357 | 325 | expected_moves=[call(60, 60), call(65, 65)])), | ||
358 | 326 | ] | ||
359 | 327 | |||
360 | 328 | def test_drag_moves(self): | ||
361 | 329 | with MockUinputTouch() as mock_touch: | ||
362 | 330 | mock_touch.drag( | ||
363 | 331 | self.start_x, self.start_y, self.stop_x, self.stop_y) | ||
364 | 332 | |||
365 | 333 | self.assertEqual( | ||
366 | 334 | self.expected_moves, mock_touch.get_finger_move_call_args_list()) | ||
367 | 335 | |||
368 | 336 | |||
369 | 337 | class PointerTestCase(TestCase): | ||
370 | 338 | |||
371 | 339 | def setUp(self): | ||
372 | 340 | super(PointerTestCase, self).setUp() | ||
373 | 341 | self.pointer = autopilot.input.Pointer(autopilot.input.Mouse.create()) | ||
374 | 342 | |||
375 | 343 | def test_drag_with_rate(self): | ||
376 | 344 | with patch.object(self.pointer._device, 'drag') as mock_drag: | ||
377 | 345 | self.pointer.drag(0, 0, 20, 20, rate=5) | ||
378 | 346 | |||
379 | 347 | mock_drag.assert_called_once_with(0, 0, 20, 20, rate=5) | ||
380 | 348 | |||
381 | 349 | def test_drag_with_default_rate(self): | ||
382 | 350 | with patch.object(self.pointer._device, 'drag') as mock_drag: | ||
383 | 351 | self.pointer.drag(0, 0, 20, 20) | ||
384 | 352 | |||
385 | 353 | mock_drag.assert_called_once_with(0, 0, 20, 20, rate=10) | ||
386 | 354 | |||
387 | 355 | |||
388 | 356 | class PointerWithTouchBackendTestCase(TestCase): | ||
389 | 357 | |||
390 | 358 | def setUp(self): | ||
391 | 359 | super(PointerWithTouchBackendTestCase, self).setUp() | ||
392 | 360 | self.pointer = autopilot.input.Pointer(autopilot.input.Touch.create()) | ||
393 | 361 | |||
394 | 362 | def test_not_pressed_move_should_not_move_pointing_finger(self): | ||
395 | 363 | with patch.object(_uinput.Touch, 'move') as mock_move: | ||
396 | 364 | self.pointer.move(1, 1) | ||
397 | 365 | |||
398 | 366 | self.assertFalse(mock_move.called) | ||
399 | 367 | |||
400 | 368 | def test_pressed_move_should_move_pointing_finger(self): | ||
401 | 369 | with MockUinputTouch() as mock_touch: | ||
402 | 370 | self.pointer._device = mock_touch | ||
403 | 371 | with patch.object(_uinput.Touch, 'move') as mock_move: | ||
404 | 372 | self.pointer.press() | ||
405 | 373 | self.pointer.move(1, 1) | ||
406 | 374 | |||
407 | 375 | mock_move.assert_called_once_with(1, 1) | ||
408 | 376 | |||
409 | 377 | def test_released_move_should_not_move_pointing_finger(self): | ||
410 | 378 | with MockUinputTouch() as mock_touch: | ||
411 | 379 | self.pointer._device = mock_touch | ||
412 | 380 | with patch.object(_uinput.Touch, 'move') as mock_move: | ||
413 | 381 | self.pointer.press() | ||
414 | 382 | self.pointer.release() | ||
415 | 383 | |||
416 | 384 | self.pointer.move(1, 1) | ||
417 | 385 | |||
418 | 386 | self.assertFalse(mock_move.called) |
FAILED: Continuous integration, rev:409 jenkins. qa.ubuntu. com/job/ autopilot- ci/376/ jenkins. qa.ubuntu. com/job/ autopilot- trusty- amd64-ci/ 102/console jenkins. qa.ubuntu. com/job/ autopilot- trusty- armhf-ci/ 102/console jenkins. qa.ubuntu. com/job/ autopilot- trusty- i386-ci/ 102/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- trusty/ 2019/console jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- trusty- amd64/2019/ console
http://
Executed test runs:
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
FAILURE: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/autopilot- ci/376/ rebuild
http://