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 page_set
as page_set_module
7 class PolymerPage(page_module
.Page
):
9 def __init__(self
, url
, page_set
, run_no_page_interactions
):
10 """ Base class for all polymer pages.
13 run_no_page_interactions: whether the page will run any interactions after
16 super(PolymerPage
, self
).__init
__(
19 self
.script_to_evaluate_on_commit
= '''
20 document.addEventListener("polymer-ready", function() {
21 window.__polymer_ready = true;
24 self
._run
_no
_page
_interactions
= run_no_page_interactions
26 def RunPageInteractions(self
, action_runner
):
27 # If a polymer page wants to customize its actions, it should
28 # override the PerformPageInteractions method instead of this method.
29 if self
._run
_no
_page
_interactions
:
31 self
.PerformPageInteractions(action_runner
)
33 def PerformPageInteractions(self
, action_runner
):
34 """ Override this to perform actions after the page has navigated. """
37 def RunNavigateSteps(self
, action_runner
):
38 super(PolymerPage
, self
).RunNavigateSteps(action_runner
)
39 action_runner
.WaitForJavaScriptCondition(
40 'window.__polymer_ready')
43 class PolymerCalculatorPage(PolymerPage
):
45 def __init__(self
, page_set
, run_no_page_interactions
):
46 super(PolymerCalculatorPage
, self
).__init
__(
47 url
=('http://www.polymer-project.org/components/paper-calculator/'
49 page_set
=page_set
, run_no_page_interactions
=run_no_page_interactions
)
51 def PerformPageInteractions(self
, action_runner
):
52 self
.TapButton(action_runner
)
53 self
.SlidePanel(action_runner
)
55 def TapButton(self
, action_runner
):
56 with action_runner
.CreateInteraction('PolymerAnimation', repeatable
=True):
57 action_runner
.TapElement(element_function
='''
58 document.querySelector(
59 'body /deep/ #outerPanels'
62 ).shadowRoot.querySelector(
63 'paper-calculator-key[label="5"]'
67 def SlidePanel(self
, action_runner
):
68 # only bother with this interaction if the drawer is hidden
69 opened
= action_runner
.EvaluateJavaScript('''
71 var outer = document.querySelector("body /deep/ #outerPanels");
72 return outer.opened || outer.wideMode;
75 with action_runner
.CreateInteraction('PolymerAnimation', repeatable
=True):
76 action_runner
.SwipeElement(
77 left_start_ratio
=0.1, top_start_ratio
=0.2,
78 direction
='left', distance
=300, speed_in_pixels_per_second
=5000,
80 document.querySelector(
81 'body /deep/ #outerPanels'
84 ).shadowRoot.querySelector(
87 action_runner
.WaitForJavaScriptCondition('''
88 var outer = document.querySelector("body /deep/ #outerPanels");
89 outer.opened || outer.wideMode;''')
92 class PolymerShadowPage(PolymerPage
):
94 def __init__(self
, page_set
, run_no_page_interactions
):
95 super(PolymerShadowPage
, self
).__init
__(
96 url
='http://www.polymer-project.org/components/paper-shadow/demo.html',
97 page_set
=page_set
, run_no_page_interactions
=run_no_page_interactions
)
99 def PerformPageInteractions(self
, action_runner
):
100 with action_runner
.CreateInteraction('ScrollAndShadowAnimation'):
101 action_runner
.ExecuteJavaScript(
102 "document.getElementById('fab').scrollIntoView()")
103 action_runner
.Wait(5)
104 self
.AnimateShadow(action_runner
, 'card')
105 #FIXME(wiltzius) disabling until this issue is fixed:
106 # https://github.com/Polymer/paper-shadow/issues/12
107 #self.AnimateShadow(action_runner, 'fab')
109 def AnimateShadow(self
, action_runner
, eid
):
110 for i
in range(1, 6):
111 action_runner
.ExecuteJavaScript(
112 'document.getElementById("{0}").z = {1}'.format(eid
, i
))
113 action_runner
.Wait(1)
116 class PolymerSampler(PolymerPage
):
118 def __init__(self
, page_set
, anchor
, run_no_page_interactions
,
119 scrolling_page
=False):
120 """Page exercising interactions with a single Paper Sampler subpage.
123 page_set: Page set to inforporate this page into.
124 anchor: string indicating which subpage to load (matches the element
125 type that page is displaying)
126 scrolling_page: Whether scrolling the content pane is relevant to this
129 super(PolymerSampler
, self
).__init
__(
130 url
=('http://www.polymer-project.org/components/%s/demo.html' % anchor
),
131 page_set
=page_set
, run_no_page_interactions
=run_no_page_interactions
)
132 self
.scrolling_page
= scrolling_page
133 self
.iframe_js
= 'document'
135 def RunNavigateSteps(self
, action_runner
):
136 super(PolymerSampler
, self
).RunNavigateSteps(action_runner
)
138 window.Polymer.whenPolymerReady(function() {
139 %s.contentWindow.Polymer.whenPolymerReady(function() {
140 window.__polymer_ready = true;
144 action_runner
.ExecuteJavaScript(waitForLoadJS
)
145 action_runner
.WaitForJavaScriptCondition(
146 'window.__polymer_ready')
148 def PerformPageInteractions(self
, action_runner
):
149 #TODO(wiltzius) Add interactions for input elements and shadow pages
150 if self
.scrolling_page
:
151 # Only bother scrolling the page if its been marked as worthwhile
152 self
.ScrollContentPane(action_runner
)
153 self
.TouchEverything(action_runner
)
155 def ScrollContentPane(self
, action_runner
):
156 element_function
= (self
.iframe_js
+ '.querySelector('
157 '"core-scroll-header-panel").$.mainContainer')
158 with action_runner
.CreateInteraction('Scroll_Page', repeatable
=True):
159 action_runner
.ScrollElement(use_touch
=True,
162 element_function
=element_function
)
163 with action_runner
.CreateInteraction('Scroll_Page', repeatable
=True):
164 action_runner
.ScrollElement(use_touch
=True,
167 element_function
=element_function
)
169 def TouchEverything(self
, action_runner
):
176 # 'paper-radio-button',
178 'paper-toggle-button',
181 for tappable_type
in tappable_types
:
182 self
.DoActionOnWidgetType(action_runner
, tappable_type
, self
.TapWidget
)
183 swipeable_types
= ['paper-slider']
184 for swipeable_type
in swipeable_types
:
185 self
.DoActionOnWidgetType(action_runner
, swipeable_type
, self
.SwipeWidget
)
187 def DoActionOnWidgetType(self
, action_runner
, widget_type
, action_function
):
188 # Find all widgets of this type, but skip any that are disabled or are
189 # currently active as they typically don't produce animation frames.
190 element_list_query
= (self
.iframe_js
+
191 ('.querySelectorAll("body %s:not([disabled]):'
192 'not([active])")' % widget_type
))
193 roles_count_query
= element_list_query
+ '.length'
194 for i
in range(action_runner
.EvaluateJavaScript(roles_count_query
)):
195 element_query
= element_list_query
+ ("[%d]" % i
)
196 if action_runner
.EvaluateJavaScript(
197 element_query
+ '.offsetParent != null'):
198 # Only try to tap on visible elements (offsetParent != null)
199 action_runner
.ExecuteJavaScript(element_query
+ '.scrollIntoView()')
200 action_runner
.Wait(1) # wait for page to settle after scrolling
201 action_function(action_runner
, element_query
)
203 def TapWidget(self
, action_runner
, element_function
):
204 with action_runner
.CreateInteraction('Tap_Widget', repeatable
=True):
205 action_runner
.TapElement(element_function
=element_function
)
206 action_runner
.Wait(1) # wait for e.g. animations on the widget
208 def SwipeWidget(self
, action_runner
, element_function
):
209 with action_runner
.CreateInteraction('Swipe_Widget'):
210 action_runner
.SwipeElement(element_function
=element_function
,
211 left_start_ratio
=0.75,
212 speed_in_pixels_per_second
=300)
215 class PolymerPageSet(page_set_module
.PageSet
):
217 def __init__(self
, run_no_page_interactions
=False):
218 super(PolymerPageSet
, self
).__init
__(
219 user_agent_type
='mobile',
220 archive_data_file
='data/polymer.json',
221 bucket
=page_set_module
.PUBLIC_BUCKET
)
223 self
.AddUserStory(PolymerCalculatorPage(self
, run_no_page_interactions
))
224 self
.AddUserStory(PolymerShadowPage(self
, run_no_page_interactions
))
226 # Polymer Sampler subpages that are interesting to tap / swipe elements on
233 # 'paper-radio-button',
234 #FIXME(wiltzius) Disabling x-shadow until this issue is fixed:
235 # https://github.com/Polymer/paper-shadow/issues/12
238 'paper-toggle-button',
240 for p
in TAPPABLE_PAGES
:
241 self
.AddUserStory(PolymerSampler(
242 self
, p
, run_no_page_interactions
=run_no_page_interactions
))
244 # Polymer Sampler subpages that are interesting to scroll
246 'core-scroll-header-panel',
248 for p
in SCROLLABLE_PAGES
:
249 self
.AddUserStory(PolymerSampler(
250 self
, p
, run_no_page_interactions
=run_no_page_interactions
,
251 scrolling_page
=True))
254 assert (page
.__class
__.RunPageInteractions
==
255 PolymerPage
.RunPageInteractions
), (
256 'Pages in this page set must not override PolymerPage\' '
257 'RunPageInteractions method.')