Merge lp:~veebers/autopilot/add_OSK_keyboard_backend into lp:autopilot

Proposed by Christopher Lee
Status: Merged
Approved by: Thomi Richards
Approved revision: 327
Merged at revision: 313
Proposed branch: lp:~veebers/autopilot/add_OSK_keyboard_backend
Merge into: lp:autopilot
Diff against target: 601 lines (+444/-8)
5 files modified
autopilot/input/__init__.py (+67/-3)
autopilot/input/_osk.py (+121/-0)
autopilot/tests/functional/test_input_stack.py (+130/-1)
docs/faq/faq.rst (+30/-3)
docs/tutorial/advanced_autopilot.rst (+96/-1)
To merge this branch: bzr merge lp:~veebers/autopilot/add_OSK_keyboard_backend
Reviewer Review Type Date Requested Status
Thomi Richards (community) Approve
PS Jenkins bot continuous-integration Approve
Review via email: mp+181456@code.launchpad.net

Commit message

Adds the Ubuntu Keyboard OSK as an input backend

Description of the change

Adds the Ubuntu Keyboard OSK as an input backend

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
323. By Christopher Lee

Documentation updates.

324. By Christopher Lee

Fix exception raised and docs

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
325. By Christopher Lee

Further docs improvements

326. By Christopher Lee

Minor doc change

Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote :

LGTM

review: Approve
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
327. By Christopher Lee

Re-order OSK Keyboard backend priority

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Approve (continuous-integration)
Revision history for this message
Thomi Richards (thomir-deactivatedaccount) wrote :

