Merge lp:~canonical-platform-qa/ubuntu-ui-toolkit/textfield-use-osk into lp:ubuntu-ui-toolkit

Proposed by Richard Huddie
Status: Superseded
Proposed branch: lp:~canonical-platform-qa/ubuntu-ui-toolkit/textfield-use-osk
Merge into: lp:ubuntu-ui-toolkit
Diff against target: 309 lines (+174/-27)
4 files modified
debian/control (+1/-0)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_common.py (+133/-3)
tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py (+36/-24)
tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py (+4/-0)
To merge this branch: bzr merge lp:~canonical-platform-qa/ubuntu-ui-toolkit/textfield-use-osk
Reviewer Review Type Date Requested Status
PS Jenkins bot continuous-integration Needs Fixing
Ubuntu SDK team Pending
Review via email: mp+260963@code.launchpad.net

This proposal has been superseded by a proposal from 2015-06-04.

Commit message

Use the OSK in text fields to enter text.

Description of the change

Use the OSK in text fields to enter text.

To post a comment you must log in.
Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1199. By Richard Huddie

Disable osk input helpers and validate text rather than displayText.

Revision history for this message
PS Jenkins bot (ps-jenkins) wrote :
review: Needs Fixing (continuous-integration)
1200. By Leo Arias

Merged with staging.

1201. By Leo Arias

Reverted the po changes.

1202. By Leo Arias

Reverted the po changes.

1203. By Richard Huddie

Delay import in _go_to_end() until it is needed.

1204. By Richard Huddie

Use activeFocus instead of focus property.

1205. By Richard Huddie

Fix flake8 by using ToolkitException.

1206. By Richard Huddie

Docstring fix.

1207. By Richard Huddie

Fix test_textinput tests to use correct textfield.write() method rather than directly calling keyboard.type().

1208. By Richard Huddie

Only run test which uses shift+left key combination on desktop.

1209. By Richard Huddie

Merge with staging branch.

1210. By Richard Huddie

Fix for textarea and test_textinput failing tests.

1211. By Richard Huddie

Fixes for failing tests. Also wait 5 seconds after re-launching maliit-server to allow it to be ready.

1212. By Richard Huddie

Merge from staging branch.

1213. By Richard Huddie

Fix review comments. Also don't enforce en language, re-enable test_clear_with_clear_button as prediction is now set off.

1214. By Richard Huddie

Merge from staging branch.

1215. By Richard Huddie

