Unity 8
 All Classes Functions Properties
dash.py
1 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2 #
3 # Unity Autopilot Test Suite
4 # Copyright (C) 2012, 2013, 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 logging
21 
22 from unity8.shell import emulators
23 
24 from autopilot import logging as autopilot_logging
25 from autopilot.introspection import dbus
26 from testtools.matchers import MatchesAny, Equals
27 from ubuntuuitoolkit import emulators as toolkit_emulators
28 
29 
30 logger = logging.getLogger(__name__)
31 
32 
34  """An emulator that understands the Dash."""
35 
36  def __init__(self, *args):
37  super(Dash, self).__init__(*args)
38  self.dash_content_list = self.wait_select_single(
39  'QQuickListView', objectName='dashContentList')
40 
41  def get_applications_grid(self):
42  get_grid = self.get_scope('clickscope').wait_select_single(
43  'CardFilterGrid', objectName='local')
44  return get_grid
45 
46  def get_application_icon(self, text):
47  """Returns a 'Tile' icon that has the text 'text' from the application
48  grid.
49 
50  :param text: String containing the text of the icon to search for.
51 
52  """
53  app_grid = self.get_applications_grid()
54  resp_grid = app_grid.wait_select_single('ResponsiveGridView')
55  return resp_grid.select_single('Tile', text=text)
56 
57  def get_scope(self, scope_name='clickscope'):
58  return self.dash_content_list.select_single(
59  'QQuickLoader', scopeId=scope_name)
60 
61  @autopilot_logging.log_action(logger.info)
62  def open_scope(self, scope_id):
63  """Open a dash scope.
64 
65  :parameter scope_id: The id of the scope.
66  :return: The scope.
67 
68  """
69  scope_loader = self._get_scope_loader(scope_id)
70  if scope_loader.isCurrent:
71  logger.info('The scope is already open.')
72  return self._get_scope_from_loader(scope_loader)
73  else:
74  return self._open_scope_scrolling(scope_loader)
75 
76  def _get_scope_loader(self, scope_id):
77  try:
78  return self.dash_content_list.select_single(
79  'QQuickLoader', scopeId=scope_id)
80  except dbus.StateNotFoundError:
82  'No scope found with id {0}'.format(scope_id))
83 
84  def _get_scope_from_loader(self, loader):
85  return loader.get_children()[0]
86 
87  def _open_scope_scrolling(self, scope_loader):
88  scroll = self._get_scroll_direction(scope_loader)
89 
90  while not scope_loader.isCurrent:
91  scroll()
92  self.dash_content_list.moving.wait_for(False)
93 
94  scope = self._get_scope_from_loader(scope_loader)
95  scope.isCurrent.wait_for(True)
96  return scope
97 
98  def _get_scroll_direction(self, scope_loader):
99  current_scope_loader = self.dash_content_list.select_single(
100  'QQuickLoader', isCurrent=True)
101  if scope_loader.globalRect.x < current_scope_loader.globalRect.x:
102  return self._scroll_to_left_scope
103  elif scope_loader.globalRect.x > current_scope_loader.globalRect.x:
104  return self._scroll_to_right_scope
105  else:
106  raise emulators.UnityEmulatorException('The scope is already open')
107 
108  @autopilot_logging.log_action(logger.info)
109  def _scroll_to_left_scope(self):
110  original_index = self.dash_content_list.currentIndex
111  dashContent = self.select_single(objectName="dashContent")
112  start_x = dashContent.width / 3
113  stop_x = dashContent.width / 3 * 2
114  start_y = stop_y = dashContent.globalRect.y + 1
115  self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
116  self.dash_content_list.currentIndex.wait_for(original_index - 1)
117 
118  @autopilot_logging.log_action(logger.info)
119  def _scroll_to_right_scope(self):
120  original_index = self.dash_content_list.currentIndex
121  dashContent = self.select_single(objectName="dashContent")
122  start_x = dashContent.width / 3 * 2
123  stop_x = dashContent.width / 3
124  start_y = stop_y = dashContent.globalRect.y + 1
125  self.pointing_device.drag(start_x, start_y, stop_x, stop_y)
126  self.dash_content_list.currentIndex.wait_for(original_index + 1)
127 
128  def enter_search_query(self, query):
129  current_header = self._get_current_page_header()
130  self.pointing_device.move(current_header.globalRect.x +
131  current_header.width - current_header.height / 2,
132  current_header.globalRect.y +
133  current_header.height / 2)
134  self.pointing_device.click()
135  headerContainer = current_header.select_single(objectName="headerContainer")
136  headerContainer.contentY.wait_for(0)
137  search_text_field = self._get_search_text_field()
138  search_text_field.write(query)
139  current_header.select_single(objectName="searchIndicator").running.wait_for(False)
140 
141  def _get_search_text_field(self):
142  page_header = self._get_current_page_header()
143  return page_header.select_single(objectName='searchTextField')
144 
145  def _get_current_page_header(self):
146  dashContentList = self.select_single(objectName="dashContentList")
147  all_headers = dashContentList.select_many("QQuickLoader")
148  for i in all_headers:
149  if i.isCurrent:
150  return i.select_single(objectName="scopePageHeader")
151  return None
152 
153 
155  """Autopilot emulator for generic scopes."""
156 
157  @autopilot_logging.log_action(logger.info)
158  def open_preview(self, category, app_name):
159  """Open the preview of an application.
160 
161  :parameter category: The name of the category where the application is.
162  :app_name: The name of the application.
163  :return: The opened preview.
164 
165  """
166  category_element = self._get_category_element(category)
167  icon = category_element.select_single('AbstractButton', title=app_name)
168  # FIXME some categories need a long press in order to see the preview.
169  # Some categories do not show previews, like recent apps.
170  # --elopio - 2014-1-14
171  self.pointing_device.click_object(icon)
172  preview_list = self.wait_select_single(
173  'PreviewListView', objectName='previewListView')
174  preview_list.x.wait_for(0)
175  return preview_list.select_single(
176  Preview, objectName='preview{}'.format(preview_list.currentIndex))
177 
178  def _get_category_element(self, category):
179  try:
180  return self.wait_select_single(
181  'Base', objectName='dashCategory{}'.format(category))
182  except dbus.StateNotFoundError:
184  'No category found with name {}'.format(category))
185 
186 
188  """Autopilot emulator for the applications scope."""
189 
190  def get_applications(self, category):
191  """Return the list of applications on a category.
192 
193  :parameter category: The name of the category.
194 
195  """
196  category_element = self._get_category_element(category)
197  application_cards = category_element.select_many('AbstractButton')
198 
199  # sort by y, x
200  application_cards = sorted(
201  application_cards,
202  key=lambda card: (card.globalRect.y, card.globalRect.x))
203 
204  result = []
205  for card in application_cards:
206  if card.objectName != 'cardToolCard':
207  result.append(card.title)
208  return result
209 
210 
212  """Autopilot custom proxy object for generic previews."""