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 5import urllib2 6 7from telemetry.core import tab 8from telemetry.core import util 9from telemetry.core.backends.chrome import inspector_backend_list 10 11 12class TabListBackend(inspector_backend_list.InspectorBackendList): 13 """A dynamic sequence of tab.Tabs in UI order.""" 14 15 def __init__(self, browser_backend): 16 super(TabListBackend, self).__init__(browser_backend, 17 backend_wrapper=tab.Tab) 18 19 def New(self, timeout): 20 assert self._browser_backend.supports_tab_control 21 self._browser_backend.Request('new', timeout=timeout) 22 return self[-1] 23 24 def CloseTab(self, debugger_url, timeout=None): 25 assert self._browser_backend.supports_tab_control 26 tab_id = inspector_backend_list.DebuggerUrlToId(debugger_url) 27 # TODO(dtu): crbug.com/160946, allow closing the last tab on some platforms. 28 # For now, just create a new tab before closing the last tab. 29 if len(self) <= 1: 30 self.New(timeout) 31 try: 32 response = self._browser_backend.Request('close/%s' % tab_id, 33 timeout=timeout, 34 throw_network_exception=True) 35 except urllib2.HTTPError: 36 raise Exception('Unable to close tab, tab id not found: %s' % tab_id) 37 assert response == 'Target is closing' 38 util.WaitFor(lambda: tab_id not in self, timeout=5) 39 40 def ActivateTab(self, debugger_url, timeout=None): 41 assert self._browser_backend.supports_tab_control 42 tab_id = inspector_backend_list.DebuggerUrlToId(debugger_url) 43 assert tab_id in self 44 try: 45 response = self._browser_backend.Request('activate/%s' % tab_id, 46 timeout=timeout, 47 throw_network_exception=True) 48 except urllib2.HTTPError: 49 raise Exception('Unable to activate tab, tab id not found: %s' % tab_id) 50 assert response == 'Target activated' 51 52 def GetTabUrl(self, debugger_url): 53 tab_id = inspector_backend_list.DebuggerUrlToId(debugger_url) 54 tab_info = self.GetContextInfo(tab_id) 55 assert tab_info is not None 56 return tab_info['url'] 57 58 def Get(self, index, ret): 59 """Returns self[index] if it exists, or ret if index is out of bounds.""" 60 if len(self) <= index: 61 return ret 62 return self[index] 63 64 def ShouldIncludeContext(self, context): 65 if 'type' in context: 66 return context['type'] == 'page' 67 # TODO: For compatibility with Chrome before r177683. 68 # This check is not completely correct, see crbug.com/190592. 69 return not context['url'].startswith('chrome-extension://') 70