Merge lp:~canonical-platform-qa/unity8/dash-as-app-autopilot into lp:~unity-team/unity8/dash-as-app

Proposed by Leo Arias
Status: Superseded
Proposed branch: lp:~canonical-platform-qa/unity8/dash-as-app-autopilot
Merge into: lp:~unity-team/unity8/dash-as-app
Prerequisite: lp:~gerboland/unity8/fix-run.sh-script
Diff against target: 958 lines (+410/-182)
12 files modified
tests/autopilot/unity8/application_lifecycle/tests/test_application_lifecycle.py (+1/-1)
tests/autopilot/unity8/application_lifecycle/tests/test_url_dispatcher.py (+3/-2)
tests/autopilot/unity8/fixture_setup.py (+65/-0)
tests/autopilot/unity8/process_helpers.py (+92/-23)
tests/autopilot/unity8/shell/emulators/dash.py (+21/-8)
tests/autopilot/unity8/shell/emulators/greeter.py (+4/-1)
tests/autopilot/unity8/shell/emulators/main_window.py (+34/-20)
tests/autopilot/unity8/shell/tests/__init__.py (+143/-50)
tests/autopilot/unity8/shell/tests/test_emulators.py (+7/-18)
tests/autopilot/unity8/shell/tests/test_lock_screen.py (+8/-47)
tests/autopilot/unity8/shell/tests/test_notifications.py (+12/-7)
tests/autopilot/unity8/shell/tests/test_upstart.py (+20/-5)
To merge this branch: bzr merge lp:~canonical-platform-qa/unity8/dash-as-app-autopilot
Reviewer Review Type Date Requested Status
Unity Team Pending
Review via email: mp+228928@code.launchpad.net

This proposal supersedes a proposal from 2014-07-30.

This proposal has been superseded by a proposal from 2014-07-31.

Commit message

Update the autopilot tests to work with the new dash app.

To post a comment you must log in.
Revision history for this message
Leo Arias (elopio) wrote : Posted in a previous version of this proposal

Not ready yet. Just proposing to start getting jenkins results earlier.

1109. By Leo Arias

Updated the notifications tests.

1110. By Leo Arias

Updated the wait for unity.

1111. By Leo Arias

Updated the test search.

1112. By Leo Arias

Updated the upstart tests.

1113. By Leo Arias

Removed the unused function.

1114. By Leo Arias

Fixed the error reporting.

1115. By Leo Arias

Make sure that unity is running and the dash is not.

1116. By Leo Arias

Hide unity7 launcher.

1117. By Leo Arias

Removed unused helper.

1118. By Leo Arias

Updated the lifecycle tests.

1119. By Leo Arias

Pass the testability as an argument.

1120. By Leo Arias

Merged with trunk.

1121. By Leo Arias

Removed extra space.

1122. By Leo Arias

Removed tags.

1123. By Leo Arias

Merged with prerequisite.

1124. By Leo Arias

Remove unused import.

1125. By Leo Arias

Fixed typo.

1126. By Leo Arias

Fixed typo.

1127. By Leo Arias

Fixed grammar erro.

1128. By Leo Arias

Only check for the start part of the status, as suggested by saviq.

Unmerged revisions

1128. By Leo Arias

Only check for the start part of the status, as suggested by saviq.

1127. By Leo Arias

Fixed grammar erro.

1126. By Leo Arias

Fixed typo.

1125. By Leo Arias

Fixed typo.

1124. By Leo Arias

Remove unused import.

1123. By Leo Arias

Merged with prerequisite.

1122. By Leo Arias

Removed tags.

1121. By Leo Arias

Removed extra space.

1120. By Leo Arias

Merged with trunk.

1119. By Leo Arias

