browser_unittest.py revision 47f0f1e200da8a481462f364f822c98fe1b1cd5b
1# Copyright 2012 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5import logging 6import os 7import shutil 8import tempfile 9import unittest 10 11from telemetry.core import util 12from telemetry.core import exceptions 13from telemetry import decorators 14from telemetry.internal.browser import browser as browser_module 15from telemetry.internal.browser import browser_finder 16from telemetry.internal.platform import gpu_device 17from telemetry.internal.platform import gpu_info 18from telemetry.internal.platform import system_info 19from telemetry.internal.util import path 20from telemetry.testing import browser_test_case 21from telemetry.testing import options_for_unittests 22from telemetry.timeline import tracing_config 23 24import mock 25 26 27class IntentionalException(Exception): 28 pass 29 30 31class BrowserTest(browser_test_case.BrowserTestCase): 32 def testBrowserCreation(self): 33 self.assertEquals(1, len(self._browser.tabs)) 34 35 # Different browsers boot up to different things. 36 assert self._browser.tabs[0].url 37 38 @decorators.Enabled('has tabs') 39 def testNewCloseTab(self): 40 existing_tab = self._browser.tabs[0] 41 self.assertEquals(1, len(self._browser.tabs)) 42 existing_tab_url = existing_tab.url 43 44 new_tab = self._browser.tabs.New() 45 self.assertEquals(2, len(self._browser.tabs)) 46 self.assertEquals(existing_tab.url, existing_tab_url) 47 self.assertEquals(new_tab.url, 'about:blank') 48 49 new_tab.Close() 50 self.assertEquals(1, len(self._browser.tabs)) 51 self.assertEquals(existing_tab.url, existing_tab_url) 52 53 def testMultipleTabCalls(self): 54 self._browser.tabs[0].Navigate(self.UrlOfUnittestFile('blank.html')) 55 self._browser.tabs[0].WaitForDocumentReadyStateToBeInteractiveOrBetter() 56 57 def testTabCallByReference(self): 58 tab = self._browser.tabs[0] 59 tab.Navigate(self.UrlOfUnittestFile('blank.html')) 60 self._browser.tabs[0].WaitForDocumentReadyStateToBeInteractiveOrBetter() 61 62 @decorators.Enabled('has tabs') 63 def testCloseReferencedTab(self): 64 self._browser.tabs.New() 65 tab = self._browser.tabs[0] 66 tab.Navigate(self.UrlOfUnittestFile('blank.html')) 67 tab.Close() 68 self.assertEquals(1, len(self._browser.tabs)) 69 70 @decorators.Enabled('has tabs') 71 def testForegroundTab(self): 72 # Should be only one tab at this stage, so that must be the foreground tab 73 original_tab = self._browser.tabs[0] 74 self.assertEqual(self._browser.foreground_tab, original_tab) 75 new_tab = self._browser.tabs.New() 76 # New tab shouls be foreground tab 77 self.assertEqual(self._browser.foreground_tab, new_tab) 78 # Make sure that activating the background tab makes it the foreground tab 79 original_tab.Activate() 80 self.assertEqual(self._browser.foreground_tab, original_tab) 81 # Closing the current foreground tab should switch the foreground tab to the 82 # other tab 83 original_tab.Close() 84 self.assertEqual(self._browser.foreground_tab, new_tab) 85 86 # This test uses the reference browser and doesn't have access to 87 # helper binaries like crashpad_database_util. 88 @decorators.Enabled('linux') 89 def testGetMinidumpPathOnCrash(self): 90 tab = self._browser.tabs[0] 91 with self.assertRaises(exceptions.AppCrashException): 92 tab.Navigate('chrome://crash', timeout=5) 93 crash_minidump_path = self._browser.GetMostRecentMinidumpPath() 94 self.assertIsNotNone(crash_minidump_path) 95 96 def testGetSystemInfo(self): 97 if not self._browser.supports_system_info: 98 logging.warning( 99 'Browser does not support getting system info, skipping test.') 100 return 101 102 info = self._browser.GetSystemInfo() 103 104 self.assertTrue(isinstance(info, system_info.SystemInfo)) 105 self.assertTrue(hasattr(info, 'model_name')) 106 self.assertTrue(hasattr(info, 'gpu')) 107 self.assertTrue(isinstance(info.gpu, gpu_info.GPUInfo)) 108 self.assertTrue(hasattr(info.gpu, 'devices')) 109 self.assertTrue(len(info.gpu.devices) > 0) 110 for g in info.gpu.devices: 111 self.assertTrue(isinstance(g, gpu_device.GPUDevice)) 112 113 def testGetSystemInfoNotCachedObject(self): 114 if not self._browser.supports_system_info: 115 logging.warning( 116 'Browser does not support getting system info, skipping test.') 117 return 118 119 info_a = self._browser.GetSystemInfo() 120 info_b = self._browser.GetSystemInfo() 121 self.assertFalse(info_a is info_b) 122 123 def testGetSystemTotalMemory(self): 124 self.assertTrue(self._browser.memory_stats['SystemTotalPhysicalMemory'] > 0) 125 126 @decorators.Disabled('cros-chrome-guest', 'system-guest', # chromeos guest 127 'chromeos') # crbug.com/628836. 128 def testIsTracingRunning(self): 129 tracing_controller = self._browser.platform.tracing_controller 130 if not tracing_controller.IsChromeTracingSupported(): 131 return 132 self.assertFalse(tracing_controller.is_tracing_running) 133 config = tracing_config.TracingConfig() 134 config.enable_chrome_trace = True 135 tracing_controller.StartTracing(config) 136 self.assertTrue(tracing_controller.is_tracing_running) 137 tracing_controller.StopTracing() 138 self.assertFalse(tracing_controller.is_tracing_running) 139 140 141class CommandLineBrowserTest(browser_test_case.BrowserTestCase): 142 @classmethod 143 def CustomizeBrowserOptions(cls, options): 144 options.AppendExtraBrowserArgs('--user-agent=telemetry') 145 146 def testCommandLineOverriding(self): 147 # This test starts the browser with --user-agent=telemetry. This tests 148 # whether the user agent is then set. 149 t = self._browser.tabs[0] 150 t.Navigate(self.UrlOfUnittestFile('blank.html')) 151 t.WaitForDocumentReadyStateToBeInteractiveOrBetter() 152 self.assertEquals(t.EvaluateJavaScript('navigator.userAgent'), 153 'telemetry') 154 155class DirtyProfileBrowserTest(browser_test_case.BrowserTestCase): 156 @classmethod 157 def CustomizeBrowserOptions(cls, options): 158 options.profile_type = 'small_profile' 159 160 @decorators.Disabled('chromeos') # crbug.com/243912 161 def testDirtyProfileCreation(self): 162 self.assertEquals(1, len(self._browser.tabs)) 163 164 165class BrowserLoggingTest(browser_test_case.BrowserTestCase): 166 @classmethod 167 def CustomizeBrowserOptions(cls, options): 168 options.logging_verbosity = options.VERBOSE_LOGGING 169 170 @decorators.Disabled('chromeos', 'android') 171 def testLogFileExist(self): 172 self.assertTrue( 173 os.path.isfile(self._browser._browser_backend.log_file_path)) 174 175 176def _GenerateBrowserProfile(number_of_tabs): 177 """ Generate a browser profile which browser had |number_of_tabs| number of 178 tabs opened before it was closed. 179 Returns: 180 profile_dir: the directory of profile. 181 """ 182 profile_dir = tempfile.mkdtemp() 183 options = options_for_unittests.GetCopy() 184 options.browser_options.output_profile_path = profile_dir 185 browser_to_create = browser_finder.FindBrowser(options) 186 with browser_to_create.Create(options) as browser: 187 browser.platform.SetHTTPServerDirectories(path.GetUnittestDataDir()) 188 blank_file_path = os.path.join(path.GetUnittestDataDir(), 'blank.html') 189 blank_url = browser.platform.http_server.UrlOf(blank_file_path) 190 browser.foreground_tab.Navigate(blank_url) 191 browser.foreground_tab.WaitForDocumentReadyStateToBeComplete() 192 for _ in xrange(number_of_tabs - 1): 193 tab = browser.tabs.New() 194 tab.Navigate(blank_url) 195 tab.WaitForDocumentReadyStateToBeComplete() 196 return profile_dir 197 198 199class BrowserCreationTest(unittest.TestCase): 200 def setUp(self): 201 self.mock_browser_backend = mock.MagicMock() 202 self.mock_platform_backend = mock.MagicMock() 203 204 def testCleanedUpCalledWhenExceptionRaisedInBrowserCreation(self): 205 self.mock_platform_backend.platform.FlushDnsCache.side_effect = ( 206 IntentionalException('Boom!')) 207 with self.assertRaises(IntentionalException): 208 browser_module.Browser( 209 self.mock_browser_backend, self.mock_platform_backend, 210 credentials_path=None) 211 self.assertTrue(self.mock_platform_backend.WillCloseBrowser.called) 212 213 def testOriginalExceptionNotSwallow(self): 214 self.mock_platform_backend.platform.FlushDnsCache.side_effect = ( 215 IntentionalException('Boom!')) 216 self.mock_platform_backend.WillCloseBrowser.side_effect = ( 217 IntentionalException('Cannot close browser!')) 218 with self.assertRaises(IntentionalException) as context: 219 browser_module.Browser( 220 self.mock_browser_backend, self.mock_platform_backend, 221 credentials_path=None) 222 self.assertIn('Boom!', context.exception.message) 223 224 225class BrowserRestoreSessionTest(unittest.TestCase): 226 227 @classmethod 228 def setUpClass(cls): 229 cls._number_of_tabs = 4 230 cls._profile_dir = _GenerateBrowserProfile(cls._number_of_tabs) 231 cls._options = options_for_unittests.GetCopy() 232 cls._options.browser_options.AppendExtraBrowserArgs( 233 ['--restore-last-session']) 234 cls._options.browser_options.profile_dir = cls._profile_dir 235 cls._browser_to_create = browser_finder.FindBrowser(cls._options) 236 237 @decorators.Enabled('has tabs') 238 @decorators.Disabled('chromeos', 'win', 'mac') 239 # TODO(nednguyen): Enable this test on windowsn platform 240 def testRestoreBrowserWithMultipleTabs(self): 241 with self._browser_to_create.Create(self._options) as browser: 242 # The number of tabs will be self._number_of_tabs + 1 as it includes the 243 # old tabs and a new blank tab. 244 expected_number_of_tabs = self._number_of_tabs + 1 245 try: 246 util.WaitFor(lambda: len(browser.tabs) == expected_number_of_tabs, 10) 247 except: 248 logging.error('Number of tabs is %s' % len(browser.tabs)) 249 raise 250 self.assertEquals(expected_number_of_tabs, len(browser.tabs)) 251 252 @classmethod 253 def tearDownClass(cls): 254 shutil.rmtree(cls._profile_dir) 255 256 257class TestBrowserOperationDoNotLeakTempFiles(unittest.TestCase): 258 259 @decorators.Enabled('win', 'mac', 'linux') 260 @decorators.Isolated 261 def testBrowserNotLeakingTempFiles(self): 262 options = options_for_unittests.GetCopy() 263 browser_to_create = browser_finder.FindBrowser(options) 264 self.assertIsNotNone(browser_to_create) 265 before_browser_run_temp_dir_content = os.listdir(tempfile.tempdir) 266 with browser_to_create.Create(options) as browser: 267 tab = browser.tabs.New() 268 tab.Navigate('about:blank') 269 self.assertEquals(2, tab.EvaluateJavaScript('1 + 1')) 270 after_browser_run_temp_dir_content = os.listdir(tempfile.tempdir) 271 self.assertEqual(before_browser_run_temp_dir_content, 272 after_browser_run_temp_dir_content) 273