# 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, run_no_page_interactions): """ Base class for all polymer pages. Args: run_no_page_interactions: whether the page will run any interactions after navigate steps. """ 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; }); ''' self._run_no_page_interactions = run_no_page_interactions def RunPageInteractions(self, action_runner): # If a polymer page wants to customize its actions, it should # override the PerformPageInteractions method instead of this method. if self._run_no_page_interactions: return self.PerformPageInteractions(action_runner) def PerformPageInteractions(self, action_runner): """ Override this to perform actions after the page has navigated. """ pass def RunNavigateSteps(self, action_runner): super(PolymerPage, self).RunNavigateSteps(action_runner) action_runner.WaitForJavaScriptCondition( 'window.__polymer_ready') class PolymerCalculatorPage(PolymerPage): def __init__(self, page_set, run_no_page_interactions): super(PolymerCalculatorPage, self).__init__( url=('http://www.polymer-project.org/components/paper-calculator/' 'demo.html'), page_set=page_set, run_no_page_interactions=run_no_page_interactions) def PerformPageInteractions(self, action_runner): self.TapButton(action_runner) self.SlidePanel(action_runner) def TapButton(self, action_runner): with action_runner.CreateInteraction('Action_TapAction'): action_runner.TapElement(element_function=''' document.querySelector( 'body /deep/ #outerPanels' ).querySelector( '#standard' ).shadowRoot.querySelector( 'paper-calculator-key[label="5"]' )''') action_runner.Wait(2) 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: with action_runner.CreateInteraction('Action_SwipeAction'): 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;''') class PolymerShadowPage(PolymerPage): def __init__(self, page_set, run_no_page_interactions): super(PolymerShadowPage, self).__init__( url='http://www.polymer-project.org/components/paper-shadow/demo.html', page_set=page_set, run_no_page_interactions=run_no_page_interactions) def PerformPageInteractions(self, action_runner): with action_runner.CreateInteraction('ScrollAndShadowAnimation'): 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, run_no_page_interactions, 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, run_no_page_interactions=run_no_page_interactions) 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 PerformPageInteractions(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') with action_runner.CreateInteraction('Scroll_Page'): action_runner.ScrollElement(use_touch=True, direction='down', distance='900', element_function=element_function) with action_runner.CreateInteraction('Scroll_Page'): action_runner.ScrollElement(use_touch=True, direction='up', distance='900', element_function=element_function) 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): with action_runner.CreateInteraction('Tap_Widget'): action_runner.TapElement(element_function=element_function) action_runner.Wait(1) # wait for e.g. animations on the widget def SwipeWidget(self, action_runner, element_function): with action_runner.CreateInteraction('Swipe_Widget'): action_runner.SwipeElement(element_function=element_function, left_start_ratio=0.75, speed_in_pixels_per_second=300) class PolymerPageSet(page_set_module.PageSet): def __init__(self, run_no_page_interactions=False): super(PolymerPageSet, self).__init__( user_agent_type='mobile', archive_data_file='data/polymer.json', bucket=page_set_module.PUBLIC_BUCKET) self.AddUserStory(PolymerCalculatorPage(self, run_no_page_interactions)) self.AddUserStory(PolymerShadowPage(self, run_no_page_interactions)) # 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.AddUserStory(PolymerSampler( self, p, run_no_page_interactions=run_no_page_interactions)) # Polymer Sampler subpages that are interesting to scroll SCROLLABLE_PAGES = [ 'core-scroll-header-panel', ] for p in SCROLLABLE_PAGES: self.AddUserStory(PolymerSampler( self, p, run_no_page_interactions=run_no_page_interactions, scrolling_page=True)) for page in self: assert (page.__class__.RunPageInteractions == PolymerPage.RunPageInteractions), ( 'Pages in this page set must not override PolymerPage\' ' 'RunPageInteractions method.')