on xenial help sign in
Added methods to scroll to other scopes on autopilot tests.
commit7f2f0bacc5aabb464bcb6172e8f44972ef8245ef authorLeo Arias <leo.arias@canonical.com> dateFri 3 Jan 2014, 12:22 (13 years ago) parent0d78a8a
4 files changed+224−11
debian/control+1 tests/autopilot/unity8/shell/emulators/__init__.py+11−4 tests/autopilot/unity8/shell/emulators/dash.py+105−7 tests/autopilot/unity8/shell/tests/test_emulators.py+107
debian/control+1
@@ -95,6 +95,7 @@ Depends: gir1.2-glib-2.0,
9595 libqt5widgets5,
9696 python-evdev,
9797 python-gi,
98+ python-mock,
9899 unity8 (>= ${source:Version}),
99100 unity8-fake-env (>= ${source:Version}),
100101 ${misc:Depends},
tests/autopilot/unity8/shell/emulators/__init__.py+11−4
@@ -1,7 +1,7 @@
11# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
22#
33# Unity Autopilot Test Suite
4−# Copyright (C) 2012-2013 Canonical
4+# Copyright (C) 2012, 2013, 2014 Canonical
55#
66# This program is free software: you can redistribute it and/or modify
77# it under the terms of the GNU General Public License as published by
@@ -17,9 +17,16 @@
1717# along with this program. If not, see <http://www.gnu.org/licenses/>.
1818#
1919
20+from autopilot import input, introspection
2021
21−from autopilot.introspection import CustomEmulatorBase
2222
23−
24−class UnityEmulatorBase(CustomEmulatorBase):
23+class UnityEmulatorBase(introspection.CustomEmulatorBase):
2524 """A base class for all unity emulators."""
25+
26+ def __init__(self, *args):
27+ super(UnityEmulatorBase, self).__init__(*args)
28+ self.pointing_device = input.Touch.create()
29+
30+
31+class UnityEmulatorException(Exception):
32+ """Exception raised when there is an error with the Unity emulators."""
tests/autopilot/unity8/shell/emulators/dash.py+105−7
@@ -17,13 +17,24 @@
1717# along with this program. If not, see <http://www.gnu.org/licenses/>.
1818#
1919
20−from unity8.shell.emulators import UnityEmulatorBase
20+import logging
2121
22+from unity8.shell import emulators
2223
23−class Dash(UnityEmulatorBase):
24+from autopilot import logging as autopilot_logging
2425
26+
27+logger = logging.getLogger(__name__)
28+
29+
30+class Dash(emulators.UnityEmulatorBase):
2531 """An emulator that understands the Dash."""
2632
33+ def __init__(self, *args):
34+ super(Dash, self).__init__(*args)
35+ self.dash_content_list = self.wait_select_single(
36+ 'QQuickListView', objectName='dashContentList')
37+
2738 def get_home_applications_grid(self):
2839 get_grid = self.get_scope('home').wait_select_single(
2940 "GenericFilterGrid",
@@ -43,9 +54,96 @@ class Dash(UnityEmulatorBase):
4354 return resp_grid.select_single('Tile', text=text)
4455
4556 def get_scope(self, scope_name='home'):
46− dash_content = self.wait_select_single(
47− 'QQuickListView',
48− objectName='dashContentList'
49− )
5057 scope_id = "%s.scope" % scope_name
51− return dash_content.select_single('QQuickLoader', scopeId=scope_id)
58+ return self.dash_content_list.select_single(
59+ 'QQuickLoader', scopeId=scope_id)
60+
61+ @autopilot_logging.log_action(logger.info)
62+ def open_scope(self, scope_name):
63+ """Open a dash scope.
64+
65+ :parameter scope_name: The name of the scope.
66+ :return: The scope.
67+
68+ """
69+ scope_id = "%s.scope" % scope_name
70+ scope_index = self._get_scope_index(scope_id)
71+ if scope_index == self.dash_content_list.currentIndex:
72+ logger.info('The scope is already open.')
73+ return self._get_scope_by_index(scope_index)
74+ else:
75+ return self._open_scope_scrolling(scope_index)
76+
77+ def _get_scope_index(self, scope_id):
78+ scope_loaders = self.dash_content_list.select_many('QQuickLoader')
79+ for index, loader in enumerate(scope_loaders):
80+ try:
81+ if loader.scopeId == scope_id:
82+ return index
83+ except AttributeError:
84+ pass
85+ else:
86+ raise emulators.UnityEmulatorException(
87+ 'No scope found with id {0}'.format(scope_id))
88+
89+ def _get_scope_by_index(self, scope_index):
90+ scope_loaders = self.dash_content_list.select_many('QQuickLoader')
91+ return self._get_scope_from_loader(scope_loaders[scope_index])
92+
93+ def _get_scope_from_loader(self, loader):
94+ if loader.scopeId == 'applications.scope':
95+ return loader.select_single(DashApps)
96+ else:
97+ return loader.select_single(GenericScopeView)
98+
99+ def _open_scope_scrolling(self, scope_index):
100+ scroll = self._get_scroll_direction(scope_index)
101+
102+ while scope_index != self.dash_content_list.currentIndex:
103+ scroll()
104+ scope = self._get_scope_by_index(scope_index)
105+ scope.moving.wait_for(False)
106+ scope.isCurrent.wait_for(True)
107+ return scope
108+
109+ def _get_scroll_direction(self, scope_index):
110+ if scope_index < self.dash_content_list.currentIndex:
111+ return self._scroll_to_left_scope
112+ elif scope_index > self.dash_content_list.currentIndex:
113+ return self._scroll_to_right_scope
114+ else:
115+ raise emulators.UnityEmulatorException('The scope is already open')
116+
117+ @autopilot_logging.log_action(logger.info)
118+ def _scroll_to_left_scope(self):
119+ original_index = self.dash_content_list.currentIndex
120+ # Scroll on the dash bar, because some scopes have contents that can be
121+ # scrolled horizontally.
122+ panel = self.select_single('DashBar').select_single('Panel')
123+ start_x = panel.width / 3
124+ stop_x = panel.width / 3 * 2
125+ start_y = stop_y = panel.globalRect.y + panel.height / 2
126+ self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
127+ self.dash_content_list.currentIndex.wait_for(original_index - 1)
128+ panel.opened.wait_for(False)
129+
130+ @autopilot_logging.log_action(logger.info)
131+ def _scroll_to_right_scope(self):
132+ original_index = self.dash_content_list.currentIndex
133+ # Scroll on the dash bar panel, because some scopes have contents that
134+ # can be scrolled horizontally.
135+ panel = self.select_single('DashBar').select_single('Panel')
136+ start_x = panel.width / 3 * 2
137+ stop_x = panel.width / 3
138+ start_y = stop_y = panel.globalRect.y + panel.height / 2
139+ self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
140+ self.dash_content_list.currentIndex.wait_for(original_index + 1)
141+ panel.opened.wait_for(False)
142+
143+
144+class GenericScopeView(emulators.UnityEmulatorBase):
145+ """Autopilot emulators for generic scopes."""
146+
147+
148+class DashApps(emulators.UnityEmulatorBase):
149+ """Autopilot emulators for the applications scope."""
tests/autopilot/unity8/shell/tests/test_emulators.pynew file+107
@@ -0,0 +1,107 @@
1+# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2+#
3+# Unity Autopilot Test Suite
4+# Copyright (C) 2014 Canonical
5+#
6+# This program is free software: you can redistribute it and/or modify
7+# it under the terms of the GNU General Public License as published by
8+# the Free Software Foundation, either version 3 of the License, or
9+# (at your option) any later version.
10+#
11+# This program is distributed in the hope that it will be useful,
12+# but WITHOUT ANY WARRANTY; without even the implied warranty of
13+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14+# GNU General Public License for more details.
15+#
16+# You should have received a copy of the GNU General Public License
17+# along with this program. If not, see <http://www.gnu.org/licenses/>.
18+#
19+
20+import mock
21+
22+from unity8.shell import emulators, tests
23+from unity8.shell.emulators import dash as dash_emulators
24+
25+
26+class DashEmulatorTestCase(tests.UnityTestCase):
27+
28+ scenarios = tests._get_device_emulation_scenarios()
29+
30+ def setUp(self):
31+ super(DashEmulatorTestCase, self).setUp()
32+ self.launch_unity()
33+ self.main_window.get_greeter().swipe()
34+ self.dash = self.main_window.get_dash()
35+ self.scope_loaders = self.dash.dash_content_list.select_many(
36+ 'QQuickLoader')
37+
38+ def test_open_unexisting_scope(self):
39+ scope_name = 'unexisting'
40+ with mock.patch.object(self.dash, 'pointing_device') as mock_pointer:
41+ exception = self.assertRaises(
42+ emulators.UnityEmulatorException,
43+ self.dash.open_scope, scope_name)
44+
45+ self.assertEqual(
46+ 'No scope found with id unexisting.scope', str(exception))
47+ self.assertFalse(mock_pointer.called)
48+
49+ def test_open_already_opened_scope(self):
50+ scope_id = self._get_current_scope_id()
51+ with mock.patch.object(self.dash, 'pointing_device') as mock_pointer:
52+ scope = self.dash.open_scope(self._get_scope_name_from_id(
53+ scope_id))
54+
55+ self.assertFalse(mock_pointer.called)
56+ self._assert_scope_is_opened(scope, scope_id)
57+
58+ def _assert_scope_is_opened(self, scope, scope_id):
59+ scope_loader = scope.get_parent()
60+ self.assertTrue(scope.isCurrent)
61+ self.assertEqual(scope_loader.scopeId, scope_id)
62+
63+ def _get_current_scope_id(self):
64+ scope = self.scope_loaders[self.dash.dash_content_list.currentIndex]
65+ return scope.scopeId
66+
67+ def test_open_scope_to_the_right(self):
68+ leftmost_scope = self._get_scope_name_from_id(
69+ self._get_leftmost_scope_id())
70+ self.dash.open_scope(leftmost_scope)
71+
72+ scope_id = self._get_rightmost_scope_id()
73+ scope = self.dash.open_scope(self._get_scope_name_from_id(scope_id))
74+ self._assert_scope_is_opened(scope, scope_id)
75+
76+ def _get_leftmost_scope_id(self):
77+ scope = self.scope_loaders[0]
78+ return scope.scopeId
79+
80+ def _get_scope_name_from_id(self, scope_id):
81+ if scope_id.endswith('.scope'):
82+ return scope_id[:-6]
83+
84+ def _get_rightmost_scope_id(self):
85+ scope = self.scope_loaders[self.dash.dash_content_list.count - 1]
86+ return scope.scopeId
87+
88+ def test_open_scope_to_the_left(self):
89+ rightmost_scope = self._get_scope_name_from_id(
90+ self._get_rightmost_scope_id())
91+ self.dash.open_scope(rightmost_scope)
92+
93+ scope_id = self._get_leftmost_scope_id()
94+ scope = self.dash.open_scope(self._get_scope_name_from_id(scope_id))
95+ self._assert_scope_is_opened(scope, scope_id)
96+
97+ def test_open_generic_scope(self):
98+ scope_id = 'home.scope'
99+ scope = self.dash.open_scope(self._get_scope_name_from_id(scope_id))
100+ self._assert_scope_is_opened(scope, scope_id)
101+ self.assertIsInstance(scope, dash_emulators.GenericScopeView)
102+
103+ def test_open_applications_scope(self):
104+ scope_id = 'applications.scope'
105+ scope = self.dash.open_scope(self._get_scope_name_from_id(scope_id))
106+ self._assert_scope_is_opened(scope, scope_id)
107+ self.assertIsInstance(scope, dash_emulators.DashApps)