Home | History | Annotate | Download | only in install_test
      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.
      4 
      5 """Extended WebDriver interface that uses helper extension.
      6 
      7 This file is makeshift and should eventually be switched over to
      8 using the new ChromeDriver python interface. However, as that is
      9 not quite ready, this class simply installs a helper extension
     10 and executes scripts in the background page to access extension
     11 APIs.
     12 
     13 This may end up being merged with chrome/test/ext_auto, if they
     14 accomplish similar enough purposes. For now, integration with that
     15 is a bit premature.
     16 """
     17 
     18 import os
     19 
     20 from selenium import webdriver
     21 
     22 
     23 _CHROME_GET_VIEW_HANDLES = 'chrome.getViewHandles'
     24 _EXTENSION = os.path.join(
     25     os.path.dirname(os.path.abspath(__file__)), 'ext_auto')
     26 
     27 
     28 class Chrome(webdriver.Remote):
     29   """Extended WebDriver interface that uses helper extension."""
     30 
     31   def __init__(self, url, desired_capabilities, options=None):
     32     """Initializes Chrome object.
     33 
     34     If both desired_capabilities and options have the same settings, the
     35     settings from options will be used.
     36 
     37     Args:
     38       url: The URL of the ChromeDriver Service.
     39       desired_capabilities: Chrome capabilities dictionary.
     40       options: chrome_options.ChromeOptions object. Settings in options will
     41           overwrite settings in desired_capabilities.
     42 
     43     Raises:
     44       RuntimeError: Unable to find helper extension.
     45     """
     46     if options is not None:
     47       desired_capabilities.update(options.GetCapabilities())
     48     switches = desired_capabilities.get('chrome.switches', [])
     49     switches += ['--load-extension=' + _EXTENSION]
     50     desired_capabilities['chrome.switches'] = switches
     51     super(Chrome, self).__init__(url, desired_capabilities)
     52 
     53     custom_commands = {
     54         _CHROME_GET_VIEW_HANDLES:
     55             ('GET', '/session/$sessionId/chrome/views'),
     56     }
     57     self.command_executor._commands.update(custom_commands)
     58     views = self.execute(_CHROME_GET_VIEW_HANDLES)['value']
     59     self.set_script_timeout(30)  # TODO(kkania): Make this configurable.
     60     for view in views:
     61       if view.get('extension_id') == 'aapnijgdinlhnhlmodcfapnahmbfebeb':
     62         self._extension = view['handle']
     63         break
     64     else:
     65       raise RuntimeError('Unable to find helper extension')
     66 
     67   def _execute_extension_command(self, name, params={}):
     68     """Executes an extension command.
     69 
     70     When Chrome is started, a helper extension is loaded which provides
     71     a simple synchronous API for manipulating Chrome via the extension
     72     APIs. Communication with the extension is accomplished by executing
     73     a script in the background page of the extension which calls the
     74     'executeCommand' function with the name of the command, a parameter
     75     dictionary, and a callback function that can be used to signal
     76     when the command is finished and potentially send a return value.
     77     """
     78     old_window = self.current_window_handle
     79     self.switch_to_window(self._extension)
     80     self.execute_async_script(
     81         'executeCommand.apply(null, arguments)', name, params)
     82     self.switch_to_window(old_window)
     83 
     84   def create_tab(self, url=None):
     85     """Creates a new tab with the given URL and switches to it.
     86 
     87     If no URL is provided, the homepage will be used.
     88     """
     89     params = {}
     90     if url is not None:
     91       params['url'] = url
     92     self._execute_extension_command('createTab', params)
     93     self.switch_to_window(self.window_handles[-1])
     94 
     95   def create_blank_tab(self):
     96     """Creates a new blank tab and switches to it."""
     97     self.create_tab('about:blank')
     98