page_action.py revision a1401311d1ab56c4ed0a474bd38c108f75cb0cd9
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 6import telemetry.core.timeline.bounds as timeline_bounds 7from telemetry.page.actions import wait_until 8 9class PageActionNotSupported(Exception): 10 pass 11 12class PageActionFailed(Exception): 13 pass 14 15class PageActionInvalidTimelineMarker(Exception): 16 pass 17 18class PageAction(object): 19 """Represents an action that a user might try to perform to a page.""" 20 _next_timeline_marker_id = 0 21 22 def __init__(self, attributes=None): 23 if attributes: 24 for k, v in attributes.iteritems(): 25 setattr(self, k, v) 26 self._timeline_marker_base_name = None 27 self._timeline_marker_id = None 28 if hasattr(self, 'wait_until'): 29 self.wait_until = wait_until.WaitUntil(self, self.wait_until) 30 else: 31 self.wait_until = None 32 33 def CustomizeBrowserOptionsForPageSet(self, options): 34 """Override to add action-specific options to the BrowserOptions 35 object. These options will be set for the whole page set. 36 37 If the browser is not being restarted for every page in the page set then 38 all browser options required for the action must be set here. This, however, 39 requires that they do not conflict with options require by other actions 40 used up by the page set. 41 """ 42 pass 43 44 def WillRunAction(self, page, tab): 45 """Override to do action-specific setup before 46 Test.WillRunAction is called.""" 47 pass 48 49 def WillWaitAfterRun(self): 50 return self.wait_until is not None 51 52 def RunActionAndMaybeWait(self, page, tab): 53 if self.wait_until: 54 self.wait_until.RunActionAndWait(page, tab) 55 else: 56 self.RunAction(page, tab) 57 58 def RunAction(self, page, tab): 59 raise NotImplementedError() 60 61 def CleanUp(self, page, tab): 62 pass 63 64 def CanBeBound(self): 65 """If this class implements BindMeasurementJavaScript, override CanBeBound 66 to return True so that a test knows it can bind measurements.""" 67 return False 68 69 def BindMeasurementJavaScript( 70 self, tab, start_js, stop_js): # pylint: disable=W0613 71 """Let this action determine when measurements should start and stop. 72 73 A measurement can call this method to provide the action 74 with JavaScript code that starts and stops measurements. The action 75 determines when to execute the provided JavaScript code, for more accurate 76 timings. 77 78 Args: 79 tab: The tab to do everything on. 80 start_js: JavaScript code that starts measurements. 81 stop_js: JavaScript code that stops measurements. 82 """ 83 raise Exception('This action cannot be bound.') 84 85 @staticmethod 86 def ResetNextTimelineMarkerId(): 87 PageAction._next_timeline_marker_id = 0 88 89 def _SetTimelineMarkerBaseName(self, name): 90 self._timeline_marker_base_name = name 91 self._timeline_marker_id = PageAction._next_timeline_marker_id 92 PageAction._next_timeline_marker_id += 1 93 94 def _GetUniqueTimelineMarkerName(self): 95 if self._timeline_marker_base_name: 96 return \ 97 '%s_%d' % (self._timeline_marker_base_name, self._timeline_marker_id) 98 else: 99 return None 100 101 def GetActiveRangeOnTimeline(self, timeline): 102 active_range = timeline_bounds.Bounds() 103 104 if self._GetUniqueTimelineMarkerName(): 105 active_range.AddEvent( 106 timeline.GetEventOfName(self._GetUniqueTimelineMarkerName(), 107 True, True)) 108 if self.wait_until: 109 active_range.AddBounds( 110 self.wait_until.GetActiveRangeOnTimeline(timeline)) 111 112 return active_range 113