Lomiri
__init__.py
1 # -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2 #
3 # Lomiri Autopilot Test Suite
4 # Copyright (C) 2012-2015 Canonical Ltd.
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 """lomiri shell autopilot tests and helpers - sub level package."""
21 
22 import logging
23 from functools import wraps
24 
25 import lomiriuitoolkit
26 from autopilot import logging as autopilot_logging
27 from autopilot import input
28 import gi
29 gi.require_version('Notify', '0.7')
30 from gi.repository import Notify
31 
32 from lomiri import (
33  greeter,
34  launcher as launcher_helpers
35 )
36 
37 
38 logger = logging.getLogger(__name__)
39 
40 
41 def disable_qml_mocking(fn):
42  """Simple decorator that disables the QML mocks from being loaded."""
43  @wraps(fn)
44  def wrapper(*args, **kwargs):
45  tests_self = args[0]
46  tests_self._qml_mock_enabled = False
47  return fn(*args, **kwargs)
48  return wrapper
49 
50 
51 def create_ephemeral_notification(
52  summary='',
53  body='',
54  icon=None,
55  hints=[],
56  urgency='NORMAL'
57 ):
58  """Create an ephemeral (non-interactive) notification
59 
60  :param summary: Summary text for the notification
61  :param body: Body text to display in the notification
62  :param icon: Path string to the icon to use
63  :param hint_strings: List of tuples containing the 'name' and value
64  for setting the hint strings for the notification
65  :param urgency: Urgency string for the noticiation, either: 'LOW',
66  'NORMAL', 'CRITICAL'
67  """
68  Notify.init('Lomiri')
69 
70  logger.info(
71  "Creating ephemeral: summary(%s), body(%s), urgency(%r) "
72  "and Icon(%s)",
73  summary,
74  body,
75  urgency,
76  icon
77  )
78 
79  notification = Notify.Notification.new(summary, body, icon)
80 
81  for hint in hints:
82  key, value = hint
83  notification.set_hint_string(key, value)
84  logger.info("Adding hint to notification: (%s, %s)", key, value)
85  notification.set_urgency(_get_urgency(urgency))
86 
87  return notification
88 
89 
90 def _get_urgency(urgency):
91  """Translates urgency string to enum."""
92  _urgency_enums = {'LOW': Notify.Urgency.LOW,
93  'NORMAL': Notify.Urgency.NORMAL,
94  'CRITICAL': Notify.Urgency.CRITICAL}
95  return _urgency_enums.get(urgency.upper())
96 
97 
98 class ShellView(lomiriuitoolkit.LomiriUIToolkitCustomProxyObjectBase):
99  """An helper class that makes it easy to interact with the shell"""
100 
101  def get_greeter(self):
102  return self.select_single(greeter.Greeter)
103 
104  def get_login_loader(self):
105  return self.select_single("QQuickLoader", objectName="loginLoader")
106 
107  def get_login_list(self):
108  return self.select_single("LoginList")
109 
110  def get_bottombar(self):
111  return self.select_single("Bottombar")
112 
113  def get_pinPadLoader(self):
114  return self.select_single(
115  "QQuickLoader",
116  objectName="pinPadLoader"
117  )
118 
119  def get_lockscreen(self):
120  return self.select_single("Lockscreen")
121 
122  def get_pinentryField(self):
123  return self.select_single(objectName="pinentryField")
124 
125  def _get_indicator_panel_item(self, indicator_name):
126  return self.select_single(
127  'IndicatorItem',
128  objectName=indicator_name+'-panelItem'
129  )
130 
131  def _get_indicator_page(self, indicator_name):
132  return self.select_single(
133  'IndicatorPage',
134  objectName=indicator_name+'-page'
135  )
136 
137  @autopilot_logging.log_action(logger.info)
138  def open_indicator_page(self, indicator_name):
139  """Swipe to open the indicator, wait until it's open.
140 
141  :returns: The indicator page.
142  """
143  widget = self._get_indicator_panel_item(indicator_name)
144  start_x, start_y = input.get_center_point(widget)
145  end_x = start_x
146  end_y = self.height
147  self.pointing_device.drag(start_x, start_y, end_x, end_y)
148  self.wait_select_single('IndicatorsMenu', fullyOpened=True)
149  return self._get_indicator_page(indicator_name)
150 
151  @autopilot_logging.log_action(logger.info)
153  """Swipe to close the opened indicator, wait until it's closed."""
154  indicators_menu = self.wait_select_single('IndicatorsMenu')
155  end_x, end_y = input.get_center_point(indicators_menu)
156  start_x = end_x
157  start_y = self.height
158  self.pointing_device.drag(start_x, start_y, end_x, end_y)
159  indicators_menu.fullyClosed.wait_for(True)
160 
161  @autopilot_logging.log_action(logger.info)
162  def show_dash_swiping(self):
163  """Show the dash swiping from the left."""
164  x, y, width, height = self._get_shell().globalRect
165  start_x = x
166  end_x = x + width
167  start_y = end_y = y + height // 2
168 
169  self.pointing_device.drag(start_x, start_y, end_x, end_y)
170  self.get_current_focused_app_id().wait_for('lomiri-dash')
171 
172  def _get_shell(self):
173  return self.select_single('Shell')
174 
176  """Return the id of the focused application."""
177  return self._get_shell().focusedApplicationId
178 
179  @autopilot_logging.log_action(logger.info)
181  """Open the dash clicking the dash icon on the launcher."""
182  launcher = self.open_launcher()
183  launcher.click_dash_icon()
184  self.get_current_focused_app_id().wait_for('lomiri-dash')
185  launcher.shown.wait_for(False)
186 
187  @autopilot_logging.log_action(logger.info)
188  def open_launcher(self):
189  launcher = self._get_launcher()
190  launcher.show()
191  return launcher
192 
193  def _get_launcher(self):
194  return self.select_single(launcher_helpers.Launcher)
195 
196  def is_launcher_open(self):
197  return self._get_launcher().shown
198 
199  @autopilot_logging.log_action(logger.info)
200  def launch_application(self, application_name):
201  """Launch an application.
202 
203  :parameter application_name: The name of the application to launch.
204 
205  """
206  launcher = self.open_launcher()
207  launcher.click_application_launcher_icon(application_name)
208  self.get_current_focused_app_id().wait_for(application_name)
209  launcher.shown.wait_for(False)
210 
211  def enter_pin_code(self, code):
212  """Enter code 'code' into the single-pin lightdm pincode entry screen.
213 
214  :param code: must be a string of numeric characters.
215  :raises: TypeError if code is not a string.
216  :raises: ValueError if code contains non-numeric characters.
217 
218  """
219  if not isinstance(code, str):
220  raise TypeError(
221  "'code' parameter must be a string, not %r."
222  % type(code)
223  )
224  for num in code:
225  if not num.isdigit():
226  raise ValueError(
227  "'code' parameter contains non-numeric characters."
228  )
229  self.pointing_device.click_object(
230  self._get_pinpad_button(int(num)))
231 
232  def _get_pinpad_button(self, button_id):
233  return self.select_single(
234  'PinPadButton',
235  objectName='pinPadButton{}'.format(button_id)
236  )
237 
238  def get_shell_orientation_angle(self):
239  return self._get_shell().orientationAngle
240 
241  def get_shell_orientation(self):
242  return self._get_shell().orientation
243 
244  def get_shell_primary_orientation(self):
245  return self._get_shell().primaryOrientation
246 
247  def get_shell_native_orientation(self):
248  return self._get_shell().nativeOrientation
249 
250  @autopilot_logging.log_action(logger.info)
252  """Wait for a notification dialog to appear.
253 
254  :return: An object for the notification dialog data.
255  :raise StateNotFoundError: if the timeout expires when the
256  notification has not appeared.
257 
258  """
259  notify_list = self.select_single('Notifications',
260  objectName='notificationList')
261  visible_notification = notify_list.wait_select_single('Notification',
262  visible=True)
263  return {'summary': visible_notification.summary,
264  'body': visible_notification.body,
265  'iconSource': visible_notification.iconSource}
lomiri::shell.ShellView.wait_for_notification
def wait_for_notification(self)
Definition: __init__.py:251
lomiri::shell.ShellView.close_indicator_page
def close_indicator_page(self)
Definition: __init__.py:152
lomiri::shell.ShellView._get_launcher
def _get_launcher(self)
Definition: __init__.py:193
lomiri::shell.ShellView.enter_pin_code
def enter_pin_code(self, code)
Definition: __init__.py:211
lomiri::shell.ShellView._get_indicator_panel_item
def _get_indicator_panel_item(self, indicator_name)
Definition: __init__.py:125
lomiri::shell.ShellView._get_shell
def _get_shell(self)
Definition: __init__.py:172
lomiri::shell.ShellView._get_pinpad_button
def _get_pinpad_button(self, button_id)
Definition: __init__.py:232
lomiri::shell.ShellView.show_dash_swiping
def show_dash_swiping(self)
Definition: __init__.py:162
lomiri::shell.ShellView._get_indicator_page
def _get_indicator_page(self, indicator_name)
Definition: __init__.py:131
lomiri::shell.ShellView.open_indicator_page
def open_indicator_page(self, indicator_name)
Definition: __init__.py:138
lomiri::shell.ShellView.get_current_focused_app_id
def get_current_focused_app_id(self)
Definition: __init__.py:175
lomiri::shell.ShellView.show_dash_from_launcher
def show_dash_from_launcher(self)
Definition: __init__.py:180
lomiri::shell.ShellView
Definition: __init__.py:98
lomiri::shell.ShellView.open_launcher
def open_launcher(self)
Definition: __init__.py:188
lomiri::shell.ShellView.launch_application
def launch_application(self, application_name)
Definition: __init__.py:200
lomiri.greeter.Greeter
Definition: __init__.py:61