15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import pyauto_tracing
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import pyauto
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import tab_tracker
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)from timeline_model import TimelineModel
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import os
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class Tracer(object):
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """Controlls chrome and system tracing, returning a TimelineModel."""
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __init__(self, browser, tab_tracker):
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      browser: an instance of a PyUITest
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      tab_tracker: an instance of a TabTracker
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._browser = browser
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._tab_tracker = tab_tracker
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._tab_uuid = tab_tracker.CreateTab('chrome://tracing')
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # TODO(eatnumber): Find a way to import timeline_model_shim.js from within
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # TimelineModelProxy
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # I'm not happy with importing timeline_model_shim.js
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # here. I'd rather pull it in from within TimelineModelProxy.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # tracing_test.js depends on timeline_model_shim.js however.
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    files = ['timeline_model_shim.js', 'tracer.js']
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for fileName in files:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      with open(os.path.join(os.path.dirname(__file__), fileName), 'r') as fd:
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self._ExecuteJavascript(fd.read())
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __del__(self):
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._tab_tracker.ReleaseTab(self._tab_uuid)
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def _ExecuteJavascript(self, js):
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return self._browser.ExecuteJavascript(
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        js = js,
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        windex = self._tab_tracker.GetWindowIndex(),
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tab_index = self._tab_tracker.GetTabIndex(self._tab_uuid)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    )
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def BeginTracing(self, system_tracing=True):
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Start tracing.
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      system_tracing: whether or not to gather system traces along with chrome
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      traces.
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._ExecuteJavascript("""
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        window.domAutomationController.send(
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)            window.pyautoRecordTrace(%s)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        );
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """ % ('true' if system_tracing else 'false'))
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def EndTracing(self):
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """End tracing and return a TimelineModel.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Returns:
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      an instance of a TimelineModel which contains the results of the trace
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return TimelineModel(
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        js_executor = self._ExecuteJavascript.__get__(self, Tracer),
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        shim_id = self._ExecuteJavascript('tracingController.endTracing();')
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    )
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TracerFactory(object):
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """A TracerFactory is used to produce a Tracer.
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  It's recommended to use the same TracerFactory to produce all Tracers so that
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  the same TabTracker can be used throughout
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Args:
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    browser: an instance of a PyUITest
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __init__(self, browser):
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._tab_tracker = tab_tracker.TabTracker(browser)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._browser = browser
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Produce(self):
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Produce an instance of a Tracer"""
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return Tracer(self._browser, self._tab_tracker)
87