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 5from telemetry.core import util 6 7DEFAULT_WEB_CONTENTS_TIMEOUT = 90 8 9# TODO(achuith, dtu, nduca): Add unit tests specifically for WebContents, 10# independent of Tab. 11class WebContents(object): 12 """Represents web contents in the browser""" 13 def __init__(self, inspector_backend): 14 self._inspector_backend = inspector_backend 15 16 def __del__(self): 17 self.Disconnect() 18 19 def Disconnect(self): 20 self._inspector_backend.Disconnect() 21 22 def Close(self): 23 """Closes this page. 24 25 Not all browsers or browser versions support this method. 26 Be sure to check browser.supports_tab_control.""" 27 self._inspector_backend.Close() 28 29 def WaitForDocumentReadyStateToBeComplete(self, 30 timeout=DEFAULT_WEB_CONTENTS_TIMEOUT): 31 self.WaitForJavaScriptExpression( 32 'document.readyState == "complete"', timeout) 33 34 def WaitForDocumentReadyStateToBeInteractiveOrBetter(self, 35 timeout=DEFAULT_WEB_CONTENTS_TIMEOUT): 36 self.WaitForJavaScriptExpression( 37 'document.readyState == "interactive" || ' 38 'document.readyState == "complete"', timeout) 39 40 def WaitForJavaScriptExpression(self, expr, timeout): 41 """Waits for the given JavaScript expression to be True. 42 43 This method is robust against any given Evaluation timing out. 44 """ 45 def IsTrue(): 46 try: 47 return bool(self.EvaluateJavaScript(expr)) 48 except util.TimeoutException: 49 # If the main thread is busy for longer than Evaluate's timeout, we 50 # may time out here early. Instead, we want to wait for the full 51 # timeout of this method. 52 return False 53 util.WaitFor(IsTrue, timeout) 54 55 def ExecuteJavaScript(self, expr, timeout=DEFAULT_WEB_CONTENTS_TIMEOUT): 56 """Executes expr in JavaScript. Does not return the result. 57 58 If the expression failed to evaluate, EvaluateException will be raised. 59 """ 60 self._inspector_backend.ExecuteJavaScript(expr, timeout) 61 62 def EvaluateJavaScript(self, expr, timeout=DEFAULT_WEB_CONTENTS_TIMEOUT): 63 """Evalutes expr in JavaScript and returns the JSONized result. 64 65 Consider using ExecuteJavaScript for cases where the result of the 66 expression is not needed. 67 68 If evaluation throws in JavaScript, a Python EvaluateException will 69 be raised. 70 71 If the result of the evaluation cannot be JSONized, then an 72 EvaluationException will be raised. 73 """ 74 return self._inspector_backend.EvaluateJavaScript(expr, timeout) 75 76 @property 77 def message_output_stream(self): 78 return self._inspector_backend.message_output_stream 79 80 @message_output_stream.setter 81 def message_output_stream(self, stream): 82 self._inspector_backend.message_output_stream = stream 83 84 @property 85 def timeline_model(self): 86 return self._inspector_backend.timeline_model 87 88 def StartTimelineRecording(self): 89 self._inspector_backend.StartTimelineRecording() 90 91 def StopTimelineRecording(self): 92 self._inspector_backend.StopTimelineRecording() 93 94 def TakeJSHeapSnapshot(self, timeout=120): 95 return self._inspector_backend.TakeJSHeapSnapshot(timeout) 96