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
5import uuid
6
7
8class TabTracker(object):
9  """Uniquely track tabs within a window.
10
11  This allows the creation of tabs whose indices can be
12  determined even after lower indexed tabs have been closed, therefore changing
13  that tab's index.
14
15  This is accomplished via a containing window which is created and tracked via
16  the window's index. As a result of this, all calls to open and close tabs in
17  this TabTracker's window must go through the appropriate instance of the
18  TabTracker. Also note that if a lower indexed window is closed after this
19  TabTracker is instantiated, this TabTracker will lose track of its window
20  """
21
22  def __init__(self, browser, visible=False):
23    """
24    Args:
25      browser: an instance of PyUITest
26      visible: whether or not this TabTracker's window will be visible
27    """
28    # A binary search tree would be faster, but this is easier to write.
29    # If this needs to become faster, understand that the important operations
30    # here are append, arbitrary deletion and searching.
31    self._uuids = [None]
32    self._window_idx = browser.GetBrowserWindowCount()
33    self._browser = browser
34    browser.OpenNewBrowserWindow(visible)
35    # We leave the 0'th tab empty to have something to close on __del__
36
37  def __del__(self):
38    self._browser.CloseBrowserWindow(self._window_idx)
39
40  def CreateTab(self, url='about:blank'):
41    """Create a tracked tab and return its uuid.
42
43    Args:
44      url: a URL to navigate to
45
46    Returns:
47      a uuid uniquely identifying that tab within this TabTracker
48    """
49    self._browser.AppendTab(url, self._window_idx)
50    # We use uuids here rather than a monotonic integer to prevent confusion
51    # with the tab index.
52    tab_uuid = uuid.uuid4()
53    self._uuids.append(tab_uuid)
54    return tab_uuid
55
56  def ReleaseTab(self, tab_uuid):
57    """Release and close a tab tracked by this TabTracker.
58
59    Args:
60      tab_uuid: the uuid of the tab to close
61    """
62    idx = self.GetTabIndex(tab_uuid)
63    self._browser.CloseTab(tab_index=idx, windex=self._window_idx)
64    del self._uuids[idx]
65
66  def GetTabIndex(self, tab_uuid):
67    """Get the index of a tracked tab within this TabTracker's window.
68
69    Args:
70      tab_uuid: the uuid of the tab to close
71
72    Returns:
73      the index of the tab within this TabTracker's window
74    """
75    return self._uuids.index(tab_uuid)
76
77  def GetWindowIndex(self):
78    """Get the index of this TabTracker's window.
79
80    Returns:
81      the index of this TabTracker's window
82    """
83    return self._window_idx
84