Still LGTM

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'autopilot/input/__init__.py'
--- autopilot/input/__init__.py 2013-07-23 04:04:43 +0000
+++ autopilot/input/__init__.py 2013-08-23 05:01:40 +0000
@@ -56,6 +56,7 @@
56"""56"""
5757
58from collections import OrderedDict58from collections import OrderedDict
59from contextlib import contextmanager
59from autopilot.utilities import _pick_backend, CleanupRegistered60from autopilot.utilities import _pick_backend, CleanupRegistered
60from autopilot.input._common import get_center_point61from autopilot.input._common import get_center_point
6162
@@ -81,12 +82,21 @@
81 For more infomration on picking specific backends, see82 For more infomration on picking specific backends, see
82 :ref:`tut-picking-backends`83 :ref:`tut-picking-backends`
8384
85 For details regarding backend limitations please see:
86 :ref:`Keyboard backend limitations<keyboard_backend_limitations>`
87
88 .. warning:: The **OSK** (On Screen Keyboard) backend option does not
89 implement either :py:meth:`press` or :py:meth:`release` methods due to
90 technical implementation details and will raise a NotImplementedError
91 exception if used.
92
84 :param preferred_backend: A string containing a hint as to which93 :param preferred_backend: A string containing a hint as to which
85 backend you would like. Possible backends are:94 backend you would like. Possible backends are:
8695
87 * ``X11`` - Generate keyboard events using the X11 client96 * ``X11`` - Generate keyboard events using the X11 client
88 libraries.97 libraries.
89 * ``UInput`` - Use UInput kernel-level device driver.98 * ``UInput`` - Use UInput kernel-level device driver.
99 * ``OSK`` - Use the graphical On Screen Keyboard as a backend.
90100
91 :raises: RuntimeError if autopilot cannot instantate any of the101 :raises: RuntimeError if autopilot cannot instantate any of the
92 possible backends.102 possible backends.
@@ -104,17 +114,67 @@
104 from autopilot.input._uinput import Keyboard114 from autopilot.input._uinput import Keyboard
105 return Keyboard()115 return Keyboard()
106116
117 def get_osk_kb():
118 try:
119 from autopilot.input._osk import Keyboard
120 return Keyboard()
121 except ImportError as e:
122 e.args += ("Unable to import the OSK backend",)
123 raise
124
107 backends = OrderedDict()125 backends = OrderedDict()
108 backends['X11'] = get_x11_kb126 backends['X11'] = get_x11_kb
109 backends['UInput'] = get_uinput_kb127 backends['UInput'] = get_uinput_kb
128 backends['OSK'] = get_osk_kb
110 return _pick_backend(backends, preferred_backend)129 return _pick_backend(backends, preferred_backend)
111130
131 @contextmanager
132 def focused_type(self, input_target, pointer=None):
133 """Type into an input widget.
134
135 This context manager takes care of making sure a particular
136 *input_target* UI control is selected before any text is entered.
137
138 Some backends extend this method to perform cleanup actions at the end
139 of the context manager block. For example, the OSK backend dismisses
140 the keyboard.
141
142 If the *pointer* argument is None (default) then either a Mouse or
143 Touch pointer will be created based on the current platform.
144
145 An example of using the context manager (with an OSK backend)::
146
147 from autopilot.input import Keyboard
148
149 text_area = self._launch_test_input_area()
150 keyboard = Keyboard.create('OSK')
151 with keyboard.focused_type(text_area) as kb:
152 kb.type("Hello World.")
153 self.assertThat(text_area.text, Equals("Hello World"))
154 # Upon leaving the context managers scope the keyboard is dismissed
155 # with a swipe
156
157 """
158 if pointer is None:
159 from autopilot.platform import model
160 if model() == 'Desktop':
161 pointer = Pointer(Mouse.create())
162 else:
163 pointer = Pointer(Touch.create())
164
165 pointer.click_object(input_target)
166 yield self
167
112 def press(self, keys, delay=0.2):168 def press(self, keys, delay=0.2):
113 """Send key press events only.169 """Send key press events only.
114170
115 :param keys: Keys you want pressed.171 :param keys: Keys you want pressed.
116 :param delay: The delay (in Seconds) after pressing the keys before172 :param delay: The delay (in Seconds) after pressing the keys before
117 returning control to the caller.173 returning control to the caller.
174 :raises: NotImplementedError If called when using the OSK Backend.
175
176 .. warning:: The **OSK** backend does not implement the press method
177 and will raise a NotImplementedError if called.
118178
119 Example:179 Example:
120180
@@ -131,6 +191,10 @@
131 :param keys: Keys you want released.191 :param keys: Keys you want released.
132 :param delay: The delay (in Seconds) after releasing the keys before192 :param delay: The delay (in Seconds) after releasing the keys before
133 returning control to the caller.193 returning control to the caller.
194 :raises: NotImplementedError If called when using the OSK Backend.
195
196 .. warning:: The **OSK** backend does not implement the press method
197 and will raise a NotImplementedError if called.
134198
135 Example:199 Example:
136200
@@ -219,14 +283,14 @@
219 from autopilot.platform import model283 from autopilot.platform import model
220 if model() != 'Desktop':284 if model() != 'Desktop':
221 logger.info(285 logger.info(
222 "You cannot create a Mouse on the phablet devices. "286 "You cannot create a Mouse on the devices where X11 is not "
223 "consider using a Touch or Pointer device. "287 "available. consider using a Touch or Pointer device. "
224 "For more information, see: "288 "For more information, see: "
225 "http://unity.ubuntu.com/autopilot/api/input.html"289 "http://unity.ubuntu.com/autopilot/api/input.html"
226 "#autopilot-unified-input-system"290 "#autopilot-unified-input-system"
227 )291 )
228 raise RuntimeError(292 raise RuntimeError(
229 "Cannot create a Mouse on the phablet devices."293 "Cannot create a Mouse on devices where X11 is not available."
230 )294 )
231295
232 backends = OrderedDict()296 backends = OrderedDict()
233297
=== added file 'autopilot/input/_osk.py'
--- autopilot/input/_osk.py 1970-01-01 00:00:00 +0000
+++ autopilot/input/_osk.py 2013-08-23 05:01:40 +0000
@@ -0,0 +1,121 @@
1# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
2#
3# Autopilot Functional Test Tool
4# Copyright (C) 2013 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
20import logging
21from time import sleep
22from contextlib import contextmanager
23
24from ubuntu_keyboard.emulators.keyboard import (
25 Keyboard as KeyboardDriver,
26 UnsupportedKey,
27)
28
29from autopilot.input import Keyboard as KeyboardBase
30
31
32logger = logging.getLogger(__name__)
33
34
35class Keyboard(KeyboardBase):
36
37 _keyboard = KeyboardDriver()
38
39 @contextmanager
40 def focused_type(self, input_target, pointer=None):
41 """Ensures that the keyboard is up and ready for input as well as
42 dismisses the keyboard afterward.
43
44 """
45 with super(Keyboard, self).focused_type(input_target, pointer):
46 try:
47 self._keyboard.wait_for_keyboard_ready()
48 yield self
49 finally:
50 self._keyboard.dismiss()
51
52 def press(self, keys, delay=0.2):
53 raise NotImplementedError(
54 "OSK Backend does not support the press method"
55 )
56
57 def release(self, keys, delay=0.2):
58 raise NotImplementedError(
59 "OSK Backend does not support the release method"
60 )
61
62 def press_and_release(self, key, delay=0.2):
63 """Press and release the key *key*.
64
65 The 'key' argument must be a string of the single key you want pressed
66 and released.
67
68 For example::
69
70 press_and_release('A')
71
72 presses then releases the 'A' key.
73
74 :raises: *UnsupportedKey* if the provided key is not supported by the
75 OSK Backend (or the current OSK langauge layout.)
76 :raises: *ValueError* if there is more than a single key supplied in
77 the *key* argument.
78
79 """
80
81 if len(self._sanitise_keys(key)) != 1:
82 raise ValueError("Only a single key can be passed in.")
83
84 try:
85 self._keyboard.press_key(key)
86 sleep(delay)
87 except UnsupportedKey as e:
88 e.args += ("OSK Backend is unable to type the key '%s" % key,)
89 raise
90
91 def type(self, string, delay=0.1):
92 """Simulate a user typing a string of text.
93
94 Only 'normal' keys can be typed with this method. There is no such
95 thing as Alt or Ctrl on the Onscreen Keyboard.
96
97 The OSK class back end will take care of ensuring that capitalized
98 keys are in fact capitalized.
99
100 :raises: *UnsupportedKey* if there is a key within the string that is
101 not supported by the OSK Backend (or the current OSK langauge layout.)
102
103 """
104 if not isinstance(string, basestring):
105 raise TypeError("'string' argument must be a string.")
106 logger.debug("Typing text: %s", string)
107 self._keyboard.type(string, delay)
108
109 @classmethod
110 def on_test_end(cls, test_instance):
111 """Dismiss (swipe hide) the keyboard.
112
113 """
114 logger.debug("Dismissing the OSK with a swipe.")
115 cls._keyboard.dismiss()
116
117 def _sanitise_keys(self, keys):
118 if keys == '+':
119 return [keys]
120 else:
121 return keys.split('+')
0122
=== modified file 'autopilot/tests/functional/test_input_stack.py'
--- autopilot/tests/functional/test_input_stack.py 2013-07-24 08:26:10 +0000
+++ autopilot/tests/functional/test_input_stack.py 2013-08-23 05:01:40 +0000
@@ -21,11 +21,13 @@
21import json21import json
22import os22import os
23from tempfile import mktemp23from tempfile import mktemp
24from testtools import TestCase24from testtools import TestCase, skipIf
25from testtools.matchers import IsInstance, Equals, raises25from testtools.matchers import IsInstance, Equals, raises
26from textwrap import dedent
26from unittest import SkipTest27from unittest import SkipTest
27from mock import patch28from mock import patch
2829
30from autopilot import platform
29from autopilot.testcase import AutopilotTestCase, multiply_scenarios31from autopilot.testcase import AutopilotTestCase, multiply_scenarios
30from autopilot.input import Keyboard, Mouse, Pointer, Touch32from autopilot.input import Keyboard, Mouse, Pointer, Touch
31from autopilot.input._common import get_center_point33from autopilot.input._common import get_center_point
@@ -106,6 +108,24 @@
106 "app shows: " + text_edit.plainText108 "app shows: " + text_edit.plainText
107 )109 )
108110
111 def test_typing_with_contextmanager(self):
112 """Typing text must produce the correct characters in the target
113 app.
114
115 """
116 app_proxy = self.start_mock_app()
117 text_edit = app_proxy.select_single('QTextEdit')
118
119 keyboard = Keyboard.create(self.backend)
120 with keyboard.focused_type(text_edit) as kb:
121 kb.type(self.input, 0.01)
122
123 self.assertThat(
124 text_edit.plainText,
125 Eventually(Equals(self.input)),
126 "app shows: " + text_edit.plainText
127 )
128
109 def test_keyboard_keys_are_released(self):129 def test_keyboard_keys_are_released(self):
110 """Typing characters must not leave keys pressed."""130 """Typing characters must not leave keys pressed."""
111 app_proxy = self.start_mock_app()131 app_proxy = self.start_mock_app()
@@ -137,6 +157,115 @@
137 )157 )
138158
139159
160@skipIf(platform.model() == 'Desktop', "Only on device")
161class OSKBackendTests(AutopilotTestCase):
162 """Testing the Onscreen Keyboard (Ubuntu Keyboard) backend specifically.
163
164 There are limitations (i.e. on device only, window-mocker doesn't work on
165 the device, can't type all the characters that X11/UInput can.) that
166 necessitate this split into it's own test class.
167
168 """
169
170 scenarios = [
171 ('lower_alpha', dict(input='abcdefghijklmnopqrstuvwxyz')),
172 ('upper_alpha', dict(input='ABCDEFGHIJKLMNOPQRSTUVWXYZ')),
173 ('numeric', dict(input='0123456789')),
174 ('punctuation', dict(input='`~!@#$%^&*()_-+={}[]|\\:;"\'<>,.?/')),
175 ]
176
177 def launch_test_input_area(self):
178 self.app = self._launch_simple_input()
179 text_area = self.app.select_single("QQuickTextInput")
180
181 return text_area
182
183 def _start_qml_script(self, script_contents):
184 """Launch a qml script."""
185 qml_path = mktemp(suffix='.qml')
186 open(qml_path, 'w').write(script_contents)
187 self.addCleanup(os.remove, qml_path)
188
189 return self.launch_test_application(
190 "qmlscene",
191 qml_path,
192 app_type='qt',
193 )
194
195 def _launch_simple_input(self):
196 simple_script = dedent("""
197 import QtQuick 2.0
198 import Ubuntu.Components 0.1
199
200 Rectangle {
201 id: window
202 objectName: "windowRectangle"
203 color: "lightgrey"
204
205 Text {
206 id: inputLabel
207 text: "OSK Tests"
208 font.pixelSize: units.gu(3)
209 anchors {
210 left: input.left
211 top: parent.top
212 topMargin: 25
213 bottomMargin: 25
214 }
215 }
216
217 TextField {
218 id: input;
219 objectName: "input"
220 anchors {
221 top: inputLabel.bottom
222 horizontalCenter: parent.horizontalCenter
223 topMargin: 10
224 }
225 inputMethodHints: Qt.ImhNoPredictiveText
226 }
227 }
228
229 """)
230
231 return self._start_qml_script(simple_script)
232
233 def test_can_type_string(self):
234 """Typing text must produce the expected characters in the input
235 field.
236
237 """
238
239 text_area = self.launch_test_input_area()
240 keyboard = Keyboard.create('OSK')
241 pointer = Pointer(Touch.create())
242 pointer.click_object(text_area)
243 keyboard._keyboard.wait_for_keyboard_ready()
244
245 keyboard.type(self.input)
246
247 self.assertThat(text_area.text, Eventually(Equals(self.input)))
248
249 def test_focused_typing_contextmanager(self):
250 """Typing text using the 'focused_typing' context manager must not only
251 produce the expected characters in the input field but also cleanup the
252 OSK afterwards too.
253
254 """
255 text_area = self.launch_test_input_area()
256 keyboard = Keyboard.create('OSK')
257 with keyboard.focused_type(text_area) as kb:
258 kb.type(self.input)
259 self.assertThat(
260 text_area.text,
261 Eventually(Equals(self.input))
262 )
263 self.assertThat(
264 keyboard._keyboard.is_available,
265 Eventually(Equals(False))
266 )
267
268
140class MouseTestCase(AutopilotTestCase):269class MouseTestCase(AutopilotTestCase):
141270
142 def test_move_to_nonint_point(self):271 def test_move_to_nonint_point(self):
143272
=== modified file 'docs/faq/faq.rst'
--- docs/faq/faq.rst 2013-07-24 08:38:59 +0000
+++ docs/faq/faq.rst 2013-08-23 05:01:40 +0000
@@ -20,7 +20,7 @@
2020
21**I am running the latest development image!**21**I am running the latest development image!**
2222
23In that case you can install autopilot directly - either by installing the ``autopilot-desktop`` or ``autopilot-touch`` packages, depending on whether you are installing to a desktop or phablet device.23In that case you can install autopilot directly - either by installing the ``autopilot-desktop`` or ``autopilot-touch`` packages, depending on whether you are installing to a desktop or an Ubuntu Touch device.
2424
25**I am running the Ubuntu release previous to the development release!**25**I am running the Ubuntu release previous to the development release!**
2626
@@ -108,8 +108,8 @@
108108
109In general, autopilot tests are more relaxed about the 'one assertion per test' rule. However, care should still be taken to produce tests that are as small and understandable as possible.109In general, autopilot tests are more relaxed about the 'one assertion per test' rule. However, care should still be taken to produce tests that are as small and understandable as possible.
110110
111How do I write a test that uses either a Mouse or a Touch device interchangeably?111Q. How do I write a test that uses either a Mouse or a Touch device interchangeably?
112==============================================================================================112====================================================================================
113113
114The :class:`autopilot.input.Pointer` class is a simple wrapper that unifies some of the differences between the :class:`~autopilot.input.Touch` and :class:`~autopilot.input.Mouse` classes. To use it, pass in the device you want to use under the hood, like so::114The :class:`autopilot.input.Pointer` class is a simple wrapper that unifies some of the differences between the :class:`~autopilot.input.Touch` and :class:`~autopilot.input.Mouse` classes. To use it, pass in the device you want to use under the hood, like so::
115115
@@ -136,6 +136,33 @@
136136
137If you only want to use the mouse on certain platforms, use the :mod:`autopilot.platform` module to determine the current platform at runtime.137If you only want to use the mouse on certain platforms, use the :mod:`autopilot.platform` module to determine the current platform at runtime.
138138
139Q. How do I use the Onscreen Keyboard (OSK) to input text in my test?
140=====================================================================
141
142The OSK is an backend option for the :meth:`autopilot.input.Keyboard.create`
143method (see this :ref:`Advanced Autopilot<adv_picking_backend>` section for
144details regarding backend selection.)
145
146Unlike the other backends (X11, UInput) the OSK has a GUI presence and thus can
147be displayed on the screen.
148
149The :class:`autopilot.input.Keyboard` class provides a context manager that
150handles any cleanup required when dealing with the input backends.
151
152For example in the instance when the backend is the OSK, when leaving the scope
153of the context manager the OSK will be dismissed with a swipe::
154
155 from autopilot.input import Keyboard
156
157 text_area = self._launch_test_input_area()
158 keyboard = Keyboard.create('OSK')
159 with keyboard.focused_type(text_area) as kb:
160 kb.type("Hello World.")
161 self.assertThat(text_area.text, Equals("Hello World"))
162 # At this point now the OSK has been swiped away.
163 self.assertThat()
164
165
139Autopilot Qt & Gtk Support166Autopilot Qt & Gtk Support
140++++++++++++++++++++++++++167++++++++++++++++++++++++++
141168
142169
=== modified file 'docs/tutorial/advanced_autopilot.rst'
--- docs/tutorial/advanced_autopilot.rst 2013-07-24 08:38:59 +0000
+++ docs/tutorial/advanced_autopilot.rst 2013-08-23 05:01:40 +0000
@@ -199,10 +199,12 @@
199199
200The code snippet above will create an instance of the Keyboard class that uses X11 on Desktop systems, and UInput on other systems. On the rare occaison when test authors need to construct these objects themselves, we expect that the default creation pattern to be used.200The code snippet above will create an instance of the Keyboard class that uses X11 on Desktop systems, and UInput on other systems. On the rare occaison when test authors need to construct these objects themselves, we expect that the default creation pattern to be used.
201201
202.. _adv_picking_backend:
203
202Picking a Backend204Picking a Backend
203+++++++++++++++++205+++++++++++++++++
204206
205Test authors may sometimes want to pick a specific backend. The possible backends are documented in the API documentation for each class. For example, the documentation for the :meth:`autopilot.input.Keyboard.create` method says there are two backends available: the ``X11`` backend, and the ``UInput`` backend. These backends can be specified in the create method. For example, to specify that you want a Keyboard that uses X11 to generate it's input events::207Test authors may sometimes want to pick a specific backend. The possible backends are documented in the API documentation for each class. For example, the documentation for the :meth:`autopilot.input.Keyboard.create` method says there are three backends available: the ``X11`` backend, the ``UInput`` backend, and the ``OSK`` backend. These backends can be specified in the create method. For example, to specify that you want a Keyboard that uses X11 to generate it's input events::
206208
207 >>> from autopilot.input import Keyboard209 >>> from autopilot.input import Keyboard
208 >>> kbd = Keyboard.create("X11")210 >>> kbd = Keyboard.create("X11")
@@ -212,8 +214,15 @@
212 >>> from autopilot.input import Keyboard214 >>> from autopilot.input import Keyboard
213 >>> kbd = Keyboard.create("UInput")215 >>> kbd = Keyboard.create("UInput")
214216
217Finally, for the Onscreen Keyboard::
218
219 >>> from autopilot.input import Keyboard
220 >>> kbd = Keyboard.create("OSK")
221
215.. warning:: Care must be taken when specifying specific backends. There is no guarantee that the backend you ask for is going to be available across all platforms. For that reason, using the default creation method is encouraged.222.. warning:: Care must be taken when specifying specific backends. There is no guarantee that the backend you ask for is going to be available across all platforms. For that reason, using the default creation method is encouraged.
216223
224.. warning:: The **OSK** backend has some known implementation limitations, please see :meth:`autopilot.input.Keyboard.create` method documenation for further details.
225
217Possible Errors when Creating Backends226Possible Errors when Creating Backends
218++++++++++++++++++++++++++++++++++++++227++++++++++++++++++++++++++++++++++++++
219228
@@ -249,6 +258,92 @@
249 'UInputError(\'"/dev/uinput" cannot be opened for writing\',)'258 'UInputError(\'"/dev/uinput" cannot be opened for writing\',)'
250 'BackendException(\'Error while initialising backend. Original exception was: "/dev/uinput" cannot be opened for writing\',)'259 'BackendException(\'Error while initialising backend. Original exception was: "/dev/uinput" cannot be opened for writing\',)'
251260
261Keyboard Backends
262=================
263
264A quick introduction to the Keyboard backends
265+++++++++++++++++++++++++++++++++++++++++++++
266
267Each backend has a different method of operating behind the scenes to provide
268the Keyboard interface.
269
270Here is a quick overview of how each backend works.
271
272.. list-table::
273 :widths: 15, 85
274 :header-rows: 1
275
276 * - Backend
277 - Description
278 * - X11
279 - The X11 backend generates X11 events using a mock input device which it
280 then syncs with X to actually action the input.
281 * - Uinput
282 - The UInput backend injects events directly in to the kernel using the
283 UInput device driver to produce input.
284 * - OSK
285 - The Onscreen Keyboard backend uses the GUI pop-up keyboard to enter
286 input. Using a pointer object it taps on the required keys to get the
287 expected output.
288
289.. _keyboard_backend_limitations:
290
291Limitations of the different Keyboard backends
292++++++++++++++++++++++++++++++++++++++++++++++
293
294While every effort has been made so that the Keyboard devices act the same
295regardless of which backend or platform is in use, the simple fact is that
296there can be some technical limitations for some backends.
297
298Some of these limitations are hidden when using the "create" method and won't
299cause any concern (i.e. X11 backend on desktop, UInput on an Ubuntu Touch device.)
300while others will raise exceptions (that are fully documented in the API docs).
301
302Here is a list of known limitations:
303
304**X11**
305
306* Only available on desktop platforms
307
308 - X11 isn't available on Ubuntu Touch devices
309
310**UInput**
311
312* Requires correct device access permissions
313
314 - The user (or group) that are running the autopilot tests need read/write
315 access to the UInput device (usually /dev/uinput).
316
317* Specific kernel support is required
318
319 - The kernel on the system running the tests must be running a kernel that
320 includes UInput support (as well as have the module loaded.
321
322**OSK**
323
324* Currently only available on Ubuntu Touch devices
325
326 - At the time of writing this the OSK/Ubuntu Keyboard is only
327 supported/available on the Ubuntu Touch devices. It is possible that it
328 will be available on the desktop in the near future.
329
330* Unable to type 'special' keys i.e. Alt
331
332 - This shouldn't be an issue as applications running on Ubuntu Touch devices
333 will be using the expected patterns of use on these platforms.
334
335* The following methods have limitations or are not implemented:
336
337 - :meth:`autopilot.input.Keyboard.press`: Raises NotImplementedError if
338 called.
339
340 - :meth:`autopilot.input.Keyboard.release`: Raises NotImplementedError if
341 called.
342
343 - :meth:`autopilot.input.Keyboard.press_and_release`: can can only handle
344 single keys/characters. Raises either ValueError if passed more than a
345 single character key or UnsupportedKey if passed a key that is not
346 supported by the OSK backend (or the current language layout).
252347
253348
254Process Control349Process Control

Subscribers

People subscribed via source and target branches