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."""
5
6import logging
7import os
8import sys
9
10from telemetry.core import browser
11from telemetry.core import possible_browser
12from telemetry.core import platform
13from telemetry.core import util
14from telemetry.core.backends.webdriver import webdriver_ie_backend
15from telemetry.page import cloud_storage
16
17# Try to import the selenium python lib which may be not available.
18util.AddDirToPythonPath(
19    util.GetChromiumSrcDir(), 'third_party', 'webdriver', 'pylib')
20try:
21  from selenium import webdriver  # pylint: disable=F0401
22except ImportError:
23  webdriver = None
24
25ALL_BROWSER_TYPES = []
26if webdriver:
27  ALL_BROWSER_TYPES = [
28      'internet-explorer',
29      'internet-explorer-x64']
30else:
31  logging.warning('Webdriver backend is unsupported without selenium pylib. '
32                  'For installation of selenium pylib, please refer to '
33                  'https://code.google.com/p/selenium/wiki/PythonBindings.')
34
35
36class PossibleWebDriverBrowser(possible_browser.PossibleBrowser):
37  """A browser that can be controlled through webdriver API."""
38
39  def __init__(self, browser_type, finder_options):
40    super(PossibleWebDriverBrowser, self).__init__(browser_type, finder_options)
41    assert browser_type in ALL_BROWSER_TYPES, \
42        'Please add %s to ALL_BROWSER_TYPES' % browser_type
43
44  def CreateWebDriverBackend(self, platform_backend):
45    raise NotImplementedError()
46
47  def Create(self):
48    platform_backend = platform.CreatePlatformBackendForCurrentOS()
49    backend = self.CreateWebDriverBackend(platform_backend)
50    b = browser.Browser(backend, platform_backend)
51    return b
52
53  def SupportsOptions(self, finder_options):
54    if len(finder_options.extensions_to_load) != 0:
55      return False
56    return True
57
58  def UpdateExecutableIfNeeded(self):
59    pass
60
61  @property
62  def last_modification_time(self):
63    return -1
64
65
66class PossibleDesktopIE(PossibleWebDriverBrowser):
67  def __init__(self, browser_type, finder_options, architecture):
68    super(PossibleDesktopIE, self).__init__(browser_type, finder_options)
69    self._architecture = architecture
70
71  def CreateWebDriverBackend(self, platform_backend):
72    assert webdriver
73    def DriverCreator():
74      ie_driver_exe = os.path.join(util.GetTelemetryDir(), 'bin',
75                                   'IEDriverServer_%s.exe' % self._architecture)
76      cloud_storage.GetIfChanged(cloud_storage.PUBLIC_BUCKET, ie_driver_exe)
77      return webdriver.Ie(executable_path=ie_driver_exe)
78    return webdriver_ie_backend.WebDriverIEBackend(
79        platform_backend, DriverCreator, self.finder_options.browser_options)
80
81def SelectDefaultBrowser(_):
82  return None
83
84def FindAllAvailableBrowsers(finder_options):
85  """Finds all the desktop browsers available on this machine."""
86  browsers = []
87  if not webdriver:
88    return browsers
89
90  # Look for the IE browser in the standard location.
91  if sys.platform.startswith('win'):
92    ie_path = os.path.join('Internet Explorer', 'iexplore.exe')
93    win_search_paths = {
94        '32' : { 'path' : os.getenv('PROGRAMFILES(X86)'),
95                 'type' : 'internet-explorer'},
96        '64' : { 'path' : os.getenv('PROGRAMFILES'),
97                 'type' : 'internet-explorer-x64'}}
98    for architecture, ie_info in win_search_paths.iteritems():
99      if not ie_info['path']:
100        continue
101      if os.path.exists(os.path.join(ie_info['path'], ie_path)):
102        browsers.append(
103            PossibleDesktopIE(ie_info['type'], finder_options, architecture))
104
105  return browsers
106