diff options
author | achuith@chromium.org <achuith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-13 22:08:34 +0000 |
---|---|---|
committer | achuith@chromium.org <achuith@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-02-13 22:08:34 +0000 |
commit | ed1744f6ce3d1d2d57fbf5cb9b10e733b6fc4534 (patch) | |
tree | 8768482f9afa1ef74a876e724073da1cbdb51e5d /tools/telemetry | |
parent | 069fa64d19fd03b444c009d1f85c6b13c2cb1a4b (diff) | |
download | chromium_src-ed1744f6ce3d1d2d57fbf5cb9b10e733b6fc4534.zip chromium_src-ed1744f6ce3d1d2d57fbf5cb9b10e733b6fc4534.tar.gz chromium_src-ed1744f6ce3d1d2d57fbf5cb9b10e733b6fc4534.tar.bz2 |
Telemetry support for extensions.
* Browser has new properties supports_extensions and extensions (of type ExtensionDict)
* BrowserBackend ctor takes additional arg supports_extensions.
* BrowserBackend has new properties supports_extensions and extension_dict_backend (of type ExtensionDictBackend)
* BrowserBackend._WaitForBrowserToComeUp waits for all extensions to load and be interactive.
* BrowserBackend.ExtensionsNotSupportedException is raised for android browser and content shell.
* Add class ExtensionToLoad which is a wrapper for an extension_path.
* Add extension_to_load (of type ExtensionToLoad) to BrowserOptions.
* Add SupportsOptions to PossibleBrowser, to test extensions support. Returns False for android and content_shell when BrowserOptions.extensions_to_load is not empty
* Add ExtensionPage which derives from WebContents
* Add ExtensionDictBackend which is a dictionary of ExtensionPage instances with extension ids as keys.
* Add ExtensionDict which passes through to ExtensionDictBackend, except it uses ExtensionToLoad instances as keys.
* Import crx_id for determining extension id from extension path.
* Simple extension manifest.json and background.js for unit tests.
* Unit tests for single and multiple extensions.
BUG=169954
TEST=browser test.
Review URL: https://codereview.chromium.org/11882033
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@182316 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools/telemetry')
19 files changed, 340 insertions, 21 deletions
diff --git a/tools/telemetry/telemetry/android_browser_backend.py b/tools/telemetry/telemetry/android_browser_backend.py index 6e2e76a..290e71d 100644 --- a/tools/telemetry/telemetry/android_browser_backend.py +++ b/tools/telemetry/telemetry/android_browser_backend.py @@ -17,9 +17,14 @@ from telemetry import browser_gone_exception class AndroidBrowserBackend(browser_backend.BrowserBackend): """The backend for controlling a browser instance running on Android. """ - def __init__(self, options, adb, package, - is_content_shell, cmdline_file, activity, devtools_remote_port): - super(AndroidBrowserBackend, self).__init__(is_content_shell, options) + def __init__(self, options, adb, package, is_content_shell, + cmdline_file, activity, devtools_remote_port): + super(AndroidBrowserBackend, self).__init__( + is_content_shell=is_content_shell, + supports_extensions=False, options=options) + if len(options.extensions_to_load) > 0: + raise browser_backend.ExtensionsNotSupportedException( + 'Android browser does not support extensions.') # Initialize fields so that an explosion during init doesn't break in Close. self._options = options self._adb = adb diff --git a/tools/telemetry/telemetry/android_browser_finder.py b/tools/telemetry/telemetry/android_browser_finder.py index 37c0b99..da85327 100644 --- a/tools/telemetry/telemetry/android_browser_finder.py +++ b/tools/telemetry/telemetry/android_browser_finder.py @@ -44,8 +44,7 @@ CONTENT_SHELL_DEVTOOLS_REMOTE_PORT = ( class PossibleAndroidBrowser(possible_browser.PossibleBrowser): """A launchable android browser instance.""" def __init__(self, browser_type, options, *args): - super(PossibleAndroidBrowser, self).__init__( - browser_type, options) + super(PossibleAndroidBrowser, self).__init__(browser_type, options) self._args = args def __repr__(self): @@ -61,6 +60,11 @@ class PossibleAndroidBrowser(possible_browser.PossibleBrowser): backend.SetBrowser(b) return b + def SupportsOptions(self, options): + if len(options.extensions_to_load) != 0: + return False + return True + def FindAllAvailableBrowsers(options, logging=real_logging): """Finds all the desktop browsers available on this machine.""" if not adb_commands.IsAndroidSupported(): diff --git a/tools/telemetry/telemetry/browser.py b/tools/telemetry/telemetry/browser.py index 25591e6..e336884 100644 --- a/tools/telemetry/telemetry/browser.py +++ b/tools/telemetry/telemetry/browser.py @@ -3,13 +3,14 @@ # found in the LICENSE file. import os +from telemetry import browser_backend from telemetry import browser_credentials +from telemetry import extension_dict from telemetry import tab_list from telemetry import temporary_http_server from telemetry import wpr_modes from telemetry import wpr_server - class Browser(object): """A running browser instance that can be controlled in a limited way. @@ -21,12 +22,16 @@ class Browser(object): with browser_to_create.Create() as browser: ... do all your operations on browser here """ - def __init__(self, browser_backend, platform): - self._browser_backend = browser_backend + def __init__(self, backend, platform): + self._browser_backend = backend self._http_server = None self._wpr_server = None self._platform = platform - self._tabs = tab_list.TabList(browser_backend.tab_list_backend) + self._tabs = tab_list.TabList(backend.tab_list_backend) + self._extensions = None + if backend.supports_extensions: + self._extensions = extension_dict.ExtensionDict( + backend.extension_dict_backend) self.credentials = browser_credentials.BrowserCredentials() def __enter__(self): @@ -49,6 +54,10 @@ class Browser(object): return self._browser_backend.is_content_shell @property + def supports_extensions(self): + return self._browser_backend.supports_extensions + + @property def supports_tab_control(self): return self._browser_backend.supports_tab_control @@ -57,6 +66,14 @@ class Browser(object): return self._tabs @property + def extensions(self): + """Returns the extension dictionary if it exists.""" + if not self.supports_extensions: + raise browser_backend.ExtensionsNotSupportedException( + 'Extensions not supported') + return self._extensions + + @property def supports_tracing(self): return self._browser_backend.supports_tracing diff --git a/tools/telemetry/telemetry/browser_backend.py b/tools/telemetry/telemetry/browser_backend.py index 7c7c685..374c867 100644 --- a/tools/telemetry/telemetry/browser_backend.py +++ b/tools/telemetry/telemetry/browser_backend.py @@ -10,6 +10,7 @@ import re import sys from telemetry import browser_gone_exception +from telemetry import extension_dict_backend from telemetry import options_for_unittests from telemetry import tab_list_backend from telemetry import tracing_backend @@ -18,15 +19,19 @@ from telemetry import util from telemetry import wpr_modes from telemetry import wpr_server +class ExtensionsNotSupportedException(Exception): + pass + class BrowserBackend(object): """A base class for browser backends. Provides basic functionality once a remote-debugger port has been established.""" WEBPAGEREPLAY_HOST = '127.0.0.1' - def __init__(self, is_content_shell, options): + def __init__(self, is_content_shell, supports_extensions, options): self.browser_type = options.browser_type self.is_content_shell = is_content_shell + self._supports_extensions = supports_extensions self.options = options self._browser = None self._port = None @@ -47,6 +52,10 @@ class BrowserBackend(object): 'such as about:flags settings, cookies, and ' 'extensions.\n') self._tab_list_backend = tab_list_backend.TabListBackend(self) + self._extension_dict_backend = None + if supports_extensions: + self._extension_dict_backend = \ + extension_dict_backend.ExtensionDictBackend(self) def SetBrowser(self, browser): self._browser = browser @@ -57,9 +66,18 @@ class BrowserBackend(object): return self._browser @property + def supports_extensions(self): + """True if this browser backend supports extensions.""" + return self._supports_extensions + + @property def tab_list_backend(self): return self._tab_list_backend + @property + def extension_dict_backend(self): + return self._extension_dict_backend + def GetBrowserStartupArgs(self): args = [] args.extend(self.options.extra_browser_args) @@ -73,6 +91,12 @@ class BrowserBackend(object): self.webpagereplay_remote_https_port)) args.extend(user_agent.GetChromeUserAgentArgumentFromType( self.options.browser_user_agent_type)) + + extensions = ','.join( + [extension.path for extension in self.options.extensions_to_load]) + if len(self.options.extensions_to_load) > 0: + args.append('--load-extension=%s' % extensions) + return args @property @@ -92,6 +116,17 @@ class BrowserBackend(object): except util.TimeoutException: raise browser_gone_exception.BrowserGoneException() + def AllExtensionsLoaded(): + for e in self.options.extensions_to_load: + extension_id = e.extension_id() + if not extension_id in self._extension_dict_backend: + return False + extension_object = self._extension_dict_backend[extension_id] + extension_object.WaitForDocumentReadyStateToBeInteractiveOrBetter() + return True + if self._supports_extensions: + util.WaitFor(AllExtensionsLoaded, timeout=30) + def _PostBrowserStartupInitialization(self): # Detect version information. data = self.Request('version') diff --git a/tools/telemetry/telemetry/browser_finder.py b/tools/telemetry/telemetry/browser_finder.py index afc7930..8ec6c3a 100644 --- a/tools/telemetry/telemetry/browser_finder.py +++ b/tools/telemetry/telemetry/browser_finder.py @@ -53,7 +53,7 @@ def FindBrowser(options): return None matching_browsers = [b for b in browsers - if b.browser_type == options.browser_type] + if b.browser_type == options.browser_type and b.SupportsOptions(options)] if len(matching_browsers) == 1: return matching_browsers[0] diff --git a/tools/telemetry/telemetry/browser_options.py b/tools/telemetry/telemetry/browser_options.py index 631499c..cb714e8 100644 --- a/tools/telemetry/telemetry/browser_options.py +++ b/tools/telemetry/telemetry/browser_options.py @@ -26,6 +26,7 @@ class BrowserOptions(optparse.Values): self.extra_browser_args = [] self.extra_wpr_args = [] self.show_stdout = False + self.extensions_to_load = [] self.cros_remote = None self.wpr_mode = wpr_modes.WPR_OFF diff --git a/tools/telemetry/telemetry/cros_browser_backend.py b/tools/telemetry/telemetry/cros_browser_backend.py index bdb73fc..28b3bce 100644 --- a/tools/telemetry/telemetry/cros_browser_backend.py +++ b/tools/telemetry/telemetry/cros_browser_backend.py @@ -9,11 +9,11 @@ from telemetry import browser_backend from telemetry import util class CrOSBrowserBackend(browser_backend.BrowserBackend): - def __init__(self, browser_type, options, is_content_shell, cri): - super(CrOSBrowserBackend, self).__init__(is_content_shell, options) + def __init__(self, browser_type, options, cri): + super(CrOSBrowserBackend, self).__init__(is_content_shell=False, + supports_extensions=True, options=options) # Initialize fields so that an explosion during init doesn't break in Close. self._options = options - assert not is_content_shell self._cri = cri self._browser_type = browser_type diff --git a/tools/telemetry/telemetry/cros_browser_finder.py b/tools/telemetry/telemetry/cros_browser_finder.py index f9b5847..593d0b9 100644 --- a/tools/telemetry/telemetry/cros_browser_finder.py +++ b/tools/telemetry/telemetry/cros_browser_finder.py @@ -16,10 +16,9 @@ ALL_BROWSER_TYPES = ','.join([ ]) class PossibleCrOSBrowser(possible_browser.PossibleBrowser): - """A launchable android browser instance.""" + """A launchable chromeos browser instance.""" def __init__(self, browser_type, options, *args): - super(PossibleCrOSBrowser, self).__init__( - browser_type, options) + super(PossibleCrOSBrowser, self).__init__(browser_type, options) self._args = args def __repr__(self): @@ -32,6 +31,9 @@ class PossibleCrOSBrowser(possible_browser.PossibleBrowser): backend.SetBrowser(b) return b + def SupportsOptions(self, options): + return True + def FindAllAvailableBrowsers(options): """Finds all the desktop browsers available on this machine.""" if options.cros_remote == None: @@ -75,4 +77,4 @@ def FindAllAvailableBrowsers(options): if not cri.FileExistsOnDevice('/opt/google/chrome/chrome'): logging.warn('Could not find a chrome on ' % cri.hostname) - return [PossibleCrOSBrowser('cros-chrome', options, False, cri)] + return [PossibleCrOSBrowser('cros-chrome', options, cri)] diff --git a/tools/telemetry/telemetry/crx_id.py b/tools/telemetry/telemetry/crx_id.py new file mode 100644 index 0000000..2e637da --- /dev/null +++ b/tools/telemetry/telemetry/crx_id.py @@ -0,0 +1,16 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +from __future__ import absolute_import + +import os +import sys + +def __init__(): + path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')) + sys.path.append(path) + +__init__() + +from crx_id import crx_id # pylint: disable=F0401 +GetCRXAppID = crx_id.GetCRXAppID diff --git a/tools/telemetry/telemetry/desktop_browser_backend.py b/tools/telemetry/telemetry/desktop_browser_backend.py index a0e3d45..cb4d7c92 100644 --- a/tools/telemetry/telemetry/desktop_browser_backend.py +++ b/tools/telemetry/telemetry/desktop_browser_backend.py @@ -14,7 +14,9 @@ class DesktopBrowserBackend(browser_backend.BrowserBackend): Mac or Windows. """ def __init__(self, options, executable, is_content_shell): - super(DesktopBrowserBackend, self).__init__(is_content_shell, options) + super(DesktopBrowserBackend, self).__init__( + is_content_shell=is_content_shell, + supports_extensions=not is_content_shell, options=options) # Initialize fields so that an explosion during init doesn't break in Close. self._proc = None @@ -25,6 +27,10 @@ class DesktopBrowserBackend(browser_backend.BrowserBackend): if not self._executable: raise Exception('Cannot create browser, no executable found!') + if len(options.extensions_to_load) > 0 and is_content_shell: + raise browser_backend.ExtensionsNotSupportedException( + 'Content shell does not support extensions.') + self._port = util.GetAvailableLocalPort() args = [self._executable] diff --git a/tools/telemetry/telemetry/desktop_browser_finder.py b/tools/telemetry/telemetry/desktop_browser_finder.py index 0264a41..2f2243d 100644 --- a/tools/telemetry/telemetry/desktop_browser_finder.py +++ b/tools/telemetry/telemetry/desktop_browser_finder.py @@ -40,6 +40,11 @@ class PossibleDesktopBrowser(possible_browser.PossibleBrowser): backend.SetBrowser(b) return b + def SupportsOptions(self, options): + if (len(options.extensions_to_load) != 0) and self._is_content_shell: + return False + return True + def FindAllAvailableBrowsers(options): """Finds all the desktop browsers available on this machine.""" browsers = [] @@ -122,8 +127,7 @@ def FindAllAvailableBrowsers(options): pass if found: browsers.append( - PossibleDesktopBrowser('system', options, - 'google-chrome', False)) + PossibleDesktopBrowser('system', options, 'google-chrome', False)) # Win32-specific options. if sys.platform.startswith('win'): diff --git a/tools/telemetry/telemetry/extension_dict.py b/tools/telemetry/telemetry/extension_dict.py new file mode 100644 index 0000000..5f84af7 --- /dev/null +++ b/tools/telemetry/telemetry/extension_dict.py @@ -0,0 +1,26 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +from telemetry import extension_to_load + +class ExtensionDict(object): + """Dictionary of ExtensionPage instances, with extension_id as key""" + + def __init__(self, extension_dict_backend): + self._extension_dict_backend = extension_dict_backend + + def __getitem__(self, load_extension): + """Given an ExtensionToLoad instance, returns the corresponding + ExtensionPage instance.""" + if not isinstance(load_extension, extension_to_load.ExtensionToLoad): + raise Exception("Input param must be of type ExtensionToLoad") + return self._extension_dict_backend.__getitem__( + load_extension.extension_id()) + + def __contains__(self, load_extension): + """Checks if this ExtensionToLoad instance has been loaded""" + if not isinstance(load_extension, extension_to_load.ExtensionToLoad): + raise Exception("Input param must be of type ExtensionToLoad") + return self._extension_dict_backend.__contains__( + load_extension.extension_id()) diff --git a/tools/telemetry/telemetry/extension_dict_backend.py b/tools/telemetry/telemetry/extension_dict_backend.py new file mode 100644 index 0000000..22f686f --- /dev/null +++ b/tools/telemetry/telemetry/extension_dict_backend.py @@ -0,0 +1,81 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +import httplib +import json +import re +import socket +import urllib2 +import weakref + +from telemetry import browser_gone_exception +from telemetry import extension_page +from telemetry import inspector_backend + +class BrowserConnectionGoneException( + browser_gone_exception.BrowserGoneException): + pass + +class ExtensionDictBackend(object): + def __init__(self, browser_backend): + self._browser_backend = browser_backend + # Maps extension ids to ExtensionPage objects. + self._extension_dict = weakref.WeakValueDictionary() + + def __getitem__(self, extension_id): + extension_object = self._extension_dict.get(extension_id) + if not extension_object: + extension_object = self._CreateExtensionObject(extension_id) + if extension_object: + self._extension_dict[extension_id] = extension_object + return extension_object + + def __contains__(self, extension_id): + return extension_id in self._GetExtensionIds() + + @staticmethod + def _ExtractExtensionId(url): + m = re.match(r"(chrome-extension://)([^/]+)", url) + assert m + return m.group(2) + + @staticmethod + def _GetExtensionId(extension_info): + if 'url' not in extension_info: + return None + return ExtensionDictBackend._ExtractExtensionId(extension_info['url']) + + def _CreateExtensionObject(self, extension_id): + extension_info = self._FindExtensionInfo(extension_id) + if not extension_info or not 'webSocketDebuggerUrl' in extension_info: + return None + return extension_page.ExtensionPage( + self._CreateInspectorBackendForDebuggerUrl( + extension_info['webSocketDebuggerUrl'])) + + def _CreateInspectorBackendForDebuggerUrl(self, debugger_url): + return inspector_backend.InspectorBackend(self._browser_backend.browser, + self._browser_backend, + debugger_url) + + def _FindExtensionInfo(self, extension_id): + for extension_info in self._GetExtensionInfoList(): + if self._GetExtensionId(extension_info) == extension_id: + return extension_info + return None + + def _GetExtensionInfoList(self, timeout=None): + try: + data = self._browser_backend.Request('', timeout=timeout) + return self._FilterExtensions(json.loads(data)) + except (socket.error, httplib.BadStatusLine, urllib2.URLError): + if not self._browser_backend.IsBrowserRunning(): + raise browser_gone_exception.BrowserGoneException() + raise BrowserConnectionGoneException() + + def _FilterExtensions(self, all_pages): + return [page_info for page_info in all_pages + if page_info['url'].startswith('chrome-extension://')] + + def _GetExtensionIds(self): + return map(self._GetExtensionId, self._GetExtensionInfoList()) diff --git a/tools/telemetry/telemetry/extension_page.py b/tools/telemetry/telemetry/extension_page.py new file mode 100644 index 0000000..59ed2fb --- /dev/null +++ b/tools/telemetry/telemetry/extension_page.py @@ -0,0 +1,12 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +from telemetry import web_contents + +class ExtensionPage(web_contents.WebContents): + """Represents a an extension page in the browser""" + def __init__(self, inspector_backend): + super(ExtensionPage, self).__init__(inspector_backend) + + def __del__(self): + super(ExtensionPage, self).__del__() diff --git a/tools/telemetry/telemetry/extension_to_load.py b/tools/telemetry/telemetry/extension_to_load.py new file mode 100644 index 0000000..608156d --- /dev/null +++ b/tools/telemetry/telemetry/extension_to_load.py @@ -0,0 +1,15 @@ +# Copyright (c) 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +import os + +from telemetry import crx_id + +class ExtensionToLoad(object): + def __init__(self, path): + if not os.path.isdir(path): + raise Exception('Extension path not a directory %s' % path) + self.path = path + + def extension_id(self): + return crx_id.GetCRXAppID(os.path.abspath(self.path)) diff --git a/tools/telemetry/telemetry/extension_unittest.py b/tools/telemetry/telemetry/extension_unittest.py new file mode 100644 index 0000000..f0578229 --- /dev/null +++ b/tools/telemetry/telemetry/extension_unittest.py @@ -0,0 +1,74 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +import os +import shutil +import tempfile +import unittest + +from telemetry import browser_finder +from telemetry import extension_to_load +from telemetry import options_for_unittests + +class ExtensionTest(unittest.TestCase): + def testExtension(self): + extension_path = os.path.join(os.path.dirname(__file__), + '..', 'unittest_data', 'simple_extension') + load_extension = extension_to_load.ExtensionToLoad(extension_path) + + options = options_for_unittests.GetCopy() + options.extensions_to_load = [load_extension] + browser_to_create = browser_finder.FindBrowser(options) + if not browser_to_create: + # Could not find a browser that supports extensions. + return + + with browser_to_create.Create() as b: + extension = b.extensions[load_extension] + assert extension + extension.ExecuteJavaScript("setTestVar('abcdef')") + self.assertEquals('abcdef', extension.EvaluateJavaScript("_testVar")) + +class MultipleExtensionTest(unittest.TestCase): + def setUp(self): + """ Copy the manifest and background.js files of simple_extension to a + number of temporary directories to load as extensions""" + self._extension_dirs = [tempfile.mkdtemp() + for i in range(3)] # pylint: disable=W0612 + src_extension_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), + '..', 'unittest_data', 'simple_extension')) + manifest_path = os.path.join(src_extension_dir, 'manifest.json') + script_path = os.path.join(src_extension_dir, 'background.js') + for d in self._extension_dirs: + shutil.copy(manifest_path, d) + shutil.copy(script_path, d) + self._extensions_to_load = [extension_to_load.ExtensionToLoad(d) + for d in self._extension_dirs] + options = options_for_unittests.GetCopy() + options.extensions_to_load = self._extensions_to_load + browser_to_create = browser_finder.FindBrowser(options) + self._browser = None + # May not find a browser that supports extensions. + if browser_to_create: + self._browser = browser_to_create.Create() + + def tearDown(self): + if self._browser: + self._browser.Close() + for d in self._extension_dirs: + shutil.rmtree(d) + + def testMultipleExtensions(self): + if not self._browser: + return + + # Test contains. + loaded_extensions = filter(lambda e: e in self._browser.extensions, + self._extensions_to_load) + self.assertEqual(len(loaded_extensions), len(self._extensions_to_load)) + + for load_extension in self._extensions_to_load: + extension = self._browser.extensions[load_extension] + assert extension + extension.ExecuteJavaScript("setTestVar('abcdef')") + self.assertEquals('abcdef', extension.EvaluateJavaScript("_testVar")) diff --git a/tools/telemetry/telemetry/possible_browser.py b/tools/telemetry/telemetry/possible_browser.py index 2cb995f..13772af 100644 --- a/tools/telemetry/telemetry/possible_browser.py +++ b/tools/telemetry/telemetry/possible_browser.py @@ -20,3 +20,7 @@ class PossibleBrowser(object): def Create(self): raise NotImplementedError() + + def SupportsOptions(self, options): + """Tests for extension support.""" + raise NotImplementedError() diff --git a/tools/telemetry/unittest_data/simple_extension/background.js b/tools/telemetry/unittest_data/simple_extension/background.js new file mode 100644 index 0000000..28b5760 --- /dev/null +++ b/tools/telemetry/unittest_data/simple_extension/background.js @@ -0,0 +1,8 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +var _testVar; +function setTestVar(x) { + _testVar = x; +} diff --git a/tools/telemetry/unittest_data/simple_extension/manifest.json b/tools/telemetry/unittest_data/simple_extension/manifest.json new file mode 100644 index 0000000..d4bb6a3 --- /dev/null +++ b/tools/telemetry/unittest_data/simple_extension/manifest.json @@ -0,0 +1,9 @@ +{ + "description": "Simple test extension which has just a background script", + "name": "Simple Telemetry Test Extension", + "background": { + "scripts": ["background.js"] + }, + "manifest_version": 2, + "version": "0.1" +} |