1 # Copyright 2013 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 """Finds desktop browsers that can be controlled by telemetry."""
11 from telemetry.core import platform as platform_module
12 from telemetry.core import browser
13 from telemetry.core import possible_browser
14 from telemetry.core.backends.chrome import desktop_browser_backend
15 from telemetry.util import path
18 class PossibleDesktopBrowser(possible_browser.PossibleBrowser):
19 """A desktop browser that can be controlled."""
21 def __init__(self, browser_type, finder_options, executable, flash_path,
22 is_content_shell, browser_directory, is_local_build=False):
23 target_os = sys.platform.lower()
24 super(PossibleDesktopBrowser, self).__init__(browser_type, target_os,
25 finder_options, not is_content_shell)
26 assert browser_type in FindAllBrowserTypes(finder_options), \
27 ('Please add %s to desktop_browser_finder.FindAllBrowserTypes' %
29 self._local_executable = executable
30 self._flash_path = flash_path
31 self._is_content_shell = is_content_shell
32 self._browser_directory = browser_directory
33 self.is_local_build = is_local_build
36 return 'PossibleDesktopBrowser(type=%s, executable=%s, flash=%s)' % (
37 self.browser_type, self._local_executable, self._flash_path)
39 def _InitPlatformIfNeeded(self):
43 self._platform = platform_module.GetHostPlatform()
45 # pylint: disable=W0212
46 self._platform_backend = self._platform._platform_backend
49 if self._flash_path and not os.path.exists(self._flash_path):
51 'Could not find Flash at %s. Continuing without Flash.\n'
52 'To run with Flash, check it out via http://go/read-src-internal',
54 self._flash_path = None
56 self._InitPlatformIfNeeded()
58 backend = desktop_browser_backend.DesktopBrowserBackend(
59 self.finder_options.browser_options, self._local_executable,
60 self._flash_path, self._is_content_shell, self._browser_directory,
61 output_profile_path=self.finder_options.output_profile_path,
62 extensions_to_load=self.finder_options.extensions_to_load)
63 return browser.Browser(backend,
64 self._platform_backend,
66 self._append_to_existing_wpr,
67 self._make_javascript_deterministic,
68 self._credentials_path)
70 def SupportsOptions(self, finder_options):
71 if (len(finder_options.extensions_to_load) != 0) and self._is_content_shell:
75 def UpdateExecutableIfNeeded(self):
78 def last_modification_time(self):
79 if os.path.exists(self._local_executable):
80 return os.path.getmtime(self._local_executable)
83 def SelectDefaultBrowser(possible_browsers):
84 local_builds_by_date = [
85 b for b in sorted(possible_browsers,
86 key=lambda b: b.last_modification_time())
88 if local_builds_by_date:
89 return local_builds_by_date[-1]
92 def CanFindAvailableBrowsers():
93 return not platform_module.GetHostPlatform().GetOSName() == 'chromeos'
95 def FindAllBrowserTypes(_):
104 'content-shell-debug',
105 'content-shell-debug_x64',
106 'content-shell-release',
107 'content-shell-release_x64',
110 def FindAllAvailableBrowsers(finder_options):
111 """Finds all the desktop browsers available on this machine."""
114 if not CanFindAvailableBrowsers():
118 if (sys.platform.startswith('linux') and
119 os.getenv('DISPLAY') == None):
122 # Look for a browser in the standard chrome build locations.
123 if finder_options.chrome_root:
124 chrome_root = finder_options.chrome_root
126 chrome_root = path.GetChromiumSrcDir()
128 flash_bin_dir = os.path.join(
129 chrome_root, 'third_party', 'adobe', 'flash', 'binaries', 'ppapi')
131 chromium_app_names = []
132 if sys.platform == 'darwin':
133 chromium_app_names.append('Chromium.app/Contents/MacOS/Chromium')
134 chromium_app_names.append('Google Chrome.app/Contents/MacOS/Google Chrome')
135 content_shell_app_name = 'Content Shell.app/Contents/MacOS/Content Shell'
136 flash_bin = 'PepperFlashPlayer.plugin'
137 flash_path = os.path.join(flash_bin_dir, 'mac', flash_bin)
138 flash_path_64 = os.path.join(flash_bin_dir, 'mac_64', flash_bin)
139 elif sys.platform.startswith('linux'):
140 chromium_app_names.append('chrome')
141 content_shell_app_name = 'content_shell'
142 flash_bin = 'libpepflashplayer.so'
143 flash_path = os.path.join(flash_bin_dir, 'linux', flash_bin)
144 flash_path_64 = os.path.join(flash_bin_dir, 'linux_x64', flash_bin)
145 elif sys.platform.startswith('win'):
146 chromium_app_names.append('chrome.exe')
147 content_shell_app_name = 'content_shell.exe'
148 flash_bin = 'pepflashplayer.dll'
149 flash_path = os.path.join(flash_bin_dir, 'win', flash_bin)
150 flash_path_64 = os.path.join(flash_bin_dir, 'win_x64', flash_bin)
152 raise Exception('Platform not recognized')
154 # Add the explicit browser executable if given.
155 if finder_options.browser_executable:
156 normalized_executable = os.path.expanduser(
157 finder_options.browser_executable)
158 if path.IsExecutable(normalized_executable):
159 browser_directory = os.path.dirname(finder_options.browser_executable)
160 browsers.append(PossibleDesktopBrowser('exact', finder_options,
161 normalized_executable, flash_path,
162 False, browser_directory))
164 raise Exception('%s specified by --browser-executable does not exist',
165 normalized_executable)
167 def AddIfFound(browser_type, build_dir, type_dir, app_name, content_shell):
168 browser_directory = os.path.join(chrome_root, build_dir, type_dir)
169 app = os.path.join(browser_directory, app_name)
170 if path.IsExecutable(app):
171 is_64 = browser_type.endswith('_x64')
172 browsers.append(PossibleDesktopBrowser(
173 browser_type, finder_options, app,
174 flash_path_64 if is_64 else flash_path,
175 content_shell, browser_directory, is_local_build=True))
180 for build_dir, build_type in path.GetBuildDirectories():
181 for chromium_app_name in chromium_app_names:
182 AddIfFound(build_type.lower(), build_dir, build_type,
183 chromium_app_name, False)
184 AddIfFound('content-shell-' + build_type.lower(), build_dir, build_type,
185 content_shell_app_name, True)
187 reference_build_root = os.path.join(
188 chrome_root, 'chrome', 'tools', 'test', 'reference_build')
190 # Mac-specific options.
191 if sys.platform == 'darwin':
192 mac_canary_root = '/Applications/Google Chrome Canary.app/'
193 mac_canary = mac_canary_root + 'Contents/MacOS/Google Chrome Canary'
194 mac_system_root = '/Applications/Google Chrome.app'
195 mac_system = mac_system_root + '/Contents/MacOS/Google Chrome'
196 mac_reference_root = reference_build_root + '/chrome_mac/Google Chrome.app/'
197 mac_reference = mac_reference_root + 'Contents/MacOS/Google Chrome'
198 if path.IsExecutable(mac_canary):
199 browsers.append(PossibleDesktopBrowser('canary', finder_options,
200 mac_canary, None, False,
203 if path.IsExecutable(mac_system):
204 browsers.append(PossibleDesktopBrowser('system', finder_options,
205 mac_system, None, False,
207 if path.IsExecutable(mac_reference):
208 browsers.append(PossibleDesktopBrowser('reference', finder_options,
209 mac_reference, None, False,
212 # Linux specific options.
213 if sys.platform.startswith('linux'):
214 # Look for a google-chrome instance.
217 with open(os.devnull, 'w') as devnull:
218 found = subprocess.call(['google-chrome', '--version'],
219 stdout=devnull, stderr=devnull) == 0
223 browsers.append(PossibleDesktopBrowser('system', finder_options,
224 'google-chrome', None, False,
225 '/opt/google/chrome'))
226 linux_reference_root = os.path.join(reference_build_root, 'chrome_linux')
227 linux_reference = os.path.join(linux_reference_root, 'chrome')
228 if path.IsExecutable(linux_reference):
229 browsers.append(PossibleDesktopBrowser('reference', finder_options,
230 linux_reference, None, False,
231 linux_reference_root))
233 # Win32-specific options.
234 if sys.platform.startswith('win'):
236 ('system', os.path.join('Google', 'Chrome', 'Application')),
237 ('canary', os.path.join('Google', 'Chrome SxS', 'Application')),
238 ('reference', os.path.join(reference_build_root, 'chrome_win')),
241 for browser_name, app_path in app_paths:
242 for chromium_app_name in chromium_app_names:
243 app_path = os.path.join(app_path, chromium_app_name)
244 app_path = path.FindInstalledWindowsApplication(app_path)
246 browsers.append(PossibleDesktopBrowser(
247 browser_name, finder_options, app_path,
248 None, False, os.path.dirname(app_path)))
250 if len(browsers) and not has_display:
252 'Found (%s), but you do not have a DISPLAY environment set.' %
253 ','.join([b.browser_type for b in browsers]))