OLD | NEW |
(Empty) | |
| 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 import json |
| 6 import time |
| 7 import websocket |
| 8 import socket |
| 9 |
| 10 class EvaluateException(Exception): |
| 11 pass |
| 12 |
| 13 class Tab(object): |
| 14 def __init__(self, browser, descriptor): |
| 15 self._browser = browser |
| 16 self._descriptor = descriptor |
| 17 self._socket = websocket.create_connection( |
| 18 descriptor["webSocketDebuggerUrl"]); |
| 19 self._socket.settimeout(0.5) |
| 20 self._next_request_id = 0 |
| 21 |
| 22 def __enter__(self): |
| 23 return self |
| 24 |
| 25 def __exit__(self, *args): |
| 26 if self._socket: |
| 27 self.Close() |
| 28 |
| 29 def Close(self): |
| 30 self._socket.close() |
| 31 self._socket = None |
| 32 self._browser = None |
| 33 |
| 34 def _SyncRequest(self, req): |
| 35 req["id"] = self._next_request_id |
| 36 self._next_request_id += 1 |
| 37 self._socket.send(json.dumps(req)) |
| 38 while True: |
| 39 try: |
| 40 data = self._socket.recv() |
| 41 except socket.error: |
| 42 req["id"] = self._next_request_id |
| 43 self._next_request_id += 1 |
| 44 self._socket.send(json.dumps(req)) |
| 45 continue |
| 46 res = json.loads(data) |
| 47 if "method" in res: |
| 48 continue |
| 49 |
| 50 if res["id"] != req["id"]: |
| 51 continue |
| 52 return res |
| 53 |
| 54 def RuntimeEvaluate(self, expr): |
| 55 request = { |
| 56 "method": "Runtime.evaluate", |
| 57 "params": { |
| 58 "expression": expr, |
| 59 "returnByValue": True |
| 60 } |
| 61 } |
| 62 res = self._SyncRequest(request) |
| 63 if res["result"]["wasThrown"]: |
| 64 # TODO(nduca): propagate stacks from javascript up to the python |
| 65 # exception. |
| 66 raise EvaluateException(res["result"]["result"]["description"]) |
| 67 if res["result"]["result"]["type"] == 'undefined': |
| 68 return None |
| 69 return res["result"]["result"]["value"] |
| 70 |
| 71 def BeginToLoadURL(self, url): |
| 72 # In order to tell when the document has actually changed, |
| 73 # we go to about:blank first and wait. When that has happened, we |
| 74 # to go the new URL and detect the document being non-about:blank as |
| 75 # indication that the new document is loading. |
| 76 self.RuntimeEvaluate("document.location = 'about:blank';") |
| 77 while True: |
| 78 hr = self.RuntimeEvaluate("document.location.href") |
| 79 if hr == "about:blank": |
| 80 break |
| 81 time.sleep(0.01) |
| 82 |
| 83 self.RuntimeEvaluate("document.location = '%s';" % url) |
| 84 while True: |
| 85 hr = self.RuntimeEvaluate("document.location.href") |
| 86 if hr != "about:blank": |
| 87 break |
| 88 time.sleep(0.01) |
| 89 |
| 90 def WaitForDocumentReadyStateToBeComplete(self): |
| 91 while True: |
| 92 rs = self.RuntimeEvaluate("document.readyState") |
| 93 if rs == 'complete': |
| 94 break |
| 95 time.sleep(0.01) |
| 96 |
| 97 def WaitForDocumentReadyStateToBeInteractiveOrBetter(self): |
| 98 while True: |
| 99 rs = self.RuntimeEvaluate("document.readyState") |
| 100 if rs == 'complete' or rs == 'interactive': |
| 101 break |
| 102 time.sleep(0.01) |
OLD | NEW |