普通文本  |  239行  |  8.72 KB

# Copyright 2014 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.
from telemetry.page import page as page_module
from telemetry.page import page_set as page_set_module

class PolymerPage(page_module.Page):

  def __init__(self, url, page_set):
    super(PolymerPage, self).__init__(
      url=url,
      page_set=page_set)
    self.script_to_evaluate_on_commit = '''
      document.addEventListener("polymer-ready", function() {
        window.__polymer_ready = true;
      });
    '''

  def RunNavigateSteps(self, action_runner):
    action_runner.NavigateToPage(self)
    action_runner.WaitForJavaScriptCondition(
        'window.__polymer_ready')


class PolymerCalculatorPage(PolymerPage):

  def __init__(self, page_set):
    super(PolymerCalculatorPage, self).__init__(
      url=('http://www.polymer-project.org/components/paper-calculator/'
          'demo.html'),
      page_set=page_set)

  def RunSmoothness(self, action_runner):
    self.TapButton(action_runner)
    self.SlidePanel(action_runner)

  def TapButton(self, action_runner):
    interaction = action_runner.BeginInteraction(
        'Action_TapAction', is_smooth=True)
    action_runner.TapElement(element_function='''
        document.querySelector(
            'body /deep/ #outerPanels'
        ).querySelector(
            '#standard'
        ).shadowRoot.querySelector(
            'paper-calculator-key[label="5"]'
        )''')
    action_runner.Wait(2)
    interaction.End()

  def SlidePanel(self, action_runner):
    # only bother with this interaction if the drawer is hidden
    opened = action_runner.EvaluateJavaScript('''
        (function() {
          var outer = document.querySelector("body /deep/ #outerPanels");
          return outer.opened || outer.wideMode;
          }());''')
    if not opened:
      interaction = action_runner.BeginInteraction(
          'Action_SwipeAction', is_smooth=True)
      action_runner.SwipeElement(
          left_start_ratio=0.1, top_start_ratio=0.2,
          direction='left', distance=300, speed_in_pixels_per_second=5000,
          element_function='''
              document.querySelector(
                'body /deep/ #outerPanels'
              ).querySelector(
                '#advanced'
              ).shadowRoot.querySelector(
                '.handle-bar'
              )''')
      action_runner.WaitForJavaScriptCondition('''
          var outer = document.querySelector("body /deep/ #outerPanels");
          outer.opened || outer.wideMode;''')
      interaction.End()


class PolymerShadowPage(PolymerPage):

  def __init__(self, page_set):
    super(PolymerShadowPage, self).__init__(
      url='http://www.polymer-project.org/components/paper-shadow/demo.html',
      page_set=page_set)

  def RunSmoothness(self, action_runner):
    action_runner.ExecuteJavaScript(
        "document.getElementById('fab').scrollIntoView()")
    action_runner.Wait(5)
    self.AnimateShadow(action_runner, 'card')
    #FIXME(wiltzius) disabling until this issue is fixed:
    # https://github.com/Polymer/paper-shadow/issues/12
    #self.AnimateShadow(action_runner, 'fab')

  def AnimateShadow(self, action_runner, eid):
    for i in range(1, 6):
      action_runner.ExecuteJavaScript(
          'document.getElementById("{0}").z = {1}'.format(eid, i))
      action_runner.Wait(1)