Pass the testability as an argument.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'tests/autopilot/unity8/application_lifecycle/tests/test_application_lifecycle.py'
2--- tests/autopilot/unity8/application_lifecycle/tests/test_application_lifecycle.py 2014-06-11 15:36:51 +0000
3+++ tests/autopilot/unity8/application_lifecycle/tests/test_application_lifecycle.py 2014-07-31 14:59:26 +0000
4@@ -106,7 +106,7 @@
5 self.assert_current_focused_application(application_name)
6
7 self.main_window.show_dash_swiping()
8- self.assert_current_focused_application('')
9+ self.assert_current_focused_application('unity8-dash')
10
11 process_helpers.lock_unity()
12 greeter = self.main_window.get_greeter()
13
14=== modified file 'tests/autopilot/unity8/application_lifecycle/tests/test_url_dispatcher.py'
15--- tests/autopilot/unity8/application_lifecycle/tests/test_url_dispatcher.py 2014-06-11 15:36:51 +0000
16+++ tests/autopilot/unity8/application_lifecycle/tests/test_url_dispatcher.py 2014-07-31 14:59:26 +0000
17@@ -39,7 +39,8 @@
18 desktop_file_name = os.path.basename(desktop_file_path)
19 application_name, _ = os.path.splitext(desktop_file_name)
20
21- self.assertEqual('', self.main_window.get_current_focused_app_id())
22+ self.assertEqual(
23+ 'unity8-dash', self.main_window.get_current_focused_app_id())
24 self.addCleanup(os.system, 'pkill qmlscene')
25
26 subprocess.check_call(
27@@ -47,4 +48,4 @@
28 self.assert_current_focused_application(application_name)
29
30 self.main_window.show_dash_swiping()
31- self.assert_current_focused_application('')
32+ self.assert_current_focused_application('unity8-dash')
33
34=== added file 'tests/autopilot/unity8/fixture_setup.py'
35--- tests/autopilot/unity8/fixture_setup.py 1970-01-01 00:00:00 +0000
36+++ tests/autopilot/unity8/fixture_setup.py 2014-07-31 14:59:26 +0000
37@@ -0,0 +1,65 @@
38+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
39+#
40+# Unity Autopilot Test Suite
41+# Copyright (C) 2014 Canonical
42+#
43+# This program is free software: you can redistribute it and/or modify
44+# it under the terms of the GNU General Public License as published by
45+# the Free Software Foundation, either version 3 of the License, or
46+# (at your option) any later version.
47+#
48+# This program is distributed in the hope that it will be useful,
49+# but WITHOUT ANY WARRANTY; without even the implied warranty of
50+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
51+# GNU General Public License for more details.
52+#
53+# You should have received a copy of the GNU General Public License
54+# along with this program. If not, see <http://www.gnu.org/licenses/>.
55+#
56+
57+import fixtures
58+from autopilot import introspection
59+from ubuntuuitoolkit import fixture_setup as toolkit_fixtures
60+
61+from unity8 import process_helpers
62+from unity8.shell import emulators
63+
64+
65+class LaunchDashApp(fixtures.Fixture):
66+
67+ """Fixture to launch the Dashh app."""
68+
69+ def __init__(self, binary_path, variables):
70+ """Initialize an instance.
71+
72+ :param str binary_path: The path to the Dash app binary.
73+ :param variables: The variables to use when launching the app.
74+ :type variables: A dictionary.
75+
76+ """
77+ super(LaunchDashApp, self).__init__()
78+ self.binary_path = binary_path
79+ self.variables = variables
80+
81+ def setUp(self):
82+ """Launch the dash app when the fixture is used."""
83+ super(LaunchDashApp, self).setUp()
84+ self.addCleanup(self.stop_application)
85+ self.application_proxy = self.launch_application()
86+
87+ def launch_application(self):
88+ binary_arg = 'BINARY={}'.format(self.binary_path)
89+ testability_arg = 'QT_LOAD_TESTABILITY={}'.format(1)
90+ env_args = [
91+ '{}={}'.format(key, value) for key, value in self.variables.items()
92+ ]
93+ all_args = [binary_arg, testability_arg] + env_args
94+
95+ pid = process_helpers.start_job('unity8-dash', *all_args)
96+ return introspection.get_proxy_object_for_existing_process(
97+ pid=pid,
98+ emulator_base=emulators.UnityEmulatorBase,
99+ )
100+
101+ def stop_application(self):
102+ process_helpers.stop_job('unity8-dash')
103
104=== modified file 'tests/autopilot/unity8/process_helpers.py'
105--- tests/autopilot/unity8/process_helpers.py 2014-06-27 13:13:04 +0000
106+++ tests/autopilot/unity8/process_helpers.py 2014-07-31 14:59:26 +0000
107@@ -36,6 +36,10 @@
108 logger = logging.getLogger(__name__)
109
110
111+class JobError(Exception):
112+ pass
113+
114+
115 class CannotAccessUnity(Exception):
116 pass
117
118@@ -134,48 +138,113 @@
119 """
120 status = _get_unity_status()
121 if "start/" in status:
122- try:
123- output = subprocess.check_output(
124- ['/sbin/initctl', 'stop', 'unity8'])
125- logger.info(output)
126- except subprocess.CalledProcessError as e:
127- e.args += (
128- "Failed to stop running instance of unity8: %s" % e.output,
129- )
130- raise
131-
132+ stop_job('unity8')
133+
134+ pid = start_job('unity8', *args)
135+ return _get_unity_proxy_object(pid)
136+
137+
138+def start_job(name, *args):
139+ """Start a job.
140+
141+ :param str name: The name of the job.
142+ :param args: The arguments to be used when starting the job.
143+ :return: The process id of the started job.
144+ :raises CalledProcessError: if the job failed to start.
145+
146+ """
147+ logger.info('Starting job {} with arguments {}.'.format(name, args))
148+ command = ['/sbin/initctl', 'start', name] + list(args)
149 try:
150- command = ['/sbin/initctl', 'start', 'unity8'] + list(args)
151 output = subprocess.check_output(
152 command,
153 stderr=subprocess.STDOUT,
154 universal_newlines=True,
155 )
156 logger.info(output)
157- pid = _get_unity_pid()
158+ pid = get_job_pid(name)
159 except subprocess.CalledProcessError as e:
160- e.args += ("Failed to start unity8: %s" % e.output,)
161+ e.args += ('Failed to start {}: {}.'.format(name, e.output),)
162 raise
163 else:
164- return _get_unity_proxy_object(pid)
165-
166-
167-def _get_unity_status():
168+ return pid
169+
170+
171+def get_job_pid(name):
172+ """Return the process id of a running job.
173+
174+ :param str name: The name of the job.
175+ :raises JobError: if the job is not running.
176+
177+ """
178+ status = get_job_status(name)
179+ if "start/" not in status:
180+ raise JobError('{} is not in the running state.'.format(name))
181+ return int(status.split()[-1])
182+
183+
184+def get_job_status(name):
185+ """Return the status of a job.
186+
187+ :param str name: The name of the job.
188+ :raises JobError: if it's not possible to get the status of the job.
189+
190+ """
191 try:
192 return subprocess.check_output([
193 '/sbin/initctl',
194 'status',
195- 'unity8'
196+ name
197 ], universal_newlines=True)
198+ except subprocess.CalledProcessError as error:
199+ raise JobError(
200+ "Unable to get {}'s status: {}".format(name, error)
201+ )
202+
203+
204+def stop_job(name):
205+ """Stop a job.
206+
207+ :param str name: The name of the job.
208+ :raises CalledProcessError: if the job failed to stop.
209+
210+ """
211+ logger.info('Stoping job {}.'.format(name))
212+ command = ['/sbin/initctl', 'stop', name]
213+ try:
214+ output = subprocess.check_output(
215+ command,
216+ stderr=subprocess.STDOUT,
217+ universal_newlines=True,
218+ )
219+ logger.info(output)
220 except subprocess.CalledProcessError as e:
221- raise CannotAccessUnity("Unable to get unity's status: %s" % str(e))
222+ e.args += ('Failed to stop {}: {}.'.format(name, e.output),)
223+ raise
224+
225+
226+def is_job_running(name):
227+ """Return True if the job is running. Otherwise, False.
228+
229+ :param str name: The name of the job.
230+ :raises JobError: if it's not possible to get the status of the job.
231+
232+ """
233+ return 'start/running' in get_job_status(name)
234+
235+
236+def _get_unity_status():
237+ try:
238+ return get_job_status('unity8')
239+ except JobError as error:
240+ raise CannotAccessUnity(str(error))
241
242
243 def _get_unity_pid():
244- status = _get_unity_status()
245- if "start/" not in status:
246- raise CannotAccessUnity("Unity is not in the running state.")
247- return int(status.split()[-1])
248+ try:
249+ return get_job_pid('unity8')
250+ except JobError as error:
251+ raise CannotAccessUnity(str(error))
252
253
254 def _get_unity_proxy_object(pid):
255
256=== modified file 'tests/autopilot/unity8/shell/emulators/dash.py'
257--- tests/autopilot/unity8/shell/emulators/dash.py 2014-07-28 17:06:57 +0000
258+++ tests/autopilot/unity8/shell/emulators/dash.py 2014-07-31 14:59:26 +0000
259@@ -31,6 +31,17 @@
260 logger = logging.getLogger(__name__)
261
262
263+class DashApp(object):
264+
265+ """Autopilot helper for the Dash app."""
266+
267+ def __init__(self, app_proxy):
268+ self.app_proxy = app_proxy
269+ self.main_view = self.app_proxy.select_single(
270+ toolkit_emulators.MainView)
271+ self.dash = self.main_view.select_single(Dash)
272+
273+
274 class Dash(emulators.UnityEmulatorBase):
275 """An emulator that understands the Dash."""
276
277@@ -109,20 +120,22 @@
278 @autopilot_logging.log_action(logger.info)
279 def _scroll_to_left_scope(self):
280 original_index = self.dash_content_list.currentIndex
281- dashContent = self.select_single(objectName="dashContent")
282- start_x = dashContent.width / 3
283- stop_x = dashContent.width / 3 * 2
284- start_y = stop_y = dashContent.globalRect.y + 1
285+ dash_content = self.select_single(objectName="dashContent")
286+ x, y, width, height = dash_content.globalRect
287+ start_x = x + width / 3
288+ stop_x = x + width / 3 * 2
289+ start_y = stop_y = y + 1
290 self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
291 self.dash_content_list.currentIndex.wait_for(original_index - 1)
292
293 @autopilot_logging.log_action(logger.info)
294 def _scroll_to_right_scope(self):
295 original_index = self.dash_content_list.currentIndex
296- dashContent = self.select_single(objectName="dashContent")
297- start_x = dashContent.width / 3 * 2
298- stop_x = dashContent.width / 3
299- start_y = stop_y = dashContent.globalRect.y + 1
300+ dash_content = self.select_single(objectName="dashContent")
301+ x, y, width, height = dash_content.globalRect
302+ start_x = x + width / 3 * 2
303+ stop_x = x + width / 3
304+ start_y = stop_y = y + 1
305 self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
306 self.dash_content_list.currentIndex.wait_for(original_index + 1)
307
308
309=== modified file 'tests/autopilot/unity8/shell/emulators/greeter.py'
310--- tests/autopilot/unity8/shell/emulators/greeter.py 2014-01-09 15:53:05 +0000
311+++ tests/autopilot/unity8/shell/emulators/greeter.py 2014-07-31 14:59:26 +0000
312@@ -17,6 +17,8 @@
313 # along with this program. If not, see <http://www.gnu.org/licenses/>.
314 #
315
316+import ubuntuuitoolkit
317+
318 from unity8.shell.emulators import UnityEmulatorBase
319
320
321@@ -37,4 +39,5 @@
322 self.created.wait_for(False)
323
324 def get_prompt(self):
325- return self.select_single("TextField", objectName="passwordInput")
326+ return self.select_single(
327+ ubuntuuitoolkit.TextField, objectName='passwordInput')
328
329=== modified file 'tests/autopilot/unity8/shell/emulators/main_window.py'
330--- tests/autopilot/unity8/shell/emulators/main_window.py 2014-07-09 13:16:20 +0000
331+++ tests/autopilot/unity8/shell/emulators/main_window.py 2014-07-31 14:59:26 +0000
332@@ -25,7 +25,6 @@
333 from unity8.shell import emulators
334 from unity8.shell.emulators.greeter import Greeter
335 from unity8.shell.emulators.hud import Hud
336-from unity8.shell.emulators.dash import Dash
337 from unity8.shell.emulators.launcher import Launcher
338
339 logger = logging.getLogger(__name__)
340@@ -61,9 +60,6 @@
341 def get_hud_edge_drag_area(self):
342 return self.select_single(objectName="hudDragArea")
343
344- def get_dash(self):
345- return self.select_single(Dash)
346-
347 def get_bottombar(self):
348 return self.select_single("Bottombar")
349
350@@ -76,12 +72,6 @@
351 objectName="pinPadLoader"
352 )
353
354- def get_pinPadButton(self, buttonId):
355- return self.select_single(
356- "PinPadButton",
357- objectName="pinPadButton%i" % buttonId
358- )
359-
360 def get_lockscreen(self):
361 return self.select_single("Lockscreen")
362
363@@ -117,20 +107,44 @@
364 @autopilot_logging.log_action(logger.info)
365 def show_dash_swiping(self):
366 """Show the dash swiping from the left."""
367- width = self.width
368- height = self.height
369- start_x = 0
370- start_y = height // 2
371- end_x = width
372- end_y = start_y
373+ x, y, width, height = self._get_shell().globalRect
374+ start_x = x
375+ end_x = x + width
376+ start_y = end_y = y + height // 2
377
378 self.pointing_device.drag(start_x, start_y, end_x, end_y)
379- return self.get_dash()
380+
381+ def _get_shell(self):
382+ return self.select_single('Shell')
383
384 def get_current_focused_app_id(self):
385 """Return the id of the focused application."""
386- return self.select_single('Shell').focusedApplicationId
387+ return self._get_shell().focusedApplicationId
388
389 @autopilot_logging.log_action(logger.info)
390- def search(self, query):
391- self.get_dash().enter_search_query(query)
392+ def enter_pin_code(self, code):
393+ """Enter code 'code' into the single-pin lightdm pincode entry screen.
394+
395+ :param code: must be a string of numeric characters.
396+ :raises: TypeError if code is not a string.
397+ :raises: ValueError if code contains non-numeric characters.
398+
399+ """
400+ if not isinstance(code, str):
401+ raise TypeError(
402+ "'code' parameter must be a string, not %r."
403+ % type(code)
404+ )
405+ for num in code:
406+ if not num.isdigit():
407+ raise ValueError(
408+ "'code' parameter contains non-numeric characters."
409+ )
410+ self.pointing_device.click_object(
411+ self._get_pinpad_button(int(num)))
412+
413+ def _get_pinpad_button(self, button_id):
414+ return self.select_single(
415+ 'PinPadButton',
416+ objectName='pinPadButton{}'.format(button_id)
417+ )
418
419=== modified file 'tests/autopilot/unity8/shell/tests/__init__.py'
420--- tests/autopilot/unity8/shell/tests/__init__.py 2014-06-27 13:13:04 +0000
421+++ tests/autopilot/unity8/shell/tests/__init__.py 2014-07-31 14:59:26 +0000
422@@ -24,6 +24,7 @@
423 except ImportError:
424 Gio = None
425
426+from autopilot import introspection
427 from autopilot.platform import model
428 from autopilot.testcase import AutopilotTestCase
429 from autopilot.matchers import Eventually
430@@ -34,6 +35,10 @@
431 import subprocess
432 import sys
433 from testtools.matchers import Equals
434+from ubuntuuitoolkit import (
435+ fixture_setup as toolkit_fixtures,
436+ ubuntu_scenarios
437+)
438
439 from unity8 import (
440 get_lib_path,
441@@ -42,9 +47,15 @@
442 get_default_extra_mock_libraries,
443 get_data_dirs
444 )
445-from unity8.process_helpers import restart_unity_with_testability
446-from unity8.shell.emulators import main_window as main_window_emulator
447-from unity8.shell.emulators.dash import Dash
448+from unity8 import (
449+ fixture_setup,
450+ process_helpers
451+)
452+from unity8.shell import emulators
453+from unity8.shell.emulators import (
454+ dash as dash_helpers,
455+ main_window as main_window_emulator,
456+)
457
458
459 logger = logging.getLogger(__name__)
460@@ -78,6 +89,26 @@
461 return [native]
462
463
464+def is_unity7_running():
465+ """Return True if Unity7 is running. Otherwise, return False."""
466+ return (
467+ Gio is not None and
468+ UNITYSHELL_GSETTINGS_SCHEMA in
469+ Gio.Settings.list_relocatable_schemas()
470+ )
471+
472+
473+def get_qml_import_path_with_mock():
474+ """Return the QML2_IMPORT_PATH value with the mock path preppended."""
475+ qml_import_path = [get_mocks_library_path()]
476+ if os.getenv('QML2_IMPORT_PATH') is not None:
477+ qml_import_path.append(os.getenv('QML2_IMPORT_PATH'))
478+
479+ qml_import_path = ':'.join(qml_import_path)
480+ logger.info("New QML2 import path: %s", qml_import_path)
481+ return qml_import_path
482+
483+
484 class UnityTestCase(AutopilotTestCase):
485
486 """A test case base class for the Unity shell tests."""
487@@ -118,23 +149,8 @@
488
489 def setUp(self):
490 super(UnityTestCase, self).setUp()
491- if (Gio is not None and
492- UNITYSHELL_GSETTINGS_SCHEMA in
493- Gio.Settings.list_relocatable_schemas()):
494-
495- # Hide Unity launcher
496- self._unityshell_schema = Gio.Settings.new_with_path(
497- UNITYSHELL_GSETTINGS_SCHEMA,
498- UNITYSHELL_GSETTINGS_PATH,
499- )
500- self._launcher_hide_mode = self._unityshell_schema.get_int(
501- UNITYSHELL_LAUNCHER_KEY,
502- )
503- self._unityshell_schema.set_int(
504- UNITYSHELL_LAUNCHER_KEY,
505- UNITYSHELL_LAUNCHER_MODE,
506- )
507- self.addCleanup(self._reset_launcher)
508+ if is_unity7_running():
509+ self.useFixture(toolkit_fixtures.HideUnity7Launcher())
510
511 self._proxy = None
512 self._lightdm_mock_type = None
513@@ -151,13 +167,6 @@
514 self.touch = Touch.create()
515 self._setup_display_details()
516
517- def _reset_launcher(self):
518- """Reset Unity launcher hide mode"""
519- self._unityshell_schema.set_int(
520- UNITYSHELL_LAUNCHER_KEY,
521- self._launcher_hide_mode,
522- )
523-
524 def _setup_display_details(self):
525 scale_divisor = self._determine_geometry()
526 self._setup_grid_size(scale_divisor)
527@@ -263,7 +272,9 @@
528 self.patch_lightdm_mock()
529
530 if self._qml_mock_enabled:
531- self._setup_extra_mock_environment_patch()
532+ self._environment['QML2_IMPORT_PATH'] = (
533+ get_qml_import_path_with_mock()
534+ )
535
536 if self._data_dirs_mock_enabled:
537 self._patch_data_dirs()
538@@ -292,9 +303,14 @@
539
540 # Ensure that the dash is visible before we return:
541 logger.debug("Unity started, waiting for it to be ready.")
542- self.assertUnityReady()
543+ self.wait_for_unity()
544 logger.debug("Unity loaded and ready.")
545
546+ if model() == 'Desktop':
547+ # On desktop, close the dash because it's opened in a separate
548+ # window and it gets on the way.
549+ process_helpers.stop_job('unity8-dash')
550+
551 return app_proxy
552
553 def _launch_unity_with_upstart(self, binary_path, args):
554@@ -308,7 +324,7 @@
555
556 self.addCleanup(self._cleanup_launching_upstart_unity)
557
558- return restart_unity_with_testability(*all_args)
559+ return process_helpers.restart_unity_with_testability(*all_args)
560
561 def _cleanup_launching_upstart_unity(self):
562 logger.info("Stopping unity")
563@@ -353,15 +369,6 @@
564 )
565 return lightdm_mock_path
566
567- def _setup_extra_mock_environment_patch(self):
568- qml_import_path = [get_mocks_library_path()]
569- if os.getenv('QML2_IMPORT_PATH') is not None:
570- qml_import_path.append(os.getenv('QML2_IMPORT_PATH'))
571-
572- qml_import_path = ':'.join(qml_import_path)
573- logger.info("New QML2 import path: %s", qml_import_path)
574- self._environment['QML2_IMPORT_PATH'] = qml_import_path
575-
576 def _set_proxy(self, proxy):
577 """Keep a copy of the proxy object, so we can use it to get common
578 parts of the shell later on.
579@@ -373,10 +380,80 @@
580 def _clear_proxy(self):
581 self._proxy = None
582
583- def assertUnityReady(self):
584- dash = self.get_dash()
585- home_scope = dash.get_scope('clickscope')
586-
587+ def wait_for_unity(self):
588+ greeter_content_loader = self.main_window.wait_select_single(
589+ objectName='greeterContentLoader')
590+ greeter_content_loader.progress.wait_for(1)
591+
592+ def get_dash(self):
593+ pid = process_helpers.get_job_pid('unity8-dash')
594+ dash_proxy = introspection.get_proxy_object_for_existing_process(
595+ pid=pid,
596+ emulator_base=emulators.UnityEmulatorBase,
597+ )
598+ dash_app = dash_helpers.DashApp(dash_proxy)
599+ return dash_app.dash
600+
601+ @property
602+ def main_window(self):
603+ return self._proxy.select_single(main_window_emulator.QQuickView)
604+
605+
606+class DashBaseTestCase(AutopilotTestCase):
607+
608+ scenarios = ubuntu_scenarios.get_device_simulation_scenarios()
609+ qml_mock_enabled = True
610+ environment = {}
611+
612+ def setUp(self):
613+ super(DashBaseTestCase, self).setUp()
614+
615+ if is_unity7_running():
616+ self.useFixture(toolkit_fixtures.HideUnity7Launcher())
617+
618+ if model() != 'Desktop':
619+ # On the phone, we need unity to be running and unlocked.
620+ self.addCleanup(process_helpers.stop_job, 'unity8')
621+ process_helpers.restart_unity_with_testability()
622+ process_helpers.unlock_unity()
623+
624+ self.ensure_dash_not_running()
625+
626+ if self.qml_mock_enabled:
627+ self.environment['QML2_IMPORT_PATH'] = (
628+ get_qml_import_path_with_mock()
629+ )
630+
631+ if self.should_simulate_device():
632+ # This sets the grid units, so it should be called before launching
633+ # the app.
634+ self.simulate_device()
635+
636+ binary_path = get_binary_path('unity8-dash')
637+ dash_proxy = self.launch_dash(binary_path, self.environment)
638+
639+ if self.should_simulate_device():
640+ # XXX Currently we have no way to launch the application with a
641+ # specific size, so we must resize it after it's launched.
642+ # --elopio - 2014-06-25
643+ self.resize_window()
644+
645+ self.dash_app = dash_helpers.DashApp(dash_proxy)
646+ self.dash = self.dash_app.dash
647+ self.wait_for_dash()
648+
649+ def ensure_dash_not_running(self):
650+ if process_helpers.is_job_running('unity8-dash'):
651+ process_helpers.stop_job('unity8-dash')
652+
653+ def launch_dash(self, binary_path, variables):
654+ launch_dash_app_fixture = fixture_setup.LaunchDashApp(
655+ binary_path, variables)
656+ self.useFixture(launch_dash_app_fixture)
657+ return launch_dash_app_fixture.application_proxy
658+
659+ def wait_for_dash(self):
660+ home_scope = self.dash.get_scope('clickscope')
661 # FIXME! There is a huge timeout here for when we're doing CI on
662 # VMs. See lp:1203715
663 self.assertThat(
664@@ -385,10 +462,26 @@
665 )
666 self.assertThat(home_scope.isCurrent, Eventually(Equals(True)))
667
668- def get_dash(self):
669- dash = self._proxy.wait_select_single(Dash)
670- return dash
671-
672- @property
673- def main_window(self):
674- return self._proxy.select_single(main_window_emulator.QQuickView)
675+ def should_simulate_device(self):
676+ return (hasattr(self, 'app_width') and hasattr(self, 'app_height') and
677+ hasattr(self, 'grid_unit_px'))
678+
679+ def simulate_device(self):
680+ simulate_device_fixture = self.useFixture(
681+ toolkit_fixtures.SimulateDevice(
682+ self.app_width, self.app_height, self.grid_unit_px))
683+ self.app_width = simulate_device_fixture.app_width
684+ self.app_height = simulate_device_fixture.app_height
685+
686+ def resize_window(self):
687+ application = self.process_manager.get_running_applications()[0]
688+ window = application.get_windows()[0]
689+ window.resize(self.app_width, self.app_height)
690+
691+ def get_window_size():
692+ _, _, window_width, window_height = window.geometry
693+ return window_width, window_height
694+
695+ self.assertThat(
696+ get_window_size,
697+ Eventually(Equals((self.app_width, self.app_height))))
698
699=== modified file 'tests/autopilot/unity8/shell/tests/test_emulators.py'
700--- tests/autopilot/unity8/shell/tests/test_emulators.py 2014-07-25 11:49:28 +0000
701+++ tests/autopilot/unity8/shell/tests/test_emulators.py 2014-07-31 14:59:26 +0000
702@@ -47,25 +47,14 @@
703 unity_proxy = self.launch_unity()
704 process_helpers.unlock_unity(unity_proxy)
705
706+
707+class DashEmulatorTestCase(tests.DashBaseTestCase):
708+
709 def test_search(self):
710- self.main_window.search('Test')
711- text_field = self.main_window.get_dash()._get_search_text_field()
712+ self.dash.enter_search_query('Test')
713+ text_field = self.dash._get_search_text_field()
714 self.assertEqual(text_field.text, 'Test')
715
716-
717-class DashBaseTestCase(tests.UnityTestCase):
718-
719- scenarios = tests._get_device_emulation_scenarios()
720-
721- def setUp(self):
722- super(DashBaseTestCase, self).setUp()
723- unity_proxy = self.launch_unity()
724- process_helpers.unlock_unity(unity_proxy)
725- self.dash = self.main_window.get_dash()
726-
727-
728-class DashEmulatorTestCase(DashBaseTestCase):
729-
730 def test_open_unexisting_scope(self):
731 scope_name = 'unexisting'
732 with mock.patch.object(self.dash, 'pointing_device') as mock_pointer:
733@@ -145,7 +134,7 @@
734 self.assertIsInstance(scope, dash_emulators.GenericScopeView)
735
736
737-class GenericScopeViewEmulatorTestCase(DashBaseTestCase):
738+class GenericScopeViewEmulatorTestCase(tests.DashBaseTestCase):
739
740 def setUp(self):
741 # Set up the fake scopes before launching unity.
742@@ -159,7 +148,7 @@
743 self.assertTrue(preview.isCurrent)
744
745
746-class DashAppsEmulatorTestCase(DashBaseTestCase):
747+class DashAppsEmulatorTestCase(tests.DashBaseTestCase):
748
749 available_applications = [
750 'Title.2.0', 'Title.2.1', 'Title.2.2', 'Title.2.3', 'Title.2.4',
751
752=== modified file 'tests/autopilot/unity8/shell/tests/test_lock_screen.py'
753--- tests/autopilot/unity8/shell/tests/test_lock_screen.py 2014-06-18 01:52:15 +0000
754+++ tests/autopilot/unity8/shell/tests/test_lock_screen.py 2014-07-31 14:59:26 +0000
755@@ -48,10 +48,11 @@
756 unity_proxy = self.launch_unity()
757 greeter = self.main_window.get_greeter()
758
759+
760 if greeter.narrowMode:
761 unlock_unity(unity_proxy)
762 lockscreen = self._wait_for_lockscreen()
763- self._enter_pincode("1234")
764+ self.main_window.enter_pin_code("1234")
765 self.assertThat(lockscreen.shown, Eventually(Equals(False)))
766 else:
767 self._enter_prompt_passphrase("1234")
768@@ -81,7 +82,7 @@
769 if greeter.narrowMode:
770 unlock_unity(unity_proxy)
771 lockscreen = self._wait_for_lockscreen()
772- self._enter_pincode("4321")
773+ self.main_window.enter_pin_code("4321")
774 pinentryField = self.main_window.get_pinentryField()
775 self.assertThat(pinentryField.text, Eventually(Equals("")))
776 self.assertThat(lockscreen.shown, Eventually(Equals(True)))
777@@ -118,28 +119,6 @@
778 self.assertThat(lockscreen.shown, Eventually(Equals(True)))
779 return lockscreen
780
781- def _enter_pincode(self, code):
782- """Enter code 'code' into the single-pin lightdm pincode entry
783- screen.
784-
785- :param code: must be a string of numeric characters.
786- :raises: TypeError if code is not a string.
787- :raises: ValueError if code contains non-numeric characters.
788-
789- """
790-
791- if not isinstance(code, basestring):
792- raise TypeError(
793- "'code' parameter must be a string, not %r."
794- % type(code)
795- )
796- for num in code:
797- if not num.isdigit():
798- raise ValueError(
799- "'code' parameter contains non-numeric characters."
800- )
801- self.touch.tap_object(self.main_window.get_pinPadButton(int(num)))
802-
803 def _enter_pin_passphrase(self, passphrase):
804 """Enter the password specified in 'passphrase' into the password entry
805 field of the pin lock screen.
806@@ -148,18 +127,15 @@
807 :raises: TypeError if passphrase is not a string.
808
809 """
810- if not isinstance(passphrase, basestring):
811+ if not isinstance(passphrase, str):
812 raise TypeError(
813 "'passphrase' parameter must be a string, not %r."
814 % type(passphrase)
815 )
816
817- pinentryField = self.main_window.get_pinentryField()
818- self.touch.tap_object(pinentryField)
819- self.assertThat(pinentryField.activeFocus, Eventually(Equals(True)))
820- for character in passphrase:
821- self._type_character(character, pinentryField)
822- logger.debug("Typed passphrase: %s", pinentryField.text)
823+ pin_entry_field = self.main_window.get_pinentryField()
824+ pin_entry_field.write(passphrase)
825+ logger.debug("Typed passphrase: %s", pin_entry_field.text)
826 self.keyboard.type("\n")
827
828 def _enter_prompt_passphrase(self, passphrase):
829@@ -177,21 +153,6 @@
830 )
831
832 prompt = self.main_window.get_greeter().get_prompt()
833- self.touch.tap_object(prompt)
834- self.assertThat(prompt.activeFocus, Eventually(Equals(True)))
835- for character in passphrase:
836- self._type_character(character, prompt)
837+ prompt.write(passphrase)
838 logger.debug("Typed passphrase: %s", prompt.text)
839 self.keyboard.type("\n")
840-
841- def _type_character(self, character, prompt, retries=5):
842- current_text = prompt.text
843- self.keyboard.type(character)
844- try:
845- self.assertThat(
846- prompt.text, Eventually(Equals(current_text + character)))
847- except AssertionError:
848- if retries > 0:
849- self._type_character(character, prompt, retries-1)
850- else:
851- raise
852
853=== modified file 'tests/autopilot/unity8/shell/tests/test_notifications.py'
854--- tests/autopilot/unity8/shell/tests/test_notifications.py 2014-07-18 15:13:35 +0000
855+++ tests/autopilot/unity8/shell/tests/test_notifications.py 2014-07-31 14:59:26 +0000
856@@ -154,7 +154,7 @@
857 'Notification', objectName='notification1')
858 notification = get_notification()
859
860- self.touch.tap_object(
861+ notification.pointing_device.click_object(
862 notification.select_single(objectName="interactiveArea")
863 )
864
865@@ -201,11 +201,14 @@
866 'Notification', objectName='notification1')
867 notification = get_notification()
868 self._assert_notification(notification, summary, body, True, True, 1.0)
869- initial_height = notification.height
870- self.touch.tap_object(notification.select_single(objectName="combobutton_dropdown"))
871- self.assertThat(notification.select_single(objectName="button2").expanded, Eventually(Equals(True)))
872+ notification.pointing_device.click_object(
873+ notification.select_single(objectName="combobutton_dropdown"))
874+ self.assertThat(
875+ notification.select_single(objectName="button2").expanded,
876+ Eventually(Equals(True)))
877 time.sleep(2)
878- self.touch.tap_object(notification.select_single(objectName="button4"))
879+ notification.pointing_device.click_object(
880+ notification.select_single(objectName="button4"))
881 self.assert_notification_action_id_was_called("action_decline_4")
882
883 def test_modal_sd_without_greeter(self):
884@@ -249,7 +252,8 @@
885 notification = get_notification()
886 self._assert_notification(
887 notification, summary, body, True, False, 1.0)
888- self.touch.tap_object(notification.select_single(objectName="button0"))
889+ notification.pointing_device.click_object(
890+ notification.select_single(objectName="button0"))
891 self.assert_notification_action_id_was_called("action_accept")
892
893 def test_modal_sd_with_greeter(self):
894@@ -291,7 +295,8 @@
895 notification = get_notification()
896 self._assert_notification(
897 notification, summary, body, True, False, 1.0)
898- self.touch.tap_object(notification.select_single(objectName="button0"))
899+ notification.pointing_device.click_object(
900+ notification.select_single(objectName="button0"))
901 self.assert_notification_action_id_was_called("action_accept")
902
903 def _create_interactive_notification(
904
905=== modified file 'tests/autopilot/unity8/shell/tests/test_upstart.py'
906--- tests/autopilot/unity8/shell/tests/test_upstart.py 2014-07-22 21:07:44 +0000
907+++ tests/autopilot/unity8/shell/tests/test_upstart.py 2014-07-31 14:59:26 +0000
908@@ -25,7 +25,8 @@
909 import subprocess
910 import time
911
912-from testtools.matchers._basic import Equals
913+import fixtures
914+from testtools.matchers import Equals, MismatchError
915 from autopilot.matchers import Eventually
916 from autopilot.introspection import get_proxy_object_for_existing_process
917
918@@ -100,16 +101,30 @@
919 emulator_base=UnityEmulatorBase,))
920
921 def test_no_sigstop(self):
922- self.patch_environment("UNITY_MIR_EMITS_SIGSTOP", "")
923+ self.useFixture(
924+ fixtures.EnvironmentVariable(
925+ 'UNITY_MIR_EMITS_SIGSTOP', newvalue=None))
926 self._launch_unity()
927+
928+ try:
929+ self.assertThat(
930+ lambda: os.WIFSTOPPED(self._get_status()),
931+ Eventually(Equals(True)))
932+ except MismatchError:
933+ pass
934+ else:
935+ self.process.send_singal(signal.SIGCONT)
936+ self.fail('Unity8 raised SIGSTOP')
937+
938 self._set_proxy()
939
940 logger.debug("Unity started, waiting for it to be ready.")
941- self.assertUnityReady()
942+ self.wait_for_unity()
943 logger.debug("Unity loaded and ready.")
944
945 def test_expect_sigstop(self):
946- self.patch_environment("UNITY_MIR_EMITS_SIGSTOP", "1")
947+ self.useFixture(
948+ fixtures.EnvironmentVariable('UNITY_MIR_EMITS_SIGSTOP', '1'))
949 self._launch_unity()
950 self.assertThat(
951 lambda: os.WIFSTOPPED(self._get_status()),
952@@ -122,5 +137,5 @@
953
954 logger.debug("Unity started, waiting for it to be ready.")
955 self._set_proxy()
956- self.assertUnityReady()
957+ self.wait_for_unity()
958 logger.debug("Unity loaded and ready.")

Subscribers

People subscribed via source and target branches