1# Copyright (c) 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.
4import logging
5import os
6import shutil
7import tempfile
8import unittest
9
10from telemetry.core import browser_finder
11from telemetry.core import extension_to_load
12from telemetry.core.chrome import extension_dict_backend
13from telemetry.unittest import options_for_unittests
14
15class ExtensionTest(unittest.TestCase):
16  def setUp(self):
17    extension_path = os.path.join(os.path.dirname(__file__),
18        '..', '..', 'unittest_data', 'simple_extension')
19
20    options = options_for_unittests.GetCopy()
21    load_extension = extension_to_load.ExtensionToLoad(
22        extension_path, options.browser_type)
23    options.extensions_to_load = [load_extension]
24    browser_to_create = browser_finder.FindBrowser(options)
25
26    self._browser = None
27    self._extension = None
28    if not browser_to_create:
29      # May not find a browser that supports extensions.
30      return
31    self._browser = browser_to_create.Create()
32    self._browser.Start()
33    self._extension = self._browser.extensions[load_extension]
34    self.assertTrue(self._extension)
35
36  def tearDown(self):
37    if self._browser:
38      self._browser.Close()
39
40  def testExtensionBasic(self):
41    """Test ExtensionPage's ExecuteJavaScript and EvaluateJavaScript."""
42    if not self._extension:
43      logging.warning('Did not find a browser that supports extensions, '
44                      'skipping test.')
45      return
46    self._extension.ExecuteJavaScript('setTestVar("abcdef")')
47    self.assertEquals('abcdef',
48                      self._extension.EvaluateJavaScript('_testVar'))
49
50  def testDisconnect(self):
51    """Test that ExtensionPage.Disconnect exists by calling it.
52    EvaluateJavaScript should reconnect."""
53    if not self._extension:
54      logging.warning('Did not find a browser that supports extensions, '
55                      'skipping test.')
56      return
57    self._extension.Disconnect()
58    self.assertEquals(2, self._extension.EvaluateJavaScript('1+1'))
59
60class NonExistentExtensionTest(unittest.TestCase):
61  def testNonExistentExtensionPath(self):
62    """Test that a non-existent extension path will raise an exception."""
63    extension_path = os.path.join(os.path.dirname(__file__),
64        '..', '..', 'unittest_data', 'foo')
65    options = options_for_unittests.GetCopy()
66    self.assertRaises(extension_to_load.ExtensionPathNonExistentException,
67                      lambda: extension_to_load.ExtensionToLoad(
68                          extension_path, options.browser_type))
69
70  def testExtensionNotLoaded(self):
71    """Querying an extension that was not loaded will return None"""
72    extension_path = os.path.join(os.path.dirname(__file__),
73        '..', '..', 'unittest_data', 'simple_extension')
74    options = options_for_unittests.GetCopy()
75    load_extension = extension_to_load.ExtensionToLoad(
76        extension_path, options.browser_type)
77    browser_to_create = browser_finder.FindBrowser(options)
78    with browser_to_create.Create() as b:
79      b.Start()
80      if b.supports_extensions:
81        self.assertRaises(extension_dict_backend.ExtensionNotFoundException,
82                          lambda: b.extensions[load_extension])
83
84class MultipleExtensionTest(unittest.TestCase):
85  def setUp(self):
86    """ Copy the manifest and background.js files of simple_extension to a
87    number of temporary directories to load as extensions"""
88    self._extension_dirs = [tempfile.mkdtemp()
89                            for i in range(3)] # pylint: disable=W0612
90    src_extension_dir = os.path.abspath(os.path.join(os.path.dirname(__file__),
91        '..', '..', 'unittest_data', 'simple_extension'))
92    manifest_path = os.path.join(src_extension_dir, 'manifest.json')
93    script_path = os.path.join(src_extension_dir, 'background.js')
94    for d in self._extension_dirs:
95      shutil.copy(manifest_path, d)
96      shutil.copy(script_path, d)
97    options = options_for_unittests.GetCopy()
98    self._extensions_to_load = [extension_to_load.ExtensionToLoad(
99                                    d, options.browser_type)
100                                for d in self._extension_dirs]
101    options.extensions_to_load = self._extensions_to_load
102    browser_to_create = browser_finder.FindBrowser(options)
103    self._browser = None
104    # May not find a browser that supports extensions.
105    if browser_to_create:
106      self._browser = browser_to_create.Create()
107      self._browser.Start()
108
109  def tearDown(self):
110    if self._browser:
111      self._browser.Close()
112    for d in self._extension_dirs:
113      shutil.rmtree(d)
114
115  def testMultipleExtensions(self):
116    if not self._browser:
117      logging.warning('Did not find a browser that supports extensions, '
118                      'skipping test.')
119      return
120
121    # Test contains.
122    loaded_extensions = filter(lambda e: e in self._browser.extensions,
123                               self._extensions_to_load)
124    self.assertEqual(len(loaded_extensions), len(self._extensions_to_load))
125
126    for load_extension in self._extensions_to_load:
127      extension = self._browser.extensions[load_extension]
128      assert extension
129      extension.ExecuteJavaScript('setTestVar("abcdef")')
130      self.assertEquals('abcdef', extension.EvaluateJavaScript('_testVar'))
131
132class ComponentExtensionTest(unittest.TestCase):
133  def testComponentExtensionBasic(self):
134    extension_path = os.path.join(os.path.dirname(__file__),
135        '..', '..', 'unittest_data', 'component_extension')
136    options = options_for_unittests.GetCopy()
137    load_extension = extension_to_load.ExtensionToLoad(
138        extension_path, options.browser_type, is_component=True)
139
140    options.extensions_to_load = [load_extension]
141    browser_to_create = browser_finder.FindBrowser(options)
142    if not browser_to_create:
143      logging.warning('Did not find a browser that supports extensions, '
144                      'skipping test.')
145      return
146
147    with browser_to_create.Create() as b:
148      b.Start()
149      extension = b.extensions[load_extension]
150      extension.ExecuteJavaScript('setTestVar("abcdef")')
151      self.assertEquals('abcdef', extension.EvaluateJavaScript('_testVar'))
152
153  def testComponentExtensionNoPublicKey(self):
154    # simple_extension does not have a public key.
155    extension_path = os.path.join(os.path.dirname(__file__),
156        '..', '..', 'unittest_data', 'simple_extension')
157    options = options_for_unittests.GetCopy()
158    self.assertRaises(extension_to_load.MissingPublicKeyException,
159                      lambda: extension_to_load.ExtensionToLoad(
160                          extension_path,
161                          browser_type=options.browser_type,
162                          is_component=True))
163