class PolymerSampler(PolymerPage):

  def __init__(self, page_set, anchor, scrolling_page=False):
    """Page exercising interactions with a single Paper Sampler subpage.

    Args:
      page_set: Page set to inforporate this page into.
      anchor: string indicating which subpage to load (matches the element
          type that page is displaying)
      scrolling_page: Whether scrolling the content pane is relevant to this
          content page or not.
    """
    super(PolymerSampler, self).__init__(
      url=('http://www.polymer-project.org/components/%s/demo.html' % anchor),
      page_set=page_set)
    self.scrolling_page = scrolling_page
    self.iframe_js = 'document'

  def RunNavigateSteps(self, action_runner):
    super(PolymerSampler, self).RunNavigateSteps(action_runner)
    waitForLoadJS = """
      window.Polymer.whenPolymerReady(function() {
        %s.contentWindow.Polymer.whenPolymerReady(function() {
          window.__polymer_ready = true;
        })
      });
      """ % self.iframe_js
    action_runner.ExecuteJavaScript(waitForLoadJS)
    action_runner.WaitForJavaScriptCondition(
        'window.__polymer_ready')

  def RunSmoothness(self, action_runner):
    #TODO(wiltzius) Add interactions for input elements and shadow pages
    if self.scrolling_page:
      # Only bother scrolling the page if its been marked as worthwhile
      self.ScrollContentPane(action_runner)
    self.TouchEverything(action_runner)

  def ScrollContentPane(self, action_runner):
    element_function = (self.iframe_js + '.querySelector('
        '"core-scroll-header-panel").$.mainContainer')
    interaction = action_runner.BeginInteraction('Scroll_Page', is_smooth=True)
    action_runner.ScrollElement(use_touch=True,
                                direction='down',
                                distance='900',
                                element_function=element_function)
    interaction.End()
    interaction = action_runner.BeginInteraction('Scroll_Page', is_smooth=True)
    action_runner.ScrollElement(use_touch=True,
                                direction='up',
                                distance='900',
                                element_function=element_function)
    interaction.End()

  def TouchEverything(self, action_runner):
    tappable_types = [
        'paper-button',
        'paper-checkbox',
        'paper-fab',
        'paper-icon-button',
        # crbug.com/394756
        # 'paper-radio-button',
        'paper-tab',
        'paper-toggle-button',
        'x-shadow',
        ]
    for tappable_type in tappable_types:
      self.DoActionOnWidgetType(action_runner, tappable_type, self.TapWidget)
    swipeable_types = ['paper-slider']
    for swipeable_type in swipeable_types:
      self.DoActionOnWidgetType(action_runner, swipeable_type, self.SwipeWidget)

  def DoActionOnWidgetType(self, action_runner, widget_type, action_function):
    # Find all widgets of this type, but skip any that are disabled or are
    # currently active as they typically don't produce animation frames.
    element_list_query = (self.iframe_js +
        ('.querySelectorAll("body %s:not([disabled]):'
         'not([active])")' % widget_type))
    roles_count_query = element_list_query + '.length'
    for i in range(action_runner.EvaluateJavaScript(roles_count_query)):
      element_query = element_list_query + ("[%d]" % i)
      if action_runner.EvaluateJavaScript(
          element_query + '.offsetParent != null'):
        # Only try to tap on visible elements (offsetParent != null)
        action_runner.ExecuteJavaScript(element_query + '.scrollIntoView()')
        action_runner.Wait(1) # wait for page to settle after scrolling
        action_function(action_runner, element_query)

  def TapWidget(self, action_runner, element_function):
    interaction = action_runner.BeginInteraction(
        'Tap_Widget', is_smooth=True)
    action_runner.TapElement(element_function=element_function)
    action_runner.Wait(1) # wait for e.g. animations on the widget
    interaction.End()

  def SwipeWidget(self, action_runner, element_function):
    interaction = action_runner.BeginInteraction(
        'Swipe_Widget', is_smooth=True)
    action_runner.SwipeElement(element_function=element_function,
                               left_start_ratio=0.75,
                               speed_in_pixels_per_second=300)
    interaction.End()


class PolymerPageSet(page_set_module.PageSet):

  def __init__(self):
    super(PolymerPageSet, self).__init__(
      user_agent_type='mobile',
      archive_data_file='data/polymer.json',
      bucket=page_set_module.PUBLIC_BUCKET)

    self.AddPage(PolymerCalculatorPage(self))
    self.AddPage(PolymerShadowPage(self))

    # Polymer Sampler subpages that are interesting to tap / swipe elements on
    TAPPABLE_PAGES = [
        'paper-button',
        'paper-checkbox',
        'paper-fab',
        'paper-icon-button',
        # crbug.com/394756
        # 'paper-radio-button',
        #FIXME(wiltzius) Disabling x-shadow until this issue is fixed:
        # https://github.com/Polymer/paper-shadow/issues/12
        #'paper-shadow',
        'paper-tabs',
        'paper-toggle-button',
        ]
    for p in TAPPABLE_PAGES:
      self.AddPage(PolymerSampler(self, p))

    # Polymer Sampler subpages that are interesting to scroll
    SCROLLABLE_PAGES = [
        'core-scroll-header-panel',
        ]
    for p in SCROLLABLE_PAGES:
      self.AddPage(PolymerSampler(self, p, scrolling_page=True))