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