Merge lp:~canonical-platform-qa/unity8/fix1306340-deprecate_emulators into lp:unity8
- fix1306340-deprecate_emulators
- Merge into trunk
Status: | Superseded |
---|---|
Proposed branch: | lp:~canonical-platform-qa/unity8/fix1306340-deprecate_emulators |
Merge into: | lp:unity8 |
Diff against target: |
1454 lines (+511/-515) 20 files modified
debian/control (+1/-1) tests/autopilot/unity8/__init__.py (+6/-2) tests/autopilot/unity8/application_lifecycle/tests/__init__.py (+2/-2) tests/autopilot/unity8/dash.py (+22/-15) tests/autopilot/unity8/greeter/__init__.py (+93/-0) tests/autopilot/unity8/greeter/__init__.py.moved (+0/-39) tests/autopilot/unity8/greeter/tests/__init__.py (+2/-2) tests/autopilot/unity8/indicators/tests/__init__.py (+1/-1) tests/autopilot/unity8/launcher.py (+3/-3) tests/autopilot/unity8/process_helpers.py (+12/-96) tests/autopilot/unity8/shell/__init__.py (+169/-2) tests/autopilot/unity8/shell/create_interactive_notification.py (+101/-0) tests/autopilot/unity8/shell/emulators.py (+52/-0) tests/autopilot/unity8/shell/emulators/__init__.py (+0/-22) tests/autopilot/unity8/shell/emulators/create_interactive_notification.py (+0/-101) tests/autopilot/unity8/shell/emulators/main_window.py (+0/-187) tests/autopilot/unity8/shell/tests/__init__.py (+3/-3) tests/autopilot/unity8/shell/tests/test_helpers.py (+19/-14) tests/autopilot/unity8/shell/tests/test_notifications.py (+23/-23) tests/autopilot/unity8/shell/tests/test_tutorial.py (+2/-2) |
To merge this branch: | bzr merge lp:~canonical-platform-qa/unity8/fix1306340-deprecate_emulators |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
PS Jenkins bot (community) | continuous-integration | Needs Fixing | |
Review via email: mp+257812@code.launchpad.net |
This proposal has been superseded by a proposal from 2015-05-15.
Commit message
Deprecate unity8 emulators.
Description of the change
PS Jenkins bot (ps-jenkins) wrote : | # |
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1533
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:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1533
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:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
PS Jenkins bot (ps-jenkins) wrote : | # |
FAILED: Continuous integration, rev:1533
http://
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
- 1534. By Leo Arias
-
Merged with the greeter branch from josh.
- 1535. By Leo Arias
-
Merged with trunk.
- 1536. By Leo Arias
-
Merged with trunk.
- 1537. By Leo Arias
-
Removed the file resulting from a wrong merge.
- 1538. By Leo Arias
-
Merged with trunk.
- 1539. By Richard Huddie
-
Merged with trunk.
- 1540. By Richard Huddie
-
Merged with trunk.
- 1541. By Richard Huddie
-
Update rotation tests to use new helpers.
- 1542. By Richard Huddie
-
Fix unlock unity in fake sensors test and remove duplicated test.
- 1543. By Richard Huddie
-
Fix flake8 errors, remove imports using emulator and rename emulator tests to helper tests.
Unmerged revisions
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2015-04-22 14:43:17 +0000 |
3 | +++ debian/control 2015-05-15 07:16:40 +0000 |
4 | @@ -150,7 +150,7 @@ |
5 | python3-fixtures, |
6 | python3-gi, |
7 | qttestability-autopilot (>= 1.4), |
8 | - ubuntu-ui-toolkit-autopilot, |
9 | + ubuntu-ui-toolkit-autopilot (>= 1.2.1485+15.04.20150417.1-0ubuntu1), |
10 | unity-scope-click, |
11 | unity8 (= ${source:Version}), |
12 | unity8-fake-env (= ${source:Version}), |
13 | |
14 | === modified file 'tests/autopilot/unity8/__init__.py' |
15 | --- tests/autopilot/unity8/__init__.py 2014-02-23 01:46:02 +0000 |
16 | +++ tests/autopilot/unity8/__init__.py 2015-05-15 07:16:40 +0000 |
17 | @@ -1,7 +1,7 @@ |
18 | # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
19 | # |
20 | # Unity Autopilot Test Suite |
21 | -# Copyright (C) 2012, 2013, 2014 Canonical |
22 | +# Copyright (C) 2012, 2013, 2014, 2015 Canonical |
23 | # |
24 | # This program is free software: you can redistribute it and/or modify |
25 | # it under the terms of the GNU General Public License as published by |
26 | @@ -17,13 +17,17 @@ |
27 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
28 | # |
29 | |
30 | -"""unity autopilot tests and emulators - top level package.""" |
31 | +"""unity autopilot tests and helpers - top level package.""" |
32 | import os |
33 | import os.path |
34 | import subprocess |
35 | import sysconfig |
36 | |
37 | |
38 | +class UnityException(Exception): |
39 | + """Exception raised when there is an error with the Unity test helpers.""" |
40 | + |
41 | + |
42 | def running_installed_tests(): |
43 | binary_path = get_binary_path() |
44 | return binary_path.startswith('/usr') |
45 | |
46 | === modified file 'tests/autopilot/unity8/application_lifecycle/tests/__init__.py' |
47 | --- tests/autopilot/unity8/application_lifecycle/tests/__init__.py 2015-02-23 17:29:04 +0000 |
48 | +++ tests/autopilot/unity8/application_lifecycle/tests/__init__.py 2015-05-15 07:16:40 +0000 |
49 | @@ -31,8 +31,8 @@ |
50 | super().setUp() |
51 | self._qml_mock_enabled = False |
52 | self._data_dirs_mock_enabled = False |
53 | - unity_proxy = self.launch_unity() |
54 | - process_helpers.unlock_unity(unity_proxy) |
55 | + self.launch_unity() |
56 | + process_helpers.unlock_unity() |
57 | |
58 | def create_test_application(self): |
59 | desktop_file_dict = fixture_setup.DEFAULT_DESKTOP_FILE_DICT |
60 | |
61 | === renamed file 'tests/autopilot/unity8/shell/emulators/dash.py' => 'tests/autopilot/unity8/dash.py' |
62 | --- tests/autopilot/unity8/shell/emulators/dash.py 2015-04-28 15:20:13 +0000 |
63 | +++ tests/autopilot/unity8/dash.py 2015-05-15 07:16:40 +0000 |
64 | @@ -23,7 +23,7 @@ |
65 | from autopilot import logging as autopilot_logging |
66 | from autopilot.introspection import dbus |
67 | |
68 | -from unity8.shell import emulators |
69 | +import unity8 |
70 | |
71 | |
72 | logger = logging.getLogger(__name__) |
73 | @@ -41,7 +41,7 @@ |
74 | |
75 | |
76 | class Dash(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
77 | - """An emulator that understands the Dash.""" |
78 | + """A helper that understands the Dash.""" |
79 | |
80 | def __init__(self, *args): |
81 | super().__init__(*args) |
82 | @@ -93,10 +93,10 @@ |
83 | for l in aux.get_children_by_type('QQuickLoader'): |
84 | if (l.scopeId == scope_id): |
85 | return l |
86 | - raise emulators.UnityEmulatorException( |
87 | + raise unity8.UnityException( |
88 | 'No scope found with id {0}'.format(scope_id)) |
89 | except dbus.StateNotFoundError: |
90 | - raise emulators.UnityEmulatorException( |
91 | + raise unity8.UnityException( |
92 | 'No scope found with id {0}'.format(scope_id)) |
93 | |
94 | def _get_scope_from_loader(self, loader): |
95 | @@ -121,7 +121,7 @@ |
96 | elif scope_loader.globalRect.x > current_scope_loader.globalRect.x: |
97 | return self._scroll_to_right_scope |
98 | else: |
99 | - raise emulators.UnityEmulatorException('The scope is already open') |
100 | + raise unity8.UnityException('The scope is already open') |
101 | |
102 | @autopilot_logging.log_action(logger.info) |
103 | def _scroll_to_left_scope(self): |
104 | @@ -185,14 +185,15 @@ |
105 | |
106 | |
107 | class ListViewWithPageHeader(ubuntuuitoolkit.QQuickFlickable): |
108 | - pass |
109 | + |
110 | + margin_to_swipe_from_bottom = ubuntuuitoolkit.units.gu(4) |
111 | |
112 | |
113 | class GenericScopeView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
114 | - """Autopilot emulator for generic scopes.""" |
115 | + """Autopilot helper for generic scopes.""" |
116 | |
117 | @autopilot_logging.log_action(logger.info) |
118 | - def open_preview(self, category, app_name): |
119 | + def open_preview(self, category, app_name, press_duration=0.10): |
120 | """Open the preview of an application. |
121 | |
122 | :parameter category: The name of the category where the application is. |
123 | @@ -203,16 +204,19 @@ |
124 | # FIXME some categories need a long press in order to see the preview. |
125 | # Some categories do not show previews, like recent apps. |
126 | # --elopio - 2014-1-14 |
127 | - self.click_scope_item(category, app_name) |
128 | + self.click_scope_item(category, app_name, press_duration) |
129 | preview_list = self.wait_select_single( |
130 | 'QQuickLoader', objectName='subPageLoader') |
131 | preview_list.subPageShown.wait_for(True) |
132 | preview_list.x.wait_for(0) |
133 | + self.get_root_instance().select_single( |
134 | + objectName='processingIndicator').visible.wait_for(False) |
135 | return preview_list.select_single( |
136 | - Preview, objectName='preview{}'.format(preview_list.currentIndex)) |
137 | + Preview, objectName='preview{}'.format( |
138 | + preview_list.initialIndex)) |
139 | |
140 | @autopilot_logging.log_action(logger.debug) |
141 | - def click_scope_item(self, category, title): |
142 | + def click_scope_item(self, category, title, press_duration=0.10): |
143 | """Click an item from the scope. |
144 | |
145 | :parameter category: The name of the category where the item is. |
146 | @@ -220,9 +224,12 @@ |
147 | |
148 | """ |
149 | category_element = self._get_category_element(category) |
150 | - icon = category_element.wait_select_single('AbstractButton', |
151 | - title=title) |
152 | - self.pointing_device.click_object(icon) |
153 | + icon = category_element.wait_select_single( |
154 | + 'AbstractButton', title=title) |
155 | + list_view = self.select_single( |
156 | + ListViewWithPageHeader, objectName='categoryListView') |
157 | + list_view.swipe_child_into_view(icon) |
158 | + self.pointing_device.click_object(icon, press_duration=press_duration) |
159 | |
160 | def _get_category_element(self, category): |
161 | try: |
162 | @@ -230,7 +237,7 @@ |
163 | 'DashCategoryBase', |
164 | objectName='dashCategory{}'.format(category)) |
165 | except dbus.StateNotFoundError: |
166 | - raise emulators.UnityEmulatorException( |
167 | + raise unity8.UnityException( |
168 | 'No category found with name {}'.format(category)) |
169 | |
170 | def get_applications(self, category): |
171 | |
172 | === modified file 'tests/autopilot/unity8/greeter/__init__.py' |
173 | --- tests/autopilot/unity8/greeter/__init__.py 2015-03-23 23:40:27 +0000 |
174 | +++ tests/autopilot/unity8/greeter/__init__.py 2015-05-15 07:16:40 +0000 |
175 | @@ -0,0 +1,93 @@ |
176 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
177 | +# |
178 | +# Unity Autopilot Test Suite |
179 | +# Copyright (C) 2012, 2013, 2014, 2015 Canonical |
180 | +# |
181 | +# This program is free software: you can redistribute it and/or modify |
182 | +# it under the terms of the GNU General Public License as published by |
183 | +# the Free Software Foundation, either version 3 of the License, or |
184 | +# (at your option) any later version. |
185 | +# |
186 | +# This program is distributed in the hope that it will be useful, |
187 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
188 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
189 | +# GNU General Public License for more details. |
190 | +# |
191 | +# You should have received a copy of the GNU General Public License |
192 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
193 | +# |
194 | + |
195 | +import dbus |
196 | + |
197 | +import ubuntuuitoolkit |
198 | +from autopilot.matchers import Eventually |
199 | +from testtools.matchers import Equals |
200 | +from autopilot.utilities import sleep |
201 | + |
202 | + |
203 | +def hide_greeter_with_dbus(): |
204 | + dbus_proxy = _get_greeter_dbus_proxy() |
205 | + if _is_greeter_active(): |
206 | + dbus_proxy.HideGreeter() |
207 | + |
208 | + |
209 | +def show_greeter_with_dbus(): |
210 | + dbus_proxy = _get_greeter_dbus_proxy() |
211 | + if not _is_greeter_active(): |
212 | + dbus_proxy.ShowGreeter() |
213 | + |
214 | + |
215 | +def wait_for_greeter(): |
216 | + Eventually(Equals(True), timeout=300).match(_is_greeter_active) |
217 | + |
218 | + |
219 | +def _get_greeter_dbus_proxy(): |
220 | + bus = dbus.SessionBus() |
221 | + return bus.get_object('com.canonical.UnityGreeter', '/') |
222 | + |
223 | + |
224 | +def _is_greeter_active(): |
225 | + try: |
226 | + dbus_proxy = _get_greeter_dbus_proxy() |
227 | + return dbus_proxy.Get('com.canonical.UnityGreeter', 'IsActive') |
228 | + except: |
229 | + return False |
230 | + |
231 | + |
232 | +class Greeter(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
233 | + """A helper that understands the greeter screen.""" |
234 | + |
235 | + def wait_swiped_away(self): |
236 | + # We have to be careful here, because coverPage can go away at any time |
237 | + # if there isn't a lockscreen behind it (it hides completely, then |
238 | + # the greeter disposes it). But if there *is* a lockscreen, then we |
239 | + # need a different check, by looking at its showProgress. So make our |
240 | + # own wait_for loop and check both possibilities. |
241 | + for i in range(10): |
242 | + if not self.required: |
243 | + return |
244 | + coverPage = self.select_single(objectName='coverPage') |
245 | + if coverPage.showProgress == 0: |
246 | + return |
247 | + sleep(1) |
248 | + |
249 | + raise AssertionError("Greeter cover page still up after 10s") |
250 | + |
251 | + def swipe(self): |
252 | + """Swipe the greeter screen away.""" |
253 | + self.waiting.wait_for(False) |
254 | + coverPage = self.select_single(objectName='coverPage') |
255 | + coverPage.showProgress.wait_for(1) |
256 | + |
257 | + rect = self.globalRect |
258 | + start_x = rect[0] + rect[2] - 3 |
259 | + start_y = int(rect[1] + rect[3] / 2) |
260 | + stop_x = int(rect[0] + rect[2] * 0.2) |
261 | + stop_y = start_y |
262 | + self.pointing_device.drag(start_x, start_y, stop_x, stop_y) |
263 | + |
264 | + self.wait_swiped_away() |
265 | + |
266 | + def get_prompt(self): |
267 | + return self.select_single( |
268 | + ubuntuuitoolkit.TextField, objectName='passwordInput') |
269 | |
270 | === renamed file 'tests/autopilot/unity8/shell/emulators/greeter.py' => 'tests/autopilot/unity8/greeter/__init__.py.moved' |
271 | --- tests/autopilot/unity8/shell/emulators/greeter.py 2015-04-28 15:20:13 +0000 |
272 | +++ tests/autopilot/unity8/greeter/__init__.py.moved 2015-05-15 07:16:40 +0000 |
273 | @@ -19,42 +19,3 @@ |
274 | |
275 | import ubuntuuitoolkit |
276 | from autopilot.utilities import sleep |
277 | - |
278 | - |
279 | -class Greeter(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
280 | - """An emulator that understands the greeter screen.""" |
281 | - |
282 | - def wait_swiped_away(self): |
283 | - # We have to be careful here, because coverPage can go away at any time |
284 | - # if there isn't a lockscreen behind it (it hides completely, then |
285 | - # the greeter disposes it). But if there *is* a lockscreen, then we |
286 | - # need a different check, by looking at its showProgress. So make our |
287 | - # own wait_for loop and check both possibilities. |
288 | - for i in range(10): |
289 | - if not self.required: |
290 | - return |
291 | - coverPage = self.select_single(objectName='coverPage') |
292 | - if coverPage.showProgress == 0: |
293 | - return |
294 | - sleep(1) |
295 | - |
296 | - raise AssertionError("Greeter cover page still up after 10s") |
297 | - |
298 | - def swipe(self): |
299 | - """Swipe the greeter screen away.""" |
300 | - self.waiting.wait_for(False) |
301 | - coverPage = self.select_single(objectName='coverPage') |
302 | - coverPage.showProgress.wait_for(1) |
303 | - |
304 | - rect = self.globalRect |
305 | - start_x = rect[0] + rect[2] - 3 |
306 | - start_y = int(rect[1] + rect[3] / 2) |
307 | - stop_x = int(rect[0] + rect[2] * 0.2) |
308 | - stop_y = start_y |
309 | - self.pointing_device.drag(start_x, start_y, stop_x, stop_y) |
310 | - |
311 | - self.wait_swiped_away() |
312 | - |
313 | - def get_prompt(self): |
314 | - return self.select_single( |
315 | - ubuntuuitoolkit.TextField, objectName='passwordInput') |
316 | |
317 | === modified file 'tests/autopilot/unity8/greeter/tests/__init__.py' |
318 | --- tests/autopilot/unity8/greeter/tests/__init__.py 2015-04-20 16:05:51 +0000 |
319 | +++ tests/autopilot/unity8/greeter/tests/__init__.py 2015-05-15 07:16:40 +0000 |
320 | @@ -17,12 +17,12 @@ |
321 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
322 | # |
323 | |
324 | -from unity8.shell.emulators import main_window as main_window_emulator |
325 | +from unity8 import shell |
326 | from unity8.shell.tests import UnityTestCase |
327 | |
328 | |
329 | class GreeterTestCase(UnityTestCase): |
330 | def get_shell(self, unity_proxy): |
331 | main_window = ( |
332 | - unity_proxy.select_single(main_window_emulator.QQuickView)) |
333 | + unity_proxy.select_single(shell.QQuickView)) |
334 | return main_window.select_single('Shell') |
335 | |
336 | === modified file 'tests/autopilot/unity8/indicators/tests/__init__.py' |
337 | --- tests/autopilot/unity8/indicators/tests/__init__.py 2015-04-24 19:51:20 +0000 |
338 | +++ tests/autopilot/unity8/indicators/tests/__init__.py 2015-05-15 07:16:40 +0000 |
339 | @@ -31,7 +31,7 @@ |
340 | def setUp(self): |
341 | super().setUp() |
342 | self.unity_proxy = self.launch_unity() |
343 | - process_helpers.unlock_unity(self.unity_proxy) |
344 | + process_helpers.unlock_unity() |
345 | |
346 | |
347 | class DeviceIndicatorTestCase(IndicatorTestCase): |
348 | |
349 | === renamed file 'tests/autopilot/unity8/shell/emulators/launcher.py' => 'tests/autopilot/unity8/launcher.py' |
350 | --- tests/autopilot/unity8/shell/emulators/launcher.py 2015-04-28 15:20:13 +0000 |
351 | +++ tests/autopilot/unity8/launcher.py 2015-05-15 07:16:40 +0000 |
352 | @@ -22,7 +22,7 @@ |
353 | import autopilot.logging |
354 | import ubuntuuitoolkit |
355 | |
356 | -from unity8.shell import emulators |
357 | +import unity8 |
358 | |
359 | |
360 | logger = logging.getLogger(__name__) |
361 | @@ -30,7 +30,7 @@ |
362 | |
363 | class Launcher(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
364 | |
365 | - """An emulator that understands the Launcher.""" |
366 | + """A helper that understands the Launcher.""" |
367 | |
368 | @autopilot.logging.log_action(logger.debug) |
369 | def show(self): |
370 | @@ -57,7 +57,7 @@ |
371 | 'QQuickImage', objectName='dashItem') |
372 | self.pointing_device.click_object(dash_icon) |
373 | else: |
374 | - raise emulators.UnityEmulatorException('The launcher is closed.') |
375 | + raise unity8.UnityException('The launcher is closed.') |
376 | |
377 | @autopilot.logging.log_action(logger.debug) |
378 | def click_application_launcher_icon(self, application_name): |
379 | |
380 | === modified file 'tests/autopilot/unity8/process_helpers.py' |
381 | --- tests/autopilot/unity8/process_helpers.py 2015-04-28 15:20:13 +0000 |
382 | +++ tests/autopilot/unity8/process_helpers.py 2015-05-15 07:16:40 +0000 |
383 | @@ -19,14 +19,12 @@ |
384 | |
385 | import logging |
386 | import subprocess |
387 | -import dbus |
388 | |
389 | import ubuntuuitoolkit |
390 | -from autopilot.exceptions import ProcessSearchError |
391 | from autopilot.introspection import get_proxy_object_for_existing_process |
392 | |
393 | -from unity8.shell import emulators |
394 | -from unity8.shell.emulators import main_window as main_window_emulator |
395 | +from unity8 import greeter |
396 | + |
397 | |
398 | logger = logging.getLogger(__name__) |
399 | |
400 | @@ -39,104 +37,22 @@ |
401 | pass |
402 | |
403 | |
404 | -def unlock_unity(unity_proxy_obj=None): |
405 | +def unlock_unity(): |
406 | """Helper function that attempts to unlock the unity greeter. |
407 | |
408 | - If unity_proxy_object is None create a proxy object by querying for the |
409 | - running unity process. |
410 | - Otherwise re-use the passed proxy object. |
411 | - |
412 | - :raises RuntimeError: if the greeter attempts and fails to be unlocked. |
413 | - |
414 | - :raises RuntimeWarning: when the greeter cannot be found because it is |
415 | - already unlocked. |
416 | - :raises CannotAccessUnity: if unity is not introspectable or cannot be |
417 | - found on dbus. |
418 | - :raises CannotAccessUnity: if unity's upstart status is not "start" or the |
419 | - upstart job cannot be found at all. |
420 | - |
421 | """ |
422 | - if unity_proxy_obj is None: |
423 | - try: |
424 | - pid = _get_unity_pid() |
425 | - unity = _get_unity_proxy_object(pid) |
426 | - main_window = unity.select_single(main_window_emulator.QQuickView) |
427 | - except ProcessSearchError as e: |
428 | - raise CannotAccessUnity( |
429 | - "Cannot introspect unity, make sure that it has been started " |
430 | - "with testability. Perhaps use the function " |
431 | - "'restart_unity_with_testability' this module provides." |
432 | - "(%s)" |
433 | - % str(e) |
434 | - ) |
435 | - else: |
436 | - main_window = unity_proxy_obj.select_single( |
437 | - main_window_emulator.QQuickView) |
438 | - |
439 | - greeter = main_window.get_greeter() |
440 | - if greeter.created is False: |
441 | - raise RuntimeWarning("Greeter appears to be already unlocked.") |
442 | - |
443 | - bus = dbus.SessionBus() |
444 | - dbus_proxy = bus.get_object("com.canonical.UnityGreeter", "/") |
445 | - try: |
446 | - dbus_proxy.HideGreeter() |
447 | - except dbus.DBusException: |
448 | - logger.info("Failed to unlock greeter") |
449 | - raise |
450 | - else: |
451 | - greeter.created.wait_for(False) |
452 | - logger.info("Greeter unlocked, continuing.") |
453 | - |
454 | - |
455 | -def lock_unity(unity_proxy_obj=None): |
456 | + |
457 | + greeter.wait_for_greeter() |
458 | + greeter.hide_greeter_with_dbus() |
459 | + |
460 | + |
461 | +def lock_unity(): |
462 | """Helper function that attempts to lock unity greeter. |
463 | |
464 | - If unity_proxy_object is None create a proxy object by querying for the |
465 | - running unity process. |
466 | - Otherwise re-use the passed proxy object. |
467 | - |
468 | - :raises RuntimeError: if the greeter attempts and fails to be locked. |
469 | - |
470 | - :raises RuntimeWarning: when the greeter is found because it is |
471 | - already locked. |
472 | - :raises CannotAccessUnity: if unity is not introspectable or cannot be |
473 | - found on dbus. |
474 | - :raises CannotAccessUnity: if unity's upstart status is not "start" or the |
475 | - upstart job cannot be found at all. |
476 | - |
477 | """ |
478 | - if unity_proxy_obj is None: |
479 | - try: |
480 | - pid = _get_unity_pid() |
481 | - unity = _get_unity_proxy_object(pid) |
482 | - main_window = unity.select_single(main_window_emulator.QQuickView) |
483 | - except ProcessSearchError as e: |
484 | - raise CannotAccessUnity( |
485 | - "Cannot introspect unity, make sure that it has been started " |
486 | - "with testability. Perhaps use the function " |
487 | - "'restart_unity_with_testability' this module provides." |
488 | - "(%s)" |
489 | - % str(e) |
490 | - ) |
491 | - else: |
492 | - main_window = unity_proxy_obj.select_single( |
493 | - main_window_emulator.QQuickView) |
494 | - |
495 | - greeter = main_window.get_greeter() |
496 | - if greeter.created is True: |
497 | - raise RuntimeWarning("Greeter appears to be already locked.") |
498 | - |
499 | - bus = dbus.SessionBus() |
500 | - dbus_proxy = bus.get_object("com.canonical.UnityGreeter", "/") |
501 | - try: |
502 | - dbus_proxy.ShowGreeter() |
503 | - except dbus.DBusException: |
504 | - logger.info("Failed to lock greeter") |
505 | - raise |
506 | - else: |
507 | - greeter.created.wait_for(True) |
508 | - logger.info("Greeter locked, continuing.") |
509 | + |
510 | + greeter.show_greeter_with_dbus() |
511 | + greeter.wait_for_greeter() |
512 | |
513 | |
514 | def restart_unity_with_testability(*args): |
515 | |
516 | === modified file 'tests/autopilot/unity8/shell/__init__.py' |
517 | --- tests/autopilot/unity8/shell/__init__.py 2015-04-24 16:10:02 +0000 |
518 | +++ tests/autopilot/unity8/shell/__init__.py 2015-05-15 07:16:40 +0000 |
519 | @@ -17,12 +17,21 @@ |
520 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
521 | # |
522 | |
523 | -"""unity shell autopilot tests and emulators - sub level package.""" |
524 | +"""unity shell autopilot tests and helpers - sub level package.""" |
525 | |
526 | +import logging |
527 | from functools import wraps |
528 | + |
529 | +import ubuntuuitoolkit |
530 | +from autopilot import logging as autopilot_logging |
531 | +from autopilot import input |
532 | from gi.repository import Notify |
533 | |
534 | -import logging |
535 | +from unity8 import ( |
536 | + greeter, |
537 | + launcher as launcher_helpers |
538 | +) |
539 | + |
540 | |
541 | logger = logging.getLogger(__name__) |
542 | |
543 | @@ -82,3 +91,161 @@ |
544 | 'NORMAL': Notify.Urgency.NORMAL, |
545 | 'CRITICAL': Notify.Urgency.CRITICAL} |
546 | return _urgency_enums.get(urgency.upper()) |
547 | + |
548 | + |
549 | +class QQuickView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
550 | + """An helper class that makes it easy to interact with the shell""" |
551 | + |
552 | + def get_greeter(self): |
553 | + return self.select_single(greeter.Greeter) |
554 | + |
555 | + def get_login_loader(self): |
556 | + return self.select_single("QQuickLoader", objectName="loginLoader") |
557 | + |
558 | + def get_login_list(self): |
559 | + return self.select_single("LoginList") |
560 | + |
561 | + def get_bottombar(self): |
562 | + return self.select_single("Bottombar") |
563 | + |
564 | + def get_pinPadLoader(self): |
565 | + return self.select_single( |
566 | + "QQuickLoader", |
567 | + objectName="pinPadLoader" |
568 | + ) |
569 | + |
570 | + def get_lockscreen(self): |
571 | + return self.select_single("Lockscreen") |
572 | + |
573 | + def get_pinentryField(self): |
574 | + return self.select_single(objectName="pinentryField") |
575 | + |
576 | + def _get_indicator_panel_item(self, indicator_name): |
577 | + return self.select_single( |
578 | + 'IndicatorItem', |
579 | + objectName=indicator_name+'-panelItem' |
580 | + ) |
581 | + |
582 | + def _get_indicator_page(self, indicator_name): |
583 | + return self.select_single( |
584 | + 'IndicatorPage', |
585 | + objectName=indicator_name+'-page' |
586 | + ) |
587 | + |
588 | + @autopilot_logging.log_action(logger.info) |
589 | + def open_indicator_page(self, indicator_name): |
590 | + """Swipe to open the indicator, wait until it's open. |
591 | + |
592 | + :returns: The indicator page. |
593 | + """ |
594 | + widget = self._get_indicator_panel_item(indicator_name) |
595 | + start_x, start_y = input.get_center_point(widget) |
596 | + end_x = start_x |
597 | + end_y = self.height |
598 | + self.pointing_device.drag(start_x, start_y, end_x, end_y) |
599 | + self.wait_select_single('IndicatorsMenu', fullyOpened=True) |
600 | + return self._get_indicator_page(indicator_name) |
601 | + |
602 | + @autopilot_logging.log_action(logger.info) |
603 | + def close_indicator_page(self): |
604 | + """Swipe to close the opened indicator, wait until it's closed.""" |
605 | + indicators_menu = self.wait_select_single('IndicatorsMenu') |
606 | + end_x, end_y = input.get_center_point(indicators_menu) |
607 | + start_x = end_x |
608 | + start_y = self.height |
609 | + self.pointing_device.drag(start_x, start_y, end_x, end_y) |
610 | + indicators_menu.fullyClosed.wait_for(True) |
611 | + |
612 | + @autopilot_logging.log_action(logger.info) |
613 | + def show_dash_swiping(self): |
614 | + """Show the dash swiping from the left.""" |
615 | + x, y, width, height = self._get_shell().globalRect |
616 | + start_x = x |
617 | + end_x = x + width |
618 | + start_y = end_y = y + height // 2 |
619 | + |
620 | + self.pointing_device.drag(start_x, start_y, end_x, end_y) |
621 | + self.get_current_focused_app_id().wait_for('unity8-dash') |
622 | + |
623 | + def _get_shell(self): |
624 | + return self.select_single('Shell') |
625 | + |
626 | + def get_current_focused_app_id(self): |
627 | + """Return the id of the focused application.""" |
628 | + return self._get_shell().focusedApplicationId |
629 | + |
630 | + @autopilot_logging.log_action(logger.info) |
631 | + def show_dash_from_launcher(self): |
632 | + """Open the dash clicking the dash icon on the launcher.""" |
633 | + launcher = self.open_launcher() |
634 | + launcher.click_dash_icon() |
635 | + self.get_current_focused_app_id().wait_for('unity8-dash') |
636 | + launcher.shown.wait_for(False) |
637 | + |
638 | + @autopilot_logging.log_action(logger.info) |
639 | + def open_launcher(self): |
640 | + launcher = self._get_launcher() |
641 | + launcher.show() |
642 | + return launcher |
643 | + |
644 | + def _get_launcher(self): |
645 | + return self.select_single(launcher_helpers.Launcher) |
646 | + |
647 | + def is_launcher_open(self): |
648 | + return self._get_launcher().shown |
649 | + |
650 | + @autopilot_logging.log_action(logger.info) |
651 | + def launch_application(self, application_name): |
652 | + """Launch an application. |
653 | + |
654 | + :parameter application_name: The name of the application to launch. |
655 | + |
656 | + """ |
657 | + launcher = self.open_launcher() |
658 | + launcher.click_application_launcher_icon(application_name) |
659 | + self.get_current_focused_app_id().wait_for(application_name) |
660 | + launcher.shown.wait_for(False) |
661 | + |
662 | + def enter_pin_code(self, code): |
663 | + """Enter code 'code' into the single-pin lightdm pincode entry screen. |
664 | + |
665 | + :param code: must be a string of numeric characters. |
666 | + :raises: TypeError if code is not a string. |
667 | + :raises: ValueError if code contains non-numeric characters. |
668 | + |
669 | + """ |
670 | + if not isinstance(code, str): |
671 | + raise TypeError( |
672 | + "'code' parameter must be a string, not %r." |
673 | + % type(code) |
674 | + ) |
675 | + for num in code: |
676 | + if not num.isdigit(): |
677 | + raise ValueError( |
678 | + "'code' parameter contains non-numeric characters." |
679 | + ) |
680 | + self.pointing_device.click_object( |
681 | + self._get_pinpad_button(int(num))) |
682 | + |
683 | + def _get_pinpad_button(self, button_id): |
684 | + return self.select_single( |
685 | + 'PinPadButton', |
686 | + objectName='pinPadButton{}'.format(button_id) |
687 | + ) |
688 | + |
689 | + @autopilot_logging.log_action(logger.info) |
690 | + def wait_for_notification(self): |
691 | + """Wait for a notification dialog to appear. |
692 | + |
693 | + :return: An object for the notification dialog data. |
694 | + :raise StateNotFoundError: if the timeout expires when the |
695 | + notification has not appeared. |
696 | + |
697 | + """ |
698 | + notify_list = self.select_single('Notifications', |
699 | + objectName='notificationList') |
700 | + visible_notification = notify_list.wait_select_single('Notification', |
701 | + visible=True) |
702 | + return {'summary': visible_notification.summary, |
703 | + 'body': visible_notification.body, |
704 | + 'iconSource': visible_notification.iconSource} |
705 | |
706 | === added file 'tests/autopilot/unity8/shell/create_interactive_notification.py' |
707 | --- tests/autopilot/unity8/shell/create_interactive_notification.py 1970-01-01 00:00:00 +0000 |
708 | +++ tests/autopilot/unity8/shell/create_interactive_notification.py 2015-05-15 07:16:40 +0000 |
709 | @@ -0,0 +1,101 @@ |
710 | +#!/usr/bin/env python3 |
711 | + |
712 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
713 | +# |
714 | +# Unity Autopilot Test Suite |
715 | +# Copyright (C) 2012, 2013, 2014, 2015 Canonical |
716 | +# |
717 | +# This program is free software: you can redistribute it and/or modify |
718 | +# it under the terms of the GNU General Public License as published by |
719 | +# the Free Software Foundation, either version 3 of the License, or |
720 | +# (at your option) any later version. |
721 | +# |
722 | +# This program is distributed in the hope that it will be useful, |
723 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
724 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
725 | +# GNU General Public License for more details. |
726 | +# |
727 | +# You should have received a copy of the GNU General Public License |
728 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
729 | +# |
730 | + |
731 | +import argparse |
732 | +from gi.repository import GLib, Notify |
733 | +import signal |
734 | + |
735 | + |
736 | +def action_callback(notification, action_id, data): |
737 | + print(action_id) |
738 | + |
739 | + |
740 | +def quit_callback(notification): |
741 | + loop.quit() |
742 | + |
743 | + |
744 | +if __name__ == '__main__': |
745 | + parser = argparse.ArgumentParser( |
746 | + description='Create an interactive notification' |
747 | + ) |
748 | + |
749 | + parser.add_argument( |
750 | + '--summary', |
751 | + help='summary text of the notification', |
752 | + default='Summary' |
753 | + ) |
754 | + parser.add_argument( |
755 | + '--body', |
756 | + help='body text of the notification', |
757 | + default='Body' |
758 | + ) |
759 | + parser.add_argument( |
760 | + '--icon', |
761 | + help='path to the icon to display', |
762 | + default=None |
763 | + ) |
764 | + parser.add_argument( |
765 | + '--action', |
766 | + help='id and label for the callback in the format: id,label', |
767 | + action='append', |
768 | + default=[] |
769 | + ) |
770 | + parser.add_argument( |
771 | + '--urgency', |
772 | + help='LOW, NORMAL, CRITICAL', |
773 | + choices=['LOW', 'NORMAL', 'CRITICAL'], |
774 | + default='NORMAL' |
775 | + ) |
776 | + parser.add_argument( |
777 | + '--hints', |
778 | + help='list of comma sep options', |
779 | + action='append', |
780 | + default=[] |
781 | + ) |
782 | + |
783 | + args = parser.parse_args() |
784 | + |
785 | + Notify.init('Interactive Notifications') |
786 | + |
787 | + notification = Notify.Notification.new(args.summary, args.body, args.icon) |
788 | + |
789 | + for hint in args.hints: |
790 | + key, value = hint.split(',', 1) |
791 | + notification.set_hint_string(key, value) |
792 | + |
793 | + for action in args.action: |
794 | + action_id, action_label = action.split(',', 1) |
795 | + notification.add_action( |
796 | + action_id, |
797 | + action_label, |
798 | + action_callback, |
799 | + None |
800 | + ) |
801 | + |
802 | + def signal_handler(signam, frame): |
803 | + loop.quit() |
804 | + |
805 | + signal.signal(signal.SIGINT, signal_handler) |
806 | + |
807 | + loop = GLib.MainLoop.new(None, False) |
808 | + notification.connect('closed', quit_callback) |
809 | + notification.show() |
810 | + loop.run() |
811 | |
812 | === removed directory 'tests/autopilot/unity8/shell/emulators' |
813 | === added file 'tests/autopilot/unity8/shell/emulators.py' |
814 | --- tests/autopilot/unity8/shell/emulators.py 1970-01-01 00:00:00 +0000 |
815 | +++ tests/autopilot/unity8/shell/emulators.py 2015-05-15 07:16:40 +0000 |
816 | @@ -0,0 +1,52 @@ |
817 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
818 | +# |
819 | +# Unity Autopilot Test Suite |
820 | +# Copyright (C) 2015 Canonical |
821 | +# |
822 | +# This program is free software: you can redistribute it and/or modify |
823 | +# it under the terms of the GNU General Public License as published by |
824 | +# the Free Software Foundation, either version 3 of the License, or |
825 | +# (at your option) any later version. |
826 | +# |
827 | +# This program is distributed in the hope that it will be useful, |
828 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
829 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
830 | +# GNU General Public License for more details. |
831 | +# |
832 | +# You should have received a copy of the GNU General Public License |
833 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
834 | +# |
835 | + |
836 | +"""Emulators was the old name for the custom proxy objects.""" |
837 | + |
838 | +import logging |
839 | + |
840 | + |
841 | +logger = logging.getLogger(__name__) |
842 | + |
843 | + |
844 | +logger.warning( |
845 | + 'The unity8.shell.emulators module is deprecated. Import the autopilot ' |
846 | + 'helpers from the top-level unity8 module.') |
847 | + |
848 | + |
849 | +__all__ = [ |
850 | + 'create_interactive_notification', |
851 | + 'dash', |
852 | + 'greeter', |
853 | + 'launcher', |
854 | + 'main_window', |
855 | + 'tutorial', |
856 | + 'UnityEmulatorException', |
857 | +] |
858 | + |
859 | + |
860 | +from unity8 import ( |
861 | + greeter, |
862 | + dash, |
863 | + launcher, |
864 | + shell as main_window, |
865 | + tutorial, |
866 | + UnityException as UnityEmulatorException |
867 | +) |
868 | +from unity8.shell import create_interactive_notification |
869 | |
870 | === removed file 'tests/autopilot/unity8/shell/emulators/__init__.py' |
871 | --- tests/autopilot/unity8/shell/emulators/__init__.py 2015-04-28 15:20:13 +0000 |
872 | +++ tests/autopilot/unity8/shell/emulators/__init__.py 1970-01-01 00:00:00 +0000 |
873 | @@ -1,22 +0,0 @@ |
874 | -# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
875 | -# |
876 | -# Unity Autopilot Test Suite |
877 | -# Copyright (C) 2012, 2013, 2014, 2015 Canonical |
878 | -# |
879 | -# This program is free software: you can redistribute it and/or modify |
880 | -# it under the terms of the GNU General Public License as published by |
881 | -# the Free Software Foundation, either version 3 of the License, or |
882 | -# (at your option) any later version. |
883 | -# |
884 | -# This program is distributed in the hope that it will be useful, |
885 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
886 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
887 | -# GNU General Public License for more details. |
888 | -# |
889 | -# You should have received a copy of the GNU General Public License |
890 | -# along with this program. If not, see <http://www.gnu.org/licenses/>. |
891 | -# |
892 | - |
893 | - |
894 | -class UnityEmulatorException(Exception): |
895 | - """Exception raised when there is an error with the Unity emulators.""" |
896 | |
897 | === removed file 'tests/autopilot/unity8/shell/emulators/create_interactive_notification.py' |
898 | --- tests/autopilot/unity8/shell/emulators/create_interactive_notification.py 2015-02-23 17:29:04 +0000 |
899 | +++ tests/autopilot/unity8/shell/emulators/create_interactive_notification.py 1970-01-01 00:00:00 +0000 |
900 | @@ -1,101 +0,0 @@ |
901 | -#!/usr/bin/env python3 |
902 | - |
903 | -# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
904 | -# |
905 | -# Unity Autopilot Test Suite |
906 | -# Copyright (C) 2012, 2013, 2014, 2015 Canonical |
907 | -# |
908 | -# This program is free software: you can redistribute it and/or modify |
909 | -# it under the terms of the GNU General Public License as published by |
910 | -# the Free Software Foundation, either version 3 of the License, or |
911 | -# (at your option) any later version. |
912 | -# |
913 | -# This program is distributed in the hope that it will be useful, |
914 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
915 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
916 | -# GNU General Public License for more details. |
917 | -# |
918 | -# You should have received a copy of the GNU General Public License |
919 | -# along with this program. If not, see <http://www.gnu.org/licenses/>. |
920 | -# |
921 | - |
922 | -import argparse |
923 | -from gi.repository import GLib, Notify |
924 | -import signal |
925 | - |
926 | - |
927 | -def action_callback(notification, action_id, data): |
928 | - print(action_id) |
929 | - |
930 | - |
931 | -def quit_callback(notification): |
932 | - loop.quit() |
933 | - |
934 | - |
935 | -if __name__ == '__main__': |
936 | - parser = argparse.ArgumentParser( |
937 | - description='Create an interactive notification' |
938 | - ) |
939 | - |
940 | - parser.add_argument( |
941 | - '--summary', |
942 | - help='summary text of the notification', |
943 | - default='Summary' |
944 | - ) |
945 | - parser.add_argument( |
946 | - '--body', |
947 | - help='body text of the notification', |
948 | - default='Body' |
949 | - ) |
950 | - parser.add_argument( |
951 | - '--icon', |
952 | - help='path to the icon to display', |
953 | - default=None |
954 | - ) |
955 | - parser.add_argument( |
956 | - '--action', |
957 | - help='id and label for the callback in the format: id,label', |
958 | - action='append', |
959 | - default=[] |
960 | - ) |
961 | - parser.add_argument( |
962 | - '--urgency', |
963 | - help='LOW, NORMAL, CRITICAL', |
964 | - choices=['LOW', 'NORMAL', 'CRITICAL'], |
965 | - default='NORMAL' |
966 | - ) |
967 | - parser.add_argument( |
968 | - '--hints', |
969 | - help='list of comma sep options', |
970 | - action='append', |
971 | - default=[] |
972 | - ) |
973 | - |
974 | - args = parser.parse_args() |
975 | - |
976 | - Notify.init('Interactive Notifications') |
977 | - |
978 | - notification = Notify.Notification.new(args.summary, args.body, args.icon) |
979 | - |
980 | - for hint in args.hints: |
981 | - key, value = hint.split(',', 1) |
982 | - notification.set_hint_string(key, value) |
983 | - |
984 | - for action in args.action: |
985 | - action_id, action_label = action.split(',', 1) |
986 | - notification.add_action( |
987 | - action_id, |
988 | - action_label, |
989 | - action_callback, |
990 | - None |
991 | - ) |
992 | - |
993 | - def signal_handler(signam, frame): |
994 | - loop.quit() |
995 | - |
996 | - signal.signal(signal.SIGINT, signal_handler) |
997 | - |
998 | - loop = GLib.MainLoop.new(None, False) |
999 | - notification.connect('closed', quit_callback) |
1000 | - notification.show() |
1001 | - loop.run() |
1002 | |
1003 | === removed file 'tests/autopilot/unity8/shell/emulators/main_window.py' |
1004 | --- tests/autopilot/unity8/shell/emulators/main_window.py 2015-04-28 15:20:13 +0000 |
1005 | +++ tests/autopilot/unity8/shell/emulators/main_window.py 1970-01-01 00:00:00 +0000 |
1006 | @@ -1,187 +0,0 @@ |
1007 | -# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1008 | -# |
1009 | -# Unity Autopilot Test Suite |
1010 | -# Copyright (C) 2012, 2013, 2014, 2015 Canonical |
1011 | -# |
1012 | -# This program is free software: you can redistribute it and/or modify |
1013 | -# it under the terms of the GNU General Public License as published by |
1014 | -# the Free Software Foundation, either version 3 of the License, or |
1015 | -# (at your option) any later version. |
1016 | -# |
1017 | -# This program is distributed in the hope that it will be useful, |
1018 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1019 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1020 | -# GNU General Public License for more details. |
1021 | -# |
1022 | -# You should have received a copy of the GNU General Public License |
1023 | -# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1024 | -# |
1025 | - |
1026 | -import logging |
1027 | - |
1028 | -import ubuntuuitoolkit |
1029 | -from autopilot import logging as autopilot_logging |
1030 | -from autopilot import input |
1031 | - |
1032 | -from unity8.shell.emulators.greeter import Greeter |
1033 | -from unity8.shell.emulators.launcher import Launcher |
1034 | - |
1035 | -logger = logging.getLogger(__name__) |
1036 | - |
1037 | - |
1038 | -class QQuickView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
1039 | - """An emulator class that makes it easy to interact with the shell""" |
1040 | - |
1041 | - def get_greeter(self): |
1042 | - return self.select_single(Greeter) |
1043 | - |
1044 | - def get_login_loader(self): |
1045 | - return self.select_single("QQuickLoader", objectName="loginLoader") |
1046 | - |
1047 | - def get_login_list(self): |
1048 | - return self.select_single("LoginList") |
1049 | - |
1050 | - def get_bottombar(self): |
1051 | - return self.select_single("Bottombar") |
1052 | - |
1053 | - def get_pinPadLoader(self): |
1054 | - return self.select_single( |
1055 | - "QQuickLoader", |
1056 | - objectName="pinPadLoader" |
1057 | - ) |
1058 | - |
1059 | - def get_lockscreen(self): |
1060 | - return self.select_single("Lockscreen") |
1061 | - |
1062 | - def get_pinentryField(self): |
1063 | - return self.select_single(objectName="pinentryField") |
1064 | - |
1065 | - def _get_indicator_panel_item(self, indicator_name): |
1066 | - return self.select_single( |
1067 | - 'IndicatorItem', |
1068 | - objectName=indicator_name+'-panelItem' |
1069 | - ) |
1070 | - |
1071 | - def _get_indicator_page(self, indicator_name): |
1072 | - return self.select_single( |
1073 | - 'IndicatorPage', |
1074 | - objectName=indicator_name+'-page' |
1075 | - ) |
1076 | - |
1077 | - @autopilot_logging.log_action(logger.info) |
1078 | - def open_indicator_page(self, indicator_name): |
1079 | - """Swipe to open the indicator, wait until it's open. |
1080 | - |
1081 | - :returns: The indicator page. |
1082 | - """ |
1083 | - widget = self._get_indicator_panel_item(indicator_name) |
1084 | - start_x, start_y = input.get_center_point(widget) |
1085 | - end_x = start_x |
1086 | - end_y = self.height |
1087 | - self.pointing_device.drag(start_x, start_y, end_x, end_y) |
1088 | - self.wait_select_single('IndicatorsMenu', fullyOpened=True) |
1089 | - return self._get_indicator_page(indicator_name) |
1090 | - |
1091 | - @autopilot_logging.log_action(logger.info) |
1092 | - def close_indicator_page(self): |
1093 | - """Swipe to close the opened indicator, wait until it's closed.""" |
1094 | - indicators_menu = self.wait_select_single('IndicatorsMenu') |
1095 | - end_x, end_y = input.get_center_point(indicators_menu) |
1096 | - start_x = end_x |
1097 | - start_y = self.height |
1098 | - self.pointing_device.drag(start_x, start_y, end_x, end_y) |
1099 | - indicators_menu.fullyClosed.wait_for(True) |
1100 | - |
1101 | - @autopilot_logging.log_action(logger.info) |
1102 | - def show_dash_swiping(self): |
1103 | - """Show the dash swiping from the left.""" |
1104 | - x, y, width, height = self._get_shell().globalRect |
1105 | - start_x = x |
1106 | - end_x = x + width |
1107 | - start_y = end_y = y + height // 2 |
1108 | - |
1109 | - self.pointing_device.drag(start_x, start_y, end_x, end_y) |
1110 | - self.get_current_focused_app_id().wait_for('unity8-dash') |
1111 | - |
1112 | - def _get_shell(self): |
1113 | - return self.select_single('Shell') |
1114 | - |
1115 | - def get_current_focused_app_id(self): |
1116 | - """Return the id of the focused application.""" |
1117 | - return self._get_shell().focusedApplicationId |
1118 | - |
1119 | - @autopilot_logging.log_action(logger.info) |
1120 | - def show_dash_from_launcher(self): |
1121 | - """Open the dash clicking the dash icon on the launcher.""" |
1122 | - launcher = self.open_launcher() |
1123 | - launcher.click_dash_icon() |
1124 | - self.get_current_focused_app_id().wait_for('unity8-dash') |
1125 | - launcher.shown.wait_for(False) |
1126 | - |
1127 | - @autopilot_logging.log_action(logger.info) |
1128 | - def open_launcher(self): |
1129 | - launcher = self._get_launcher() |
1130 | - launcher.show() |
1131 | - return launcher |
1132 | - |
1133 | - def _get_launcher(self): |
1134 | - return self.select_single(Launcher) |
1135 | - |
1136 | - def is_launcher_open(self): |
1137 | - return self._get_launcher().shown |
1138 | - |
1139 | - @autopilot_logging.log_action(logger.info) |
1140 | - def launch_application(self, application_name): |
1141 | - """Launch an application. |
1142 | - |
1143 | - :parameter application_name: The name of the application to launch. |
1144 | - |
1145 | - """ |
1146 | - launcher = self.open_launcher() |
1147 | - launcher.click_application_launcher_icon(application_name) |
1148 | - self.get_current_focused_app_id().wait_for(application_name) |
1149 | - launcher.shown.wait_for(False) |
1150 | - |
1151 | - def enter_pin_code(self, code): |
1152 | - """Enter code 'code' into the single-pin lightdm pincode entry screen. |
1153 | - |
1154 | - :param code: must be a string of numeric characters. |
1155 | - :raises: TypeError if code is not a string. |
1156 | - :raises: ValueError if code contains non-numeric characters. |
1157 | - |
1158 | - """ |
1159 | - if not isinstance(code, str): |
1160 | - raise TypeError( |
1161 | - "'code' parameter must be a string, not %r." |
1162 | - % type(code) |
1163 | - ) |
1164 | - for num in code: |
1165 | - if not num.isdigit(): |
1166 | - raise ValueError( |
1167 | - "'code' parameter contains non-numeric characters." |
1168 | - ) |
1169 | - self.pointing_device.click_object( |
1170 | - self._get_pinpad_button(int(num))) |
1171 | - |
1172 | - def _get_pinpad_button(self, button_id): |
1173 | - return self.select_single( |
1174 | - 'PinPadButton', |
1175 | - objectName='pinPadButton{}'.format(button_id) |
1176 | - ) |
1177 | - |
1178 | - @autopilot_logging.log_action(logger.info) |
1179 | - def wait_for_notification(self): |
1180 | - """Wait for a notification dialog to appear. |
1181 | - |
1182 | - :return: An object for the notification dialog data. |
1183 | - :raise StateNotFoundError: if the timeout expires when the |
1184 | - notification has not appeared. |
1185 | - |
1186 | - """ |
1187 | - notify_list = self.select_single('Notifications', |
1188 | - objectName='notificationList') |
1189 | - visible_notification = notify_list.wait_select_single('Notification', |
1190 | - visible=True) |
1191 | - return {'summary': visible_notification.summary, |
1192 | - 'body': visible_notification.body, |
1193 | - 'iconSource': visible_notification.iconSource} |
1194 | |
1195 | === modified file 'tests/autopilot/unity8/shell/tests/__init__.py' |
1196 | --- tests/autopilot/unity8/shell/tests/__init__.py 2015-05-05 14:46:49 +0000 |
1197 | +++ tests/autopilot/unity8/shell/tests/__init__.py 2015-05-15 07:16:40 +0000 |
1198 | @@ -51,9 +51,9 @@ |
1199 | fixture_setup, |
1200 | process_helpers |
1201 | ) |
1202 | -from unity8.shell.emulators import ( |
1203 | +from unity8 import ( |
1204 | dash as dash_helpers, |
1205 | - main_window as main_window_emulator, |
1206 | + shell |
1207 | ) |
1208 | |
1209 | |
1210 | @@ -297,7 +297,7 @@ |
1211 | |
1212 | @property |
1213 | def main_window(self): |
1214 | - return self._proxy.select_single(main_window_emulator.QQuickView) |
1215 | + return self._proxy.select_single(shell.QQuickView) |
1216 | |
1217 | |
1218 | class DashBaseTestCase(AutopilotTestCase): |
1219 | |
1220 | === renamed file 'tests/autopilot/unity8/shell/tests/test_emulators.py' => 'tests/autopilot/unity8/shell/tests/test_helpers.py' |
1221 | --- tests/autopilot/unity8/shell/tests/test_emulators.py 2015-04-17 21:58:16 +0000 |
1222 | +++ tests/autopilot/unity8/shell/tests/test_helpers.py 2015-05-15 07:16:40 +0000 |
1223 | @@ -17,13 +17,13 @@ |
1224 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
1225 | # |
1226 | |
1227 | -"""Tests for the Dash autopilot emulators. |
1228 | +"""Tests for the Dash autopilot custom proxy objects. |
1229 | |
1230 | -The autopilot emulators are helpers for tests that check a user journey that |
1231 | -involves the dash. The code for some of those tests will not be inside this |
1232 | -branch, but in projects that depend on unity or that test the whole system |
1233 | -integration. So, we need to test the helpers in order to make sure that we |
1234 | -don't break them for those external projects. |
1235 | +The autopilot custom proxy objects are helpers for tests that check a user |
1236 | +journey that involves the dash. The code for some of those tests will not be |
1237 | +inside this branch, but in projects that depend on unity or that test the |
1238 | +whole system integration. So, we need to test the helpers in order to make |
1239 | +sure that we don't break them for those external projects. |
1240 | |
1241 | """ |
1242 | |
1243 | @@ -31,8 +31,7 @@ |
1244 | |
1245 | from unity8 import process_helpers |
1246 | from unity8.shell import fixture_setup, tests |
1247 | -from unity8.shell.emulators import dash as dash_emulators |
1248 | -from unity8.shell.emulators.dash import ListViewWithPageHeader |
1249 | +from unity8 import dash as dash_helpers |
1250 | |
1251 | |
1252 | class MainWindowTestCase(tests.UnityTestCase): |
1253 | @@ -41,8 +40,8 @@ |
1254 | |
1255 | def setUp(self): |
1256 | super().setUp() |
1257 | - unity_proxy = self.launch_unity() |
1258 | - process_helpers.unlock_unity(unity_proxy) |
1259 | + self.launch_unity() |
1260 | + process_helpers.unlock_unity() |
1261 | |
1262 | |
1263 | class DashEmulatorTestCase(tests.DashBaseTestCase): |
1264 | @@ -98,13 +97,13 @@ |
1265 | scope_id = 'musicaggregator' |
1266 | scope = self.dash.open_scope(scope_id) |
1267 | self._assert_scope_is_opened(scope, scope_id) |
1268 | - self.assertIsInstance(scope, dash_emulators.GenericScopeView) |
1269 | + self.assertIsInstance(scope, dash_helpers.GenericScopeView) |
1270 | |
1271 | def test_open_applications_scope(self): |
1272 | scope_id = 'clickscope' |
1273 | scope = self.dash.open_scope(scope_id) |
1274 | self._assert_scope_is_opened(scope, scope_id) |
1275 | - self.assertIsInstance(scope, dash_emulators.GenericScopeView) |
1276 | + self.assertIsInstance(scope, dash_helpers.GenericScopeView) |
1277 | |
1278 | |
1279 | class GenericScopeViewEmulatorTestCase(tests.DashBaseTestCase): |
1280 | @@ -117,7 +116,13 @@ |
1281 | |
1282 | def test_open_preview(self): |
1283 | preview = self.generic_scope.open_preview('0', 'Title.0.0') |
1284 | - self.assertIsInstance(preview, dash_emulators.Preview) |
1285 | + self.assertIsInstance(preview, dash_helpers.Preview) |
1286 | + self.assertTrue(preview.isCurrent) |
1287 | + |
1288 | + def test_open_preview_of_non_visible_item(self): |
1289 | + """Open an item that requires swiping to make it visible.""" |
1290 | + preview = self.generic_scope.open_preview('2', 'Title.2.0') |
1291 | + self.assertIsInstance(preview, dash_helpers.Preview) |
1292 | self.assertTrue(preview.isCurrent) |
1293 | |
1294 | |
1295 | @@ -139,7 +144,7 @@ |
1296 | category_element = self.applications_scope._get_category_element( |
1297 | category) |
1298 | list_view = self.dash.get_scope('clickscope')\ |
1299 | - .select_single(ListViewWithPageHeader) |
1300 | + .select_single(dash_helpers.ListViewWithPageHeader) |
1301 | expected_apps_count = self._get_number_of_application_slots(category) |
1302 | expected_applications = self.available_applications[ |
1303 | :expected_apps_count] |
1304 | |
1305 | === modified file 'tests/autopilot/unity8/shell/tests/test_notifications.py' |
1306 | --- tests/autopilot/unity8/shell/tests/test_notifications.py 2015-04-17 21:58:16 +0000 |
1307 | +++ tests/autopilot/unity8/shell/tests/test_notifications.py 2015-05-15 07:16:40 +0000 |
1308 | @@ -119,8 +119,8 @@ |
1309 | |
1310 | def test_interactive(self): |
1311 | """Interactive notification must react upon click on itself.""" |
1312 | - unity_proxy = self.launch_unity() |
1313 | - unlock_unity(unity_proxy) |
1314 | + self.launch_unity() |
1315 | + unlock_unity() |
1316 | |
1317 | notify_list = self._get_notifications_list() |
1318 | |
1319 | @@ -156,8 +156,8 @@ |
1320 | """Snap-decision with three actions should use |
1321 | one-over two button layout. |
1322 | """ |
1323 | - unity_proxy = self.launch_unity() |
1324 | - unlock_unity(unity_proxy) |
1325 | + self.launch_unity() |
1326 | + unlock_unity() |
1327 | |
1328 | summary = "Theatre at Ferria Stadium" |
1329 | body = "at Ferria Stadium in Bilbao, Spain\n07578545317" |
1330 | @@ -197,8 +197,8 @@ |
1331 | """Snap-decision should block input to shell |
1332 | without greeter/lockscreen. |
1333 | """ |
1334 | - unity_proxy = self.launch_unity() |
1335 | - unlock_unity(unity_proxy) |
1336 | + self.launch_unity() |
1337 | + unlock_unity() |
1338 | |
1339 | summary = "Incoming file" |
1340 | body = "Frank would like to send you the file: essay.pdf" |
1341 | @@ -362,7 +362,7 @@ |
1342 | """Returns the path to the interactive notification |
1343 | creation script. |
1344 | """ |
1345 | - file_path = "../../emulators/create_interactive_notification.py" |
1346 | + file_path = "../../create_interactive_notification.py" |
1347 | |
1348 | the_path = os.path.abspath( |
1349 | os.path.join(__file__, file_path)) |
1350 | @@ -421,8 +421,8 @@ |
1351 | |
1352 | def test_icon_summary_body(self): |
1353 | """Notification must display the expected summary and body text.""" |
1354 | - unity_proxy = self.launch_unity() |
1355 | - unlock_unity(unity_proxy) |
1356 | + self.launch_unity() |
1357 | + unlock_unity() |
1358 | |
1359 | notify_list = self._get_notifications_list() |
1360 | |
1361 | @@ -458,8 +458,8 @@ |
1362 | def test_icon_summary(self): |
1363 | """Notification must display the expected summary and secondary |
1364 | icon.""" |
1365 | - unity_proxy = self.launch_unity() |
1366 | - unlock_unity(unity_proxy) |
1367 | + self.launch_unity() |
1368 | + unlock_unity() |
1369 | |
1370 | notify_list = self._get_notifications_list() |
1371 | |
1372 | @@ -491,8 +491,8 @@ |
1373 | def test_urgency_order(self): |
1374 | """Notifications must be displayed in order according to their |
1375 | urgency.""" |
1376 | - unity_proxy = self.launch_unity() |
1377 | - unlock_unity(unity_proxy) |
1378 | + self.launch_unity() |
1379 | + unlock_unity() |
1380 | |
1381 | notify_list = self._get_notifications_list() |
1382 | |
1383 | @@ -578,8 +578,8 @@ |
1384 | |
1385 | def test_summary_and_body(self): |
1386 | """Notification must display the expected summary- and body-text.""" |
1387 | - unity_proxy = self.launch_unity() |
1388 | - unlock_unity(unity_proxy) |
1389 | + self.launch_unity() |
1390 | + unlock_unity() |
1391 | |
1392 | notify_list = self._get_notifications_list() |
1393 | |
1394 | @@ -603,8 +603,8 @@ |
1395 | |
1396 | def test_summary_only(self): |
1397 | """Notification must display only the expected summary-text.""" |
1398 | - unity_proxy = self.launch_unity() |
1399 | - unlock_unity(unity_proxy) |
1400 | + self.launch_unity() |
1401 | + unlock_unity() |
1402 | |
1403 | notify_list = self._get_notifications_list() |
1404 | |
1405 | @@ -621,8 +621,8 @@ |
1406 | def test_update_notification_same_layout(self): |
1407 | """Notification must allow updating its contents while being |
1408 | displayed.""" |
1409 | - unity_proxy = self.launch_unity() |
1410 | - unlock_unity(unity_proxy) |
1411 | + self.launch_unity() |
1412 | + unlock_unity() |
1413 | |
1414 | notify_list = self._get_notifications_list() |
1415 | |
1416 | @@ -660,8 +660,8 @@ |
1417 | def test_update_notification_layout_change(self): |
1418 | """Notification must allow updating its contents and layout while |
1419 | being displayed.""" |
1420 | - unity_proxy = self.launch_unity() |
1421 | - unlock_unity(unity_proxy) |
1422 | + self.launch_unity() |
1423 | + unlock_unity() |
1424 | |
1425 | notify_list = self._get_notifications_list() |
1426 | |
1427 | @@ -709,8 +709,8 @@ |
1428 | """ use the create notification script to get a notification dialog. |
1429 | Check that the arguments passed to the script match the fields. """ |
1430 | |
1431 | - unity_proxy = self.launch_unity() |
1432 | - unlock_unity(unity_proxy) |
1433 | + self.launch_unity() |
1434 | + unlock_unity() |
1435 | |
1436 | summary = 'Helper summary' |
1437 | body = 'Helper body' |
1438 | |
1439 | === modified file 'tests/autopilot/unity8/shell/tests/test_tutorial.py' |
1440 | --- tests/autopilot/unity8/shell/tests/test_tutorial.py 2015-04-20 16:04:34 +0000 |
1441 | +++ tests/autopilot/unity8/shell/tests/test_tutorial.py 2015-05-15 07:16:40 +0000 |
1442 | @@ -24,8 +24,8 @@ |
1443 | fixture_setup, |
1444 | tests |
1445 | ) |
1446 | -# unused import to load the tutorial emulators custom proxy objects. |
1447 | -from unity8.shell.emulators import tutorial as tutorial_emulator # NOQA |
1448 | +# unused import to load the tutorial helpers custom proxy objects. |
1449 | +from unity8 import tutorial as tutorial_helpers # NOQA |
1450 | |
1451 | |
1452 | class TutorialTestCase(tests.UnityTestCase): |
1453 | |
1454 | === renamed file 'tests/autopilot/unity8/shell/emulators/tutorial.py' => 'tests/autopilot/unity8/tutorial.py' |
FAILED: Continuous integration, rev:1532 /code.launchpad .net/~canonical -platform- qa/unity8/ fix1306340- deprecate_ emulators/ +merge/ 257812/ +edit-commit- message
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:// jenkins. qa.ubuntu. com/job/ unity8- ci/5641/ jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- vivid-touch/ 2538 jenkins. qa.ubuntu. com/job/ unity-phablet- qmluitests- vivid/804 jenkins. qa.ubuntu. com/job/ unity8- vivid-amd64- ci/806 jenkins. qa.ubuntu. com/job/ unity8- vivid-i386- ci/806 jenkins. qa.ubuntu. com/job/ generic- deb-autopilot- runner- vivid-mako/ 2199 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 2536 jenkins. qa.ubuntu. com/job/ generic- mediumtests- builder- vivid-armhf/ 2536/artifact/ work/output/ *zip*/output. zip s-jenkins. ubuntu- ci:8080/ job/touch- flash-device/ 20045
Executed test runs:
UNSTABLE: http://
SUCCESS: http://
SUCCESS: http://
SUCCESS: http://
UNSTABLE: http://
SUCCESS: http://
deb: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity8- ci/5641/ rebuild
http://