Commit 4596fc4c authored by erikchen's avatar erikchen Committed by Commit bot

Telemetry: Finish documenting exceptions thrown by tab.py.

All the major work has already been done. This CL just finishes flushing out
the documentation on tab.py and web_contents.py so that consumers know exactly
which exceptions can be thrown.

This CL contains one small behavioral change: InspectorBackend.IsInspectable()
catches DevToolsClientConnectionError and returns False. This is useful since
IsInspectable() gets called in the exception handling code, and no other
consumers of IsInspectable expect the method to throw an exception.

BUG=460625

Review URL: https://codereview.chromium.org/1007903004

Cr-Commit-Position: refs/heads/master@{#321393}
parent 73777224
...@@ -11,6 +11,7 @@ import sys ...@@ -11,6 +11,7 @@ import sys
from telemetry import decorators from telemetry import decorators
from telemetry.core import exceptions from telemetry.core import exceptions
from telemetry.core import util from telemetry.core import util
from telemetry.core.backends.chrome_inspector import devtools_http
from telemetry.core.backends.chrome_inspector import inspector_console from telemetry.core.backends.chrome_inspector import inspector_console
from telemetry.core.backends.chrome_inspector import inspector_memory from telemetry.core.backends.chrome_inspector import inspector_memory
from telemetry.core.backends.chrome_inspector import inspector_network from telemetry.core.backends.chrome_inspector import inspector_network
...@@ -108,12 +109,11 @@ class InspectorBackend(object): ...@@ -108,12 +109,11 @@ class InspectorBackend(object):
return self._context['webSocketDebuggerUrl'] return self._context['webSocketDebuggerUrl']
def IsInspectable(self): def IsInspectable(self):
"""Whether the tab is inspectable, as reported by devtools. """Whether the tab is inspectable, as reported by devtools."""
try:
Raises: return self._devtools_client.IsInspectable(self.id)
devtools_http.DevToolsClientConnectionError except devtools_http.DevToolsClientConnectionError:
""" return False
return self._devtools_client.IsInspectable(self.id)
# Public methods implemented in JavaScript. # Public methods implemented in JavaScript.
...@@ -146,6 +146,13 @@ class InspectorBackend(object): ...@@ -146,6 +146,13 @@ class InspectorBackend(object):
@_HandleInspectorWebSocketExceptions @_HandleInspectorWebSocketExceptions
def GetDOMStats(self, timeout): def GetDOMStats(self, timeout):
"""Gets memory stats from the DOM.
Raises:
inspector_memory.InspectorMemoryException
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
"""
dom_counters = self._memory.GetDOMCounters(timeout) dom_counters = self._memory.GetDOMCounters(timeout)
return { return {
'document_count': dom_counters['documents'], 'document_count': dom_counters['documents'],
......
...@@ -3,10 +3,13 @@ ...@@ -3,10 +3,13 @@
# found in the LICENSE file. # found in the LICENSE file.
import json import json
from telemetry.core import exceptions
class InspectorMemoryException(Exception):
class InspectorMemoryException(exceptions.Error):
pass pass
class InspectorMemory(object): class InspectorMemory(object):
"""Communicates with the remote inspector's Memory domain.""" """Communicates with the remote inspector's Memory domain."""
...@@ -27,6 +30,11 @@ class InspectorMemory(object): ...@@ -27,6 +30,11 @@ class InspectorMemory(object):
Returns: Returns:
A dictionary containing the counts associated with "nodes", "documents", A dictionary containing the counts associated with "nodes", "documents",
and "jsEventListeners". and "jsEventListeners".
Raises:
InspectorMemoryException
websocket.WebSocketException
socket.error
exceptions.WebSocketDisconnected
""" """
res = self._inspector_websocket.SyncRequest({ res = self._inspector_websocket.SyncRequest({
'method': 'Memory.getDOMCounters' 'method': 'Memory.getDOMCounters'
......
...@@ -31,6 +31,11 @@ class Tab(web_contents.WebContents): ...@@ -31,6 +31,11 @@ class Tab(web_contents.WebContents):
@property @property
def url(self): def url(self):
"""Returns the URL of the tab, as reported by devtools.
Raises:
devtools_http.DevToolsClientConnectionError
"""
return self._inspector_backend.url return self._inspector_backend.url
@property @property
...@@ -43,6 +48,11 @@ class Tab(web_contents.WebContents): ...@@ -43,6 +48,11 @@ class Tab(web_contents.WebContents):
'node_count': integer, 'node_count': integer,
'event_listener_count': integer 'event_listener_count': integer
} }
Raises:
inspector_memory.InspectorMemoryException
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
""" """
dom_counters = self._inspector_backend.GetDOMStats( dom_counters = self._inspector_backend.GetDOMStats(
timeout=DEFAULT_TAB_TIMEOUT) timeout=DEFAULT_TAB_TIMEOUT)
...@@ -93,6 +103,10 @@ class Tab(web_contents.WebContents): ...@@ -93,6 +103,10 @@ class Tab(web_contents.WebContents):
Returns: Returns:
A telemetry.core.Bitmap. A telemetry.core.Bitmap.
Raises:
exceptions.WebSocketDisconnected
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
""" """
return self._inspector_backend.Screenshot(timeout) return self._inspector_backend.Screenshot(timeout)
...@@ -106,6 +120,12 @@ class Tab(web_contents.WebContents): ...@@ -106,6 +120,12 @@ class Tab(web_contents.WebContents):
TODO(tonyg): It is possible that the z-index hack here might not work for TODO(tonyg): It is possible that the z-index hack here might not work for
all pages. If this happens, DevTools also provides a method for this. all pages. If this happens, DevTools also provides a method for this.
Raises:
exceptions.EvaluateException
exceptions.WebSocketDisconnected
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
""" """
self.ExecuteJavaScript(""" self.ExecuteJavaScript("""
(function() { (function() {
...@@ -129,7 +149,14 @@ class Tab(web_contents.WebContents): ...@@ -129,7 +149,14 @@ class Tab(web_contents.WebContents):
'!!window.__telemetry_screen_%d' % int(color), 5) '!!window.__telemetry_screen_%d' % int(color), 5)
def ClearHighlight(self, color): def ClearHighlight(self, color):
"""Clears a highlight of the given bitmap.RgbaColor.""" """Clears a highlight of the given bitmap.RgbaColor.
Raises:
exceptions.EvaluateException
exceptions.WebSocketDisconnected
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
"""
self.ExecuteJavaScript(""" self.ExecuteJavaScript("""
(function() { (function() {
document.body.removeChild(window.__telemetry_screen_%d); document.body.removeChild(window.__telemetry_screen_%d);
...@@ -157,6 +184,13 @@ class Tab(web_contents.WebContents): ...@@ -157,6 +184,13 @@ class Tab(web_contents.WebContents):
min_bitrate_mbps: The minimum caputre bitrate in MegaBits Per Second. min_bitrate_mbps: The minimum caputre bitrate in MegaBits Per Second.
The platform is free to deliver a higher bitrate if it can do so The platform is free to deliver a higher bitrate if it can do so
without increasing overhead. without increasing overhead.
Raises:
exceptions.EvaluateException
exceptions.WebSocketDisconnected
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
ValueError: If the required |min_bitrate_mbps| can't be achieved.
""" """
self.Highlight(highlight_bitmap) self.Highlight(highlight_bitmap)
self.browser.platform.StartVideoCapture(min_bitrate_mbps) self.browser.platform.StartVideoCapture(min_bitrate_mbps)
...@@ -178,10 +212,23 @@ class Tab(web_contents.WebContents): ...@@ -178,10 +212,23 @@ class Tab(web_contents.WebContents):
return self.browser.platform.StopVideoCapture() return self.browser.platform.StopVideoCapture()
def GetCookieByName(self, name, timeout=DEFAULT_TAB_TIMEOUT): def GetCookieByName(self, name, timeout=DEFAULT_TAB_TIMEOUT):
"""Returns the value of the cookie by the given |name|.""" """Returns the value of the cookie by the given |name|.
Raises:
exceptions.WebSocketDisconnected
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
"""
return self._inspector_backend.GetCookieByName(name, timeout) return self._inspector_backend.GetCookieByName(name, timeout)
def CollectGarbage(self): def CollectGarbage(self):
"""Forces a garbage collection.
Raises:
exceptions.WebSocketDisconnected
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
"""
self._inspector_backend.CollectGarbage() self._inspector_backend.CollectGarbage()
def ClearCache(self, force): def ClearCache(self, force):
...@@ -191,6 +238,13 @@ class Tab(web_contents.WebContents): ...@@ -191,6 +238,13 @@ class Tab(web_contents.WebContents):
force: Iff true, navigates to about:blank which destroys the previous force: Iff true, navigates to about:blank which destroys the previous
renderer, ensuring that even "live" resources in the memory cache are renderer, ensuring that even "live" resources in the memory cache are
cleared. cleared.
Raises:
exceptions.EvaluateException
exceptions.WebSocketDisconnected
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
errors.DeviceUnresponsiveError
""" """
self.browser.platform.FlushDnsCache() self.browser.platform.FlushDnsCache()
self.ExecuteJavaScript(""" self.ExecuteJavaScript("""
......
...@@ -27,11 +27,24 @@ class WebContents(object): ...@@ -27,11 +27,24 @@ class WebContents(object):
def WaitForDocumentReadyStateToBeComplete(self, def WaitForDocumentReadyStateToBeComplete(self,
timeout=DEFAULT_WEB_CONTENTS_TIMEOUT): timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
"""Waits for the document to finish loading.
Raises:
exceptions.Error: See WaitForJavaScriptExpression() for a detailed list
of possible exceptions.
"""
self.WaitForJavaScriptExpression( self.WaitForJavaScriptExpression(
'document.readyState == "complete"', timeout) 'document.readyState == "complete"', timeout)
def WaitForDocumentReadyStateToBeInteractiveOrBetter(self, def WaitForDocumentReadyStateToBeInteractiveOrBetter(self,
timeout=DEFAULT_WEB_CONTENTS_TIMEOUT): timeout=DEFAULT_WEB_CONTENTS_TIMEOUT):
"""Waits for the document to be interactive.
Raises:
exceptions.Error: See WaitForJavaScriptExpression() for a detailed list
of possible exceptions.
"""
self.WaitForJavaScriptExpression( self.WaitForJavaScriptExpression(
'document.readyState == "interactive" || ' 'document.readyState == "interactive" || '
'document.readyState == "complete"', timeout) 'document.readyState == "complete"', timeout)
...@@ -47,6 +60,11 @@ class WebContents(object): ...@@ -47,6 +60,11 @@ class WebContents(object):
timeout: The number of seconds to wait for the expression to be True. timeout: The number of seconds to wait for the expression to be True.
dump_page_state_on_timeout: Whether to provide additional information on dump_page_state_on_timeout: Whether to provide additional information on
the page state if a TimeoutException is thrown. the page state if a TimeoutException is thrown.
Raises:
exceptions.TimeoutException: On a timeout.
exceptions.Error: See EvaluateJavaScript() for a detailed list of
possible exceptions.
""" """
def IsJavaScriptExpressionTrue(): def IsJavaScriptExpressionTrue():
try: try:
...@@ -92,7 +110,11 @@ class WebContents(object): ...@@ -92,7 +110,11 @@ class WebContents(object):
Returns: Returns:
True if 2 seconds have passed since last resource received, false True if 2 seconds have passed since last resource received, false
otherwise.""" otherwise.
Raises:
exceptions.Error: See EvaluateJavaScript() for a detailed list of
possible exceptions.
"""
# Inclusion of the script that provides # Inclusion of the script that provides
# window.__telemetry_testHasReachedNetworkQuiescence() # window.__telemetry_testHasReachedNetworkQuiescence()
...@@ -109,10 +131,8 @@ class WebContents(object): ...@@ -109,10 +131,8 @@ class WebContents(object):
If the statement failed to evaluate, EvaluateException will be raised. If the statement failed to evaluate, EvaluateException will be raised.
Raises: Raises:
exceptions.EvaluateException exceptions.Error: See ExecuteJavaScriptInContext() for a detailed list of
exceptions.WebSocketDisconnected possible exceptions.
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
""" """
return self.ExecuteJavaScriptInContext( return self.ExecuteJavaScriptInContext(
statement, context_id=None, timeout=timeout) statement, context_id=None, timeout=timeout)
...@@ -130,10 +150,8 @@ class WebContents(object): ...@@ -130,10 +150,8 @@ class WebContents(object):
EvaluationException will be raised. EvaluationException will be raised.
Raises: Raises:
exceptions.EvaluateException exceptions.Error: See EvaluateJavaScriptInContext() for a detailed list
exceptions.WebSocketDisconnected of possible exceptions.
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
""" """
return self.EvaluateJavaScriptInContext( return self.EvaluateJavaScriptInContext(
expr, context_id=None, timeout=timeout) expr, context_id=None, timeout=timeout)
...@@ -182,6 +200,10 @@ class WebContents(object): ...@@ -182,6 +200,10 @@ class WebContents(object):
The current page is expect to be in a navigation. The current page is expect to be in a navigation.
This function returns when the navigation is complete or when This function returns when the navigation is complete or when
the timeout has been exceeded. the timeout has been exceeded.
Raises:
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
""" """
self._inspector_backend.WaitForNavigate(timeout) self._inspector_backend.WaitForNavigate(timeout)
...@@ -192,6 +214,10 @@ class WebContents(object): ...@@ -192,6 +214,10 @@ class WebContents(object):
If |script_to_evaluate_on_commit| is given, the script source string will be If |script_to_evaluate_on_commit| is given, the script source string will be
evaluated when the navigation is committed. This is after the context of evaluated when the navigation is committed. This is after the context of
the page exists, but before any script on the page itself has executed. the page exists, but before any script on the page itself has executed.
Raises:
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
""" """
self._inspector_backend.Navigate(url, script_to_evaluate_on_commit, timeout) self._inspector_backend.Navigate(url, script_to_evaluate_on_commit, timeout)
...@@ -208,9 +234,21 @@ class WebContents(object): ...@@ -208,9 +234,21 @@ class WebContents(object):
return self._inspector_backend.timeline_model return self._inspector_backend.timeline_model
def StartTimelineRecording(self): def StartTimelineRecording(self):
"""Starts timeline recording.
Raises:
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
"""
self._inspector_backend.StartTimelineRecording() self._inspector_backend.StartTimelineRecording()
def StopTimelineRecording(self): def StopTimelineRecording(self):
"""Stops timeline recording.
Raises:
exceptions.TimeoutException
exceptions.DevtoolsTargetCrashException
"""
self._inspector_backend.StopTimelineRecording() self._inspector_backend.StopTimelineRecording()
def IsAlive(self): def IsAlive(self):
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment