1import webbrowser 2import unittest 3import os 4import sys 5import subprocess 6from unittest import mock 7from test import support 8from test.support import import_helper 9from test.support import os_helper 10 11if not support.has_subprocess_support: 12 raise unittest.SkipTest("test webserver requires subprocess") 13 14URL = 'http://www.example.com' 15CMD_NAME = 'test' 16 17 18class PopenMock(mock.MagicMock): 19 20 def poll(self): 21 return 0 22 23 def wait(self, seconds=None): 24 return 0 25 26 27class CommandTestMixin: 28 29 def _test(self, meth, *, args=[URL], kw={}, options, arguments): 30 """Given a web browser instance method name along with arguments and 31 keywords for same (which defaults to the single argument URL), creates 32 a browser instance from the class pointed to by self.browser, calls the 33 indicated instance method with the indicated arguments, and compares 34 the resulting options and arguments passed to Popen by the browser 35 instance against the 'options' and 'args' lists. Options are compared 36 in a position independent fashion, and the arguments are compared in 37 sequence order to whatever is left over after removing the options. 38 39 """ 40 popen = PopenMock() 41 support.patch(self, subprocess, 'Popen', popen) 42 browser = self.browser_class(name=CMD_NAME) 43 getattr(browser, meth)(*args, **kw) 44 popen_args = subprocess.Popen.call_args[0][0] 45 self.assertEqual(popen_args[0], CMD_NAME) 46 popen_args.pop(0) 47 for option in options: 48 self.assertIn(option, popen_args) 49 popen_args.pop(popen_args.index(option)) 50 self.assertEqual(popen_args, arguments) 51 52 53class GenericBrowserCommandTest(CommandTestMixin, unittest.TestCase): 54 55 browser_class = webbrowser.GenericBrowser 56 57 def test_open(self): 58 self._test('open', 59 options=[], 60 arguments=[URL]) 61 62 63class BackgroundBrowserCommandTest(CommandTestMixin, unittest.TestCase): 64 65 browser_class = webbrowser.BackgroundBrowser 66 67 def test_open(self): 68 self._test('open', 69 options=[], 70 arguments=[URL]) 71 72 73class ChromeCommandTest(CommandTestMixin, unittest.TestCase): 74 75 browser_class = webbrowser.Chrome 76 77 def test_open(self): 78 self._test('open', 79 options=[], 80 arguments=[URL]) 81 82 def test_open_with_autoraise_false(self): 83 self._test('open', kw=dict(autoraise=False), 84 options=[], 85 arguments=[URL]) 86 87 def test_open_new(self): 88 self._test('open_new', 89 options=['--new-window'], 90 arguments=[URL]) 91 92 def test_open_new_tab(self): 93 self._test('open_new_tab', 94 options=[], 95 arguments=[URL]) 96 97 98class MozillaCommandTest(CommandTestMixin, unittest.TestCase): 99 100 browser_class = webbrowser.Mozilla 101 102 def test_open(self): 103 self._test('open', 104 options=[], 105 arguments=[URL]) 106 107 def test_open_with_autoraise_false(self): 108 self._test('open', kw=dict(autoraise=False), 109 options=[], 110 arguments=[URL]) 111 112 def test_open_new(self): 113 self._test('open_new', 114 options=[], 115 arguments=['-new-window', URL]) 116 117 def test_open_new_tab(self): 118 self._test('open_new_tab', 119 options=[], 120 arguments=['-new-tab', URL]) 121 122 123class NetscapeCommandTest(CommandTestMixin, unittest.TestCase): 124 125 browser_class = webbrowser.Netscape 126 127 def test_open(self): 128 self._test('open', 129 options=['-raise', '-remote'], 130 arguments=['openURL({})'.format(URL)]) 131 132 def test_open_with_autoraise_false(self): 133 self._test('open', kw=dict(autoraise=False), 134 options=['-noraise', '-remote'], 135 arguments=['openURL({})'.format(URL)]) 136 137 def test_open_new(self): 138 self._test('open_new', 139 options=['-raise', '-remote'], 140 arguments=['openURL({},new-window)'.format(URL)]) 141 142 def test_open_new_tab(self): 143 self._test('open_new_tab', 144 options=['-raise', '-remote'], 145 arguments=['openURL({},new-tab)'.format(URL)]) 146 147 148class GaleonCommandTest(CommandTestMixin, unittest.TestCase): 149 150 browser_class = webbrowser.Galeon 151 152 def test_open(self): 153 self._test('open', 154 options=['-n'], 155 arguments=[URL]) 156 157 def test_open_with_autoraise_false(self): 158 self._test('open', kw=dict(autoraise=False), 159 options=['-noraise', '-n'], 160 arguments=[URL]) 161 162 def test_open_new(self): 163 self._test('open_new', 164 options=['-w'], 165 arguments=[URL]) 166 167 def test_open_new_tab(self): 168 self._test('open_new_tab', 169 options=['-w'], 170 arguments=[URL]) 171 172 173class OperaCommandTest(CommandTestMixin, unittest.TestCase): 174 175 browser_class = webbrowser.Opera 176 177 def test_open(self): 178 self._test('open', 179 options=[], 180 arguments=[URL]) 181 182 def test_open_with_autoraise_false(self): 183 self._test('open', kw=dict(autoraise=False), 184 options=[], 185 arguments=[URL]) 186 187 def test_open_new(self): 188 self._test('open_new', 189 options=['--new-window'], 190 arguments=[URL]) 191 192 def test_open_new_tab(self): 193 self._test('open_new_tab', 194 options=[], 195 arguments=[URL]) 196 197 198class ELinksCommandTest(CommandTestMixin, unittest.TestCase): 199 200 browser_class = webbrowser.Elinks 201 202 def test_open(self): 203 self._test('open', options=['-remote'], 204 arguments=['openURL({})'.format(URL)]) 205 206 def test_open_with_autoraise_false(self): 207 self._test('open', 208 options=['-remote'], 209 arguments=['openURL({})'.format(URL)]) 210 211 def test_open_new(self): 212 self._test('open_new', 213 options=['-remote'], 214 arguments=['openURL({},new-window)'.format(URL)]) 215 216 def test_open_new_tab(self): 217 self._test('open_new_tab', 218 options=['-remote'], 219 arguments=['openURL({},new-tab)'.format(URL)]) 220 221 222class BrowserRegistrationTest(unittest.TestCase): 223 224 def setUp(self): 225 # Ensure we don't alter the real registered browser details 226 self._saved_tryorder = webbrowser._tryorder 227 webbrowser._tryorder = [] 228 self._saved_browsers = webbrowser._browsers 229 webbrowser._browsers = {} 230 231 def tearDown(self): 232 webbrowser._tryorder = self._saved_tryorder 233 webbrowser._browsers = self._saved_browsers 234 235 def _check_registration(self, preferred): 236 class ExampleBrowser: 237 pass 238 239 expected_tryorder = [] 240 expected_browsers = {} 241 242 self.assertEqual(webbrowser._tryorder, expected_tryorder) 243 self.assertEqual(webbrowser._browsers, expected_browsers) 244 245 webbrowser.register('Example1', ExampleBrowser) 246 expected_tryorder = ['Example1'] 247 expected_browsers['example1'] = [ExampleBrowser, None] 248 self.assertEqual(webbrowser._tryorder, expected_tryorder) 249 self.assertEqual(webbrowser._browsers, expected_browsers) 250 251 instance = ExampleBrowser() 252 if preferred is not None: 253 webbrowser.register('example2', ExampleBrowser, instance, 254 preferred=preferred) 255 else: 256 webbrowser.register('example2', ExampleBrowser, instance) 257 if preferred: 258 expected_tryorder = ['example2', 'Example1'] 259 else: 260 expected_tryorder = ['Example1', 'example2'] 261 expected_browsers['example2'] = [ExampleBrowser, instance] 262 self.assertEqual(webbrowser._tryorder, expected_tryorder) 263 self.assertEqual(webbrowser._browsers, expected_browsers) 264 265 def test_register(self): 266 self._check_registration(preferred=False) 267 268 def test_register_default(self): 269 self._check_registration(preferred=None) 270 271 def test_register_preferred(self): 272 self._check_registration(preferred=True) 273 274 275class ImportTest(unittest.TestCase): 276 def test_register(self): 277 webbrowser = import_helper.import_fresh_module('webbrowser') 278 self.assertIsNone(webbrowser._tryorder) 279 self.assertFalse(webbrowser._browsers) 280 281 class ExampleBrowser: 282 pass 283 webbrowser.register('Example1', ExampleBrowser) 284 self.assertTrue(webbrowser._tryorder) 285 self.assertEqual(webbrowser._tryorder[-1], 'Example1') 286 self.assertTrue(webbrowser._browsers) 287 self.assertIn('example1', webbrowser._browsers) 288 self.assertEqual(webbrowser._browsers['example1'], [ExampleBrowser, None]) 289 290 def test_get(self): 291 webbrowser = import_helper.import_fresh_module('webbrowser') 292 self.assertIsNone(webbrowser._tryorder) 293 self.assertFalse(webbrowser._browsers) 294 295 with self.assertRaises(webbrowser.Error): 296 webbrowser.get('fakebrowser') 297 self.assertIsNotNone(webbrowser._tryorder) 298 299 def test_synthesize(self): 300 webbrowser = import_helper.import_fresh_module('webbrowser') 301 name = os.path.basename(sys.executable).lower() 302 webbrowser.register(name, None, webbrowser.GenericBrowser(name)) 303 webbrowser.get(sys.executable) 304 305 def test_environment(self): 306 webbrowser = import_helper.import_fresh_module('webbrowser') 307 try: 308 browser = webbrowser.get().name 309 except webbrowser.Error as err: 310 self.skipTest(str(err)) 311 with os_helper.EnvironmentVarGuard() as env: 312 env["BROWSER"] = browser 313 webbrowser = import_helper.import_fresh_module('webbrowser') 314 webbrowser.get() 315 316 def test_environment_preferred(self): 317 webbrowser = import_helper.import_fresh_module('webbrowser') 318 try: 319 webbrowser.get() 320 least_preferred_browser = webbrowser.get(webbrowser._tryorder[-1]).name 321 except (webbrowser.Error, IndexError) as err: 322 self.skipTest(str(err)) 323 324 with os_helper.EnvironmentVarGuard() as env: 325 env["BROWSER"] = least_preferred_browser 326 webbrowser = import_helper.import_fresh_module('webbrowser') 327 self.assertEqual(webbrowser.get().name, least_preferred_browser) 328 329 with os_helper.EnvironmentVarGuard() as env: 330 env["BROWSER"] = sys.executable 331 webbrowser = import_helper.import_fresh_module('webbrowser') 332 self.assertEqual(webbrowser.get().name, sys.executable) 333 334 335if __name__=='__main__': 336 unittest.main() 337