OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |