1# Copyright 2013 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. 4from telemetry.core import exceptions 5 6 7class InspectorRuntime(object): 8 def __init__(self, inspector_websocket): 9 self._inspector_websocket = inspector_websocket 10 self._inspector_websocket.RegisterDomain('Runtime', self._OnNotification) 11 self._contexts_enabled = False 12 self._max_context_id = None 13 14 def _OnNotification(self, msg): 15 if (self._contexts_enabled and 16 msg['method'] == 'Runtime.executionContextCreated'): 17 self._max_context_id = max(self._max_context_id, 18 msg['params']['context']['id']) 19 20 def Execute(self, expr, context_id, timeout): 21 self.Evaluate(expr + '; 0;', context_id, timeout) 22 23 def Evaluate(self, expr, context_id, timeout): 24 """Evaluates a javascript expression and returns the result. 25 26 |context_id| can refer to an iframe. The main page has context_id=1, the 27 first iframe context_id=2, etc. 28 29 Raises: 30 exceptions.EvaluateException 31 exceptions.WebSocketDisconnected 32 websocket.WebSocketException 33 socket.error 34 """ 35 request = { 36 'method': 'Runtime.evaluate', 37 'params': { 38 'expression': expr, 39 'returnByValue': True 40 } 41 } 42 if context_id is not None: 43 self.EnableAllContexts() 44 request['params']['contextId'] = context_id 45 res = self._inspector_websocket.SyncRequest(request, timeout) 46 if 'error' in res: 47 raise exceptions.EvaluateException(res['error']['message']) 48 49 if 'wasThrown' in res['result'] and res['result']['wasThrown']: 50 # TODO(nduca): propagate stacks from javascript up to the python 51 # exception. 52 raise exceptions.EvaluateException(res['result']['result']['description']) 53 if res['result']['result']['type'] == 'undefined': 54 return None 55 return res['result']['result']['value'] 56 57 def EnableAllContexts(self): 58 """Allow access to iframes. 59 60 Raises: 61 exceptions.WebSocketDisconnected 62 websocket.WebSocketException 63 socket.error 64 """ 65 if not self._contexts_enabled: 66 self._contexts_enabled = True 67 self._inspector_websocket.SyncRequest({'method': 'Runtime.enable'}, 68 timeout=30) 69 return self._max_context_id 70 71 def RunInspectorCommand(self, command, timeout): 72 """Runs an inspector command. 73 74 Raises: 75 exceptions.WebSocketDisconnected 76 websocket.WebSocketException 77 socket.error 78 """ 79 res = self._inspector_websocket.SyncRequest(command, timeout) 80 return res 81