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 import decorators 13from telemetry.internal.browser import browser_finder 14from telemetry.internal.browser import extension_to_load 15from telemetry.testing import options_for_unittests 16 17 18class ExtensionTest(unittest.TestCase): 19 def setUp(self): 20 self._browser = None 21 self._platform = None 22 self._extension = None 23 self._extension_id = None 24 25 def CreateBrowserWithExtension(self, ext_path): 26 extension_path = os.path.join(util.GetUnittestDataDir(), ext_path) 27 options = options_for_unittests.GetCopy() 28 load_extension = extension_to_load.ExtensionToLoad( 29 extension_path, options.browser_type) 30 options.browser_options.extensions_to_load = [load_extension] 31 browser_to_create = browser_finder.FindBrowser(options) 32 33 if not browser_to_create: 34 # May not find a browser that supports extensions. 35 return False 36 self._platform = browser_to_create.platform 37 self._platform.network_controller.InitializeIfNeeded() 38 self._browser = browser_to_create.Create(options) 39 self._extension = self._browser.extensions[load_extension] 40 self._extension_id = load_extension.extension_id 41 self.assertTrue(self._extension) 42 return True 43 44 def tearDown(self): 45 if self._browser: 46 self._browser.Close() 47 self._platform.network_controller.Close() 48 49 def testExtensionBasic(self): 50 """Test ExtensionPage's ExecuteJavaScript and EvaluateJavaScript.""" 51 if not self.CreateBrowserWithExtension('simple_extension'): 52 logging.warning('Did not find a browser that supports extensions, ' 53 'skipping test.') 54 return 55 self.assertTrue( 56 self._extension.EvaluateJavaScript('chrome.runtime != null')) 57 self._extension.ExecuteJavaScript('setTestVar("abcdef")') 58 self.assertEquals('abcdef', 59 self._extension.EvaluateJavaScript('_testVar')) 60 61 def testExtensionGetByExtensionId(self): 62 """Test GetByExtensionId for a simple extension with a background page.""" 63 if not self.CreateBrowserWithExtension('simple_extension'): 64 logging.warning('Did not find a browser that supports extensions, ' 65 'skipping test.') 66 return 67 ext = self._browser.extensions.GetByExtensionId(self._extension_id) 68 self.assertEqual(1, len(ext)) 69 self.assertEqual(ext[0], self._extension) 70 self.assertTrue( 71 ext[0].EvaluateJavaScript('chrome.runtime != null')) 72 73 @decorators.Disabled('mac') 74 def testWebApp(self): 75 """Tests GetByExtensionId for a web app with multiple pages.""" 76 if not self.CreateBrowserWithExtension('simple_app'): 77 logging.warning('Did not find a browser that supports extensions, ' 78 'skipping test.') 79 return 80 extensions = self._browser.extensions.GetByExtensionId(self._extension_id) 81 extension_urls = set([ext.EvaluateJavaScript('location.href;') 82 for ext in extensions]) 83 expected_urls = set(['chrome-extension://' + self._extension_id + '/' + path 84 for path in ['main.html', 'second.html', 85 '_generated_background_page.html']]) 86 87 self.assertEqual(expected_urls, extension_urls) 88 89class NonExistentExtensionTest(unittest.TestCase): 90 def testNonExistentExtensionPath(self): 91 """Test that a non-existent extension path will raise an exception.""" 92 extension_path = os.path.join(util.GetUnittestDataDir(), 'foo') 93 options = options_for_unittests.GetCopy() 94 self.assertRaises(extension_to_load.ExtensionPathNonExistentException, 95 lambda: extension_to_load.ExtensionToLoad( 96 extension_path, options.browser_type)) 97 98 def testExtensionNotLoaded(self): 99 """Querying an extension that was not loaded will return None""" 100 extension_path = os.path.join(util.GetUnittestDataDir(), 'simple_extension') 101 options = options_for_unittests.GetCopy() 102 load_extension = extension_to_load.ExtensionToLoad( 103 extension_path, options.browser_type) 104 browser_to_create = browser_finder.FindBrowser(options) 105 try: 106 browser_to_create.platform.network_controller.InitializeIfNeeded() 107 with browser_to_create.Create(options) as b: 108 if b.supports_extensions: 109 self.assertRaises(KeyError, lambda: b.extensions[load_extension]) 110 finally: 111 browser_to_create.platform.network_controller.Close() 112 113class MultipleExtensionTest(unittest.TestCase): 114 def setUp(self): 115 """ Copy the manifest and background.js files of simple_extension to a 116 number of temporary directories to load as extensions""" 117 self._extension_dirs = [tempfile.mkdtemp() for _ in range(3)] 118 src_extension_dir = os.path.join( 119 util.GetUnittestDataDir(), 'simple_extension') 120 manifest_path = os.path.join(src_extension_dir, 'manifest.json') 121 script_path = os.path.join(src_extension_dir, 'background.js') 122 for d in self._extension_dirs: 123 shutil.copy(manifest_path, d) 124 shutil.copy(script_path, d) 125 options = options_for_unittests.GetCopy() 126 self._extensions_to_load = [extension_to_load.ExtensionToLoad( 127 d, options.browser_type) 128 for d in self._extension_dirs] 129 options.browser_options.extensions_to_load = self._extensions_to_load 130 browser_to_create = browser_finder.FindBrowser(options) 131 self._platform = None 132 self._browser = None 133 # May not find a browser that supports extensions. 134 if browser_to_create: 135 self._platform = browser_to_create.platform 136 self._platform.network_controller.InitializeIfNeeded() 137 self._browser = browser_to_create.Create(options) 138 139 def tearDown(self): 140 if self._platform: 141 self._platform.network_controller.Close() 142 if self._browser: 143 self._browser.Close() 144 for d in self._extension_dirs: 145 shutil.rmtree(d) 146 147 def testMultipleExtensions(self): 148 if not self._browser: 149 logging.warning('Did not find a browser that supports extensions, ' 150 'skipping test.') 151 return 152 153 # Test contains. 154 loaded_extensions = [e for e in self._extensions_to_load 155 if e in self._browser.extensions] 156 self.assertEqual(len(loaded_extensions), len(self._extensions_to_load)) 157 for load_extension in self._extensions_to_load: 158 extension = self._browser.extensions[load_extension] 159 assert extension 160 self.assertTrue( 161 extension.EvaluateJavaScript('chrome.runtime != null')) 162 extension.ExecuteJavaScript('setTestVar("abcdef")') 163 self.assertEquals('abcdef', extension.EvaluateJavaScript('_testVar')) 164 165 166class ComponentExtensionTest(unittest.TestCase): 167 def testComponentExtensionBasic(self): 168 extension_path = os.path.join( 169 util.GetUnittestDataDir(), 'component_extension') 170 options = options_for_unittests.GetCopy() 171 load_extension = extension_to_load.ExtensionToLoad( 172 extension_path, options.browser_type, is_component=True) 173 174 options.browser_options.extensions_to_load = [load_extension] 175 browser_to_create = browser_finder.FindBrowser(options) 176 if not browser_to_create: 177 logging.warning('Did not find a browser that supports extensions, ' 178 'skipping test.') 179 return 180 181 try: 182 browser_to_create.platform.network_controller.InitializeIfNeeded() 183 with browser_to_create.Create(options) as b: 184 extension = b.extensions[load_extension] 185 self.assertTrue( 186 extension.EvaluateJavaScript('chrome.runtime != null')) 187 extension.ExecuteJavaScript('setTestVar("abcdef")') 188 self.assertEquals('abcdef', extension.EvaluateJavaScript('_testVar')) 189 finally: 190 browser_to_create.platform.network_controller.Close() 191 192 def testComponentExtensionNoPublicKey(self): 193 # simple_extension does not have a public key. 194 extension_path = os.path.join(util.GetUnittestDataDir(), 'simple_extension') 195 options = options_for_unittests.GetCopy() 196 self.assertRaises(extension_to_load.MissingPublicKeyException, 197 lambda: extension_to_load.ExtensionToLoad( 198 extension_path, 199 browser_type=options.browser_type, 200 is_component=True)) 201 202 203class WebviewInExtensionTest(ExtensionTest): 204 205 # Flaky on windows, hits an exception: http://crbug.com/508325 206 @decorators.Disabled('win', 'linux') 207 def testWebviewInExtension(self): 208 """Tests GetWebviewContext() for a web app containing <webview> element.""" 209 if not self.CreateBrowserWithExtension('webview_app'): 210 logging.warning('Did not find a browser that supports extensions, ' 211 'skipping test.') 212 return 213 214 self._browser.extensions.GetByExtensionId(self._extension_id) 215 webview_contexts = self._extension.GetWebviewContexts() 216 self.assertEquals(1, len(webview_contexts)) 217 webview_context = webview_contexts[0] 218 webview_context.WaitForDocumentReadyStateToBeComplete() 219 # Check that the context has the right url from the <webview> element. 220 self.assertTrue(webview_context.GetUrl().startswith('data:')) 221 # Check |test_input_id| element is accessible from the webview context. 222 self.assertTrue(webview_context.EvaluateJavaScript( 223 'document.getElementById("test_input_id") != null')) 224 # Check that |test_input_id| is not accessible from outside webview context 225 self.assertFalse(self._extension.EvaluateJavaScript( 226 'document.getElementById("test_input_id") != null')) 227