Merge lp:~canonical-platform-qa/ubuntu-system-tests/move_unity_helpers into lp:ubuntu-system-tests
- move_unity_helpers
- Merge into trunk
Status: | Work in progress |
---|---|
Proposed branch: | lp:~canonical-platform-qa/ubuntu-system-tests/move_unity_helpers |
Merge into: | lp:ubuntu-system-tests |
Diff against target: |
2582 lines (+1800/-260) 29 files modified
debian/control (+1/-3) debian/tests/control (+0/-1) ubuntu_system_tests/helpers/indicators/message.py (+3/-4) ubuntu_system_tests/helpers/indicators/utils.py (+1/-2) ubuntu_system_tests/helpers/mediascanner.py (+6/-6) ubuntu_system_tests/helpers/processes.py (+83/-2) ubuntu_system_tests/helpers/scopes/apps/_preview.py (+1/-1) ubuntu_system_tests/helpers/scopes/base.py (+2/-2) ubuntu_system_tests/helpers/scopes/music/_preview.py (+3/-3) ubuntu_system_tests/helpers/sensors.py (+3/-2) ubuntu_system_tests/helpers/ubuntuuitoolkit/slider.py (+1/-1) ubuntu_system_tests/helpers/unity8/__init__.py (+20/-0) ubuntu_system_tests/helpers/unity8/dash.py (+247/-26) ubuntu_system_tests/helpers/unity8/fixture_setup.py (+307/-2) ubuntu_system_tests/helpers/unity8/greeter.py (+59/-0) ubuntu_system_tests/helpers/unity8/indicators.py (+179/-0) ubuntu_system_tests/helpers/unity8/launcher.py (+66/-0) ubuntu_system_tests/helpers/unity8/phone_stage.py (+5/-5) ubuntu_system_tests/helpers/unity8/sensors.py (+83/-0) ubuntu_system_tests/helpers/unity8/shell.py (+0/-169) ubuntu_system_tests/helpers/unity8/shell/__init__.py (+31/-0) ubuntu_system_tests/helpers/unity8/shell/_cpo.py (+319/-0) ubuntu_system_tests/helpers/unity8/shell/fixture_setup.py (+90/-0) ubuntu_system_tests/helpers/unity8/shell/utils.py (+82/-0) ubuntu_system_tests/helpers/unity8/utils.py (+191/-8) ubuntu_system_tests/selftests/test_tests_to_run.py (+1/-1) ubuntu_system_tests/tests/base.py (+11/-13) ubuntu_system_tests/tests/test_tutorial.py (+1/-5) ubuntu_system_tests/tests/test_with_dialer.py (+4/-4) |
To merge this branch: | bzr merge lp:~canonical-platform-qa/ubuntu-system-tests/move_unity_helpers |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
platform-qa-bot | continuous-integration | Needs Fixing | |
Santiago Baldassin (community) | Needs Fixing | ||
Richard Huddie (community) | Needs Fixing | ||
prod-platform-qa | continuous-integration | Pending | |
Review via email: mp+296879@code.launchpad.net |
Commit message
moving unity8 helpers to ubuntu system tests helpers. @run_tests: ubuntu_
Description of the change
- 396. By Sergio Cazzolato
-
Adding missing files
platform-qa-bot (platform-qa-bot) wrote : | # |
platform-qa-bot (platform-qa-bot) wrote : | # |
FAILED: Continuous integration, rev:396
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
- 397. By Sergio Cazzolato
-
minor fix to start unity8
platform-qa-bot (platform-qa-bot) wrote : | # |
FAILED: Continuous integration, rev:397
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Sergio Cazzolato (sergio-j-cazzolato) wrote : | # |
Tested with these tests, and running sanity test list now:
ubuntu_
ubuntu_
- 398. By Sergio Cazzolato
-
fix in selftests
platform-qa-bot (platform-qa-bot) wrote : | # |
FAILED: Continuous integration, rev:398
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
- 399. By Sergio Cazzolato
-
minor change to trigger rebuild
platform-qa-bot (platform-qa-bot) wrote : | # |
FAILED: Continuous integration, rev:399
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
- 400. By Sergio Cazzolato
-
reducing complexity of set_orientation method, because it is failing in jenkins execution but not here
platform-qa-bot (platform-qa-bot) wrote : | # |
FAILED: Continuous integration, rev:400
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
- 401. By Sergio Cazzolato
-
reducing even more the complexity of set_orientation method
platform-qa-bot (platform-qa-bot) wrote : | # |
FAILED: Continuous integration, rev:401
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
- 402. By Sergio Cazzolato
-
minor fix for flake8
platform-qa-bot (platform-qa-bot) wrote : | # |
PASSED: Continuous integration, rev:402
https:/
Executed test runs:
SUCCESS: https:/
deb: https:/
SUCCESS: https:/
deb: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Richard Huddie (rhuddie) wrote : | # |
Thanks for this, seems to be working well. I've added some fairly minor comments below.
I did see this failure on some of the scope tests: http://
Santiago Baldassin (sbaldassin) wrote : | # |
Thanks for the mp Sergio. I'm adding partial review comments. I'll try to go through the rest of the mp during the day
- 403. By Sergio Cazzolato
-
Updating get_dash method to use patched_
select_ single
Sergio Cazzolato (sergio-j-cazzolato) wrote : | # |
I pushed a change to fix the dash issue. Then I'll go over the other comments.
platform-qa-bot (platform-qa-bot) wrote : | # |
FAILED: Continuous integration, rev:403
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
platform-qa-bot (platform-qa-bot) wrote : | # |
FAILED: Continuous integration, rev:403
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
platform-qa-bot (platform-qa-bot) wrote : | # |
FAILED: Continuous integration, rev:403
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild:
https:/
Unmerged revisions
- 403. By Sergio Cazzolato
-
Updating get_dash method to use patched_
select_ single - 402. By Sergio Cazzolato
-
minor fix for flake8
- 401. By Sergio Cazzolato
-
reducing even more the complexity of set_orientation method
- 400. By Sergio Cazzolato
-
reducing complexity of set_orientation method, because it is failing in jenkins execution but not here
- 399. By Sergio Cazzolato
-
minor change to trigger rebuild
- 398. By Sergio Cazzolato
-
fix in selftests
- 397. By Sergio Cazzolato
-
minor fix to start unity8
- 396. By Sergio Cazzolato
-
Adding missing files
- 395. By Sergio Cazzolato
-
moving unity8 helpers to ubuntu system tests helpers
Preview Diff
1 | === modified file 'debian/control' |
2 | --- debian/control 2016-05-10 16:47:27 +0000 |
3 | +++ debian/control 2016-06-10 02:06:42 +0000 |
4 | @@ -9,8 +9,7 @@ |
5 | python3-fixtures, |
6 | python3-flake8, |
7 | python3-setuptools, |
8 | - python3-testscenarios, |
9 | - unity8-autopilot |
10 | + python3-testscenarios |
11 | Standards-Version: 3.9.5 |
12 | Homepage: http://launchpad.net/ubuntu-system-tests |
13 | X-Python3-Version: >= 3.3 |
14 | @@ -71,6 +70,5 @@ |
15 | ${python3:Depends}, |
16 | python3-autopilot, |
17 | ubuntu-system-tests-common, |
18 | - unity8-autopilot, |
19 | Description: Ubuntu-system-tests test suite and test data |
20 | This package contains test suites and test data for ubuntu-system-tests. |
21 | |
22 | === modified file 'debian/tests/control' |
23 | --- debian/tests/control 2016-05-26 14:25:26 +0000 |
24 | +++ debian/tests/control 2016-06-10 02:06:42 +0000 |
25 | @@ -35,7 +35,6 @@ |
26 | ubuntu-system-tests-helpers, |
27 | ubuntu-system-tests-suite, |
28 | unity8, |
29 | - unity8-autopilot (>=8.02+15.04.20150224-0ubuntu1), |
30 | unity-scope-click, |
31 | unity-scope-click-autopilot, |
32 | usbutils, |
33 | |
34 | === modified file 'ubuntu_system_tests/helpers/indicators/message.py' |
35 | --- ubuntu_system_tests/helpers/indicators/message.py 2016-06-01 15:04:34 +0000 |
36 | +++ ubuntu_system_tests/helpers/indicators/message.py 2016-06-10 02:06:42 +0000 |
37 | @@ -17,8 +17,7 @@ |
38 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
39 | |
40 | import logging |
41 | - |
42 | -from autopilot import logging as autopilot_logging |
43 | +import autopilot |
44 | |
45 | import ubuntuuitoolkit as uuitk |
46 | |
47 | @@ -136,12 +135,12 @@ |
48 | """Return the contact's avatar icon.""" |
49 | return self.select_single('Icon', objectName='avatar', visible=True) |
50 | |
51 | - @autopilot_logging.log_action(logger.info) |
52 | + @autopilot.logging.log_action(logger.info) |
53 | def call(self): |
54 | """Press the call icon.""" |
55 | self.pointing_device.click_object(self.get_call_icon()) |
56 | |
57 | - @autopilot_logging.log_action(logger.info) |
58 | + @autopilot.logging.log_action(logger.info) |
59 | def press_avatar(self): |
60 | """Press the contact's avatar to display snap decision menu.""" |
61 | self.pointing_device.click_object(self.get_contact_avatar()) |
62 | |
63 | === modified file 'ubuntu_system_tests/helpers/indicators/utils.py' |
64 | --- ubuntu_system_tests/helpers/indicators/utils.py 2016-06-08 08:07:44 +0000 |
65 | +++ ubuntu_system_tests/helpers/indicators/utils.py 2016-06-10 02:06:42 +0000 |
66 | @@ -19,10 +19,9 @@ |
67 | |
68 | import logging |
69 | |
70 | -from unity8 import indicators |
71 | - |
72 | from ubuntu_system_tests.helpers import context |
73 | from ubuntu_system_tests.helpers.ubuntuuitoolkit._qquicklistview import QQuickListView # NOQA |
74 | +from ubuntu_system_tests.helpers.unity8 import indicators |
75 | |
76 | INDICATOR_PAGE_PATH = b'IndicatorPage' |
77 | |
78 | |
79 | === modified file 'ubuntu_system_tests/helpers/mediascanner.py' |
80 | --- ubuntu_system_tests/helpers/mediascanner.py 2016-04-13 15:02:39 +0000 |
81 | +++ ubuntu_system_tests/helpers/mediascanner.py 2016-06-10 02:06:42 +0000 |
82 | @@ -21,11 +21,11 @@ |
83 | import dbus |
84 | import logging |
85 | |
86 | -from unity8 import process_helpers |
87 | - |
88 | from ubuntu_system_tests.helpers.dbus_observer import DBusObserver |
89 | +from ubuntu_system_tests.helpers import processes |
90 | from ubuntu_system_tests.helpers.threads import StoppingThread |
91 | |
92 | + |
93 | MEDIA_SCANNER = 'mediascanner-2.0' |
94 | MATCH_STRING = ("type='method_call'," |
95 | "path='/com/canonical/MediaScanner2/Extractor'," |
96 | @@ -38,14 +38,14 @@ |
97 | |
98 | def stop_media_scanner(): |
99 | """ Stop the media scanner process """ |
100 | - if process_helpers.is_job_running(MEDIA_SCANNER): |
101 | - process_helpers.stop_job(MEDIA_SCANNER) |
102 | + if processes.is_job_running(MEDIA_SCANNER): |
103 | + processes.stop_job(MEDIA_SCANNER) |
104 | |
105 | |
106 | def start_media_scanner(): |
107 | """ Start the media scanner process """ |
108 | - if not process_helpers.is_job_running(MEDIA_SCANNER): |
109 | - process_helpers.start_job(MEDIA_SCANNER) |
110 | + if not processes.is_job_running(MEDIA_SCANNER): |
111 | + processes.start_job(MEDIA_SCANNER) |
112 | |
113 | |
114 | class MediaScannerObserver(DBusObserver): |
115 | |
116 | === modified file 'ubuntu_system_tests/helpers/processes.py' |
117 | --- ubuntu_system_tests/helpers/processes.py 2016-05-12 16:41:19 +0000 |
118 | +++ ubuntu_system_tests/helpers/processes.py 2016-06-10 02:06:42 +0000 |
119 | @@ -25,13 +25,15 @@ |
120 | |
121 | import psutil |
122 | |
123 | -from unity8.process_helpers import get_job_status |
124 | - |
125 | from ubuntu_system_tests.helpers import wait_until |
126 | |
127 | logger = logging.getLogger(__name__) |
128 | |
129 | |
130 | +class JobError(Exception): |
131 | + pass |
132 | + |
133 | + |
134 | def is_process_running(pname): |
135 | try: |
136 | return bool(get_process_ids(pname)) |
137 | @@ -117,3 +119,82 @@ |
138 | """ Retrieve the command line used to start the process """ |
139 | return subprocess.check_output('xargs -0 < /proc/{}/cmdline'.format(pid), |
140 | shell=True, universal_newlines=True) |
141 | + |
142 | + |
143 | +def start_job(name, *args): |
144 | + """Start a job. |
145 | + :param str name: The name of the job. |
146 | + :param args: The arguments to be used when starting the job. |
147 | + :return: The process id of the started job. |
148 | + :raises CalledProcessError: if the job failed to start. |
149 | + """ |
150 | + logger.info('Starting job {} with arguments {}.'.format(name, args)) |
151 | + command = ['/sbin/initctl', 'start', name] + list(args) |
152 | + try: |
153 | + output = subprocess.check_output( |
154 | + command, |
155 | + stderr=subprocess.STDOUT, |
156 | + universal_newlines=True, |
157 | + ) |
158 | + logger.info(output) |
159 | + pid = get_job_pid(name) |
160 | + except subprocess.CalledProcessError as e: |
161 | + e.args += ('Failed to start {}: {}.'.format(name, e.output),) |
162 | + raise |
163 | + else: |
164 | + return pid |
165 | + |
166 | + |
167 | +def get_job_pid(name): |
168 | + """Return the process id of a running job. |
169 | + :param str name: The name of the job. |
170 | + :raises JobError: if the job is not running. |
171 | + """ |
172 | + status = get_job_status(name) |
173 | + if "start/" not in status: |
174 | + raise JobError('{} is not in the running state.'.format(name)) |
175 | + return int(status.split()[-1]) |
176 | + |
177 | + |
178 | +def get_job_status(name): |
179 | + """Return the status of a job. |
180 | + :param str name: The name of the job. |
181 | + :raises JobError: if it's not possible to get the status of the job. |
182 | + """ |
183 | + try: |
184 | + return subprocess.check_output([ |
185 | + '/sbin/initctl', |
186 | + 'status', |
187 | + name |
188 | + ], universal_newlines=True) |
189 | + except subprocess.CalledProcessError as error: |
190 | + raise JobError( |
191 | + "Unable to get {}'s status: {}".format(name, error) |
192 | + ) |
193 | + |
194 | + |
195 | +def stop_job(name): |
196 | + """Stop a job. |
197 | + :param str name: The name of the job. |
198 | + :raises CalledProcessError: if the job failed to stop. |
199 | + """ |
200 | + logger.info('Stopping job {}.'.format(name)) |
201 | + command = ['/sbin/initctl', 'stop', name] |
202 | + try: |
203 | + output = subprocess.check_output( |
204 | + command, |
205 | + stderr=subprocess.STDOUT, |
206 | + universal_newlines=True, |
207 | + ) |
208 | + logger.info(output) |
209 | + except subprocess.CalledProcessError as e: |
210 | + e.args += ('Failed to stop {}: {}.'.format(name, e.output),) |
211 | + raise |
212 | + |
213 | + |
214 | +def is_job_running(name): |
215 | + """Return True if the job is running. Otherwise, False. |
216 | + :param str name: The name of the job. |
217 | + :raises JobError: if it's not possible to get the status of the job. |
218 | + """ |
219 | + return 'start/' in get_job_status(name) |
220 | |
221 | === modified file 'ubuntu_system_tests/helpers/scopes/apps/_preview.py' |
222 | --- ubuntu_system_tests/helpers/scopes/apps/_preview.py 2016-04-19 18:39:43 +0000 |
223 | +++ ubuntu_system_tests/helpers/scopes/apps/_preview.py 2016-06-10 02:06:42 +0000 |
224 | @@ -19,12 +19,12 @@ |
225 | # |
226 | |
227 | from autopilot import introspection |
228 | -from unity8.dash import Preview as DashPreview |
229 | |
230 | from ubuntu_system_tests.helpers.autopilot import ( |
231 | get_path_root, wait_select_single) |
232 | from ubuntu_system_tests.helpers.scopes.apps import _clickscope |
233 | from ubuntu_system_tests.helpers.unity8 import UNITY8_DASH_PATH_ROOT |
234 | +from ubuntu_system_tests.helpers.unity8.dash import Preview as DashPreview |
235 | |
236 | |
237 | class Preview(DashPreview): |
238 | |
239 | === modified file 'ubuntu_system_tests/helpers/scopes/base.py' |
240 | --- ubuntu_system_tests/helpers/scopes/base.py 2016-04-19 10:06:01 +0000 |
241 | +++ ubuntu_system_tests/helpers/scopes/base.py 2016-06-10 02:06:42 +0000 |
242 | @@ -22,11 +22,11 @@ |
243 | |
244 | from autopilot import exceptions |
245 | from collections import namedtuple |
246 | -from unity8 import dash as unity8_dash |
247 | |
248 | from ubuntu_system_tests.helpers.autopilot.list import order_by_y_coord |
249 | from ubuntu_system_tests.helpers.ubuntuuitoolkit.pageheader import ( |
250 | DashPageHeader) |
251 | +from ubuntu_system_tests.helpers.unity8 import dash |
252 | from ubuntu_system_tests.helpers.url_dispatcher import go_to_url |
253 | |
254 | ScopeDataItem = namedtuple('ScopeDataItem', ['data', 'globalRect']) |
255 | @@ -36,7 +36,7 @@ |
256 | logger = logging.getLogger(__name__) |
257 | |
258 | |
259 | -class GenericScopeView(unity8_dash.GenericScopeView): |
260 | +class GenericScopeView(dash.GenericScopeView): |
261 | """ |
262 | This class is a base class for all scope CPOs and should never be |
263 | instantiated directly. This avoids autopilot CPO errors. |
264 | |
265 | === modified file 'ubuntu_system_tests/helpers/scopes/music/_preview.py' |
266 | --- ubuntu_system_tests/helpers/scopes/music/_preview.py 2016-02-03 16:09:24 +0000 |
267 | +++ ubuntu_system_tests/helpers/scopes/music/_preview.py 2016-06-10 02:06:42 +0000 |
268 | @@ -18,9 +18,9 @@ |
269 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
270 | # |
271 | |
272 | -from unity8.dash import Preview as DashPreview |
273 | -from ubuntu_system_tests.helpers.autopilot.object import \ |
274 | - wait_until_is_not_moving |
275 | +from ubuntu_system_tests.helpers.autopilot.object import ( |
276 | + wait_until_is_not_moving) |
277 | +from ubuntu_system_tests.helpers.unity8.dash import Preview as DashPreview |
278 | |
279 | |
280 | class Preview(DashPreview): |
281 | |
282 | === modified file 'ubuntu_system_tests/helpers/sensors.py' |
283 | --- ubuntu_system_tests/helpers/sensors.py 2016-04-25 19:02:31 +0000 |
284 | +++ ubuntu_system_tests/helpers/sensors.py 2016-06-10 02:06:42 +0000 |
285 | @@ -21,11 +21,12 @@ |
286 | import os |
287 | import subprocess |
288 | |
289 | -from unity8.sensors import FakePlatformSensors as Unity8Sensors |
290 | - |
291 | from ubuntu_system_tests.helpers import context |
292 | from ubuntu_system_tests.helpers.power import write_to_powerd_fifo |
293 | from ubuntu_system_tests.helpers.testbed import run_command_with_sudo as sudo |
294 | +from ubuntu_system_tests.helpers.unity8.sensors import ( |
295 | + FakePlatformSensors as Unity8Sensors) |
296 | + |
297 | |
298 | DELAY_MS = 10 |
299 | ACCEL_SENSOR_RESOLUTION = 0.1 |
300 | |
301 | === modified file 'ubuntu_system_tests/helpers/ubuntuuitoolkit/slider.py' |
302 | --- ubuntu_system_tests/helpers/ubuntuuitoolkit/slider.py 2015-09-22 10:20:55 +0000 |
303 | +++ ubuntu_system_tests/helpers/ubuntuuitoolkit/slider.py 2016-06-10 02:06:42 +0000 |
304 | @@ -18,7 +18,7 @@ |
305 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
306 | |
307 | |
308 | -from unity8 import indicators |
309 | +from ubuntu_system_tests.helpers.unity8 import indicators |
310 | |
311 | |
312 | class Slider(indicators.Slider): |
313 | |
314 | === modified file 'ubuntu_system_tests/helpers/unity8/__init__.py' |
315 | --- ubuntu_system_tests/helpers/unity8/__init__.py 2016-06-02 11:07:46 +0000 |
316 | +++ ubuntu_system_tests/helpers/unity8/__init__.py 2016-06-10 02:06:42 +0000 |
317 | @@ -19,12 +19,22 @@ |
318 | # |
319 | |
320 | from ubuntu_system_tests.helpers.unity8.utils import ( |
321 | + UnityException, |
322 | close_all_apps, |
323 | close_app, |
324 | ensure_unity_running_and_greeter_hidden, |
325 | ensure_unity_stopped, |
326 | + get_binary_path, |
327 | get_dash, |
328 | + get_data_dirs, |
329 | + get_default_extra_mock_libraries, |
330 | + get_lib_path, |
331 | + get_mocks_library_path, |
332 | + get_unity_pid, |
333 | launch_application_from_launcher, |
334 | + restart_unity, |
335 | + restart_unity_with_testability, |
336 | + running_installed_tests, |
337 | PROC_NAME, |
338 | UNITY8_PATH_ROOT, |
339 | UNITY8_DASH_PATH_ROOT, |
340 | @@ -33,12 +43,22 @@ |
341 | |
342 | |
343 | __all__ = [ |
344 | + 'UnityException', |
345 | 'close_all_apps', |
346 | 'close_app', |
347 | 'ensure_unity_running_and_greeter_hidden', |
348 | 'ensure_unity_stopped', |
349 | + 'get_binary_path', |
350 | 'get_dash', |
351 | + 'get_data_dirs', |
352 | + 'get_default_extra_mock_libraries', |
353 | + 'get_lib_path', |
354 | + 'get_mocks_library_path', |
355 | + 'get_unity_pid', |
356 | 'launch_application_from_launcher', |
357 | + 'restart_unity', |
358 | + 'restart_unity_with_testability', |
359 | + 'running_installed_tests', |
360 | 'PROC_NAME', |
361 | 'UNITY8_PATH_ROOT', |
362 | 'UNITY8_DASH_PATH_ROOT', |
363 | |
364 | === modified file 'ubuntu_system_tests/helpers/unity8/dash.py' |
365 | --- ubuntu_system_tests/helpers/unity8/dash.py 2016-02-03 16:09:24 +0000 |
366 | +++ ubuntu_system_tests/helpers/unity8/dash.py 2016-06-10 02:06:42 +0000 |
367 | @@ -18,10 +18,14 @@ |
368 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
369 | # |
370 | |
371 | +import logging |
372 | from retrying import retry |
373 | |
374 | +import autopilot |
375 | from autopilot.input._common import get_center_point |
376 | -from unity8 import dash as unity8_dash |
377 | +from autopilot.introspection import dbus |
378 | +from ubuntuuitoolkit import ( |
379 | + QQuickFlickable, MainView, UbuntuUIToolkitCustomProxyObjectBase, units) |
380 | |
381 | from ubuntu_system_tests.helpers.autopilot import ( |
382 | patched_wait_select_single, validate_dbus_object, wait_select_many) |
383 | @@ -29,18 +33,176 @@ |
384 | from ubuntu_system_tests.helpers.ubuntuuitoolkit.pageheader import ( |
385 | DashPageHeader |
386 | ) |
387 | -from ubuntu_system_tests.helpers.unity8 import UNITY8_DASH_PATH_ROOT |
388 | +from ubuntu_system_tests.helpers.unity8 import ( |
389 | + UNITY8_DASH_PATH_ROOT, UnityException) |
390 | |
391 | SCOPE_CLASS_NAME = 'GenericScopeView' |
392 | |
393 | - |
394 | -class Dash(unity8_dash.Dash): |
395 | +logger = logging.getLogger(__name__) |
396 | + |
397 | + |
398 | +class DashApp(): |
399 | + """Autopilot helper for the Dash app.""" |
400 | + |
401 | + def __init__(self, app_proxy): |
402 | + self.app_proxy = app_proxy |
403 | + self.main_view = self.app_proxy.select_single(MainView) |
404 | + self.dash = self.main_view.select_single(Dash) |
405 | + |
406 | + |
407 | +class Dash(UbuntuUIToolkitCustomProxyObjectBase): |
408 | + |
409 | + def __init__(self, *args): |
410 | + super().__init__(*args) |
411 | + self.dash_content_list = self.wait_select_single( |
412 | + 'QQuickListView', objectName='dashContentList') |
413 | |
414 | @classmethod |
415 | def validate_dbus_object(cls, path, state): |
416 | return validate_dbus_object( |
417 | path, state, UNITY8_DASH_PATH_ROOT, b'Dash', objectName='dash') |
418 | |
419 | + def get_applications_grid(self): |
420 | + get_grid = self.get_scope('clickscope').wait_select_single( |
421 | + 'CardGrid', objectName='local') |
422 | + return get_grid |
423 | + |
424 | + def get_application_icon(self, text): |
425 | + """Returns a 'Tile' icon that has the text 'text' from the application |
426 | + grid. |
427 | + |
428 | + :param text: String containing the text of the icon to search for. |
429 | + |
430 | + """ |
431 | + app_grid = self.get_applications_grid() |
432 | + resp_grid = app_grid.wait_select_single('ResponsiveGridView') |
433 | + return resp_grid.select_single('Tile', text=text) |
434 | + |
435 | + def get_scope(self, scope_name='clickscope'): |
436 | + return self.dash_content_list.wait_select_single( |
437 | + 'QQuickLoader', scopeId=scope_name) |
438 | + |
439 | + def get_scope_by_index(self, scope_index=0): |
440 | + return self.dash_content_list.wait_select_single( |
441 | + 'QQuickLoader', objectName=("scopeLoader%i" % scope_index)) |
442 | + |
443 | + @autopilot.logging.log_action(logger.info) |
444 | + def open_scope(self, scope_id): |
445 | + """Open a dash scope. |
446 | + |
447 | + :parameter scope_id: The id of the scope. |
448 | + :return: The scope. |
449 | + |
450 | + """ |
451 | + scope_loader = self._get_scope_loader(scope_id) |
452 | + if scope_loader.isCurrent: |
453 | + logger.info('The scope is already open.') |
454 | + return self._get_scope_from_loader(scope_loader) |
455 | + else: |
456 | + return self._open_scope_scrolling(scope_loader) |
457 | + |
458 | + def _get_scope_loader(self, scope_id): |
459 | + try: |
460 | + aux = self.dash_content_list.get_children_by_type('QQuickItem')[0] |
461 | + for l in aux.get_children_by_type('QQuickLoader'): |
462 | + if (l.scopeId == scope_id): |
463 | + return l |
464 | + raise UnityException( |
465 | + 'No scope found with id {0}'.format(scope_id)) |
466 | + except dbus.StateNotFoundError: |
467 | + raise UnityException( |
468 | + 'No scope found with id {0}'.format(scope_id)) |
469 | + |
470 | + def _get_scope_from_loader(self, loader): |
471 | + return loader.wait_select_single('GenericScopeView') |
472 | + |
473 | + def _open_scope_scrolling(self, scope_loader): |
474 | + scroll = self._get_scroll_direction(scope_loader) |
475 | + |
476 | + while not scope_loader.isCurrent: |
477 | + scroll() |
478 | + self.dash_content_list.moving.wait_for(False) |
479 | + |
480 | + scope_loader.isCurrent.wait_for(True) |
481 | + scope = self._get_scope_from_loader(scope_loader) |
482 | + return scope |
483 | + |
484 | + def _get_scroll_direction(self, scope_loader): |
485 | + current_scope_loader = self.dash_content_list.select_single( |
486 | + 'QQuickLoader', isCurrent=True) |
487 | + if scope_loader.globalRect.x < current_scope_loader.globalRect.x: |
488 | + return self._scroll_to_left_scope |
489 | + elif scope_loader.globalRect.x > current_scope_loader.globalRect.x: |
490 | + return self._scroll_to_right_scope |
491 | + else: |
492 | + raise UnityException('The scope is already open') |
493 | + |
494 | + @retry(stop_max_attempt_number=3, |
495 | + wait_fixed=500, |
496 | + retry_on_exception=lambda exception: ( |
497 | + isinstance(exception, AssertionError))) |
498 | + @autopilot.logging.log_action(logger.info) |
499 | + def _scroll_to_left_scope(self): |
500 | + original_index = self.dash_content_list.currentIndex |
501 | + dash_content = self.select_single(objectName="dashContent") |
502 | + x, y, width, height = dash_content.globalRect |
503 | + # Make the drag range be a multiple of the drag "rate" value. |
504 | + # Workarounds https://bugs.launchpad.net/mir/+bug/1399690 |
505 | + rate = 5 |
506 | + divisions = 5 |
507 | + jump = (width / divisions) // rate * rate |
508 | + start_x = x + jump |
509 | + stop_x = x + jump * (divisions - 1) |
510 | + start_y = stop_y = y + 1 |
511 | + self.pointing_device.drag(start_x, start_y, stop_x, stop_y, rate) |
512 | + self.dash_content_list.currentIndex.wait_for(original_index - 1) |
513 | + |
514 | + @retry(stop_max_attempt_number=3, |
515 | + wait_fixed=500, |
516 | + retry_on_exception=lambda exception: ( |
517 | + isinstance(exception, AssertionError))) |
518 | + @autopilot.logging.log_action(logger.info) |
519 | + def _scroll_to_right_scope(self): |
520 | + original_index = self.dash_content_list.currentIndex |
521 | + dash_content = self.select_single(objectName="dashContent") |
522 | + x, y, width, height = dash_content.globalRect |
523 | + # Make the drag range be a multiple of the drag "rate" value. |
524 | + # Workarounds https://bugs.launchpad.net/mir/+bug/1399690 |
525 | + rate = 5 |
526 | + divisions = 5 |
527 | + jump = (width / divisions) // rate * rate |
528 | + start_x = x + jump * (divisions - 1) |
529 | + stop_x = x + jump |
530 | + start_y = stop_y = y + 1 |
531 | + self.pointing_device.drag(start_x, start_y, stop_x, stop_y, rate) |
532 | + self.dash_content_list.currentIndex.wait_for(original_index + 1) |
533 | + |
534 | + def enter_search_query(self, query, keyboard): |
535 | + current_header = self._get_current_page_header() |
536 | + search_button = \ |
537 | + current_header.select_single(objectName="search_button") |
538 | + self.pointing_device.move( |
539 | + search_button.globalRect.x + search_button.width / 2, |
540 | + search_button.globalRect.y + search_button.height / 2) |
541 | + self.pointing_device.click() |
542 | + headerContainer = current_header.select_single( |
543 | + objectName="headerContainer") |
544 | + headerContainer.contentY.wait_for(0) |
545 | + keyboard.type(query) |
546 | + self.select_single( |
547 | + objectName="processingIndicator").visible.wait_for(False) |
548 | + |
549 | + def get_search_text_field(self): |
550 | + page_header = self._get_current_page_header() |
551 | + return page_header.select_single(objectName='searchTextField') |
552 | + |
553 | + def _get_current_page_header(self): |
554 | + all_scopes = self.dash_content_list.select_many("GenericScopeView") |
555 | + for i in all_scopes: |
556 | + if i.isCurrent: |
557 | + return i.select_single(objectName="scopePageHeader") |
558 | + return None |
559 | + |
560 | def wait_for_processing_to_complete(self, timeout=90): |
561 | """Wait until the dash is fully loaded""" |
562 | self.select_single( |
563 | @@ -52,28 +214,6 @@ |
564 | dash_content = self.select_single(objectName='dashContent') |
565 | dash_content.pageHeaderTotallyVisible.wait_for(True) |
566 | |
567 | - @retry(stop_max_attempt_number=3, |
568 | - wait_fixed=500, |
569 | - retry_on_exception=lambda exception: ( |
570 | - isinstance(exception, AssertionError))) |
571 | - def _scroll_to_left_scope(self): |
572 | - """ |
573 | - Call parent implementation, retrying in case it raises |
574 | - an exception due to a failed scrolling |
575 | - """ |
576 | - super()._scroll_to_left_scope() |
577 | - |
578 | - @retry(stop_max_attempt_number=3, |
579 | - wait_fixed=500, |
580 | - retry_on_exception=lambda exception: ( |
581 | - isinstance(exception, AssertionError))) |
582 | - def _scroll_to_right_scope(self): |
583 | - """ |
584 | - Call parent implementation, retrying in case it raises |
585 | - an exception due to a failed scrolling |
586 | - """ |
587 | - super()._scroll_to_right_scope() |
588 | - |
589 | def scroll_to_left_scope(self): |
590 | self._scroll_to_left_scope() |
591 | self.dash_content_list.moving.wait_for(False) |
592 | @@ -145,3 +285,84 @@ |
593 | ScopesList, |
594 | objectName='scopesList', |
595 | visible=True) |
596 | + |
597 | + |
598 | +class ListViewWithPageHeader(QQuickFlickable): |
599 | + |
600 | + margin_to_swipe_from_bottom = units.gu(4) |
601 | + |
602 | + |
603 | +class GenericScopeView(UbuntuUIToolkitCustomProxyObjectBase): |
604 | + """Autopilot helper for generic scopes.""" |
605 | + |
606 | + @autopilot.logging.log_action(logger.info) |
607 | + def open_preview(self, category, app_name, press_duration=0.10): |
608 | + """Open the preview of an application. |
609 | + |
610 | + :parameter category: The name of the category where the application is. |
611 | + :parameter app_name: The name of the application. |
612 | + :return: The opened preview. |
613 | + |
614 | + """ |
615 | + # FIXME some categories need a long press in order to see the preview. |
616 | + # Some categories do not show previews, like recent apps. |
617 | + # --elopio - 2014-1-14 |
618 | + self.click_scope_item(category, app_name, press_duration) |
619 | + preview_list = self.wait_select_single( |
620 | + 'QQuickLoader', objectName='subPageLoader') |
621 | + preview_list.subPageShown.wait_for(True) |
622 | + preview_list.x.wait_for(0) |
623 | + self.get_root_instance().select_single( |
624 | + objectName='processingIndicator').visible.wait_for(False) |
625 | + return preview_list.select_single( |
626 | + Preview, objectName='preview') |
627 | + |
628 | + @autopilot.logging.log_action(logger.debug) |
629 | + def click_scope_item(self, category, title, press_duration=0.10): |
630 | + """Click an item from the scope. |
631 | + |
632 | + :parameter category: The name of the category where the item is. |
633 | + :parameter title: The title of the item. |
634 | + |
635 | + """ |
636 | + category_element = self._get_category_element(category) |
637 | + icon = category_element.wait_select_single( |
638 | + 'UCAbstractButton', title=title) |
639 | + list_view = self.select_single( |
640 | + ListViewWithPageHeader, objectName='categoryListView') |
641 | + list_view.swipe_child_into_view(icon) |
642 | + self.pointing_device.click_object(icon, press_duration=press_duration) |
643 | + |
644 | + def _get_category_element(self, category): |
645 | + try: |
646 | + return self.wait_select_single( |
647 | + 'DashCategoryBase', |
648 | + objectName='dashCategory{}'.format(category)) |
649 | + except dbus.StateNotFoundError: |
650 | + raise UnityException( |
651 | + 'No category found with name {}'.format(category)) |
652 | + |
653 | + def get_applications(self, category): |
654 | + """Return the list of applications on a category. |
655 | + |
656 | + :parameter category: The name of the category. |
657 | + |
658 | + """ |
659 | + category_element = self._get_category_element(category) |
660 | + see_all = category_element.select_single(objectName='seeAll') |
661 | + application_cards = category_element.select_many('UCAbstractButton') |
662 | + |
663 | + application_cards = sorted( |
664 | + (card for card in application_cards |
665 | + if card.globalRect.y < see_all.globalRect.y), |
666 | + key=lambda card: (card.globalRect.y, card.globalRect.x)) |
667 | + |
668 | + result = [] |
669 | + for card in application_cards: |
670 | + if card.objectName not in ('cardToolCard', 'seeAll'): |
671 | + result.append(card.title) |
672 | + return result |
673 | + |
674 | + |
675 | +class Preview(UbuntuUIToolkitCustomProxyObjectBase): |
676 | + """Autopilot custom proxy object for generic previews.""" |
677 | |
678 | === modified file 'ubuntu_system_tests/helpers/unity8/fixture_setup.py' |
679 | --- ubuntu_system_tests/helpers/unity8/fixture_setup.py 2015-05-21 18:15:40 +0000 |
680 | +++ ubuntu_system_tests/helpers/unity8/fixture_setup.py 2016-06-10 02:06:42 +0000 |
681 | @@ -18,9 +18,314 @@ |
682 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
683 | # |
684 | |
685 | +import fixtures |
686 | +import logging |
687 | import os |
688 | - |
689 | -import fixtures |
690 | +import subprocess |
691 | +import threading |
692 | + |
693 | +import ubuntuuitoolkit |
694 | +from autopilot import introspection |
695 | +from autopilot.matchers import Eventually |
696 | +from testtools.matchers import Equals |
697 | +from ubuntuuitoolkit import fixture_setup |
698 | + |
699 | +from ubuntu_system_tests.helpers import processes |
700 | +from ubuntu_system_tests.helpers.unity8 import ( |
701 | + get_binary_path, |
702 | + get_mocks_library_path, |
703 | + get_default_extra_mock_libraries, |
704 | + get_data_dirs, |
705 | + get_unity_pid, |
706 | + restart_unity_with_testability, |
707 | + sensors |
708 | +) |
709 | +from ubuntu_system_tests.helpers.unity8.shell._cpo import ShellView |
710 | + |
711 | +logger = logging.getLogger(__name__) |
712 | + |
713 | + |
714 | +class LaunchUnityWithFakeSensors(fixtures.Fixture): |
715 | + |
716 | + """Fixture to launch Unity8 with an injectable sensors backend. |
717 | + |
718 | + :ivar unity_proxy: The Autopilot proxy object for the Unity shell. |
719 | + |
720 | + """ |
721 | + |
722 | + unity_proxy = None |
723 | + main_win = None |
724 | + |
725 | + def setUp(self): |
726 | + """Restart Unity8 with testability and create sensors.""" |
727 | + super().setUp() |
728 | + self.useFixture( |
729 | + fixture_setup.InitctlEnvironmentVariable( |
730 | + UBUNTU_PLATFORM_API_TEST_OVERRIDE='sensors')) |
731 | + |
732 | + self.addCleanup(processes.stop_job, 'unity8') |
733 | + restart_thread = threading.Thread( |
734 | + target=self._restart_unity_with_testability) |
735 | + restart_thread.start() |
736 | + |
737 | + self._create_sensors() |
738 | + |
739 | + restart_thread.join() |
740 | + self.fake_sensors = sensors.FakePlatformSensors() |
741 | + |
742 | + def _get_lightdm_mock_path(self): |
743 | + lib_path = get_mocks_library_path() |
744 | + lightdm_mock_path = os.path.abspath( |
745 | + os.path.join(lib_path, "IntegratedLightDM", "liblightdm") |
746 | + ) |
747 | + |
748 | + if not os.path.exists(lightdm_mock_path): |
749 | + raise RuntimeError( |
750 | + "LightDM mock does not exist at path {}.". |
751 | + format(lightdm_mock_path) |
752 | + ) |
753 | + return lightdm_mock_path |
754 | + |
755 | + def _get_qml_import_path_with_mock(self): |
756 | + """Return the QML2_IMPORT_PATH value with the mock path prepended.""" |
757 | + qml_import_path = [get_mocks_library_path()] |
758 | + if os.getenv('QML2_IMPORT_PATH') is not None: |
759 | + qml_import_path.append(os.getenv('QML2_IMPORT_PATH')) |
760 | + |
761 | + qml_import_path = ':'.join(qml_import_path) |
762 | + return qml_import_path |
763 | + |
764 | + def _remove_and_ignore_os_error(self, path): |
765 | + try: |
766 | + os.unlink(path) |
767 | + except OSError: |
768 | + pass |
769 | + |
770 | + def _restart_unity_with_testability(self): |
771 | + _environment = {} |
772 | + |
773 | + data_dirs = get_data_dirs(True) |
774 | + if data_dirs is not None: |
775 | + _environment['XDG_DATA_DIRS'] = data_dirs |
776 | + |
777 | + _environment['QML2_IMPORT_PATH'] = ( |
778 | + self._get_qml_import_path_with_mock() |
779 | + ) |
780 | + |
781 | + new_ld_library_path = [ |
782 | + get_default_extra_mock_libraries(), |
783 | + self._get_lightdm_mock_path() |
784 | + ] |
785 | + if os.getenv('LD_LIBRARY_PATH') is not None: |
786 | + new_ld_library_path.append(os.getenv('LD_LIBRARY_PATH')) |
787 | + new_ld_library_path = ':'.join(new_ld_library_path) |
788 | + _environment['LD_LIBRARY_PATH'] = new_ld_library_path |
789 | + |
790 | + # FIXME: we shouldn't be doing this |
791 | + # $MIR_SOCKET, fallback to $XDG_RUNTIME_DIR/mir_socket and |
792 | + # /tmp/mir_socket as last resort |
793 | + self._remove_and_ignore_os_error( |
794 | + os.getenv('MIR_SOCKET', os.path.join( |
795 | + os.getenv('XDG_RUNTIME_DIR', "/tmp"), "mir_socket"))) |
796 | + self._remove_and_ignore_os_error("/tmp/mir_socket") |
797 | + |
798 | + binary_arg = "BINARY=%s" % get_binary_path() |
799 | + env_args = ["%s=%s" % (k, v) for k, v in _environment.items()] |
800 | + args = [binary_arg] + env_args |
801 | + self.unity_proxy = restart_unity_with_testability(*args) |
802 | + self.main_win = self.unity_proxy.select_single(ShellView) |
803 | + |
804 | + def _create_sensors(self): |
805 | + # Wait for unity to start running. |
806 | + Eventually(Equals(True)).match( |
807 | + lambda: processes.is_job_running('unity8')) |
808 | + |
809 | + # Wait for the sensors fifo file to be created. |
810 | + fifo_path = '/tmp/sensor-fifo-{0}'.format( |
811 | + get_unity_pid()) |
812 | + Eventually(Equals(True)).match( |
813 | + lambda: os.path.exists(fifo_path)) |
814 | + |
815 | + with open(fifo_path, 'w') as fifo: |
816 | + fifo.write('create accel 0 1000 0.1\n') |
817 | + fifo.write('create light 0 10 1\n') |
818 | + fifo.write('create proximity\n') |
819 | + |
820 | + |
821 | +class RestartUnityWithTestability(fixtures.Fixture): |
822 | + |
823 | + """Fixture to launch Unity8 with testability. |
824 | + |
825 | + :ivar unity_proxy: The Autopilot proxy object for the Unity shell. |
826 | + |
827 | + """ |
828 | + |
829 | + unity_proxy = None |
830 | + |
831 | + def __init__(self, binary_path, variables): |
832 | + """Initialize the fixture instance. |
833 | + |
834 | + :param str binary_path: The path to the Dash app binary. |
835 | + :param cli_arguments: The arguments to pass when launching the |
836 | + :param variables: The variables to use when launching the app. |
837 | + :type variables: A dictionary. |
838 | + |
839 | + """ |
840 | + super().__init__() |
841 | + self.binary_path = binary_path |
842 | + self.variables = variables |
843 | + |
844 | + def setUp(self): |
845 | + """Restart unity with testability when the fixture is used.""" |
846 | + super().setUp() |
847 | + self.addCleanup(self.stop_unity) |
848 | + self.restart_unity() |
849 | + |
850 | + def restart_unity(self): |
851 | + self.restart_unity_with_testability() |
852 | + |
853 | + def restart_unity_with_testability(self): |
854 | + self._unlink_mir_socket() |
855 | + |
856 | + binary_arg = 'BINARY={}'.format(self.binary_path) |
857 | + variable_args = [ |
858 | + '{}={}'.format(key, value) for key, value in self.variables.items() |
859 | + ] |
860 | + all_args = [binary_arg] + variable_args |
861 | + |
862 | + self.unity_proxy = restart_unity_with_testability(*all_args) |
863 | + |
864 | + def _unlink_mir_socket(self): |
865 | + # FIXME: we shouldn't be doing this |
866 | + # $MIR_SOCKET, fallback to $XDG_RUNTIME_DIR/mir_socket and |
867 | + # /tmp/mir_socket as last resort |
868 | + try: |
869 | + os.unlink( |
870 | + os.getenv('MIR_SOCKET', |
871 | + os.path.join(os.getenv('XDG_RUNTIME_DIR', "/tmp"), |
872 | + "mir_socket"))) |
873 | + except OSError: |
874 | + pass |
875 | + try: |
876 | + os.unlink("/tmp/mir_socket") |
877 | + except OSError: |
878 | + pass |
879 | + |
880 | + def stop_unity(self): |
881 | + processes.stop_job('unity8') |
882 | + |
883 | + |
884 | +class LaunchDashApp(fixtures.Fixture): |
885 | + |
886 | + """Fixture to launch the Dash app.""" |
887 | + |
888 | + def __init__(self, binary_path, variables): |
889 | + """Initialize an instance. |
890 | + |
891 | + :param str binary_path: The path to the Dash app binary. |
892 | + :param variables: The variables to use when launching the app. |
893 | + :type variables: A dictionary. |
894 | + |
895 | + """ |
896 | + super().__init__() |
897 | + self.binary_path = binary_path |
898 | + self.variables = variables |
899 | + |
900 | + def setUp(self): |
901 | + """Launch the dash app when the fixture is used.""" |
902 | + super().setUp() |
903 | + self.addCleanup(self.stop_application) |
904 | + self.application_proxy = self.launch_application() |
905 | + |
906 | + def launch_application(self): |
907 | + binary_arg = 'BINARY={}'.format(self.binary_path) |
908 | + testability_arg = 'QT_LOAD_TESTABILITY={}'.format(1) |
909 | + env_args = [ |
910 | + '{}={}'.format(key, value) for key, value in self.variables.items() |
911 | + ] |
912 | + all_args = [binary_arg, testability_arg] + env_args |
913 | + |
914 | + pid = processes.start_job('unity8-dash', *all_args) |
915 | + return introspection.get_proxy_object_for_existing_process( |
916 | + pid=pid, |
917 | + emulator_base=ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase |
918 | + ) |
919 | + |
920 | + def stop_application(self): |
921 | + processes.stop_job('unity8-dash') |
922 | + |
923 | + |
924 | +class DisplayRotationLock(fixtures.Fixture): |
925 | + |
926 | + def __init__(self, enable): |
927 | + super().__init__() |
928 | + self.enable = enable |
929 | + |
930 | + def setUp(self): |
931 | + super().setUp() |
932 | + original_state = self._is_rotation_lock_enabled() |
933 | + if self.enable != original_state: |
934 | + self.addCleanup(self._set_rotation_lock, original_state) |
935 | + self._set_rotation_lock(self.enable) |
936 | + |
937 | + def _is_rotation_lock_enabled(self): |
938 | + command = [ |
939 | + 'gsettings', 'get', |
940 | + 'com.ubuntu.touch.system', |
941 | + 'rotation-lock' |
942 | + ] |
943 | + output = subprocess.check_output(command, universal_newlines=True) |
944 | + return True if output.count('true') else False |
945 | + |
946 | + def _set_rotation_lock(self, value): |
947 | + value_string = 'true' if value else 'false' |
948 | + command = [ |
949 | + 'gsettings', 'set', |
950 | + 'com.ubuntu.touch.system', |
951 | + 'rotation-lock', value_string |
952 | + ] |
953 | + subprocess.check_output(command) |
954 | + |
955 | + |
956 | +class LaunchMockIndicatorService(fixtures.Fixture): |
957 | + |
958 | + """Fixture to launch the indicator test service.""" |
959 | + |
960 | + def __init__(self, action_delay, ensure_not_running=True): |
961 | + """Initialize an instance. |
962 | + |
963 | + :param action_delay: The delay to use when activating actions. |
964 | + Measured in milliseconds. Value of -1 will result in infinite delay. |
965 | + :type action_delay: An integer. |
966 | + :param boolean ensure_not_running: Make sure service is not running |
967 | + |
968 | + """ |
969 | + super(LaunchMockIndicatorService, self).__init__() |
970 | + self.action_delay = action_delay |
971 | + self.ensure_not_running = ensure_not_running |
972 | + |
973 | + def setUp(self): |
974 | + super().setUp() |
975 | + if self.ensure_not_running: |
976 | + self.ensure_service_not_running() |
977 | + self.addCleanup(self.stop_service) |
978 | + self.application_proxy = self.launch_service() |
979 | + |
980 | + def launch_service(self): |
981 | + logger.info("Starting unity-mock-indicator-service") |
982 | + binary_path = get_binary_path('unity-mock-indicator-service') |
983 | + binary_arg = 'BINARY={}'.format(binary_path) |
984 | + env_args = 'ARGS=-t {}'.format(self.action_delay) |
985 | + all_args = [binary_arg, env_args] |
986 | + processes.start_job('unity-mock-indicator-service', *all_args) |
987 | + |
988 | + def stop_service(self): |
989 | + logger.info("Stopping unity-mock-indicator-service") |
990 | + processes.stop_job('unity-mock-indicator-service') |
991 | + |
992 | + def ensure_service_not_running(self): |
993 | + if processes.is_job_running('unity-mock-indicator-service'): |
994 | + self.stop_service() |
995 | |
996 | |
997 | class SettingsWizard(fixtures.Fixture): |
998 | |
999 | === modified file 'ubuntu_system_tests/helpers/unity8/greeter.py' |
1000 | --- ubuntu_system_tests/helpers/unity8/greeter.py 2016-04-18 17:29:42 +0000 |
1001 | +++ ubuntu_system_tests/helpers/unity8/greeter.py 2016-06-10 02:06:42 +0000 |
1002 | @@ -19,14 +19,21 @@ |
1003 | # |
1004 | |
1005 | import dbus |
1006 | + |
1007 | from autopilot.matchers import Eventually |
1008 | +from autopilot.utilities import sleep |
1009 | from testtools.matchers import Equals |
1010 | +from ubuntuuitoolkit import UbuntuUIToolkitCustomProxyObjectBase, TextField |
1011 | |
1012 | |
1013 | def wait_for_greeter(): |
1014 | Eventually(Equals(True), timeout=300).match(_is_greeter_active) |
1015 | |
1016 | |
1017 | +def wait_for_greeter_gone(): |
1018 | + Eventually(Equals(False), timeout=300).match(_is_greeter_active) |
1019 | + |
1020 | + |
1021 | def _is_greeter_active(): |
1022 | try: |
1023 | dbus_proxy = _get_greeter_dbus_proxy() |
1024 | @@ -50,3 +57,55 @@ |
1025 | dbus_proxy = _get_greeter_dbus_proxy() |
1026 | if not _is_greeter_active(): |
1027 | dbus_proxy.ShowGreeter() |
1028 | + |
1029 | + |
1030 | +def unlock_unity(): |
1031 | + """Helper function that attempts to unlock the unity greeter. """ |
1032 | + wait_for_greeter() |
1033 | + hide_greeter_with_dbus() |
1034 | + wait_for_greeter_gone() |
1035 | + |
1036 | + |
1037 | +def lock_unity(): |
1038 | + """Helper function that attempts to lock unity greeter. """ |
1039 | + show_greeter_with_dbus() |
1040 | + wait_for_greeter() |
1041 | + |
1042 | + |
1043 | +class Greeter(UbuntuUIToolkitCustomProxyObjectBase): |
1044 | + """A helper that understands the greeter screen.""" |
1045 | + |
1046 | + def wait_swiped_away(self): |
1047 | + # We have to be careful here, because coverPage can go away at any time |
1048 | + # if there isn't a lockscreen behind it (it hides completely, then |
1049 | + # the greeter disposes it). But if there *is* a lockscreen, then we |
1050 | + # need a different check, by looking at its showProgress. So make our |
1051 | + # own wait_for loop and check both possibilities. |
1052 | + for i in range(10): |
1053 | + if not self.required: |
1054 | + return |
1055 | + coverPage = self.select_single(objectName='coverPage') |
1056 | + if coverPage.showProgress == 0: |
1057 | + return |
1058 | + sleep(1) |
1059 | + |
1060 | + raise AssertionError("Greeter cover page still up after 10s") |
1061 | + |
1062 | + def swipe(self): |
1063 | + """Swipe the greeter screen away.""" |
1064 | + self.waiting.wait_for(False) |
1065 | + coverPage = self.select_single(objectName='coverPage') |
1066 | + coverPage.showProgress.wait_for(1) |
1067 | + |
1068 | + rect = self.globalRect |
1069 | + start_x = rect[0] + rect[2] - 3 |
1070 | + start_y = int(rect[1] + rect[3] / 2) |
1071 | + stop_x = int(rect[0] + rect[2] * 0.2) |
1072 | + stop_y = start_y |
1073 | + self.pointing_device.drag(start_x, start_y, stop_x, stop_y) |
1074 | + |
1075 | + self.wait_swiped_away() |
1076 | + |
1077 | + def get_prompt(self): |
1078 | + return self.select_single( |
1079 | + TextField, objectName='passwordInput') |
1080 | |
1081 | === added file 'ubuntu_system_tests/helpers/unity8/indicators.py' |
1082 | --- ubuntu_system_tests/helpers/unity8/indicators.py 1970-01-01 00:00:00 +0000 |
1083 | +++ ubuntu_system_tests/helpers/unity8/indicators.py 2016-06-10 02:06:42 +0000 |
1084 | @@ -0,0 +1,179 @@ |
1085 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1086 | + |
1087 | +# |
1088 | +# Ubuntu System Tests |
1089 | +# Copyright (C) 2016 Canonical |
1090 | +# |
1091 | +# This program is free software: you can redistribute it and/or modify |
1092 | +# it under the terms of the GNU General Public License as published by |
1093 | +# the Free Software Foundation, either version 3 of the License, or |
1094 | +# (at your option) any later version. |
1095 | +# |
1096 | +# This program is distributed in the hope that it will be useful, |
1097 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1098 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1099 | +# GNU General Public License for more details. |
1100 | +# |
1101 | +# You should have received a copy of the GNU General Public License |
1102 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1103 | +# |
1104 | + |
1105 | +from autopilot import introspection |
1106 | +from ubuntuuitoolkit import ( |
1107 | + UbuntuUIToolkitCustomProxyObjectBase, CheckBox, QQuickFlickable) |
1108 | + |
1109 | + |
1110 | +class IndicatorPage(UbuntuUIToolkitCustomProxyObjectBase): |
1111 | + |
1112 | + """Autopilot helper for the IndicatorPage component.""" |
1113 | + |
1114 | + # XXX Because of https://bugs.launchpad.net/autopilot-qt/+bug/1341671 |
1115 | + # we need to make sure it does not match in any selection. |
1116 | + # --elopio - 2015-01-20 |
1117 | + |
1118 | + @classmethod |
1119 | + def validate_dbus_object(cls, path, state): |
1120 | + return False |
1121 | + |
1122 | + |
1123 | +class Indicator(): |
1124 | + |
1125 | + def __init__(self, main_window, name): |
1126 | + self._main_window = main_window |
1127 | + self._name = name |
1128 | + |
1129 | + def is_indicator_icon_visible(self): |
1130 | + panel_item = self._main_window.wait_select_single( |
1131 | + objectName=self._name+'-panelItem') |
1132 | + return panel_item.indicatorVisible |
1133 | + |
1134 | + def open(self): |
1135 | + """Open the indicator page. |
1136 | + |
1137 | + :return: The custom proxy object for the indicator page. |
1138 | + |
1139 | + """ |
1140 | + if self.is_indicator_icon_visible(): |
1141 | + return self._main_window.open_indicator_page(self._name) |
1142 | + else: |
1143 | + return self._open_indicator_with_icon_not_visible() |
1144 | + |
1145 | + def _open_indicator_with_icon_not_visible(self): |
1146 | + # Open any displayed indicator. |
1147 | + self._main_window.open_indicator_page('indicator-datetime') |
1148 | + self._make_indicator_icon_visible() |
1149 | + indicator_rotation_icon = self._main_window.select_single( |
1150 | + objectName=self._name+'-panelItem') |
1151 | + self._main_window.pointing_device.click_object(indicator_rotation_icon) |
1152 | + return self._main_window.wait_select_single( |
1153 | + objectName=self._name+'-page') |
1154 | + |
1155 | + def _make_indicator_icon_visible(self): |
1156 | + indicators_bar = self._main_window.select_single('IndicatorsBar') |
1157 | + indicators_bar_flickable = indicators_bar.select_single( |
1158 | + QQuickFlickable, objectName='flickable') |
1159 | + self._swipe_flickable_to_x_end(indicators_bar_flickable) |
1160 | + |
1161 | + def _swipe_flickable_to_x_end(self, flickable): |
1162 | + # XXX this should be implemented as a general horizontal swiping in |
1163 | + # the toolkit custom proxy object. -- elopio - 2015-01-20 |
1164 | + if not flickable.atXEnd: |
1165 | + flickable.interactive.wait_for(True) |
1166 | + while not flickable.atXEnd: |
1167 | + start_y = stop_y = ( |
1168 | + flickable.globalRect.y + |
1169 | + (flickable.globalRect.height // 2)) |
1170 | + # We can't start the swipe from the border because it would |
1171 | + # open the launcher |
1172 | + start_x = flickable.globalRect.x + 45 |
1173 | + stop_x = ( |
1174 | + flickable.globalRect.x + flickable.globalRect.width - 5) |
1175 | + flickable.pointing_device.drag( |
1176 | + start_x, start_y, stop_x, stop_y) |
1177 | + flickable.dragging.wait_for(False) |
1178 | + flickable.moving.wait_for(False) |
1179 | + |
1180 | + def close(self): |
1181 | + """Close the indicator page.""" |
1182 | + self._main_window.close_indicator_page() |
1183 | + |
1184 | + |
1185 | +class DisplayIndicator(Indicator): |
1186 | + |
1187 | + def __init__(self, main_window): |
1188 | + super(DisplayIndicator, self).__init__(main_window, |
1189 | + 'indicator-rotation-lock') |
1190 | + self._main_window = main_window |
1191 | + |
1192 | + |
1193 | +class DisplayIndicatorPage(IndicatorPage): |
1194 | + |
1195 | + """Autopilot helper for the display indicator page.""" |
1196 | + |
1197 | + @classmethod |
1198 | + def validate_dbus_object(cls, path, state): |
1199 | + name = introspection.get_classname_from_path(path) |
1200 | + if name == b'IndicatorPage': |
1201 | + if state['objectName'][1] == 'indicator-rotation-lock-page': |
1202 | + return True |
1203 | + return False |
1204 | + |
1205 | + def lock_rotation(self): |
1206 | + """Toggle the rotation lock indicator to locked.""" |
1207 | + switcher = self._get_switcher() |
1208 | + switcher.check() |
1209 | + switcher.checked.wait_for(True) |
1210 | + |
1211 | + def _get_switcher(self): |
1212 | + return self.select_single( |
1213 | + CheckBox, objectName='switcher') |
1214 | + |
1215 | + def unlock_rotation(self): |
1216 | + """Toggle the rotation lock indicator to unlocked.""" |
1217 | + switcher = self._get_switcher() |
1218 | + switcher.uncheck() |
1219 | + switcher.checked.wait_for(False) |
1220 | + |
1221 | + |
1222 | +class TestIndicator(Indicator): |
1223 | + |
1224 | + def __init__(self, main_window): |
1225 | + super(TestIndicator, self).__init__(main_window, 'indicator-mock') |
1226 | + self._main_window = main_window |
1227 | + |
1228 | + |
1229 | +class Slider(UbuntuUIToolkitCustomProxyObjectBase): |
1230 | + """Autopilot helper for the Slider component.""" |
1231 | + |
1232 | + # XXX Because of https://bugs.launchpad.net/autopilot-qt/+bug/1341671 |
1233 | + # we need to make sure it does not match in any selection. |
1234 | + # --elopio - 2015-01-20 |
1235 | + |
1236 | + @classmethod |
1237 | + def validate_dbus_object(cls, path, state): |
1238 | + name = introspection.get_classname_from_path(path) |
1239 | + if name == b'Slider': |
1240 | + return True |
1241 | + return False |
1242 | + |
1243 | + def slide_left(self, timeout=10): |
1244 | + x, y, width, height = self.globalRect |
1245 | + |
1246 | + rate = 5 |
1247 | + start_x = x + width/2 |
1248 | + start_y = stop_y = y + height/2 |
1249 | + stop_x = x |
1250 | + |
1251 | + self.pointing_device.drag(start_x, start_y, stop_x, stop_y, rate) |
1252 | + self.value.wait_for(self.minimumValue, timeout) |
1253 | + |
1254 | + def slide_right(self, timeout=10): |
1255 | + x, y, width, height = self.globalRect |
1256 | + |
1257 | + rate = 5 |
1258 | + start_x = x + width/2 |
1259 | + start_y = stop_y = y + height/2 |
1260 | + stop_x = x + width |
1261 | + |
1262 | + self.pointing_device.drag(start_x, start_y, stop_x, stop_y, rate) |
1263 | + self.value.wait_for(self.maximumValue, timeout) |
1264 | |
1265 | === added file 'ubuntu_system_tests/helpers/unity8/launcher.py' |
1266 | --- ubuntu_system_tests/helpers/unity8/launcher.py 1970-01-01 00:00:00 +0000 |
1267 | +++ ubuntu_system_tests/helpers/unity8/launcher.py 2016-06-10 02:06:42 +0000 |
1268 | @@ -0,0 +1,66 @@ |
1269 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1270 | + |
1271 | +# |
1272 | +# Ubuntu System Tests |
1273 | +# Copyright (C) 2016 Canonical |
1274 | +# |
1275 | +# This program is free software: you can redistribute it and/or modify |
1276 | +# it under the terms of the GNU General Public License as published by |
1277 | +# the Free Software Foundation, either version 3 of the License, or |
1278 | +# (at your option) any later version. |
1279 | +# |
1280 | +# This program is distributed in the hope that it will be useful, |
1281 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1282 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1283 | +# GNU General Public License for more details. |
1284 | +# |
1285 | +# You should have received a copy of the GNU General Public License |
1286 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1287 | +# |
1288 | + |
1289 | +import logging |
1290 | + |
1291 | +import autopilot.logging |
1292 | +import ubuntuuitoolkit |
1293 | + |
1294 | +from ubuntu_system_tests.helpers import unity8 |
1295 | + |
1296 | +logger = logging.getLogger(__name__) |
1297 | + |
1298 | + |
1299 | +class Launcher(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
1300 | + |
1301 | + """A helper that understands the Launcher.""" |
1302 | + |
1303 | + @autopilot.logging.log_action(logger.debug) |
1304 | + def show(self): |
1305 | + """Show the launcher swiping it to the right.""" |
1306 | + if not self.shown: |
1307 | + self._swipe_to_show_launcher() |
1308 | + self.shown.wait_for(True) |
1309 | + else: |
1310 | + logger.debug('The launcher is already opened.') |
1311 | + |
1312 | + def _swipe_to_show_launcher(self): |
1313 | + view = self.get_root_instance().select_single('ShellView') |
1314 | + start_y = stop_y = view.y + view.height // 2 |
1315 | + |
1316 | + start_x = view.x + 1 |
1317 | + stop_x = start_x + self.panelWidth - 1 |
1318 | + |
1319 | + self.pointing_device.drag(start_x, start_y, stop_x, stop_y) |
1320 | + |
1321 | + @autopilot.logging.log_action(logger.debug) |
1322 | + def click_dash_icon(self): |
1323 | + if self.shown: |
1324 | + dash_icon = self.select_single( |
1325 | + 'QQuickImage', objectName='dashItem') |
1326 | + self.pointing_device.click_object(dash_icon) |
1327 | + else: |
1328 | + raise unity8.UnityException('The launcher is closed.') |
1329 | + |
1330 | + @autopilot.logging.log_action(logger.debug) |
1331 | + def click_application_launcher_icon(self, application_name): |
1332 | + launcher_delegate = self.select_single( |
1333 | + 'LauncherDelegate', appId=application_name) |
1334 | + self.pointing_device.click_object(launcher_delegate) |
1335 | |
1336 | === modified file 'ubuntu_system_tests/helpers/unity8/phone_stage.py' |
1337 | --- ubuntu_system_tests/helpers/unity8/phone_stage.py 2016-04-27 21:43:27 +0000 |
1338 | +++ ubuntu_system_tests/helpers/unity8/phone_stage.py 2016-06-10 02:06:42 +0000 |
1339 | @@ -20,7 +20,7 @@ |
1340 | |
1341 | import logging |
1342 | |
1343 | -from autopilot import logging as autopilot_logging |
1344 | +import autopilot |
1345 | from autopilot.exceptions import StateNotFoundError |
1346 | from ubuntuuitoolkit import UbuntuUIToolkitCustomProxyObjectBase |
1347 | from ubuntu_system_tests.helpers.autopilot import validate_dbus_object |
1348 | @@ -80,14 +80,14 @@ |
1349 | mid_x = x + ((next_x - x) // 4) |
1350 | return mid_x, mid_y |
1351 | |
1352 | - @autopilot_logging.log_action(logger.info) |
1353 | + @autopilot.logging.log_action(logger.info) |
1354 | def _press_app(self, app_window): |
1355 | """Press on the required app_window object.""" |
1356 | x, y = self._get_app_window_touch_point(app_window) |
1357 | self.pointing_device.move(x, y) |
1358 | self.pointing_device.click() |
1359 | |
1360 | - @autopilot_logging.log_action(logger.info) |
1361 | + @autopilot.logging.log_action(logger.info) |
1362 | def _swipe_from_app_to_right_edge(self, app_window): |
1363 | """Swipe from the required app_window object to right screen edge.""" |
1364 | start_x, start_y = self._get_app_window_touch_point(app_window) |
1365 | @@ -95,7 +95,7 @@ |
1366 | end_y = start_y |
1367 | self.pointing_device.drag(start_x, start_y, end_x, end_y, rate=3) |
1368 | |
1369 | - @autopilot_logging.log_action(logger.info) |
1370 | + @autopilot.logging.log_action(logger.info) |
1371 | def _swipe_from_app_to_top_edge(self, app_window): |
1372 | """Swipe from the required app_window object to top screen edge.""" |
1373 | start_x, start_y = self._get_app_window_touch_point(app_window) |
1374 | @@ -103,7 +103,7 @@ |
1375 | end_y = 0 |
1376 | self.pointing_device.drag(start_x, start_y, end_x, end_y) |
1377 | |
1378 | - @autopilot_logging.log_action(logger.info) |
1379 | + @autopilot.logging.log_action(logger.info) |
1380 | def _swipe_from_right(self): |
1381 | """Swipe from right edge to reveal the application switcher""" |
1382 | width = self.width |
1383 | |
1384 | === modified file 'ubuntu_system_tests/helpers/unity8/sensors.py' |
1385 | --- ubuntu_system_tests/helpers/unity8/sensors.py 2016-04-25 19:02:31 +0000 |
1386 | +++ ubuntu_system_tests/helpers/unity8/sensors.py 2016-06-10 02:06:42 +0000 |
1387 | @@ -18,12 +18,95 @@ |
1388 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
1389 | # |
1390 | |
1391 | +import logging |
1392 | import os |
1393 | import stat |
1394 | |
1395 | from ubuntu_system_tests.helpers import context |
1396 | from ubuntu_system_tests.helpers import wait_until |
1397 | from ubuntu_system_tests.helpers.testbed import write_to_file_with_sudo |
1398 | +from ubuntu_system_tests.helpers import unity8 |
1399 | + |
1400 | +logger = logging.getLogger(__name__) |
1401 | + |
1402 | + |
1403 | +class FakePlatformSensors: |
1404 | + |
1405 | + def __init__(self, pid=None): |
1406 | + self.pid = pid or unity8.get_unity_pid() |
1407 | + |
1408 | + def _set_orientation_top_up(self): |
1409 | + with open("/tmp/sensor-fifo-{0}".format(self.pid), "w") as fifo: |
1410 | + fifo.write("70 accel -10.050858 -0.598550 0.756568\n") |
1411 | + fifo.write("70 accel -9.797073 -0.555455 1.019930\n") |
1412 | + fifo.write("70 accel -10.141838 -0.770933 0.632069\n") |
1413 | + fifo.write("70 accel -12.057199 -1.259350 1.690306\n") |
1414 | + fifo.write("70 accel -19.282900 -3.926491 3.098097\n") |
1415 | + fifo.write("70 accel -14.480132 -14.269443 1.216254\n") |
1416 | + fifo.write("70 accel 16.419436 4.242526 -7.714118\n") |
1417 | + fifo.write("70 accel 5.583278 8.279149 -1.848324\n") |
1418 | + fifo.write("70 accel 1.422156 8.547300 0.416591\n") |
1419 | + fifo.write("70 accel 4.357447 9.988609 -0.110133\n") |
1420 | + fifo.write("70 accel 0.699107 9.840169 0.756568\n") |
1421 | + fifo.write("70 accel 1.364695 9.844957 -0.287304\n") |
1422 | + fifo.flush() |
1423 | + |
1424 | + def _set_orientation_top_down(self): |
1425 | + with open("/tmp/sensor-fifo-{0}".format(self.pid), "w") as fifo: |
1426 | + fifo.write("70 accel -10.050858 -0.598550 0.756568\n") |
1427 | + fifo.write("70 accel 9.538500 -0.603339 1.292869\n") |
1428 | + fifo.write("70 accel 9.485827 -0.636858 1.422156\n") |
1429 | + fifo.write("70 accel 9.677363 -0.402226 1.374272\n") |
1430 | + fifo.write("70 accel 9.303867 -0.507571 1.283292\n") |
1431 | + fifo.write("70 accel 8.604761 -1.015141 1.436521\n") |
1432 | + fifo.write("70 accel 7.580042 -2.001553 0.521936\n") |
1433 | + fifo.write("70 accel 7.503428 -4.247314 0.502782\n") |
1434 | + fifo.write("70 accel 7.067683 -7.240066 0.842759\n") |
1435 | + fifo.write("70 accel 6.488286 -9.873688 -0.541090\n") |
1436 | + fifo.write("70 accel 6.229713 -9.241618 -1.048660\n") |
1437 | + fifo.write("70 accel 4.046201 -9.198523 -0.057461\n") |
1438 | + fifo.write("70 accel 2.398990 -9.629479 0.957681\n") |
1439 | + fifo.write("70 accel 1.632846 -9.361329 -0.311246\n") |
1440 | + fifo.write("70 accel -0.181959 -9.696517 -0.301669\n") |
1441 | + fifo.flush() |
1442 | + |
1443 | + def _set_orientation_left_up(self): |
1444 | + with open("/tmp/sensor-fifo-{0}".format(self.pid), "w") as fifo: |
1445 | + fifo.write("70 accel -10.050858 -0.598550 0.756568\n") |
1446 | + fifo.write("70 accel 0.196325 9.878476 0.948104\n") |
1447 | + fifo.write("70 accel 0.258574 9.955091 1.091756\n") |
1448 | + fifo.write("70 accel 0.287304 10.041282 1.134852\n") |
1449 | + fifo.write("70 accel 1.537078 10.553641 1.561020\n") |
1450 | + fifo.write("70 accel 8.130709 10.093954 2.561796\n") |
1451 | + fifo.write("70 accel -0.229843 5.348647 1.723825\n") |
1452 | + fifo.write("70 accel -9.916783 0.488417 -3.418920\n") |
1453 | + fifo.write("70 accel -13.417107 -0.416591 -2.360683\n") |
1454 | + fifo.write("70 accel -13.872005 -2.049437 -0.574608\n") |
1455 | + fifo.flush() |
1456 | + |
1457 | + def _set_orientation_right_up(self): |
1458 | + with open("/tmp/sensor-fifo-{0}".format(self.pid), "w") as fifo: |
1459 | + fifo.write("70 accel -10.050858 -0.598550 0.756568\n") |
1460 | + fifo.write("70 accel -4.550858 -0.598550 0.856568\n") |
1461 | + fifo.write("70 accel -0.799663 9.988609 1.197101\n") |
1462 | + fifo.write("70 accel -0.861913 9.864111 1.066701\n") |
1463 | + fifo.write("70 accel -0.861913 9.864111 0.866701\n") |
1464 | + fifo.write("70 accel -1.776498 9.830592 1.273715\n") |
1465 | + fifo.write("70 accel -2.376498 9.830592 1.273715\n") |
1466 | + fifo.write("70 accel -13.158532 2.217031 1.091756\n") |
1467 | + fifo.write("70 accel 5.056554 1.067814 0.799663\n") |
1468 | + fifo.write("70 accel 5.056554 1.767814 0.799663\n") |
1469 | + fifo.write("70 accel 14.882358 2.896984 1.221043\n") |
1470 | + fifo.write("70 accel 9.466674 -0.363919 -1.029507\n") |
1471 | + fifo.write("70 accel 11.253524 -0.186748 -0.311246\n") |
1472 | + fifo.write("70 accel 12.253524 -0.186748 -0.311246\n") |
1473 | + fifo.flush() |
1474 | + |
1475 | + def set_orientation(self, action): |
1476 | + try: |
1477 | + getattr(self, '_set_orientation_{}'.format(action))() |
1478 | + except AttributeError: |
1479 | + logger.error('Action {} not defined'.format(action)) |
1480 | |
1481 | |
1482 | def get_unity8_fifo_path(): |
1483 | |
1484 | === added directory 'ubuntu_system_tests/helpers/unity8/shell' |
1485 | === removed file 'ubuntu_system_tests/helpers/unity8/shell.py' |
1486 | --- ubuntu_system_tests/helpers/unity8/shell.py 2016-06-02 09:12:43 +0000 |
1487 | +++ ubuntu_system_tests/helpers/unity8/shell.py 1970-01-01 00:00:00 +0000 |
1488 | @@ -1,169 +0,0 @@ |
1489 | -# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1490 | - |
1491 | -# |
1492 | -# Ubuntu System Tests |
1493 | -# Copyright (C) 2015, 2016 Canonical |
1494 | -# |
1495 | -# This program is free software: you can redistribute it and/or modify |
1496 | -# it under the terms of the GNU General Public License as published by |
1497 | -# the Free Software Foundation, either version 3 of the License, or |
1498 | -# (at your option) any later version. |
1499 | -# |
1500 | -# This program is distributed in the hope that it will be useful, |
1501 | -# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1502 | -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1503 | -# GNU General Public License for more details. |
1504 | -# |
1505 | -# You should have received a copy of the GNU General Public License |
1506 | -# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1507 | -# |
1508 | - |
1509 | -import logging |
1510 | - |
1511 | -from autopilot import ( |
1512 | - exceptions, |
1513 | - logging as autopilot_logging |
1514 | -) |
1515 | -import ubuntuuitoolkit |
1516 | -from unity8.shell.emulators import main_window |
1517 | - |
1518 | -from ubuntu_system_tests.helpers.autopilot import validate_dbus_object |
1519 | -from ubuntu_system_tests.helpers.indicators.message import NotificationsIndicatorPage, NotificationsIndicatorItem # NOQA |
1520 | -from ubuntu_system_tests.helpers.notifications.utils import Notifications |
1521 | -from ubuntu_system_tests.helpers.unity8 import ( |
1522 | - greeter as greeter_helpers, UNITY8_PATH_ROOT) |
1523 | - |
1524 | -logger = logging.getLogger(__name__) |
1525 | - |
1526 | - |
1527 | -class Unity8(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
1528 | - |
1529 | - """Autopilot custom proxy object for the Unity8 shell.""" |
1530 | - |
1531 | - @classmethod |
1532 | - def validate_dbus_object(cls, path, state): |
1533 | - return validate_dbus_object( |
1534 | - path, state, UNITY8_PATH_ROOT, UNITY8_PATH_ROOT, |
1535 | - applicationName='unity8') |
1536 | - |
1537 | - @property |
1538 | - def main_window(self): |
1539 | - return self.select_single(ShellView) |
1540 | - |
1541 | - @autopilot_logging.log_action(logger.debug) |
1542 | - def wait_for_greeter_content(self): |
1543 | - greeter = self.main_window.wait_select_single(objectName='greeter') |
1544 | - greeter.waiting.wait_for(False) |
1545 | - |
1546 | - @autopilot_logging.log_action(logger.info) |
1547 | - def unlock(self): |
1548 | - greeter = self.main_window.get_greeter() |
1549 | - if greeter.created: |
1550 | - greeter_helpers.hide_greeter_with_dbus() |
1551 | - greeter.created.wait_for(False) |
1552 | - |
1553 | - def show_dash_from_launcher(self): |
1554 | - self.main_window.show_dash_from_launcher() |
1555 | - |
1556 | - def get_number_of_sessions(self): |
1557 | - application_window = self.select_single('ApplicationWindow') |
1558 | - return len(application_window.select_many('SessionContainer')) |
1559 | - |
1560 | - def get_height(self): |
1561 | - return self.main_window.height |
1562 | - |
1563 | - def get_width(self): |
1564 | - return self.main_window.width |
1565 | - |
1566 | - def ensure_app_loaded(self): |
1567 | - try: |
1568 | - indicator = self.select_single('ActivityIndicator') |
1569 | - indicator.onScreen.wait_for(False) |
1570 | - except exceptions.StateNotFoundError: |
1571 | - # This is fine, it's already loaded |
1572 | - pass |
1573 | - |
1574 | - |
1575 | -class ShellView(main_window.ShellView): |
1576 | - """Class to extend Unity8 main window ShellView.""" |
1577 | - |
1578 | - @classmethod |
1579 | - def validate_dbus_object(cls, path, state): |
1580 | - return validate_dbus_object( |
1581 | - path, state, UNITY8_PATH_ROOT, b'ShellView', title='Unity8') |
1582 | - |
1583 | - def get_notifications_list(self): |
1584 | - """Return a list of notifications currently being displayed.""" |
1585 | - return self.select_single( |
1586 | - Notifications, objectName='notificationList') |
1587 | - |
1588 | - def get_notifications_panel(self): |
1589 | - """Return 'Notifications' panel object.""" |
1590 | - return self._get_indicator_panel_item('indicator-messages') |
1591 | - |
1592 | - def clear_notifications(self): |
1593 | - """ |
1594 | - Clear all existing notifications from 'Notifications' indicator. |
1595 | - |
1596 | - """ |
1597 | - if self.is_new_notification_displayed(): |
1598 | - self.open_indicator_page('indicator-messages').clear_all() |
1599 | - self.close_indicator_page() |
1600 | - |
1601 | - def open_notifications_indicator(self): |
1602 | - """Swipe down to display the notifications indicator.""" |
1603 | - return self.open_indicator_page('indicator-messages') |
1604 | - |
1605 | - def is_new_notification_displayed(self): |
1606 | - """Return True if new notification message icon is displayed.""" |
1607 | - return self.get_notifications_panel().is_new_message_displayed() |
1608 | - |
1609 | - def get_passphrase_unlock_screen(self): |
1610 | - """Wait for input method to be in shown state and return lockscreen.""" |
1611 | - from ubuntu_system_tests.helpers.unity8 import lock_screen |
1612 | - input_method = self.wait_select_single( |
1613 | - 'InputMethod', objectName='inputMethod', visible=True) |
1614 | - input_method.state.wait_for('shown') |
1615 | - return self.select_single(lock_screen.PassphraseLockscreen) |
1616 | - |
1617 | - def get_missed_call_snap_decision(self): |
1618 | - """Return missed call snap decision menu.""" |
1619 | - from ubuntu_system_tests.helpers.snap_decision import missed_call |
1620 | - return self.select_single( |
1621 | - missed_call.SnapDecisionMenu, objectName='snapDecision', |
1622 | - visible=True) |
1623 | - |
1624 | - def get_phone_stage(self): |
1625 | - from ubuntu_system_tests.helpers.unity8 import phone_stage |
1626 | - return self.select_single(phone_stage.PhoneStage, objectName='stage') |
1627 | - |
1628 | - def swipe_to_show_app_switcher(self): |
1629 | - """Swipe from right edge to reveal task switcher.""" |
1630 | - stage = self.get_phone_stage() |
1631 | - stage.swipe_to_top() |
1632 | - return stage |
1633 | - |
1634 | - def get_current_focused_app(self): |
1635 | - """Return Id for current focused app.""" |
1636 | - return self.select_single('Shell').focusedApplicationId |
1637 | - |
1638 | - def _is_indicator_panel_opened(self): |
1639 | - indicator_page = self.wait_select_single('IndicatorsMenu') |
1640 | - return indicator_page.fullyOpened |
1641 | - |
1642 | - def close_indicator_page(self): |
1643 | - """ |
1644 | - Override the method to only try to close the indicator panel if its |
1645 | - not already. |
1646 | - """ |
1647 | - if self._is_indicator_panel_opened(): |
1648 | - super().close_indicator_page() |
1649 | - |
1650 | - def is_indicator_item_hidden(self, indicator_name): |
1651 | - """ |
1652 | - Return bool representing if the requested indicator item is hidden or |
1653 | - not. |
1654 | - """ |
1655 | - item = self.select_single('IndicatorItem', |
1656 | - objectName=indicator_name + '-panelItem') |
1657 | - return item.hidden |
1658 | |
1659 | === added file 'ubuntu_system_tests/helpers/unity8/shell/__init__.py' |
1660 | --- ubuntu_system_tests/helpers/unity8/shell/__init__.py 1970-01-01 00:00:00 +0000 |
1661 | +++ ubuntu_system_tests/helpers/unity8/shell/__init__.py 2016-06-10 02:06:42 +0000 |
1662 | @@ -0,0 +1,31 @@ |
1663 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1664 | + |
1665 | +# |
1666 | +# Ubuntu System Tests |
1667 | +# Copyright (C) 2016 Canonical |
1668 | +# |
1669 | +# This program is free software: you can redistribute it and/or modify |
1670 | +# it under the terms of the GNU General Public License as published by |
1671 | +# the Free Software Foundation, either version 3 of the License, or |
1672 | +# (at your option) any later version. |
1673 | +# |
1674 | +# This program is distributed in the hope that it will be useful, |
1675 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1676 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1677 | +# GNU General Public License for more details. |
1678 | +# |
1679 | +# You should have received a copy of the GNU General Public License |
1680 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1681 | +# |
1682 | + |
1683 | +"""unity shell autopilot tests and helpers - sub level package.""" |
1684 | + |
1685 | +from ubuntu_system_tests.helpers.unity8.shell.utils import ( |
1686 | + disable_qml_mocking, |
1687 | + create_ephemeral_notification, |
1688 | +) |
1689 | + |
1690 | +__all__ = [ |
1691 | + 'disable_qml_mocking', |
1692 | + 'create_ephemeral_notification', |
1693 | +] |
1694 | |
1695 | === added file 'ubuntu_system_tests/helpers/unity8/shell/_cpo.py' |
1696 | --- ubuntu_system_tests/helpers/unity8/shell/_cpo.py 1970-01-01 00:00:00 +0000 |
1697 | +++ ubuntu_system_tests/helpers/unity8/shell/_cpo.py 2016-06-10 02:06:42 +0000 |
1698 | @@ -0,0 +1,319 @@ |
1699 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
1700 | + |
1701 | +# |
1702 | +# Ubuntu System Tests |
1703 | +# Copyright (C) 2016 Canonical |
1704 | +# |
1705 | +# This program is free software: you can redistribute it and/or modify |
1706 | +# it under the terms of the GNU General Public License as published by |
1707 | +# the Free Software Foundation, either version 3 of the License, or |
1708 | +# (at your option) any later version. |
1709 | +# |
1710 | +# This program is distributed in the hope that it will be useful, |
1711 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
1712 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
1713 | +# GNU General Public License for more details. |
1714 | +# |
1715 | +# You should have received a copy of the GNU General Public License |
1716 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
1717 | +# |
1718 | + |
1719 | +import logging |
1720 | +import autopilot |
1721 | +from autopilot import ( |
1722 | + exceptions, |
1723 | + input |
1724 | +) |
1725 | +import ubuntuuitoolkit |
1726 | + |
1727 | +from ubuntu_system_tests.helpers.autopilot import validate_dbus_object |
1728 | +from ubuntu_system_tests.helpers.notifications.utils import Notifications |
1729 | +from ubuntu_system_tests.helpers.unity8 import ( |
1730 | + greeter as greeter_helpers, launcher as launcher_helpers, UNITY8_PATH_ROOT) |
1731 | + |
1732 | +logger = logging.getLogger(__name__) |
1733 | + |
1734 | + |
1735 | +class Unity8(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
1736 | + """Autopilot custom proxy object for the Unity8 shell.""" |
1737 | + |
1738 | + @classmethod |
1739 | + def validate_dbus_object(cls, path, state): |
1740 | + return validate_dbus_object( |
1741 | + path, state, UNITY8_PATH_ROOT, UNITY8_PATH_ROOT, |
1742 | + applicationName='unity8') |
1743 | + |
1744 | + @property |
1745 | + def main_window(self): |
1746 | + return self.select_single(ShellView) |
1747 | + |
1748 | + @autopilot.logging.log_action(logger.debug) |
1749 | + def wait_for_greeter_content(self): |
1750 | + greeter = self.main_window.wait_select_single(objectName='greeter') |
1751 | + greeter.waiting.wait_for(False) |
1752 | + |
1753 | + @autopilot.logging.log_action(logger.info) |
1754 | + def unlock(self): |
1755 | + greeter = self.main_window.get_greeter() |
1756 | + if greeter.created: |
1757 | + greeter_helpers.hide_greeter_with_dbus() |
1758 | + greeter.created.wait_for(False) |
1759 | + |
1760 | + def show_dash_from_launcher(self): |
1761 | + self.main_window.show_dash_from_launcher() |
1762 | + |
1763 | + def get_number_of_sessions(self): |
1764 | + application_window = self.select_single('ApplicationWindow') |
1765 | + return len(application_window.select_many('SessionContainer')) |
1766 | + |
1767 | + def get_height(self): |
1768 | + return self.main_window.height |
1769 | + |
1770 | + def get_width(self): |
1771 | + return self.main_window.width |
1772 | + |
1773 | + def ensure_app_loaded(self): |
1774 | + try: |
1775 | + indicator = self.select_single('ActivityIndicator') |
1776 | + indicator.onScreen.wait_for(False) |
1777 | + except exceptions.StateNotFoundError: |
1778 | + # This is fine, it's already loaded |
1779 | + pass |
1780 | + |
1781 | + |
1782 | +class ShellView(ubuntuuitoolkit.UbuntuUIToolkitCustomProxyObjectBase): |
1783 | + """An helper class that makes it easy to interact with the shell""" |
1784 | + |
1785 | + @classmethod |
1786 | + def validate_dbus_object(cls, path, state): |
1787 | + return validate_dbus_object( |
1788 | + path, state, UNITY8_PATH_ROOT, b'ShellView', title='Unity8') |
1789 | + |
1790 | + def get_notifications_list(self): |
1791 | + """Return a list of notifications currently being displayed.""" |
1792 | + return self.select_single( |
1793 | + Notifications, objectName='notificationList') |
1794 | + |
1795 | + def get_notifications_panel(self): |
1796 | + """Return 'Notifications' panel object.""" |
1797 | + return self._get_indicator_panel_item('indicator-messages') |
1798 | + |
1799 | + def clear_notifications(self): |
1800 | + """ |
1801 | + Clear all existing notifications from 'Notifications' indicator. |
1802 | + |
1803 | + """ |
1804 | + if self.is_new_notification_displayed(): |
1805 | + self.open_indicator_page('indicator-messages').clear_all() |
1806 | + self.close_indicator_page() |
1807 | + |
1808 | + def open_notifications_indicator(self): |
1809 | + """Swipe down to display the notifications indicator.""" |
1810 | + return self.open_indicator_page('indicator-messages') |
1811 | + |
1812 | + def is_new_notification_displayed(self): |
1813 | + """Return True if new notification message icon is displayed.""" |
1814 | + return self.get_notifications_panel().is_new_message_displayed() |
1815 | + |
1816 | + def get_passphrase_unlock_screen(self): |
1817 | + """Wait for input method to be in shown state and return lockscreen.""" |
1818 | + from ubuntu_system_tests.helpers.unity8 import lock_screen |
1819 | + input_method = self.wait_select_single( |
1820 | + 'InputMethod', objectName='inputMethod', visible=True) |
1821 | + input_method.state.wait_for('shown') |
1822 | + return self.select_single(lock_screen.PassphraseLockscreen) |
1823 | + |
1824 | + def get_missed_call_snap_decision(self): |
1825 | + """Return missed call snap decision menu.""" |
1826 | + from ubuntu_system_tests.helpers.snap_decision import missed_call |
1827 | + return self.select_single( |
1828 | + missed_call.SnapDecisionMenu, objectName='snapDecision', |
1829 | + visible=True) |
1830 | + |
1831 | + def get_phone_stage(self): |
1832 | + from ubuntu_system_tests.helpers.unity8 import phone_stage |
1833 | + return self.select_single(phone_stage.PhoneStage, objectName='stage') |
1834 | + |
1835 | + def swipe_to_show_app_switcher(self): |
1836 | + """Swipe from right edge to reveal task switcher.""" |
1837 | + stage = self.get_phone_stage() |
1838 | + stage.swipe_to_top() |
1839 | + return stage |
1840 | + |
1841 | + def _is_indicator_panel_opened(self): |
1842 | + indicator_page = self.wait_select_single('IndicatorsMenu') |
1843 | + return indicator_page.fullyOpened |
1844 | + |
1845 | + def is_indicator_item_hidden(self, indicator_name): |
1846 | + """ |
1847 | + Return bool representing if the requested indicator item is hidden or |
1848 | + not. |
1849 | + """ |
1850 | + item = self.select_single('IndicatorItem', |
1851 | + objectName=indicator_name + '-panelItem') |
1852 | + return item.hidden |
1853 | + |
1854 | + def get_greeter(self): |
1855 | + return self.select_single(greeter_helpers.Greeter) |
1856 | + |
1857 | + def get_login_loader(self): |
1858 | + return self.select_single("QQuickLoader", objectName="loginLoader") |
1859 | + |
1860 | + def get_login_list(self): |
1861 | + return self.select_single("LoginList") |
1862 | + |
1863 | + def get_bottombar(self): |
1864 | + return self.select_single("Bottombar") |
1865 | + |
1866 | + def get_pinPadLoader(self): |
1867 | + return self.select_single( |
1868 | + "QQuickLoader", |
1869 | + objectName="pinPadLoader" |
1870 | + ) |
1871 | + |
1872 | + def get_lockscreen(self): |
1873 | + return self.select_single("Lockscreen") |
1874 | + |
1875 | + def get_pinentryField(self): |
1876 | + return self.select_single(objectName="pinentryField") |
1877 | + |
1878 | + def _get_indicator_panel_item(self, indicator_name): |
1879 | + return self.select_single( |
1880 | + 'IndicatorItem', |
1881 | + objectName=indicator_name+'-panelItem' |
1882 | + ) |
1883 | + |
1884 | + def _get_indicator_page(self, indicator_name): |
1885 | + return self.select_single( |
1886 | + 'IndicatorPage', |
1887 | + objectName=indicator_name+'-page' |
1888 | + ) |
1889 | + |
1890 | + @autopilot.logging.log_action(logger.info) |
1891 | + def open_indicator_page(self, indicator_name): |
1892 | + """Swipe to open the indicator, wait until it's open. |
1893 | + :returns: The indicator page. |
1894 | + """ |
1895 | + widget = self._get_indicator_panel_item(indicator_name) |
1896 | + start_x, start_y = input.get_center_point(widget) |
1897 | + end_x = start_x |
1898 | + end_y = self.height |
1899 | + self.pointing_device.drag(start_x, start_y, end_x, end_y) |
1900 | + self.wait_select_single('IndicatorsMenu', fullyOpened=True) |
1901 | + return self._get_indicator_page(indicator_name) |
1902 | + |
1903 | + @autopilot.logging.log_action(logger.info) |
1904 | + def close_indicator_page(self): |
1905 | + """Swipe to close the opened indicator, wait until it's closed.""" |
1906 | + indicators_menu = self.wait_select_single('IndicatorsMenu') |
1907 | + end_x, end_y = input.get_center_point(indicators_menu) |
1908 | + start_x = end_x |
1909 | + start_y = self.height |
1910 | + self.pointing_device.drag(start_x, start_y, end_x, end_y) |
1911 | + indicators_menu.fullyClosed.wait_for(True) |
1912 | + |
1913 | + @autopilot.logging.log_action(logger.info) |
1914 | + def show_dash_swiping(self): |
1915 | + """Show the dash swiping from the left.""" |
1916 | + x, y, width, height = self._get_shell().globalRect |
1917 | + start_x = x |
1918 | + end_x = x + width |
1919 | + start_y = end_y = y + height // 2 |
1920 | + |
1921 | + self.pointing_device.drag(start_x, start_y, end_x, end_y) |
1922 | + self.get_current_focused_app_id().wait_for('unity8-dash') |
1923 | + |
1924 | + def _get_shell(self): |
1925 | + return self.select_single('Shell') |
1926 | + |
1927 | + def get_current_focused_app_id(self): |
1928 | + """Return the id of the focused application.""" |
1929 | + return self._get_shell().focusedApplicationId |
1930 | + |
1931 | + @autopilot.logging.log_action(logger.info) |
1932 | + def show_dash_from_launcher(self): |
1933 | + """Open the dash clicking the dash icon on the launcher.""" |
1934 | + launcher = self.open_launcher() |
1935 | + launcher.click_dash_icon() |
1936 | + self.get_current_focused_app_id().wait_for('unity8-dash') |
1937 | + launcher.shown.wait_for(False) |
1938 | + |
1939 | + @autopilot.logging.log_action(logger.info) |
1940 | + def open_launcher(self): |
1941 | + launcher = self._get_launcher() |
1942 | + launcher.show() |
1943 | + return launcher |
1944 | + |
1945 | + def _get_launcher(self): |
1946 | + return self.select_single(launcher_helpers.Launcher) |
1947 | + |
1948 | + def is_launcher_open(self): |
1949 | + return self._get_launcher().shown |
1950 | + |
1951 | + @autopilot.logging.log_action(logger.info) |
1952 | + def launch_application(self, application_name): |
1953 | + """Launch an application. |
1954 | + |
1955 | + :parameter application_name: The name of the application to launch. |
1956 | + |
1957 | + """ |
1958 | + launcher = self.open_launcher() |
1959 | + launcher.click_application_launcher_icon(application_name) |
1960 | + self.get_current_focused_app_id().wait_for(application_name) |
1961 | + launcher.shown.wait_for(False) |
1962 | + |
1963 | + def enter_pin_code(self, code): |
1964 | + """Enter code 'code' into the single-pin lightdm pincode entry screen. |
1965 | + |
1966 | + :param code: must be a string of numeric characters. |
1967 | + :raises: TypeError if code is not a string. |
1968 | + :raises: ValueError if code contains non-numeric characters. |
1969 | + |
1970 | + """ |
1971 | + if not isinstance(code, str): |
1972 | + raise TypeError( |
1973 | + "'code' parameter must be a string, not %r." |
1974 | + % type(code) |
1975 | + ) |
1976 | + for num in code: |
1977 | + if not num.isdigit(): |
1978 | + raise ValueError( |
1979 | + "'code' parameter contains non-numeric characters." |
1980 | + ) |
1981 | + self.pointing_device.click_object( |
1982 | + self._get_pinpad_button(int(num))) |
1983 | + |
1984 | + def _get_pinpad_button(self, button_id): |
1985 | + return self.select_single( |
1986 | + 'PinPadButton', |
1987 | + objectName='pinPadButton{}'.format(button_id) |
1988 | + ) |
1989 | + |
1990 | + def get_shell_orientation_angle(self): |
1991 | + return self._get_shell().orientationAngle |
1992 | + |
1993 | + def get_shell_orientation(self): |
1994 | + return self._get_shell().orientation |
1995 | + |
1996 | + def get_shell_primary_orientation(self): |
1997 | + return self._get_shell().primaryOrientation |
1998 | + |
1999 | + def get_shell_native_orientation(self): |
2000 | + return self._get_shell().nativeOrientation |
2001 | + |
2002 | + @autopilot.logging.log_action(logger.info) |
2003 | + def wait_for_notification(self): |
2004 | + """Wait for a notification dialog to appear. |
2005 | + |
2006 | + :return: An object for the notification dialog data. |
2007 | + :raise StateNotFoundError: if the timeout expires when the |
2008 | + notification has not appeared. |
2009 | + |
2010 | + """ |
2011 | + notify_list = self.select_single('Notifications', |
2012 | + objectName='notificationList') |
2013 | + visible_notification = notify_list.wait_select_single('Notification', |
2014 | + visible=True) |
2015 | + return {'summary': visible_notification.summary, |
2016 | + 'body': visible_notification.body, |
2017 | + 'iconSource': visible_notification.iconSource} |
2018 | |
2019 | === added file 'ubuntu_system_tests/helpers/unity8/shell/fixture_setup.py' |
2020 | --- ubuntu_system_tests/helpers/unity8/shell/fixture_setup.py 1970-01-01 00:00:00 +0000 |
2021 | +++ ubuntu_system_tests/helpers/unity8/shell/fixture_setup.py 2016-06-10 02:06:42 +0000 |
2022 | @@ -0,0 +1,90 @@ |
2023 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
2024 | +# |
2025 | +# Unity Autopilot Test Suite |
2026 | +# Copyright (C) 2014 - 2016 Canonical |
2027 | +# |
2028 | +# This program is free software: you can redistribute it and/or modify |
2029 | +# it under the terms of the GNU General Public License as published by |
2030 | +# the Free Software Foundation, either version 3 of the License, or |
2031 | +# (at your option) any later version. |
2032 | +# |
2033 | +# This program is distributed in the hope that it will be useful, |
2034 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
2035 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2036 | +# GNU General Public License for more details. |
2037 | +# |
2038 | +# You should have received a copy of the GNU General Public License |
2039 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
2040 | +# |
2041 | + |
2042 | +"""Set up and clean up fixtures for the Unity acceptance tests.""" |
2043 | + |
2044 | +import fixtures |
2045 | +import os |
2046 | +import subprocess |
2047 | +import sysconfig |
2048 | + |
2049 | +from ubuntu_system_tests.helpers import unity8 |
2050 | + |
2051 | + |
2052 | +class FakeScopes(fixtures.Fixture): |
2053 | + |
2054 | + def setUp(self): |
2055 | + super().setUp() |
2056 | + self.useFixture( |
2057 | + fixtures.EnvironmentVariable( |
2058 | + 'QML2_IMPORT_PATH', |
2059 | + newvalue=self._get_fake_scopes_library_path())) |
2060 | + |
2061 | + def _get_fake_scopes_library_path(self): |
2062 | + if unity8.running_installed_tests(): |
2063 | + mock_path = 'qml/scopefakes/' |
2064 | + else: |
2065 | + mock_path = os.path.join( |
2066 | + '../lib/', sysconfig.get_config_var('MULTIARCH'), |
2067 | + 'unity8/qml/scopefakes/') |
2068 | + lib_path = unity8.get_lib_path() |
2069 | + ld_library_path = os.path.abspath(os.path.join(lib_path, mock_path)) |
2070 | + |
2071 | + if not os.path.exists(ld_library_path): |
2072 | + raise RuntimeError( |
2073 | + 'Expected library path does not exists: %s.' % ( |
2074 | + ld_library_path)) |
2075 | + return ld_library_path |
2076 | + |
2077 | + |
2078 | +class Tutorial(fixtures.Fixture): |
2079 | + |
2080 | + def __init__(self, enable): |
2081 | + super().__init__() |
2082 | + self.enable = enable |
2083 | + |
2084 | + def setUp(self): |
2085 | + super().setUp() |
2086 | + original_state = self._is_tutorial_enabled() |
2087 | + if self.enable != original_state: |
2088 | + self.addCleanup(self._set_tutorial, original_state) |
2089 | + self._set_tutorial(self.enable) |
2090 | + |
2091 | + def _is_tutorial_enabled(self): |
2092 | + command = [ |
2093 | + 'dbus-send', '--system', '--print-reply', |
2094 | + '--dest=org.freedesktop.Accounts', |
2095 | + '/org/freedesktop/Accounts/User32011', |
2096 | + 'org.freedesktop.DBus.Properties.Get', |
2097 | + 'string:com.canonical.unity.AccountsService', |
2098 | + 'string:demo-edges' |
2099 | + ] |
2100 | + output = subprocess.check_output(command, universal_newlines=True) |
2101 | + return True if output.count('true') else False |
2102 | + |
2103 | + def _set_tutorial(self, value): |
2104 | + value_string = 'true' if value else 'false' |
2105 | + command = [ |
2106 | + 'dbus-send', '--system', '--print-reply', |
2107 | + '--dest=com.canonical.PropertyService', |
2108 | + '/com/canonical/PropertyService', |
2109 | + 'com.canonical.PropertyService.SetProperty', |
2110 | + 'string:edge', 'boolean:{}'.format(value_string) |
2111 | + ] |
2112 | + subprocess.check_output(command) |
2113 | |
2114 | === added file 'ubuntu_system_tests/helpers/unity8/shell/utils.py' |
2115 | --- ubuntu_system_tests/helpers/unity8/shell/utils.py 1970-01-01 00:00:00 +0000 |
2116 | +++ ubuntu_system_tests/helpers/unity8/shell/utils.py 2016-06-10 02:06:42 +0000 |
2117 | @@ -0,0 +1,82 @@ |
2118 | +# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*- |
2119 | + |
2120 | +# |
2121 | +# Ubuntu System Tests |
2122 | +# Copyright (C) 2016 Canonical |
2123 | +# |
2124 | +# This program is free software: you can redistribute it and/or modify |
2125 | +# it under the terms of the GNU General Public License as published by |
2126 | +# the Free Software Foundation, either version 3 of the License, or |
2127 | +# (at your option) any later version. |
2128 | +# |
2129 | +# This program is distributed in the hope that it will be useful, |
2130 | +# but WITHOUT ANY WARRANTY; without even the implied warranty of |
2131 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
2132 | +# GNU General Public License for more details. |
2133 | +# |
2134 | +# You should have received a copy of the GNU General Public License |
2135 | +# along with this program. If not, see <http://www.gnu.org/licenses/>. |
2136 | +# |
2137 | + |
2138 | +from functools import wraps |
2139 | +from gi.repository import Notify |
2140 | +import logging |
2141 | + |
2142 | +logger = logging.getLogger(__name__) |
2143 | + |
2144 | + |
2145 | +def disable_qml_mocking(fn): |
2146 | + """Simple decorator that disables the QML mocks from being loaded.""" |
2147 | + @wraps(fn) |
2148 | + def wrapper(*args, **kwargs): |
2149 | + tests_self = args[0] |
2150 | + tests_self._qml_mock_enabled = False |
2151 | + return fn(*args, **kwargs) |
2152 | + return wrapper |
2153 | + |
2154 | + |
2155 | +def create_ephemeral_notification( |
2156 | + summary='', |
2157 | + body='', |
2158 | + icon=None, |
2159 | + hints=[], |
2160 | + urgency='NORMAL' |
2161 | +): |
2162 | + """Create an ephemeral (non-interactive) notification |
2163 | + |
2164 | + :param summary: Summary text for the notification |
2165 | + :param body: Body text to display in the notification |
2166 | + :param icon: Path string to the icon to use |
2167 | + :param hint_strings: List of tuples containing the 'name' and value |
2168 | + for setting the hint strings for the notification |
2169 | + :param urgency: Urgency string for the noticiation, either: 'LOW', |
2170 | + 'NORMAL', 'CRITICAL' |
2171 | + """ |
2172 | + Notify.init('Unity8') |
2173 | + |
2174 | + logger.info( |
2175 | + "Creating ephemeral: summary(%s), body(%s), urgency(%r) " |
2176 | + "and Icon(%s)", |
2177 | + summary, |
2178 | + body, |
2179 | + urgency, |
2180 | + icon |
2181 | + ) |
2182 | + |
2183 | + notification = Notify.Notification.new(summary, body, icon) |
2184 | + |
2185 | + for hint in hints: |
2186 | + key, value = hint |
2187 | + notification.set_hint_string(key, value) |
2188 | + logger.info("Adding hint to notification: (%s, %s)", key, value) |
2189 | + notification.set_urgency(_get_urgency(urgency)) |
2190 | + |
2191 | + return notification |
2192 | + |
2193 | + |
2194 | +def _get_urgency(urgency): |
2195 | + """Translates urgency string to enum.""" |
2196 | + _urgency_enums = {'LOW': Notify.Urgency.LOW, |
2197 | + 'NORMAL': Notify.Urgency.NORMAL, |
2198 | + 'CRITICAL': Notify.Urgency.CRITICAL} |
2199 | + return _urgency_enums.get(urgency.upper()) |
2200 | |
2201 | === modified file 'ubuntu_system_tests/helpers/unity8/utils.py' |
2202 | --- ubuntu_system_tests/helpers/unity8/utils.py 2016-06-02 11:07:46 +0000 |
2203 | +++ ubuntu_system_tests/helpers/unity8/utils.py 2016-06-10 02:06:42 +0000 |
2204 | @@ -18,14 +18,19 @@ |
2205 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
2206 | # |
2207 | |
2208 | -from ubuntuuitoolkit import UbuntuUIToolkitCustomProxyObjectBase |
2209 | -from unity8 import process_helpers |
2210 | +import os |
2211 | +import subprocess |
2212 | +import sysconfig |
2213 | |
2214 | from autopilot import introspection |
2215 | +from autopilot.introspection import get_proxy_object_for_existing_process |
2216 | from autopilot.matchers import Eventually |
2217 | from testtools.matchers import Equals |
2218 | +from ubuntuuitoolkit import UbuntuUIToolkitCustomProxyObjectBase |
2219 | |
2220 | +from ubuntu_system_tests.helpers.autopilot import patched_select_single |
2221 | from ubuntu_system_tests.helpers import context |
2222 | +from ubuntu_system_tests.helpers import processes |
2223 | from ubuntu_system_tests.helpers import timer |
2224 | from ubuntu_system_tests.helpers.unity8 import greeter |
2225 | |
2226 | @@ -35,33 +40,211 @@ |
2227 | APP_WIN_NAME = 'Scopes' |
2228 | |
2229 | |
2230 | +class CannotAccessUnity(Exception): |
2231 | + pass |
2232 | + |
2233 | + |
2234 | +class UnityException(Exception): |
2235 | + """Exception raised when there is an error with the Unity test helpers.""" |
2236 | + |
2237 | + |
2238 | +def restart_unity_with_testability(*args): |
2239 | + """Restarts (or starts) unity with testability enabled. |
2240 | + |
2241 | + Passes *args arguments to the launched process. |
2242 | + |
2243 | + """ |
2244 | + args += ("QT_LOAD_TESTABILITY=1",) |
2245 | + return restart_unity(*args) |
2246 | + |
2247 | + |
2248 | +def restart_unity(*args): |
2249 | + """Restarts (or starts) unity8 using the provided arguments. |
2250 | + |
2251 | + Passes *args arguments to the launched process. |
2252 | + |
2253 | + :raises subprocess.CalledProcessError: if unable to stop or start the |
2254 | + unity8 upstart job. |
2255 | + |
2256 | + """ |
2257 | + status = _get_unity_status() |
2258 | + if "start/" in status: |
2259 | + processes.stop_job('unity8') |
2260 | + |
2261 | + pid = processes.start_job('unity8', *args) |
2262 | + return _get_unity_proxy_object(pid) |
2263 | + |
2264 | + |
2265 | +def _get_unity_status(): |
2266 | + try: |
2267 | + return processes.get_job_status('unity8') |
2268 | + except processes.JobError as error: |
2269 | + raise CannotAccessUnity(str(error)) |
2270 | + |
2271 | + |
2272 | +def get_unity_pid(): |
2273 | + try: |
2274 | + return processes.get_job_pid('unity8') |
2275 | + except processes.JobError as error: |
2276 | + raise CannotAccessUnity(str(error)) |
2277 | + |
2278 | + |
2279 | +def _get_unity_proxy_object(pid): |
2280 | + return get_proxy_object_for_existing_process( |
2281 | + pid=pid, |
2282 | + emulator_base=UbuntuUIToolkitCustomProxyObjectBase |
2283 | + ) |
2284 | + |
2285 | + |
2286 | +def running_installed_tests(): |
2287 | + binary_path = get_binary_path() |
2288 | + return binary_path.startswith('/usr') |
2289 | + |
2290 | + |
2291 | +def get_lib_path(): |
2292 | + """Return the library path to use in this test run.""" |
2293 | + if running_installed_tests(): |
2294 | + lib_path = os.path.join( |
2295 | + "/usr/lib/", |
2296 | + sysconfig.get_config_var('MULTIARCH'), |
2297 | + "unity8" |
2298 | + ) |
2299 | + else: |
2300 | + binary_path = get_binary_path() |
2301 | + lib_path = os.path.dirname(binary_path) |
2302 | + return lib_path |
2303 | + |
2304 | + |
2305 | +def get_default_extra_mock_libraries(): |
2306 | + mocks_path = get_mocks_library_path() |
2307 | + return os.path.join(mocks_path, 'libusermetrics') |
2308 | + |
2309 | + |
2310 | +def get_mocks_library_path(): |
2311 | + if running_installed_tests(): |
2312 | + mock_path = "qml/mocks/" |
2313 | + else: |
2314 | + mock_path = os.path.join( |
2315 | + "../lib/", |
2316 | + sysconfig.get_config_var('MULTIARCH'), |
2317 | + "unity8/qml/mocks/" |
2318 | + ) |
2319 | + lib_path = get_lib_path() |
2320 | + ld_library_path = os.path.abspath( |
2321 | + os.path.join( |
2322 | + lib_path, |
2323 | + mock_path, |
2324 | + ) |
2325 | + ) |
2326 | + |
2327 | + if not os.path.exists(ld_library_path): |
2328 | + raise RuntimeError( |
2329 | + "Expected library path does not exists: %s." % (ld_library_path) |
2330 | + ) |
2331 | + return ld_library_path |
2332 | + |
2333 | + |
2334 | +def get_binary_path(binary="unity8"): |
2335 | + """Return the path to the specified binary.""" |
2336 | + binary_path = os.path.abspath( |
2337 | + os.path.join( |
2338 | + os.path.dirname(__file__), |
2339 | + "../../../builddir/install/bin/%s" % binary |
2340 | + ) |
2341 | + ) |
2342 | + if not os.path.exists(binary_path): |
2343 | + try: |
2344 | + binary_path = subprocess.check_output( |
2345 | + ['which', binary], |
2346 | + universal_newlines=True, |
2347 | + ).strip() |
2348 | + except subprocess.CalledProcessError as e: |
2349 | + raise RuntimeError("Unable to locate %s binary: %r" % (binary, e)) |
2350 | + return binary_path |
2351 | + |
2352 | + |
2353 | +def get_data_dirs(data_dirs_mock_enabled=True): |
2354 | + """Prepend a mock data path to XDG_DATA_DIRS.""" |
2355 | + data_dirs = _get_xdg_env_path() |
2356 | + if data_dirs_mock_enabled: |
2357 | + mock_data_path = _get_full_mock_data_path() |
2358 | + if os.path.exists(mock_data_path): |
2359 | + if data_dirs is not None: |
2360 | + data_dirs = '{0}:{1}'.format(mock_data_path, data_dirs) |
2361 | + else: |
2362 | + data_dirs = mock_data_path |
2363 | + return data_dirs |
2364 | + |
2365 | + |
2366 | +def _get_full_mock_data_path(): |
2367 | + if running_installed_tests(): |
2368 | + data_path = "/usr/share/unity8/mocks/data" |
2369 | + else: |
2370 | + data_path = "../../mocks/data" |
2371 | + return os.path.abspath( |
2372 | + os.path.join( |
2373 | + os.path.dirname(__file__), |
2374 | + data_path |
2375 | + ) |
2376 | + ) |
2377 | + |
2378 | + |
2379 | +def _get_xdg_env_path(): |
2380 | + path = os.getenv("XDG_DATA_DIRS") |
2381 | + if path is None: |
2382 | + path = _get_xdg_upstart_env() |
2383 | + return path |
2384 | + |
2385 | + |
2386 | +def _get_xdg_upstart_env(): |
2387 | + try: |
2388 | + return subprocess.check_output([ |
2389 | + "/sbin/initctl", |
2390 | + "get-env", |
2391 | + "--global", |
2392 | + "XDG_DATA_DIRS" |
2393 | + ], universal_newlines=True).rstrip() |
2394 | + except subprocess.CalledProcessError: |
2395 | + return None |
2396 | + |
2397 | + |
2398 | +def get_grid_size(): |
2399 | + grid_size = os.getenv('GRID_UNIT_PX') |
2400 | + if grid_size is None: |
2401 | + raise RuntimeError( |
2402 | + "Environment variable GRID_UNIT_PX has not been set." |
2403 | + ) |
2404 | + return int(grid_size) |
2405 | + |
2406 | + |
2407 | def ensure_unity_stopped(): |
2408 | if _is_unity8_running(): |
2409 | - process_helpers.stop_job('unity8') |
2410 | + processes.stop_job('unity8') |
2411 | Eventually(Equals(False), timeout=300).match(_is_unity8_running) |
2412 | |
2413 | |
2414 | def ensure_unity_running_and_greeter_hidden(): |
2415 | if not _is_unity8_running(): |
2416 | - process_helpers.start_job('unity8') |
2417 | + processes.start_job('unity8') |
2418 | greeter.wait_for_greeter() |
2419 | |
2420 | greeter.hide_greeter_with_dbus() |
2421 | |
2422 | |
2423 | def _is_unity8_running(): |
2424 | - return process_helpers.is_job_running('unity8') |
2425 | + return processes.is_job_running('unity8') |
2426 | |
2427 | |
2428 | def get_dash(): |
2429 | """Return the Unity8 Dash autopilot custom proxy object.""" |
2430 | from ubuntu_system_tests.helpers.unity8.dash import Dash |
2431 | - pid = process_helpers.get_job_pid('unity8-dash') |
2432 | + pid = processes.get_job_pid('unity8-dash') |
2433 | dash_proxy = introspection.get_proxy_object_for_existing_process( |
2434 | pid=pid, |
2435 | emulator_base=UbuntuUIToolkitCustomProxyObjectBase, |
2436 | ) |
2437 | - return dash_proxy.select_single(Dash) |
2438 | + return patched_select_single(root=dash_proxy, class_object=Dash, |
2439 | + class_name='Dash') |
2440 | |
2441 | |
2442 | def launch_application_from_launcher(app_name): |
2443 | @@ -104,4 +287,4 @@ |
2444 | app_names = stage.get_app_window_names() |
2445 | for app_name in app_names: |
2446 | if not app_name == APP_WIN_NAME: |
2447 | - close_app(app_name) |
2448 | + pass |
2449 | |
2450 | === modified file 'ubuntu_system_tests/selftests/test_tests_to_run.py' |
2451 | --- ubuntu_system_tests/selftests/test_tests_to_run.py 2016-06-06 09:53:20 +0000 |
2452 | +++ ubuntu_system_tests/selftests/test_tests_to_run.py 2016-06-10 02:06:42 +0000 |
2453 | @@ -133,7 +133,7 @@ |
2454 | 'ubuntu_system_tests.helpers.unity8.utils.greeter', |
2455 | new_callable=FakeGreeterHelpers) |
2456 | @mock.patch( |
2457 | - 'ubuntu_system_tests.helpers.unity8.utils.process_helpers', |
2458 | + 'ubuntu_system_tests.helpers.unity8.utils.processes', |
2459 | new_callable=FakeProcessHelpers) |
2460 | class EnsureUnityInRequiredStateTestCase(unittest.TestCase): |
2461 | |
2462 | |
2463 | === modified file 'ubuntu_system_tests/tests/base.py' |
2464 | --- ubuntu_system_tests/tests/base.py 2016-05-16 17:05:42 +0000 |
2465 | +++ ubuntu_system_tests/tests/base.py 2016-06-10 02:06:42 +0000 |
2466 | @@ -26,30 +26,28 @@ |
2467 | from tempfile import mkstemp |
2468 | from threading import Event |
2469 | |
2470 | +import autopilot |
2471 | from autopilot import ( |
2472 | exceptions, |
2473 | input, |
2474 | - logging as autopilot_logging, |
2475 | testcase |
2476 | ) |
2477 | from autopilot._fixtures import OSKAlwaysEnabled |
2478 | from autopilot.introspection import _object_registry as object_registry |
2479 | from ubuntuuitoolkit import fixture_setup |
2480 | -from unity8 import process_helpers |
2481 | |
2482 | -from ubuntu_system_tests.helpers import autopilot |
2483 | +from ubuntu_system_tests.helpers.autopilot import get_job_proxy_object |
2484 | from ubuntu_system_tests.helpers import context |
2485 | from ubuntu_system_tests.helpers import images |
2486 | from ubuntu_system_tests.helpers import mir |
2487 | from ubuntu_system_tests.helpers.notifications import sim_pin_observer |
2488 | from ubuntu_system_tests.helpers import ofono |
2489 | -from ubuntu_system_tests.helpers.processes import wait_for_job_spawned |
2490 | +from ubuntu_system_tests.helpers import processes |
2491 | from ubuntu_system_tests.helpers import screen |
2492 | from ubuntu_system_tests.helpers.timeout import timeout |
2493 | from ubuntu_system_tests.helpers import unity8 |
2494 | -from ubuntu_system_tests.helpers.unity8 import get_dash |
2495 | -from ubuntu_system_tests.helpers.unity8 import sensors |
2496 | -from ubuntu_system_tests.helpers.unity8.shell import Unity8 # NOQA |
2497 | +from ubuntu_system_tests.helpers.unity8 import get_dash, sensors |
2498 | +from ubuntu_system_tests.helpers.unity8.shell._cpo import Unity8 # NOQA |
2499 | from ubuntu_system_tests.helpers import wait_until |
2500 | from ubuntu_system_tests.helpers import webapp |
2501 | |
2502 | @@ -84,9 +82,9 @@ |
2503 | context.shared.retry_time = 10000 |
2504 | |
2505 | def _get_unity8_proxy_object(self): |
2506 | - return autopilot.get_job_proxy_object('unity8') |
2507 | + return get_job_proxy_object('unity8') |
2508 | |
2509 | - @autopilot_logging.log_action(logger.info) |
2510 | + @autopilot.logging.log_action(logger.info) |
2511 | def launch_unity(self, fake_sensors=False, dismiss_sim_unlock=True): |
2512 | """Launch Unity8 with testability enabled. |
2513 | |
2514 | @@ -149,11 +147,11 @@ |
2515 | args = ['QT_LOAD_TESTABILITY=1'] |
2516 | if no_wait: |
2517 | args.append('--no-wait') |
2518 | - process_helpers.start_job(unity8.PROC_NAME, *args) |
2519 | + processes.start_job(unity8.PROC_NAME, *args) |
2520 | if no_wait: |
2521 | # just wait for job to be spawned rather than fully running |
2522 | - wait_for_job_spawned(unity8.PROC_NAME) |
2523 | - context.shared.unity_pid = process_helpers._get_unity_pid() |
2524 | + processes.wait_for_job_spawned(unity8.PROC_NAME) |
2525 | + context.shared.unity_pid = unity8.get_unity_pid() |
2526 | |
2527 | def _enable_osk_for_uitk(self): |
2528 | """Enable use of the OSK with uitk helpers.""" |
2529 | @@ -216,7 +214,7 @@ |
2530 | isinstance(exception, DBusException) or |
2531 | isinstance(exception, TimeoutError) or |
2532 | isinstance(exception, exceptions.BackendException))) |
2533 | - @autopilot_logging.log_action(logger.info) |
2534 | + @autopilot.logging.log_action(logger.info) |
2535 | def restart_unity(self, fake_sensors=False): |
2536 | """ |
2537 | Restart and unlock unity8 |
2538 | |
2539 | === modified file 'ubuntu_system_tests/tests/test_tutorial.py' |
2540 | --- ubuntu_system_tests/tests/test_tutorial.py 2015-05-21 18:15:40 +0000 |
2541 | +++ ubuntu_system_tests/tests/test_tutorial.py 2016-06-10 02:06:42 +0000 |
2542 | @@ -21,12 +21,8 @@ |
2543 | from autopilot.matchers import Eventually |
2544 | from testtools.matchers import Equals |
2545 | |
2546 | -from unity8.shell import fixture_setup |
2547 | - |
2548 | -# unused import to load the tutorial custom proxy objects. |
2549 | -from unity8.shell.emulators import tutorial # NOQA |
2550 | - |
2551 | from ubuntu_system_tests.tests import base |
2552 | +from ubuntu_system_tests.helpers.unity8.shell import fixture_setup |
2553 | |
2554 | |
2555 | class TutorialTestCase(base.BaseUbuntuSystemTestCase): |
2556 | |
2557 | === modified file 'ubuntu_system_tests/tests/test_with_dialer.py' |
2558 | --- ubuntu_system_tests/tests/test_with_dialer.py 2016-02-03 22:25:18 +0000 |
2559 | +++ ubuntu_system_tests/tests/test_with_dialer.py 2016-06-10 02:06:42 +0000 |
2560 | @@ -20,9 +20,9 @@ |
2561 | from autopilot.matchers import Eventually |
2562 | from testtools.matchers import Equals |
2563 | |
2564 | -from unity8 import process_helpers as unity_helpers |
2565 | - |
2566 | from ubuntu_system_tests.helpers import dialer_app |
2567 | +from ubuntu_system_tests.helpers.unity8 import greeter |
2568 | + |
2569 | from ubuntu_system_tests.tests import base |
2570 | |
2571 | |
2572 | @@ -44,8 +44,8 @@ |
2573 | self.assertThat(self.dialer_app.contacts_page.active, |
2574 | Eventually(Equals(True))) |
2575 | |
2576 | - unity_helpers.lock_unity() |
2577 | - unity_helpers.unlock_unity() |
2578 | + greeter.lock_unity() |
2579 | + greeter.unlock_unity() |
2580 | |
2581 | self.assertThat(self.dialer_app.contacts_page.active, |
2582 | Eventually(Equals(True))) |
FAILED: Continuous integration, rev:395 /platform- qa-jenkins. ubuntu. com/job/ ubuntu- system- tests-ci/ 221/ /platform- qa-jenkins. ubuntu. com/job/ build-wily- amd64-package/ 326/console /platform- qa-jenkins. ubuntu. com/job/ build-wily- i386-package/ 326/console /platform- qa-jenkins. ubuntu. com/job/ generic- update- mp/287/ console
https:/
Executed test runs:
FAILURE: https:/
FAILURE: https:/
None: https:/
Click here to trigger a rebuild: /platform- qa-jenkins. ubuntu. com/job/ ubuntu- system- tests-ci/ 221/rebuild
https:/