| Index: chrome/test/functional/ui_model.py
|
| diff --git a/chrome/test/functional/ui_model.py b/chrome/test/functional/ui_model.py
|
| deleted file mode 100644
|
| index aac358758f343c629f1795ea87fae7ba4d111bf3..0000000000000000000000000000000000000000
|
| --- a/chrome/test/functional/ui_model.py
|
| +++ /dev/null
|
| @@ -1,424 +0,0 @@
|
| -# Copyright (c) 2011 The Chromium Authors. All rights reserved.
|
| -# Use of this source code is governed by a BSD-style license that can be
|
| -# found in the LICENSE file.
|
| -
|
| -"""Logic for generating random ui actions on the browser.
|
| -
|
| -Takes into account the expected state of the browser in order to generate
|
| -relevant ui actions.
|
| -"""
|
| -
|
| -import random
|
| -
|
| -
|
| -class TabState(object):
|
| - """A set of properties representing a browser tab."""
|
| -
|
| - def __init__(self, location):
|
| - """Init for a new tab.
|
| -
|
| - Args:
|
| - location: url string for the initial location of this tab.
|
| - """
|
| - self._history = [location]
|
| - self._position = 0
|
| -
|
| - @property
|
| - def navs(self):
|
| - return self._position
|
| -
|
| - @property
|
| - def backs(self):
|
| - return len(self._history) - self._position - 1
|
| -
|
| - @property
|
| - def location(self):
|
| - return self._history[self._position]
|
| -
|
| - def Navigate(self, target):
|
| - self._history = self._history[:self._position + 1]
|
| - self._position += 1
|
| - self._history.append(target)
|
| -
|
| - def Back(self):
|
| - assert self.navs > 0, 'illegal Back'
|
| - self._position -= 1
|
| -
|
| - def Forward(self):
|
| - assert self.backs > 0, 'illegal Forward'
|
| - self._position += 1
|
| -
|
| -
|
| -class WindowState(object):
|
| - """A set of properties representing state of browser window."""
|
| -
|
| - def __init__(self, tab=None, private=False):
|
| - self._tabs = []
|
| - self._saved_position = 0
|
| - self._position = 0
|
| - self._private = private
|
| - if tab:
|
| - self._tabs.append(tab)
|
| - else:
|
| - self.NewTab()
|
| -
|
| - @property
|
| - def tab(self):
|
| - return self._tabs[self._position]
|
| -
|
| - @property
|
| - def num_tabs(self):
|
| - return len(self._tabs)
|
| -
|
| - @property
|
| - def tab_position(self):
|
| - return self._position
|
| -
|
| - @property
|
| - def private(self):
|
| - return self._private
|
| -
|
| - def NewTab(self, location='chrome://newtab'):
|
| - new_tab = TabState(location)
|
| - self._tabs.append(new_tab)
|
| - self._saved_position = self._position
|
| - self._position = len(self._tabs) - 1
|
| -
|
| - def FindTab(self, location):
|
| - """Return position of first tab at location, or -1"""
|
| - for position in xrange(self.num_tabs):
|
| - tab = self._tabs[position]
|
| - if tab.location == location:
|
| - return position
|
| - return -1
|
| -
|
| - def ForgetPosition(self):
|
| - self._saved_position = None
|
| -
|
| - def DragLeft(self):
|
| - assert self._position > 0, 'illegal DragLeft'
|
| - tab = self.tab
|
| - self._position -= 1
|
| - self._tabs.remove(tab)
|
| - self._tabs.insert(self._position, tab)
|
| -
|
| - def DragRight(self):
|
| - assert self._position < self.num_tabs - 1, 'illegal DragRight'
|
| - tab = self.tab
|
| - self._position += 1
|
| - self._tabs.remove(tab)
|
| - self._tabs.insert(self._position, tab)
|
| -
|
| - def RemoveTab(self):
|
| - self._tabs.pop(self._position)
|
| - if self._saved_position != None:
|
| - self._position = self._saved_position
|
| - if self._position == self.num_tabs:
|
| - self._position -= 1
|
| - self.ForgetPosition()
|
| -
|
| - def RestoreTab(self, tab, position):
|
| - self._tabs.insert(position, tab)
|
| - self._position = position
|
| - self.ForgetPosition()
|
| -
|
| - def Focus(self, position):
|
| - self._position = position
|
| - self.ForgetPosition()
|
| -
|
| - def TabLeft(self):
|
| - if self._position == 0:
|
| - self.Focus(self.num_tabs - 1)
|
| - else:
|
| - self.Focus(self._position - 1)
|
| -
|
| - def TabRight(self):
|
| - if self._position == self.num_tabs - 1:
|
| - self.Focus(0)
|
| - else:
|
| - self.Focus(self._position + 1)
|
| -
|
| -
|
| -class BrowserState(object):
|
| - """A set of properties representing browser after an action sequence."""
|
| -
|
| - def __init__(self, advanced_actions=False):
|
| - self._windows = []
|
| - self._focus_stack = []
|
| - self._closed = []
|
| - blank_tab = TabState('about:blank')
|
| - self.NewWindow(tab=blank_tab)
|
| - self.advanced = advanced_actions
|
| -
|
| - @property
|
| - def num_windows(self):
|
| - return len(self._windows)
|
| -
|
| - @property
|
| - def window(self):
|
| - return self._focus_stack[self.num_windows - 1]
|
| -
|
| - @property
|
| - def window_position(self):
|
| - return self._windows.index(self.window)
|
| -
|
| - def NewWindow(self, tab=None, private=False):
|
| - window = WindowState(tab=tab, private=private)
|
| - self._windows.append(window)
|
| - self._focus_stack.append(window)
|
| -
|
| - def RemoveWindow(self):
|
| - assert self.num_windows > 1, 'not enough windows to RemoveWindow'
|
| - window = self._focus_stack.pop()
|
| - window.ForgetPosition()
|
| - self._windows.remove(window)
|
| - self._Remember(window)
|
| -
|
| - def _Remember(self, window, tab=None, position=None):
|
| - if window.private:
|
| - return
|
| - self._closed.append((window, tab, position))
|
| - if len(self._closed) > 10:
|
| - self._closed = self._closed[-10:]
|
| -
|
| - def _Focus(self, position):
|
| - window = self._windows[position]
|
| - self._focus_stack.remove(window)
|
| - self._focus_stack.append(window)
|
| -
|
| - def NewTab(self, location='chrome://newtab'):
|
| - self.window.NewTab(location)
|
| -
|
| - def Downloads(self):
|
| - position = self.window.FindTab('chrome://downloads')
|
| - if position >= 0:
|
| - self.window.Focus(position)
|
| - else:
|
| - self.NewTab('chrome://downloads')
|
| - self.window.ForgetPosition()
|
| -
|
| - def RemoveTab(self, destroy_tab=True):
|
| - """Remove active tab from active window.
|
| -
|
| - Args:
|
| - destroy_tab: boolean, true if the tab is being closed.
|
| - """
|
| - assert self.window.num_tabs > 1 or self.num_windows > 1, 'illegal RemoveTab'
|
| - if self.window.num_tabs == 1:
|
| - self.RemoveWindow()
|
| - return
|
| - if destroy_tab and not self.window.private:
|
| - self._Remember(self.window, self.window.tab, self.window.tab_position)
|
| - self.window.RemoveTab()
|
| -
|
| - def CanRestore(self):
|
| - """Return True if Restore is a valid action."""
|
| - if self.window.private:
|
| - return False
|
| - if self._closed:
|
| - return True
|
| - return False
|
| -
|
| - def Restore(self):
|
| - """Restore a previously removed tab/window.
|
| -
|
| - Expected behavior:
|
| - - If a private window is in focus, you cannot restore tabs.
|
| - - If the last removed tab was in a different window, that window comes back
|
| - into focus.
|
| - - If the window is gone, a new window will come to focus with the restored
|
| - tab.
|
| - - Tabs restore to the same index they were removed at, else the last
|
| - position.
|
| - """
|
| - assert self._closed, 'nothing to Restore'
|
| - assert not self.window.private, 'cannot Restore (private window)'
|
| - window, tab, position = self._closed.pop()
|
| - try:
|
| - i = self._windows.index(window)
|
| - self._Focus(i)
|
| - except ValueError:
|
| - pass
|
| - if self.window == window:
|
| - self.window.RestoreTab(tab, position)
|
| - else:
|
| - self._windows.append(window)
|
| - self._focus_stack.append(window)
|
| -
|
| - def DragOut(self):
|
| - """Drag tab out of window, spawns new window."""
|
| - assert self.window.num_tabs > 1, 'not enough tabs to DragOut'
|
| - tab = self.window.tab
|
| - self.RemoveTab(destroy_tab=False)
|
| - self.NewWindow(tab=tab, private=self.window.private)
|
| -
|
| - def DragLeft(self):
|
| - self.window.DragLeft()
|
| -
|
| - def DragRight(self):
|
| - self.window.DragRight()
|
| -
|
| - def Navigate(self, target):
|
| - self.window.ForgetPosition()
|
| - self.window.tab.Navigate(target)
|
| -
|
| - def Back(self):
|
| - self.window.tab.Back()
|
| -
|
| - def Forward(self):
|
| - self.window.tab.Forward()
|
| -
|
| - def NextTab(self):
|
| - self.window.TabRight()
|
| -
|
| - def LastTab(self):
|
| - self.window.TabLeft()
|
| -
|
| -
|
| -def UpdateState(browser, action):
|
| - """Return new browser state after performing action.
|
| -
|
| - Args:
|
| - browser: current browser state.
|
| - action: next action performed.
|
| -
|
| - Returns:
|
| - new browser state.
|
| - """
|
| - a = action.split(';')[0]
|
| - if a == 'openwindow':
|
| - browser.NewWindow()
|
| - elif a == 'goofftherecord':
|
| - browser.NewWindow(private=True)
|
| - elif a == 'newtab':
|
| - browser.NewTab()
|
| - elif a == 'dragtabout':
|
| - browser.DragOut()
|
| - elif a == 'dragtableft':
|
| - browser.DragLeft()
|
| - elif a == 'dragtabright':
|
| - browser.DragRight()
|
| - elif a == 'closetab':
|
| - browser.RemoveTab()
|
| - elif a == 'closewindow':
|
| - browser.RemoveWindow()
|
| - elif a == 'restoretab':
|
| - browser.Restore()
|
| - elif a == 'navigate':
|
| - browser.Navigate(action.split(';')[1])
|
| - elif a == 'downloads':
|
| - browser.Downloads()
|
| - elif a == 'back':
|
| - browser.Back()
|
| - elif a == 'forward':
|
| - browser.Forward()
|
| - elif a == 'nexttab':
|
| - browser.NextTab()
|
| - elif a == 'lasttab':
|
| - browser.LastTab()
|
| - return browser
|
| -
|
| -
|
| -def GetRandomAction(browser):
|
| - """Return a random possible action for a UI sequence in given state.
|
| -
|
| - Args:
|
| - browser: current browser state.
|
| -
|
| - Returns:
|
| - UI action (string).
|
| - """
|
| - possible_actions = []
|
| -
|
| - def AddActionWithWeight(action, weight=1):
|
| - """Add action to possible actions list with given weight.
|
| -
|
| - Args:
|
| - action: action string.
|
| - weight: integer weight value.
|
| - """
|
| - for _ in xrange(weight):
|
| - possible_actions.append(action)
|
| -
|
| - AddActionWithWeight('showbookmarks')
|
| - if browser.num_windows < 6:
|
| - AddActionWithWeight('openwindow')
|
| - if browser.window.num_tabs < 10:
|
| - AddActionWithWeight('newtab', weight=3)
|
| -
|
| - # Throw in some navigates to generate a realistic environment.
|
| - nav_options = ['http://www.craigslist.com',
|
| - 'http://www.google.com',
|
| - 'http://www.bing.com']
|
| - for location in nav_options:
|
| - if browser.window.tab.location != location:
|
| - AddActionWithWeight('navigate;%s' % location)
|
| -
|
| - if browser.window.tab.location != 'Downloads':
|
| - AddActionWithWeight('downloads')
|
| -
|
| - # Actions on a web page.
|
| - if browser.window.tab.navs > 0:
|
| - AddActionWithWeight('star')
|
| - AddActionWithWeight('zoomplus')
|
| - AddActionWithWeight('zoomminus')
|
| - AddActionWithWeight('pagedown', weight=3)
|
| -
|
| - # Other conditional actions.
|
| - if browser.window.tab.navs > 0:
|
| - AddActionWithWeight('back', weight=3)
|
| - if browser.window.tab.backs > 0:
|
| - AddActionWithWeight('forward', weight=2)
|
| - if browser.window.num_tabs > 1 or browser.num_windows > 1:
|
| - AddActionWithWeight('closetab', weight=2)
|
| - if browser.window.num_tabs > 1:
|
| - AddActionWithWeight('dragtabout')
|
| - if browser.window.tab_position > 0:
|
| - AddActionWithWeight('dragtableft')
|
| - if browser.window.tab_position < browser.window.num_tabs - 1:
|
| - AddActionWithWeight('dragtabright')
|
| -
|
| - # (v2) actions. separated for backwards compatability.
|
| - if browser.advanced:
|
| - if browser.num_windows > 1:
|
| - AddActionWithWeight('closewindow')
|
| - #TODO(ace): fix support for restore action.
|
| - #if browser.CanRestore():
|
| - # AddActionWithWeight('restoretab')
|
| - if browser.window.tab_position > 0:
|
| - AddActionWithWeight('lasttab')
|
| - if browser.window.tab_position < browser.window.num_tabs - 1:
|
| - AddActionWithWeight('nexttab')
|
| - if browser.num_windows < 6:
|
| - AddActionWithWeight('goofftherecord')
|
| -
|
| - return ChooseFrom(possible_actions)
|
| -
|
| -
|
| -def Seed(seed=None):
|
| - """Seed random for reproducible command sequences.
|
| -
|
| - Args:
|
| - seed: optional long int input for random.seed. If none is given,
|
| - one is generated.
|
| -
|
| - Returns:
|
| - The given or generated seed.
|
| - """
|
| - if not seed:
|
| - random.seed()
|
| - seed = random.getrandbits(64)
|
| - random.seed(seed)
|
| - return seed
|
| -
|
| -
|
| -def ChooseFrom(choice_list):
|
| - """Return a random choice from given list.
|
| -
|
| - Args:
|
| - choice_list: list of possible choices.
|
| -
|
| - Returns:
|
| - One random element from choice_list
|
| - """
|
| - return random.choice(choice_list)
|
|
|