diff options
author | dennisjeffrey@chromium.org <dennisjeffrey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-14 16:09:15 +0000 |
---|---|---|
committer | dennisjeffrey@chromium.org <dennisjeffrey@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-03-14 16:09:15 +0000 |
commit | 097769d43b74ca2d03470617f711dd8c98cc84a5 (patch) | |
tree | 3c327c05a64afdae44fd4a8c6e910d1eee155630 /tools | |
parent | 8c64b8f42e04ba6db4d873995fa909dcdb580cf4 (diff) | |
download | chromium_src-097769d43b74ca2d03470617f711dd8c98cc84a5.zip chromium_src-097769d43b74ca2d03470617f711dd8c98cc84a5.tar.gz chromium_src-097769d43b74ca2d03470617f711dd8c98cc84a5.tar.bz2 |
[Telemetry] Add tab property "dom_stats".
Currently, the associated function reaches into the inspector_backend, which in
turn now has a new module to communicate with the remote inspector's
"Memory" domain. This allows us to query the remote inspector for the
DOM node count, document count, and event listener count, for a tab.
Making this change is a prerequisite to converting the Chrome Endure
endurance tests over to Telemetry from their current pyauto-based
implementation.
BUG=chromium-os:39589
TEST=tools/telemetry/run_tests InspectorMemoryTest
Review URL: https://chromiumcodereview.appspot.com/12800004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@188092 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'tools')
5 files changed, 114 insertions, 0 deletions
diff --git a/tools/telemetry/telemetry/core/chrome/inspector_backend.py b/tools/telemetry/telemetry/core/chrome/inspector_backend.py index 8a5f8b1..ee5c06c 100644 --- a/tools/telemetry/telemetry/core/chrome/inspector_backend.py +++ b/tools/telemetry/telemetry/core/chrome/inspector_backend.py @@ -9,6 +9,7 @@ import sys from telemetry.core import util from telemetry.core import exceptions from telemetry.core.chrome import inspector_console +from telemetry.core.chrome import inspector_memory from telemetry.core.chrome import inspector_page from telemetry.core.chrome import inspector_runtime from telemetry.core.chrome import inspector_timeline @@ -30,6 +31,7 @@ class InspectorBackend(object): self._next_request_id = 0 self._console = inspector_console.InspectorConsole(self) + self._memory = inspector_memory.InspectorMemory(self) self._page = inspector_page.InspectorPage(self) self._runtime = inspector_runtime.InspectorRuntime(self) self._timeline = inspector_timeline.InspectorTimeline(self) @@ -152,6 +154,16 @@ class InspectorBackend(object): def message_output_stream(self, stream): # pylint: disable=E0202 self._console.message_output_stream = stream + # Memory public methods. + + def GetDOMStats(self, timeout): + dom_counters = self._memory.GetDOMCounters(timeout) + return { + 'document_count': dom_counters['documents'], + 'node_count': dom_counters['nodes'], + 'event_listener_count': dom_counters['jsEventListeners'] + } + # Page public methods. def PerformActionAndWaitForNavigate(self, action_function, timeout): diff --git a/tools/telemetry/telemetry/core/chrome/inspector_memory.py b/tools/telemetry/telemetry/core/chrome/inspector_memory.py new file mode 100644 index 0000000..931cb6e --- /dev/null +++ b/tools/telemetry/telemetry/core/chrome/inspector_memory.py @@ -0,0 +1,50 @@ +# Copyright (c) 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +import json + +class InspectorMemoryException(Exception): + pass + +class InspectorMemory(object): + """Communicates with the remote inspector's Memory domain.""" + + def __init__(self, inspector_backend): + self._inspector_backend = inspector_backend + self._inspector_backend.RegisterDomain( + 'Memory', + self._OnNotification, + self._OnClose) + + def _OnNotification(self, msg): + pass + + def _OnClose(self): + pass + + def GetDOMCounters(self, timeout): + """Retrieves DOM element counts. + + Args: + timeout: The number of seconds to wait for the inspector backend to + service the request before timing out. + + Returns: + A dictionary containing the counts associated with "nodes", "documents", + and "jsEventListeners". + """ + res = self._inspector_backend.SyncRequest({ + 'method': 'Memory.getDOMCounters' + }, timeout) + if ('result' not in res or + 'nodes' not in res['result'] or + 'documents' not in res['result'] or + 'jsEventListeners' not in res['result']): + raise InspectorMemoryException( + 'Inspector returned unexpected result for Memory.getDOMCounters:\n' + + json.dumps(res, indent=2)) + return { + 'nodes': res['result']['nodes'], + 'documents': res['result']['documents'], + 'jsEventListeners': res['result']['jsEventListeners'] + } diff --git a/tools/telemetry/telemetry/core/chrome/inspector_memory_unittest.py b/tools/telemetry/telemetry/core/chrome/inspector_memory_unittest.py new file mode 100644 index 0000000..a84be78 --- /dev/null +++ b/tools/telemetry/telemetry/core/chrome/inspector_memory_unittest.py @@ -0,0 +1,21 @@ +# Copyright (c) 2013 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +import os + +from telemetry.test import tab_test_case + +class InspectorMemoryTest(tab_test_case.TabTestCase): + def testGetDOMStats(self): + unittest_data_dir = os.path.join(os.path.dirname(__file__), + '..', '..', '..', 'unittest_data') + self._browser.SetHTTPServerDirectory(unittest_data_dir) + + self._tab.Navigate( + self._browser.http_server.UrlOf('dom_counter_sample.html')) + self._tab.WaitForDocumentReadyStateToBeComplete() + + counts = self._tab.dom_stats + self.assertEqual(counts['document_count'], 1) + self.assertEqual(counts['node_count'], 14) + self.assertEqual(counts['event_listener_count'], 2) diff --git a/tools/telemetry/telemetry/core/tab.py b/tools/telemetry/telemetry/core/tab.py index 6e5c804..979b645 100644 --- a/tools/telemetry/telemetry/core/tab.py +++ b/tools/telemetry/telemetry/core/tab.py @@ -31,6 +31,25 @@ class Tab(web_contents.WebContents): def url(self): return self._inspector_backend.url + @property + def dom_stats(self): + """A dictionary populated with measured DOM statistics. + + Currently this dictionary contains: + { + 'document_count': integer, + 'node_count': integer, + 'event_listener_count': integer + } + """ + dom_counters = self._inspector_backend.GetDOMStats( + timeout=DEFAULT_TAB_TIMEOUT) + assert (len(dom_counters) == 3 and + all([x in dom_counters for x in ['document_count', 'node_count', + 'event_listener_count']])) + return dom_counters + + def Activate(self): """Brings this tab to the foreground asynchronously. diff --git a/tools/telemetry/unittest_data/dom_counter_sample.html b/tools/telemetry/unittest_data/dom_counter_sample.html new file mode 100644 index 0000000..483d1e0 --- /dev/null +++ b/tools/telemetry/unittest_data/dom_counter_sample.html @@ -0,0 +1,12 @@ +<html> + <title>DOM counter unit test page</title> + <body> + <h1 onclick="">Webpage to be used for DOM counter unit testing.</h1> + <p onclick=""> + This webpage is meant to be used by a unit test that checks DOM element + counters. The test expects there to be exactly 1 document, 14 nodes, + and 2 event listeners. Beware, modifying the HTML of this page may + change the element count, causing the unit test to fail! + </p> + </body> +</html> |