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.
4 from telemetry
.page
import page
as page_module
5 from telemetry
.page
import shared_page_state
6 from telemetry
import story
9 class PolymerPage(page_module
.Page
):
11 def __init__(self
, url
, page_set
, run_no_page_interactions
):
12 """ Base class for all polymer pages.
15 run_no_page_interactions: whether the page will run any interactions after
18 super(PolymerPage
, self
).__init
__(
20 shared_page_state_class
=shared_page_state
.SharedMobilePageState
,
22 self
.script_to_evaluate_on_commit
= '''
23 document.addEventListener("polymer-ready", function() {
24 window.__polymer_ready = true;
27 self
._run
_no
_page
_interactions
= run_no_page_interactions
29 def RunPageInteractions(self
, action_runner
):
30 # If a polymer page wants to customize its actions, it should
31 # override the PerformPageInteractions method instead of this method.
32 if self
._run
_no
_page
_interactions
:
34 self
.PerformPageInteractions(action_runner
)
36 def PerformPageInteractions(self
, action_runner
):
37 """ Override this to perform actions after the page has navigated. """
40 def RunNavigateSteps(self
, action_runner
):
41 super(PolymerPage
, self
).RunNavigateSteps(action_runner
)
42 action_runner
.WaitForJavaScriptCondition(
43 'window.__polymer_ready')
46 class PolymerCalculatorPage(PolymerPage
):
48 def __init__(self
, page_set
, run_no_page_interactions
):
49 super(PolymerCalculatorPage
, self
).__init
__(
50 url
=('http://www.polymer-project.org/components/paper-calculator/'
52 page_set
=page_set
, run_no_page_interactions
=run_no_page_interactions
)
54 def PerformPageInteractions(self
, action_runner
):
55 self
.TapButton(action_runner
)
56 self
.SlidePanel(action_runner
)
58 def TapButton(self
, action_runner
):
59 with action_runner
.CreateInteraction('PolymerAnimation', repeatable
=True):
60 action_runner
.TapElement(element_function
='''
61 document.querySelector(
62 'body /deep/ #outerPanels'
65 ).shadowRoot.querySelector(
66 'paper-calculator-key[label="5"]'
70 def SlidePanel(self
, action_runner
):
71 # only bother with this interaction if the drawer is hidden
72 opened
= action_runner
.EvaluateJavaScript('''
74 var outer = document.querySelector("body /deep/ #outerPanels");
75 return outer.opened || outer.wideMode;
78 with action_runner
.CreateInteraction('PolymerAnimation', repeatable
=True):
79 action_runner
.SwipeElement(
80 left_start_ratio
=0.1, top_start_ratio
=0.2,
81 direction
='left', distance
=300, speed_in_pixels_per_second
=5000,
83 document.querySelector(
84 'body /deep/ #outerPanels'
87 ).shadowRoot.querySelector(
90 action_runner
.WaitForJavaScriptCondition('''
91 var outer = document.querySelector("body /deep/ #outerPanels");
92 outer.opened || outer.wideMode;''')
95 class PolymerShadowPage(PolymerPage
):
97 def __init__(self
, page_set
, run_no_page_interactions
):
98 super(PolymerShadowPage
, self
).__init
__(
99 url
='http://www.polymer-project.org/components/paper-shadow/demo.html',
100 page_set
=page_set
, run_no_page_interactions
=run_no_page_interactions
)
102 def PerformPageInteractions(self
, action_runner
):
103 with action_runner
.CreateInteraction('ScrollAndShadowAnimation'):
104 action_runner
.ExecuteJavaScript(
105 "document.getElementById('fab').scrollIntoView()")
106 action_runner
.Wait(5)
107 self
.AnimateShadow(action_runner
, 'card')
108 #FIXME(wiltzius) disabling until this issue is fixed:
109 # https://github.com/Polymer/paper-shadow/issues/12
110 #self.AnimateShadow(action_runner, 'fab')
112 def AnimateShadow(self
, action_runner
, eid
):
113 for i
in range(1, 6):
114 action_runner
.ExecuteJavaScript(
115 'document.getElementById("{0}").z = {1}'.format(eid
, i
))
116 action_runner
.Wait(1)
119 class PolymerSampler(PolymerPage
):
121 def __init__(self
, page_set
, anchor
, run_no_page_interactions
,
122 scrolling_page
=False):
123 """Page exercising interactions with a single Paper Sampler subpage.
126 page_set: Page set to inforporate this page into.
127 anchor: string indicating which subpage to load (matches the element
128 type that page is displaying)
129 scrolling_page: Whether scrolling the content pane is relevant to this
132 super(PolymerSampler
, self
).__init
__(
133 url
=('http://www.polymer-project.org/components/%s/demo.html' % anchor
),
134 page_set
=page_set
, run_no_page_interactions
=run_no_page_interactions
)
135 self
.scrolling_page
= scrolling_page
136 self
.iframe_js
= 'document'
138 def RunNavigateSteps(self
, action_runner
):
139 super(PolymerSampler
, self
).RunNavigateSteps(action_runner
)
141 window.Polymer.whenPolymerReady(function() {
142 %s.contentWindow.Polymer.whenPolymerReady(function() {
143 window.__polymer_ready = true;
147 action_runner
.ExecuteJavaScript(waitForLoadJS
)
148 action_runner
.WaitForJavaScriptCondition(
149 'window.__polymer_ready')
151 def PerformPageInteractions(self
, action_runner
):
152 #TODO(wiltzius) Add interactions for input elements and shadow pages
153 if self
.scrolling_page
:
154 # Only bother scrolling the page if its been marked as worthwhile
155 self
.ScrollContentPane(action_runner
)
156 self
.TouchEverything(action_runner
)
158 def ScrollContentPane(self
, action_runner
):
159 element_function
= (self
.iframe_js
+ '.querySelector('
160 '"core-scroll-header-panel").$.mainContainer')
161 with action_runner
.CreateInteraction('Scroll_Page', repeatable
=True):
162 action_runner
.ScrollElement(use_touch
=True,
165 element_function
=element_function
)
166 with action_runner
.CreateInteraction('Scroll_Page', repeatable
=True):
167 action_runner
.ScrollElement(use_touch
=True,
170 element_function
=element_function
)
172 def TouchEverything(self
, action_runner
):
179 # 'paper-radio-button',
181 'paper-toggle-button',
184 for tappable_type
in tappable_types
:
185 self
.DoActionOnWidgetType(action_runner
, tappable_type
, self
.TapWidget
)
186 swipeable_types
= ['paper-slider']
187 for swipeable_type
in swipeable_types
:
188 self
.DoActionOnWidgetType(action_runner
, swipeable_type
, self
.SwipeWidget
)
190 def DoActionOnWidgetType(self
, action_runner
, widget_type
, action_function
):
191 # Find all widgets of this type, but skip any that are disabled or are
192 # currently active as they typically don't produce animation frames.
193 element_list_query
= (self
.iframe_js
+
194 ('.querySelectorAll("body %s:not([disabled]):'
195 'not([active])")' % widget_type
))
196 roles_count_query
= element_list_query
+ '.length'
197 for i
in range(action_runner
.EvaluateJavaScript(roles_count_query
)):
198 element_query
= element_list_query
+ ("[%d]" % i
)
199 if action_runner
.EvaluateJavaScript(
200 element_query
+ '.offsetParent != null'):
201 # Only try to tap on visible elements (offsetParent != null)
202 action_runner
.ExecuteJavaScript(element_query
+ '.scrollIntoView()')
203 action_runner
.Wait(1) # wait for page to settle after scrolling
204 action_function(action_runner
, element_query
)
206 def TapWidget(self
, action_runner
, element_function
):
207 with action_runner
.CreateInteraction('Tap_Widget', repeatable
=True):
208 action_runner
.TapElement(element_function
=element_function
)
209 action_runner
.Wait(1) # wait for e.g. animations on the widget
211 def SwipeWidget(self
, action_runner
, element_function
):
212 with action_runner
.CreateInteraction('Swipe_Widget'):
213 action_runner
.SwipeElement(element_function
=element_function
,
214 left_start_ratio
=0.75,
215 speed_in_pixels_per_second
=300)
218 class PolymerPageSet(story
.StorySet
):
220 def __init__(self
, run_no_page_interactions
=False):
221 super(PolymerPageSet
, self
).__init
__(
222 archive_data_file
='data/polymer.json',
223 cloud_storage_bucket
=story
.PUBLIC_BUCKET
)
225 self
.AddStory(PolymerCalculatorPage(self
, run_no_page_interactions
))
226 self
.AddStory(PolymerShadowPage(self
, run_no_page_interactions
))
228 # Polymer Sampler subpages that are interesting to tap / swipe elements on
235 # 'paper-radio-button',
236 #FIXME(wiltzius) Disabling x-shadow until this issue is fixed:
237 # https://github.com/Polymer/paper-shadow/issues/12
240 'paper-toggle-button',
242 for p
in TAPPABLE_PAGES
:
243 self
.AddStory(PolymerSampler(
244 self
, p
, run_no_page_interactions
=run_no_page_interactions
))
246 # Polymer Sampler subpages that are interesting to scroll
248 'core-scroll-header-panel',
250 for p
in SCROLLABLE_PAGES
:
251 self
.AddStory(PolymerSampler(
252 self
, p
, run_no_page_interactions
=run_no_page_interactions
,
253 scrolling_page
=True))
256 assert (page
.__class
__.RunPageInteractions
==
257 PolymerPage
.RunPageInteractions
), (
258 'Pages in this page set must not override PolymerPage\' '
259 'RunPageInteractions method.')