Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(307)

Side by Side Diff: tools/accessibility/nvda/nvda_chrome_tests.py

Issue 660633002: Fixed IAccessibleText::TextAtOffset with IA2_TEXT_BOUNDARY_WORD to return text that spans from the … (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added semi-automated NVDA test for word navigation and removed dependency on pywinauto. Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2014 The Chromium Authors. All rights reserved. 2 # Copyright 2014 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Semi-automated tests of Chrome with NVDA. 6 """Semi-automated tests of Chrome with NVDA.
7 7
8 This file performs (semi) automated tests of Chrome with NVDA 8 This file performs (semi) automated tests of Chrome with NVDA
9 (NonVisual Desktop Access), a popular open-source screen reader for 9 (NonVisual Desktop Access), a popular open-source screen reader for
10 visually impaired users on Windows. It works by launching Chrome in a 10 visually impaired users on Windows. It works by launching Chrome in a
11 subprocess, then launching NVDA in a special environment that simulates 11 subprocess, then launching NVDA in a special environment that simulates
12 speech rather than actually speaking, and ignores all events coming from 12 speech rather than actually speaking, and ignores all events coming from
13 processes other than a specific Chrome process ID. Each test automates 13 processes other than a specific Chrome process ID. Each test automates
14 Chrome with a series of actions and asserts that NVDA gives the expected 14 Chrome with a series of actions and asserts that NVDA gives the expected
15 feedback in response. 15 feedback in response.
16 16
17 The tests are "semi" automated in the sense that they are not intended to be 17 The tests are "semi" automated in the sense that they are not intended to be
18 run from any developer machine, or on a buildbot - it requires setting up the 18 run from any developer machine, or on a buildbot - it requires setting up the
19 environment according to the instructions in README.txt, then running the 19 environment according to the instructions in README.txt, then running the
20 test script, then filing bugs for any potential failures. If the environment 20 test script, then filing bugs for any potential failures. If the environment
21 is set up correctly, the actual tests should run automatically and unattended. 21 is set up correctly, the actual tests should run automatically and unattended.
22 """ 22 """
23 23
24
24 import os 25 import os
25 import pywinauto
26 import re 26 import re
27 import shutil 27 import shutil
28 import signal 28 import signal
29 import subprocess 29 import subprocess
30 import sys 30 import sys
31 import tempfile 31 import tempfile
32 import time 32 import time
33 import unittest 33 import unittest
34 import winapi
dmazzoni 2014/11/01 06:45:13 I can't find the winapi module. Did you mean win32
34 35
35 CHROME_PROFILES_PATH = os.path.join(os.getcwd(), 'chrome_profiles') 36 CHROME_PROFILES_PATH = os.path.join(os.getcwd(), 'chrome_profiles')
36 CHROME_PATH = os.path.join(os.environ['USERPROFILE'], 37 CHROME_PATH = os.path.join(os.environ['USERPROFILE'],
37 'AppData', 38 'AppData',
38 'Local', 39 'Local',
39 'Google', 40 'Google',
40 'Chrome SxS', 41 'Chrome SxS',
41 'Application', 42 'Application',
42 'chrome.exe') 43 'chrome.exe')
43 NVDA_PATH = os.path.join(os.getcwd(), 44 NVDA_PATH = os.path.join(os.getcwd(),
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
98 NVDA_LOGPATH] 99 NVDA_LOGPATH]
99 self._nvda_proc = subprocess.Popen(args) 100 self._nvda_proc = subprocess.Popen(args)
100 self._nvda_proc.poll() 101 self._nvda_proc.poll()
101 if self._nvda_proc.returncode is None: 102 if self._nvda_proc.returncode is None:
102 print 'NVDA is running' 103 print 'NVDA is running'
103 else: 104 else:
104 print 'NVDA exited with code', self._nvda_proc.returncode 105 print 'NVDA exited with code', self._nvda_proc.returncode
105 sys.exit() 106 sys.exit()
106 print 'NVDA pid: %d' % self._nvda_proc.pid 107 print 'NVDA pid: %d' % self._nvda_proc.pid
107 108
108 app = pywinauto.application.Application() 109 winapi.focusWindow(self._chrome_proc.pid)
dmazzoni 2014/11/01 06:45:13 I can't find the focusWindow function in win32api,
109 app.connect_(process = self._chrome_proc.pid)
110 self._pywinauto_window = app.top_window_()
111 110
112 try: 111 try:
113 self._WaitForSpeech(['Address and search bar edit', 'about:blank']) 112 self._WaitForSpeech(['Address and search bar edit', 'about:blank'])
114 except: 113 except:
115 self.tearDown() 114 self.tearDown()
116 115
117 def tearDown(self): 116 def tearDown(self):
118 print 117 print
119 print 'Shutting down' 118 print 'Shutting down'
120 119
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
184 print '"%s"' % line 183 print '"%s"' % line
185 raise Exception('Timed out') 184 raise Exception('Timed out')
186 time.sleep(0.1) 185 time.sleep(0.1)
187 186
188 # 187 #
189 # Tests 188 # Tests
190 # 189 #
191 190
192 def testTypingInOmnibox(self): 191 def testTypingInOmnibox(self):
193 # Ctrl+A: Select all. 192 # Ctrl+A: Select all.
194 self._pywinauto_window.TypeKeys('^A') 193 winapi.typeKeys('{control}+a')
195 self._WaitForSpeech('selecting about:blank') 194 self._WaitForSpeech('selecting about:blank')
196 195
197 # Type three characters. 196 # Type three characters.
198 self._pywinauto_window.TypeKeys('xyz') 197 winapi.typeKeys('xyz')
199 self._WaitForSpeech(['x', 'y', 'z']) 198 self._WaitForSpeech(['x', 'y', 'z'])
200 199
201 # Arrow back over two characters. 200 # Arrow back over two characters.
202 self._pywinauto_window.TypeKeys('{LEFT}') 201 winapi.typeKeys('{left}')
203 self._WaitForSpeech(['z', 'z', 'unselecting']) 202 self._WaitForSpeech(['z', 'z', 'unselecting'])
204 203
205 self._pywinauto_window.TypeKeys('{LEFT}') 204 winapi.typeKeys('{left}')
206 self._WaitForSpeech('y') 205 self._WaitForSpeech('y')
207 206
208 def testFocusToolbarButton(self): 207 def testFocusToolbarButton(self):
209 # Alt+Shift+T. 208 # Alt+Shift+T.
210 self._pywinauto_window.TypeKeys('%+T') 209 winapi.typeKeys('{alt}+{shift}+t')
211 self._WaitForSpeech('Reload button Reload this page') 210 self._WaitForSpeech('Reload button Reload this page')
212 211
213 def testReadAllOnPageLoad(self): 212 def testReadAllOnPageLoad(self):
214 # Ctrl+A: Select all 213 # Ctrl+A: Select all
215 self._pywinauto_window.TypeKeys('^A') 214 winapi.typeKeys('{control}+a')
216 self._WaitForSpeech('selecting about:blank') 215 self._WaitForSpeech('selecting about:blank')
217 216
218 # Load data url. 217 # Load data url.
219 self._pywinauto_window.TypeKeys('data:text/html,Hello<p>World.') 218 winapi.typeKeys('data:text/html,Hello<p>World.')
220 self._WaitForSpeech('dot') 219 self._WaitForSpeech('dot')
221 self._pywinauto_window.TypeKeys('{ENTER}') 220 winapi.typeKeys('{enter}')
222 self._WaitForSpeech( 221 self._WaitForSpeech(
223 ['document', 222 ['document',
224 'Hello', 223 'Hello',
225 'World.']) 224 'World.'])
226 225
226 def testNavigatingByWord(self):
227 winapi.typeKeys(
228 'data:text/html,<!DOCTYPE html><html><body>Word navigation</body></html> ')
dmazzoni 2014/11/01 06:45:13 You'll need an editable text field here for this t
229 self._WaitForSpeech('greater')
230 winapi.typeKeys('{enter}')
231 self._WaitForSpeech(
232 ['document',
233 'Word navigation'])
234 winapi.typeKeys('{control}+{right}')
235 self._WaitForSpeech('navigation')
236 winapi.typeKeys('{control}+{left}')
237 self._WaitForSpeech('Word ')
238
227 if __name__ == '__main__': 239 if __name__ == '__main__':
228 unittest.main() 240 unittest.main()
229 241
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698