blob: 708e76be92bfa2ae68957d4ded5d0f8bad4d4eb7 [file] [log] [blame]
#!/usr/bin/python
# 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.
"""Pyauto powered ui action runner.
Developed primarily to verify validity of the model based action generator.
"""
import time
import sys
import pyauto_functional
import pyauto
import ui_model
class Runner(pyauto.PyUITest):
def setUp(self):
self.debug_mode = False
pyauto.PyUITest.setUp(self)
def RunActionList(self):
"""Runs actions from a file."""
f = open('list')
actions = f.readlines()
self.browser = ui_model.BrowserState(advanced_actions=True)
count = 0
for action in actions:
count += 1
sys.stdout.write('%d > ' % count)
action = action.strip()
self.ApplyAction(action)
raw_input('Press key to continue.')
def DebugUIActions(self):
"""Run testUIActions with debug mode on.
Allows inspection of the browser after unexpected state is encountered.
"""
self.debug_mode = True
self.testUIActions()
def testUIActions(self):
"""Generates and runs actions forever."""
self.browser = ui_model.BrowserState(advanced_actions=True)
count = 0
start_time = time.time()
while True:
count += 1
sys.stdout.write('%d:%.3f > ' % (count, time.time() - start_time))
action = ui_model.GetRandomAction(self.browser)
self.ApplyAction(action)
def ApplyAction(self, action):
sys.stdout.write('%s, ' % action)
if self._DoAction(action):
ui_model.UpdateState(self.browser, action)
self._CheckState()
def Error(self, msg=''):
"""Called when an unexpected state is encountered."""
if msg:
print 'Error: %s' % msg
else:
print 'Error'
while self.debug_mode:
raw_input('Press key to continue.')
assertTrue(False, msg)
def _CheckState(self):
"""Check some basic properties of the browser against expected state."""
active_window = self.browser.window_position
active_tab = self.GetActiveTabIndex(active_window)
expected_tab = self.browser.window.tab_position
print 'win: %d tab: %d navs: %d backs: %d' % (
active_window, active_tab, self.browser.window.tab.navs,
self.browser.window.tab.backs)
if active_tab != expected_tab:
self.Error('active index out of sync: expected %d' % expected_tab)
tab_count = self.GetTabCount(active_window)
expected_count = self.browser.window.num_tabs
if tab_count != expected_count:
self.Error('tab count out of sync: count: %d expected: %d' % (
tab_count, expected_count))
window_count = self.GetBrowserWindowCount()
expected_count = self.browser.num_windows
if window_count != expected_count:
self.Error('window count out of sync: count: %d expected %d' % (
window_count, expected_count))
def _GrabTab(self):
active_window = self.browser.window_position
window = self.GetBrowserWindow(active_window)
tab_count = self.GetTabCount(self.browser.window_position)
active_tab = self.browser.window.tab_position
if active_tab >= tab_count:
self.Error('active tab out of bounds: count: %d expected active: %d' % (
(tab_count, active_tab)))
return window.GetTab(self.browser.window.tab_position)
def _RunInActiveWindow(self, command):
active_window = self.browser.window_position
self.RunCommand(command, active_window)
def _RunAsyncInActiveWindow(self, command):
active_window = self.browser.window_position
self.ApplyAccelerator(command, active_window)
def _Zoom(self, command):
active_window = self.browser.window_position
title = self.GetActiveTabTitle(active_window)
model_active_tab = self.browser.window.tab_position
active_tab = self.GetActiveTabIndex(active_window)
num_tabs = self.GetTabCount(active_window)
self._RunAsyncInActiveWindow(command)
if title == 'New Tab':
self.Error('zoom called on new tab')
def _WaitFor(self, test):
start = time.time()
test_result, detail = test()
while not test_result:
if time.time() - start > self.action_max_timeout_ms():
self.Error('TIMEOUT: %s' % detail)
time.sleep(.1)
test_result, detail = test()
def _DoAction(self, action):
"""Execute action in the browser.
Attempts to simulate synchronous execution for most actions.
Args:
action: action string.
"""
a = action.split(';')[0]
if a == 'showbookmarks':
self._RunAsyncInActiveWindow(pyauto.IDC_SHOW_BOOKMARK_BAR)
if a == 'openwindow' or a == 'goofftherecord':
def NewWindowHasTab():
result = self.GetTabCount(self.browser.num_windows) == 1
return (result, 'NewWindowHasTab')
def TabLoaded():
result = self.GetActiveTabTitle(self.browser.num_windows) == 'New Tab'
return (result, 'TabLoaded')
if a == 'openwindow':
self.OpenNewBrowserWindow(True)
elif a == 'goofftherecord':
self._RunAsyncInActiveWindow(pyauto.IDC_NEW_INCOGNITO_WINDOW)
self._WaitFor(NewWindowHasTab)
self._WaitFor(TabLoaded)
if a == 'newtab':
active_window = self.browser.window_position
target = pyauto.GURL('chrome://newtab')
self.AppendTab(target, active_window)
if a == 'downloads':
active_window = self.browser.window_position
def TabLoaded():
result = self.GetActiveTabTitle(active_window) == 'Downloads'
return (result, 'TabLoaded')
self._RunAsyncInActiveWindow(pyauto.IDC_SHOW_DOWNLOADS)
self._WaitFor(TabLoaded)
if a == 'star':
self._RunAsyncInActiveWindow(pyauto.IDC_BOOKMARK_PAGE)
if a == 'zoomplus':
self._Zoom(pyauto.IDC_ZOOM_PLUS)
if a == 'zoomminus':
self._Zoom(pyauto.IDC_ZOOM_MINUS)
if a == 'pagedown':
return False
if a == 'back' or a == 'forward' or a == 'navigate':
tab = self._GrabTab()
active_window = self.browser.window_position
old_title = self.GetActiveTabTitle(active_window)
retries = 0
nav_result = 0
while nav_result != 1:
if retries == 1:
break
if retries == 1:
sys.stdout.write('retry ')
if retries > 0:
time.sleep(.1)
sys.stdout.write('%d, ' % retries)
if a == 'navigate':
target = pyauto.GURL(action.split(';')[1])
nav_result = tab.NavigateToURL(target)
elif a == 'back':
self.browser.Back()
self.browser.Forward()
nav_result = tab.GoBack()
elif a == 'forward':
self.browser.Forward()
self.browser.Back()
nav_result = tab.GoForward()
retries += 1
if a == 'closetab':
tab = self._GrabTab()
ui_model.UpdateState(self.browser, action)
active_window = self.browser.window_position
window_count = self.browser.num_windows
tab_count = self.browser.window.num_tabs
def WindowCount():
actual = self.GetBrowserWindowCount()
result = actual == window_count
return (result, 'WindowCount (expected %d, actual %d)' %
(window_count, actual))
def TabCount():
actual = self.GetTabCount(active_window)
result = actual == tab_count
return (result, 'TabCount (expected %d, actual %d)' %
(tab_count, actual))
tab.Close(True)
self._WaitFor(WindowCount)
self._WaitFor(TabCount)
return False
if a == 'closewindow':
window_count = self.browser.num_windows - 1
def WindowCount():
result = self.GetBrowserWindowCount() == window_count
return (result, 'WindowCount (expected %d)' % window_count)
self._RunInActiveWindow(pyauto.IDC_CLOSE_WINDOW)
self._WaitFor(WindowCount)
if a == 'dragtabout':
return False
if a == 'dragtableft':
self._RunAsyncInActiveWindow(pyauto.IDC_MOVE_TAB_PREVIOUS)
if a == 'dragtabright':
self._RunAsyncInActiveWindow(pyauto.IDC_MOVE_TAB_NEXT)
if a == 'lasttab':
self._RunAsyncInActiveWindow(pyauto.IDC_SELECT_PREVIOUS_TAB)
if a == 'nexttab':
self._RunAsyncInActiveWindow(pyauto.IDC_SELECT_NEXT_TAB)
if a == 'restoretab':
active_window = self.browser.window_position
self.ApplyAccelerator(pyauto.IDC_RESTORE_TAB, active_window)
self._GrabTab().WaitForTabToBeRestored(self.action_max_timeout_ms())
ui_model.UpdateState(self.browser, action)
return False
return True
if __name__ == '__main__':
pyauto_functional.Main()