1# Copyright 2014 The Chromium Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4from telemetry.page import page as page_module 5from telemetry.page import page_set as page_set_module 6 7class PolymerPage(page_module.Page): 8 9 def __init__(self, url, page_set): 10 super(PolymerPage, self).__init__( 11 url=url, 12 page_set=page_set) 13 self.script_to_evaluate_on_commit = ''' 14 document.addEventListener("polymer-ready", function() { 15 window.__polymer_ready = true; 16 }); 17 ''' 18 19 def RunNavigateSteps(self, action_runner): 20 action_runner.NavigateToPage(self) 21 action_runner.WaitForJavaScriptCondition( 22 'window.__polymer_ready') 23 24 25class PolymerCalculatorPage(PolymerPage): 26 27 def __init__(self, page_set): 28 super(PolymerCalculatorPage, self).__init__( 29 url=('http://www.polymer-project.org/components/paper-calculator/' 30 'demo.html'), 31 page_set=page_set) 32 33 def RunSmoothness(self, action_runner): 34 self.TapButton(action_runner) 35 self.SlidePanel(action_runner) 36 37 def TapButton(self, action_runner): 38 interaction = action_runner.BeginInteraction( 39 'Action_TapAction', is_smooth=True) 40 action_runner.TapElement(element_function=''' 41 document.querySelector( 42 'body /deep/ #outerPanels' 43 ).querySelector( 44 '#standard' 45 ).shadowRoot.querySelector( 46 'paper-calculator-key[label="5"]' 47 )''') 48 action_runner.Wait(2) 49 interaction.End() 50 51 def SlidePanel(self, action_runner): 52 # only bother with this interaction if the drawer is hidden 53 opened = action_runner.EvaluateJavaScript(''' 54 (function() { 55 var outer = document.querySelector("body /deep/ #outerPanels"); 56 return outer.opened || outer.wideMode; 57 }());''') 58 if not opened: 59 interaction = action_runner.BeginInteraction( 60 'Action_SwipeAction', is_smooth=True) 61 action_runner.SwipeElement( 62 left_start_ratio=0.1, top_start_ratio=0.2, 63 direction='left', distance=300, speed_in_pixels_per_second=5000, 64 element_function=''' 65 document.querySelector( 66 'body /deep/ #outerPanels' 67 ).querySelector( 68 '#advanced' 69 ).shadowRoot.querySelector( 70 '.handle-bar' 71 )''') 72 action_runner.WaitForJavaScriptCondition(''' 73 var outer = document.querySelector("body /deep/ #outerPanels"); 74 outer.opened || outer.wideMode;''') 75 interaction.End() 76 77 78class PolymerShadowPage(PolymerPage): 79 80 def __init__(self, page_set): 81 super(PolymerShadowPage, self).__init__( 82 url='http://www.polymer-project.org/components/paper-shadow/demo.html', 83 page_set=page_set) 84 85 def RunSmoothness(self, action_runner): 86 action_runner.ExecuteJavaScript( 87 "document.getElementById('fab').scrollIntoView()") 88 action_runner.Wait(5) 89 self.AnimateShadow(action_runner, 'card') 90 #FIXME(wiltzius) disabling until this issue is fixed: 91 # https://github.com/Polymer/paper-shadow/issues/12 92 #self.AnimateShadow(action_runner, 'fab') 93 94 def AnimateShadow(self, action_runner, eid): 95 for i in range(1, 6): 96 action_runner.ExecuteJavaScript( 97 'document.getElementById("{0}").z = {1}'.format(eid, i)) 98 action_runner.Wait(1) 99 100 101class PolymerSampler(PolymerPage): 102 103 def __init__(self, page_set, anchor, scrolling_page=False): 104 """Page exercising interactions with a single Paper Sampler subpage. 105 106 Args: 107 page_set: Page set to inforporate this page into. 108 anchor: string indicating which subpage to load (matches the element 109 type that page is displaying) 110 scrolling_page: Whether scrolling the content pane is relevant to this 111 content page or not. 112 """ 113 super(PolymerSampler, self).__init__( 114 url=('http://www.polymer-project.org/components/%s/demo.html' % anchor), 115 page_set=page_set) 116 self.scrolling_page = scrolling_page 117 self.iframe_js = 'document' 118 119 def RunNavigateSteps(self, action_runner): 120 super(PolymerSampler, self).RunNavigateSteps(action_runner) 121 waitForLoadJS = """ 122 window.Polymer.whenPolymerReady(function() { 123 %s.contentWindow.Polymer.whenPolymerReady(function() { 124 window.__polymer_ready = true; 125 }) 126 }); 127 """ % self.iframe_js 128 action_runner.ExecuteJavaScript(waitForLoadJS) 129 action_runner.WaitForJavaScriptCondition( 130 'window.__polymer_ready') 131 132 def RunSmoothness(self, action_runner): 133 #TODO(wiltzius) Add interactions for input elements and shadow pages 134 if self.scrolling_page: 135 # Only bother scrolling the page if its been marked as worthwhile 136 self.ScrollContentPane(action_runner) 137 self.TouchEverything(action_runner) 138 139 def ScrollContentPane(self, action_runner): 140 element_function = (self.iframe_js + '.querySelector(' 141 '"core-scroll-header-panel").$.mainContainer') 142 interaction = action_runner.BeginInteraction('Scroll_Page', is_smooth=True) 143 action_runner.ScrollElement(use_touch=True, 144 direction='down', 145 distance='900', 146 element_function=element_function) 147 interaction.End() 148 interaction = action_runner.BeginInteraction('Scroll_Page', is_smooth=True) 149 action_runner.ScrollElement(use_touch=True, 150 direction='up', 151 distance='900', 152 element_function=element_function) 153 interaction.End() 154 155 def TouchEverything(self, action_runner): 156 tappable_types = [ 157 'paper-button', 158 'paper-checkbox', 159 'paper-fab', 160 'paper-icon-button', 161 # crbug.com/394756 162 # 'paper-radio-button', 163 'paper-tab', 164 'paper-toggle-button', 165 'x-shadow', 166 ] 167 for tappable_type in tappable_types: 168 self.DoActionOnWidgetType(action_runner, tappable_type, self.TapWidget) 169 swipeable_types = ['paper-slider'] 170 for swipeable_type in swipeable_types: 171 self.DoActionOnWidgetType(action_runner, swipeable_type, self.SwipeWidget) 172 173 def DoActionOnWidgetType(self, action_runner, widget_type, action_function): 174 # Find all widgets of this type, but skip any that are disabled or are 175 # currently active as they typically don't produce animation frames. 176 element_list_query = (self.iframe_js + 177 ('.querySelectorAll("body %s:not([disabled]):' 178 'not([active])")' % widget_type)) 179 roles_count_query = element_list_query + '.length' 180 for i in range(action_runner.EvaluateJavaScript(roles_count_query)): 181 element_query = element_list_query + ("[%d]" % i) 182 if action_runner.EvaluateJavaScript( 183 element_query + '.offsetParent != null'): 184 # Only try to tap on visible elements (offsetParent != null) 185 action_runner.ExecuteJavaScript(element_query + '.scrollIntoView()') 186 action_runner.Wait(1) # wait for page to settle after scrolling 187 action_function(action_runner, element_query) 188 189 def TapWidget(self, action_runner, element_function): 190 interaction = action_runner.BeginInteraction( 191 'Tap_Widget', is_smooth=True) 192 action_runner.TapElement(element_function=element_function) 193 action_runner.Wait(1) # wait for e.g. animations on the widget 194 interaction.End() 195 196 def SwipeWidget(self, action_runner, element_function): 197 interaction = action_runner.BeginInteraction( 198 'Swipe_Widget', is_smooth=True) 199 action_runner.SwipeElement(element_function=element_function, 200 left_start_ratio=0.75, 201 speed_in_pixels_per_second=300) 202 interaction.End() 203 204 205class PolymerPageSet(page_set_module.PageSet): 206 207 def __init__(self): 208 super(PolymerPageSet, self).__init__( 209 user_agent_type='mobile', 210 archive_data_file='data/polymer.json', 211 bucket=page_set_module.PUBLIC_BUCKET) 212 213 self.AddPage(PolymerCalculatorPage(self)) 214 self.AddPage(PolymerShadowPage(self)) 215 216 # Polymer Sampler subpages that are interesting to tap / swipe elements on 217 TAPPABLE_PAGES = [ 218 'paper-button', 219 'paper-checkbox', 220 'paper-fab', 221 'paper-icon-button', 222 # crbug.com/394756 223 # 'paper-radio-button', 224 #FIXME(wiltzius) Disabling x-shadow until this issue is fixed: 225 # https://github.com/Polymer/paper-shadow/issues/12 226 #'paper-shadow', 227 'paper-tabs', 228 'paper-toggle-button', 229 ] 230 for p in TAPPABLE_PAGES: 231 self.AddPage(PolymerSampler(self, p)) 232 233 # Polymer Sampler subpages that are interesting to scroll 234 SCROLLABLE_PAGES = [ 235 'core-scroll-header-panel', 236 ] 237 for p in SCROLLABLE_PAGES: 238 self.AddPage(PolymerSampler(self, p, scrolling_page=True)) 239