Set the osk language to en.

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'debian/control'
2--- debian/control 2015-05-20 15:36:55 +0000
3+++ debian/control 2015-06-04 11:35:43 +0000
4@@ -147,6 +147,7 @@
5 python3-autopilot (>= 1.4),
6 python3-autopilot-trace,
7 qttestability-autopilot,
8+ ubuntu-keyboard-autopilot,
9 ubuntu-ui-toolkit-examples (>= ${source:Version}),
10 upstart,
11 qtdeclarative5-ubuntu-ui-toolkit-plugin (>= ${source:Version}) | qtdeclarative5-ubuntu-ui-toolkit-plugin-gles,
12
13=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_common.py'
14--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_common.py 2015-04-14 21:02:06 +0000
15+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_common.py 2015-06-04 11:35:43 +0000
16@@ -17,7 +17,9 @@
17 """Common helpers for Ubuntu UI Toolkit Autopilot custom proxy objects."""
18
19 import logging
20+import subprocess
21 from distutils import version
22+from gi.repository import Gio
23
24 import autopilot
25 from autopilot import (
26@@ -27,9 +29,10 @@
27 )
28 from autopilot.introspection import dbus
29
30-
31 logger = logging.getLogger(__name__)
32
33+MALIIT = 'maliit-server'
34+
35
36 class ToolkitException(Exception):
37 """Exception raised when there is an error with the custom proxy object."""
38@@ -51,8 +54,135 @@
39
40 def get_keyboard():
41 """Return the keyboard device."""
42- # TODO return the OSK if we are on the phone. --elopio - 2014-01-13
43- return input.Keyboard.create()
44+ if is_process_running(MALIIT):
45+ configure_osk_settings()
46+ restart_maliit_with_testability()
47+ return input.Keyboard.create('OSK')
48+ else:
49+ return input.Keyboard.create()
50+
51+
52+def restart_maliit_with_testability():
53+ """Restart maliit-server with testability enabled."""
54+ if is_process_running(MALIIT):
55+ pid = get_process_pid(MALIIT)
56+ if _is_testability_enabled_for_process(pid):
57+ return
58+ _stop_process(MALIIT)
59+ _start_process(MALIIT, 'QT_LOAD_TESTABILITY=1')
60+
61+
62+def configure_osk_settings():
63+ """Configure OSK ready for testing by turning off all helpers."""
64+ gsettings = Gio.Settings.new("com.canonical.keyboard.maliit")
65+ gsettings.set_string("active-language", "en")
66+ gsettings.set_boolean("auto-capitalization", False)
67+ gsettings.set_boolean("auto-completion", False)
68+ gsettings.set_boolean("predictive-text", False)
69+ gsettings.set_boolean("spell-checking", False)
70+ gsettings.set_boolean("double-space-full-stop", False)
71+
72+
73+def _is_testability_enabled_for_process(pid):
74+ """Return True if testability is enabled for specified process."""
75+ proc_env = '/proc/{pid}/environ'.format(pid=pid)
76+ command = ['cat', proc_env]
77+ try:
78+ output = subprocess.check_output(
79+ command,
80+ stderr=subprocess.STDOUT,
81+ universal_newlines=True,
82+ )
83+ except subprocess.CalledProcessError as e:
84+ e.args += ('Failed to get environment for pid {}: {}.'.format(
85+ pid, e.output),)
86+ raise
87+ return output.find('QT_LOAD_TESTABILITY=1') >= 0
88+
89+
90+def _stop_process(proc_name):
91+ """Stop process with name proc_name."""
92+ logger.info('Stoping process {}.'.format(proc_name))
93+ command = ['/sbin/initctl', 'stop', proc_name]
94+ try:
95+ output = subprocess.check_output(
96+ command,
97+ stderr=subprocess.STDOUT,
98+ universal_newlines=True,
99+ )
100+ logger.info(output)
101+ except subprocess.CalledProcessError as e:
102+ e.args += ('Failed to stop {}: {}.'.format(proc_name, e.output),)
103+ raise
104+
105+
106+def _start_process(proc_name, *args):
107+ """Start a process.
108+
109+ :param proc_name: The name of the process.
110+ :param args: The arguments to be used when starting the job.
111+ :return: The process id of the started job.
112+ :raises CalledProcessError: if the job failed to start.
113+
114+ """
115+ logger.info('Starting job {} with arguments {}.'.format(proc_name, args))
116+ command = ['/sbin/initctl', 'start', proc_name] + list(args)
117+ try:
118+ output = subprocess.check_output(
119+ command,
120+ stderr=subprocess.STDOUT,
121+ universal_newlines=True,
122+ )
123+ logger.info(output)
124+ pid = get_process_pid(proc_name)
125+ except subprocess.CalledProcessError as e:
126+ e.args += ('Failed to start {}: {}.'.format(proc_name, e.output),)
127+ raise
128+ else:
129+ return pid
130+
131+
132+def get_process_pid(proc_name):
133+ """Return the process id of a running job.
134+
135+ :param str name: The name of the job.
136+ :raises JobError: if the job is not running.
137+
138+ """
139+ status = get_process_status(proc_name)
140+ if "start/" not in status:
141+ raise JobError('{} is not in the running state.'.format(proc_name))
142+ return int(status.split()[-1])
143+
144+
145+def get_process_status(name):
146+ """
147+ Return the status of a process.
148+
149+ :param str name: The name of the process.
150+ :raises JobError: if it's not possible to get the status of the job.
151+
152+ """
153+ try:
154+ return subprocess.check_output([
155+ '/sbin/initctl',
156+ 'status',
157+ name
158+ ], universal_newlines=True)
159+ except subprocess.CalledProcessError as error:
160+ raise JobError(
161+ "Unable to get {}'s status: {}".format(name, error)
162+ )
163+
164+
165+def is_process_running(name):
166+ """Return True if the process is running. Otherwise, False.
167+
168+ :param str name: The name of the process.
169+ :raises JobError: if it's not possible to get the status of the process.
170+
171+ """
172+ return 'start/' in get_process_status(name)
173
174
175 def check_autopilot_version():
176
177=== modified file 'tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py'
178--- tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py 2015-04-14 21:02:06 +0000
179+++ tests/autopilot/ubuntuuitoolkit/_custom_proxy_objects/_textfield.py 2015-06-04 11:35:43 +0000
180@@ -16,17 +16,13 @@
181
182 import logging
183
184-from autopilot import (
185- logging as autopilot_logging,
186- platform
187-)
188+from autopilot import logging as autopilot_logging
189
190 from ubuntuuitoolkit._custom_proxy_objects import (
191 _common,
192 _mainview
193 )
194
195-
196 logger = logging.getLogger(__name__)
197
198
199@@ -47,18 +43,18 @@
200 of the text field. Default is True.
201
202 """
203- with self.keyboard.focused_type(self):
204- self.focus.wait_for(True)
205- if clear:
206- self.clear()
207- else:
208- if not self.is_empty():
209- self.keyboard.press_and_release('End')
210- self.keyboard.type(text)
211+ self._ensure_focused()
212+ if clear:
213+ self.clear()
214+ else:
215+ if not self.is_empty():
216+ self._go_to_end()
217+ self.keyboard.type(text)
218
219 @autopilot_logging.log_action(logger.info)
220 def clear(self):
221 """Clear the text field."""
222+ self._ensure_focused()
223 if not self.is_empty():
224 if self.hasClearButton:
225 self._click_clear_button()
226@@ -80,16 +76,16 @@
227
228 @autopilot_logging.log_action(logger.debug)
229 def _clear_with_keys(self):
230- if platform.model() == 'Desktop':
231- self._select_all()
232- self.keyboard.press_and_release('BackSpace')
233- else:
234+ if self._is_keyboard_osk():
235 # Touch tap currently doesn't have a press_duration parameter, so
236 # we can't select all the text.
237 # Reported as bug http://pad.lv/1268782 --elopio - 2014-01-13
238 self._go_to_end()
239- while self.cursorPosition != 0:
240- self._delete_one_character()
241+ while self.text != '':
242+ self._delete_one_character_using_osk()
243+ else:
244+ self._select_all()
245+ self.keyboard.press_and_release('BackSpace')
246 if not self.is_empty():
247 raise _common.ToolkitException('Failed to clear the text field.')
248
249@@ -107,17 +103,33 @@
250 def _is_all_text_selected(self):
251 return self.text == self.selectedText
252
253+ def _is_keyboard_osk(self):
254+ """Return True if the keyboard instance is the OSK."""
255+ from autopilot.input import _osk
256+ return isinstance(self.keyboard, _osk.Keyboard)
257+
258 @autopilot_logging.log_action(logger.debug)
259 def _go_to_end(self):
260- # XXX Here we are cheating because the on-screen keyboard doesn't have
261- # an END key. --elopio - 2014-08-20
262- self.keyboard.press_and_release('End')
263+ from autopilot import input
264+ if self._is_keyboard_osk():
265+ # XXX Here we are cheating because the on-screen keyboard doesn't
266+ # have an END key. --elopio - 2014-08-20
267+ keyboard = input.Keyboard.create()
268+ keyboard.press_and_release('End')
269+ else:
270+ self.keyboard.press_and_release('End')
271
272 @autopilot_logging.log_action(logger.debug)
273- def _delete_one_character(self):
274+ def _delete_one_character_using_osk(self):
275 original_text = self.text
276 # We delete with backspace because the on-screen keyboard has
277 # that key.
278- self.keyboard.press_and_release('BackSpace')
279+ self.keyboard.press_and_release('backspace')
280 if len(self.text) != len(original_text) - 1:
281 raise _common.ToolkitException('Failed to delete one character.')
282+
283+ @autopilot_logging.log_action(logger.debug)
284+ def _ensure_focused(self):
285+ if not self.focus:
286+ self.pointing_device.click_object(self)
287+ self.focus.wait_for(True)
288
289=== modified file 'tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py'
290--- tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py 2015-04-14 21:02:06 +0000
291+++ tests/autopilot/ubuntuuitoolkit/tests/custom_proxy_objects/test_textfield.py 2015-06-04 11:35:43 +0000
292@@ -17,6 +17,7 @@
293 from unittest import mock
294
295 from autopilot import platform
296+from testtools import skipUnless
297
298 import ubuntuuitoolkit
299 from ubuntuuitoolkit import tests
300@@ -61,6 +62,9 @@
301 self.simple_text_field.write('test')
302 self.assertEqual(self.simple_text_field.text, 'test')
303
304+ @skipUnless(platform.model() == 'Desktop',
305+ 'Due to launchpad.net/bugs/1461571 this only runs on desktop.')
306+ # Once launchpad.net/bugs/1461571 is fixed this will work on touch.
307 def test_clear_with_clear_button(self):
308 self.simple_text_field.write('test')
309 self.simple_text_field.clear()

Subscribers

People subscribed via source and target branches

to status/vote changes: