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
8 class KeySilkCasesPage(page_module
.Page
):
10 def __init__(self
, url
, page_set
):
11 super(KeySilkCasesPage
, self
).__init
__(url
=url
, page_set
=page_set
)
12 self
.credentials_path
= 'data/credentials.json'
13 self
.user_agent_type
= 'mobile'
14 self
.archive_data_file
= 'data/key_silk_cases.json'
16 def RunNavigateSteps(self
, action_runner
):
17 action_runner
.NavigateToPage(self
)
20 def RunSmoothness(self
, action_runner
):
21 interaction
= action_runner
.BeginGestureInteraction(
22 'ScrollAction', is_smooth
=True)
23 action_runner
.ScrollPage()
27 class Page1(KeySilkCasesPage
):
29 """ Why: Infinite scroll. Brings out all of our perf issues. """
31 def __init__(self
, page_set
):
32 super(Page1
, self
).__init
__(
33 url
='http://groupcloned.com/test/plain/list-recycle-transform.html',
36 def RunSmoothness(self
, action_runner
):
37 interaction
= action_runner
.BeginGestureInteraction(
38 'ScrollAction', is_smooth
=True)
39 action_runner
.ScrollElement(selector
='#scrollable')
43 class Page2(KeySilkCasesPage
):
45 """ Why: Brings out layer management bottlenecks. """
47 def __init__(self
, page_set
):
48 super(Page2
, self
).__init
__(
49 url
='http://groupcloned.com/test/plain/list-animation-simple.html',
52 def RunSmoothness(self
, action_runner
):
56 class Page3(KeySilkCasesPage
):
59 Why: Best-known method for fake sticky. Janks sometimes. Interacts badly with
63 def __init__(self
, page_set
):
64 super(Page3
, self
).__init
__(
65 # pylint: disable=C0301
66 url
='http://groupcloned.com/test/plain/sticky-using-webkit-backface-visibility.html',
69 def RunSmoothness(self
, action_runner
):
70 interaction
= action_runner
.BeginGestureInteraction(
71 'ScrollAction', is_smooth
=True)
72 action_runner
.ScrollElement(selector
='#container')
76 class Page4(KeySilkCasesPage
):
79 Why: Card expansion: only the card should repaint, but in reality lots of
83 def __init__(self
, page_set
):
84 super(Page4
, self
).__init
__(
85 url
='http://jsfiddle.net/3yDKh/15/show/',
88 def RunSmoothness(self
, action_runner
):
92 class Page5(KeySilkCasesPage
):
95 Why: Card expansion with animated contents, using will-change on the card
98 def __init__(self
, page_set
):
99 super(Page5
, self
).__init
__(
100 url
='http://jsfiddle.net/jx5De/14/show/',
103 self
.gpu_raster
= True
105 def RunSmoothness(self
, action_runner
):
106 action_runner
.Wait(4)
109 class Page6(KeySilkCasesPage
):
112 Why: Card fly-in: It should be fast to animate in a bunch of cards using
113 margin-top and letting layout do the rest.
116 def __init__(self
, page_set
):
117 super(Page6
, self
).__init
__(
118 url
='http://jsfiddle.net/3yDKh/16/show/',
121 def RunSmoothness(self
, action_runner
):
122 action_runner
.Wait(3)
125 class Page7(KeySilkCasesPage
):
128 Why: Image search expands a spacer div when you click an image to accomplish
129 a zoomin effect. Each image has a layer. Even so, this triggers a lot of
130 unnecessary repainting.
133 def __init__(self
, page_set
):
134 super(Page7
, self
).__init
__(
135 url
='http://jsfiddle.net/R8DX9/4/show/',
138 def RunSmoothness(self
, action_runner
):
139 action_runner
.Wait(3)
142 class Page8(KeySilkCasesPage
):
145 Why: Swipe to dismiss of an element that has a fixed-position child that is
146 its pseudo-sticky header. Brings out issues with layer creation and
150 def __init__(self
, page_set
):
151 super(Page8
, self
).__init
__(
152 url
='http://jsfiddle.net/rF9Gh/7/show/',
155 def RunSmoothness(self
, action_runner
):
156 action_runner
.Wait(3)
159 class Page9(KeySilkCasesPage
):
162 Why: Horizontal and vertical expansion of a card that is cheap to layout but
166 def __init__(self
, page_set
):
167 super(Page9
, self
).__init
__(
168 url
='http://jsfiddle.net/TLXLu/3/show/',
171 self
.gpu_raster
= True
173 def RunSmoothness(self
, action_runner
):
174 action_runner
.Wait(4)
177 class Page10(KeySilkCasesPage
):
180 Why: Vertical Expansion of a card that is cheap to layout but costly to
184 def __init__(self
, page_set
):
185 super(Page10
, self
).__init
__(
186 url
='http://jsfiddle.net/cKB9D/7/show/',
189 self
.gpu_raster
= True
191 def RunSmoothness(self
, action_runner
):
192 action_runner
.Wait(4)
195 class Page11(KeySilkCasesPage
):
198 Why: Parallax effect is common on photo-viewer-like applications, overloading
199 software rasterization
202 def __init__(self
, page_set
):
203 super(Page11
, self
).__init
__(
204 url
='http://jsfiddle.net/vBQHH/11/show/',
207 self
.gpu_raster
= True
209 def RunSmoothness(self
, action_runner
):
210 action_runner
.Wait(4)
213 class Page12(KeySilkCasesPage
):
215 """ Why: Addressing paint storms during coordinated animations. """
217 def __init__(self
, page_set
):
218 super(Page12
, self
).__init
__(
219 url
='http://jsfiddle.net/ugkd4/10/show/',
222 def RunSmoothness(self
, action_runner
):
223 action_runner
.Wait(5)
226 class Page13(KeySilkCasesPage
):
228 """ Why: Mask transitions are common mobile use cases. """
230 def __init__(self
, page_set
):
231 super(Page13
, self
).__init
__(
232 url
='http://jsfiddle.net/xLuvC/1/show/',
235 self
.gpu_raster
= True
237 def RunSmoothness(self
, action_runner
):
238 action_runner
.Wait(4)
241 class Page14(KeySilkCasesPage
):
243 """ Why: Card expansions with images and text are pretty and common. """
245 def __init__(self
, page_set
):
246 super(Page14
, self
).__init
__(
247 url
='http://jsfiddle.net/bNp2h/3/show/',
250 self
.gpu_raster
= True
252 def RunSmoothness(self
, action_runner
):
253 action_runner
.Wait(4)
256 class Page15(KeySilkCasesPage
):
258 """ Why: Coordinated animations for expanding elements. """
260 def __init__(self
, page_set
):
261 super(Page15
, self
).__init
__(
262 url
='file://key_silk_cases/font_wipe.html',
265 def RunSmoothness(self
, action_runner
):
266 action_runner
.Wait(5)
269 class Page16(KeySilkCasesPage
):
271 def __init__(self
, page_set
):
272 super(Page16
, self
).__init
__(
273 url
='file://key_silk_cases/inbox_app.html?swipe_to_dismiss',
276 def RunNavigateSteps(self
, action_runner
):
277 action_runner
.NavigateToPage(self
)
278 action_runner
.Wait(2)
280 def SwipeToDismiss(self
, action_runner
):
281 interaction
= action_runner
.BeginGestureInteraction(
282 'SwipeAction', is_smooth
=True)
283 action_runner
.SwipeElement(
284 left_start_ratio
=0.8, top_start_ratio
=0.2,
285 direction
='left', distance
=200, speed_in_pixels_per_second
=5000,
286 element_function
='document.getElementsByClassName("message")[2]')
288 interaction
= action_runner
.BeginInteraction('Wait', is_smooth
=True)
289 action_runner
.WaitForJavaScriptCondition(
290 'document.getElementsByClassName("message").length < 18')
293 def RunSmoothness(self
, action_runner
):
294 self
.SwipeToDismiss(action_runner
)
297 class Page17(KeySilkCasesPage
):
299 def __init__(self
, page_set
):
300 super(Page17
, self
).__init
__(
301 url
='file://key_silk_cases/inbox_app.html?stress_hidey_bars',
304 def RunNavigateSteps(self
, action_runner
):
305 action_runner
.NavigateToPage(self
)
306 action_runner
.Wait(2)
308 def RunSmoothness(self
, action_runner
):
309 self
.StressHideyBars(action_runner
)
311 def StressHideyBars(self
, action_runner
):
312 interaction
= action_runner
.BeginGestureInteraction(
313 'ScrollAction', is_smooth
=True)
314 action_runner
.ScrollElement(
315 selector
='#messages', direction
='down', speed_in_pixels_per_second
=200)
317 interaction
= action_runner
.BeginGestureInteraction(
318 'ScrollAction', is_smooth
=True)
319 action_runner
.ScrollElement(
320 selector
='#messages', direction
='up', speed_in_pixels_per_second
=200)
322 interaction
= action_runner
.BeginGestureInteraction(
323 'ScrollAction', is_smooth
=True)
324 action_runner
.ScrollElement(
325 selector
='#messages', direction
='down', speed_in_pixels_per_second
=200)
329 class Page18(KeySilkCasesPage
):
331 def __init__(self
, page_set
):
332 super(Page18
, self
).__init
__(
333 url
='file://key_silk_cases/inbox_app.html?toggle_drawer',
336 def RunNavigateSteps(self
, action_runner
):
337 action_runner
.NavigateToPage(self
)
338 action_runner
.Wait(2)
340 def RunSmoothness(self
, action_runner
):
342 self
.ToggleDrawer(action_runner
)
344 def ToggleDrawer(self
, action_runner
):
345 interaction
= action_runner
.BeginInteraction(
346 'Action_TapAction', is_smooth
=True)
347 action_runner
.TapElement('#menu-button')
348 action_runner
.Wait(1)
352 class Page19(KeySilkCasesPage
):
354 def __init__(self
, page_set
):
355 super(Page19
, self
).__init
__(
356 url
='file://key_silk_cases/inbox_app.html?slide_drawer',
359 def ToggleDrawer(self
, action_runner
):
360 interaction
= action_runner
.BeginGestureInteraction(
361 'TapAction', is_smooth
=True)
362 action_runner
.TapElement('#menu-button')
365 interaction
= action_runner
.BeginInteraction('Wait', is_smooth
=True)
366 action_runner
.WaitForJavaScriptCondition('''
367 document.getElementById("nav-drawer").active &&
368 document.getElementById("nav-drawer").children[0]
369 .getBoundingClientRect().left == 0''')
372 def RunNavigateSteps(self
, action_runner
):
373 action_runner
.NavigateToPage(self
)
374 action_runner
.Wait(2)
375 self
.ToggleDrawer(action_runner
)
377 def RunSmoothness(self
, action_runner
):
378 self
.SlideDrawer(action_runner
)
380 def SlideDrawer(self
, action_runner
):
381 interaction
= action_runner
.BeginInteraction(
382 'Action_SwipeAction', is_smooth
=True)
383 action_runner
.SwipeElement(
384 left_start_ratio
=0.8, top_start_ratio
=0.2,
385 direction
='left', distance
=200,
386 element_function
='document.getElementById("nav-drawer").children[0]')
387 action_runner
.WaitForJavaScriptCondition(
388 '!document.getElementById("nav-drawer").active')
392 class Page20(KeySilkCasesPage
):
394 """ Why: Shadow DOM infinite scrolling. """
396 def __init__(self
, page_set
):
397 super(Page20
, self
).__init
__(
398 url
='file://key_silk_cases/infinite_scrolling.html',
401 def RunSmoothness(self
, action_runner
):
402 interaction
= action_runner
.BeginGestureInteraction(
403 'ScrollAction', is_smooth
=True)
404 action_runner
.ScrollElement(
405 selector
='#container', speed_in_pixels_per_second
=5000)
409 class GwsExpansionPage(KeySilkCasesPage
):
410 """Abstract base class for pages that expand Google knowledge panels."""
412 def NavigateWait(self
, action_runner
):
413 action_runner
.NavigateToPage(self
)
414 action_runner
.Wait(3)
416 def ExpandKnowledgeCard(self
, action_runner
):
418 interaction
= action_runner
.BeginInteraction(
419 'Action_TapAction', is_smooth
=True)
420 action_runner
.TapElement(
421 element_function
='document.getElementsByClassName("vk_arc")[0]')
422 action_runner
.Wait(2)
425 def ScrollKnowledgeCardToTop(self
, action_runner
, card_id
):
426 # scroll until the knowledge card is at the top
427 action_runner
.ExecuteJavaScript(
428 "document.getElementById('%s').scrollIntoView()" % card_id
)
430 def RunSmoothness(self
, action_runner
):
431 self
.ExpandKnowledgeCard(action_runner
)
434 class GwsGoogleExpansion(GwsExpansionPage
):
436 """ Why: Animating height of a complex content card is common. """
438 def __init__(self
, page_set
):
439 super(GwsGoogleExpansion
, self
).__init
__(
440 url
='http://www.google.com/#q=google',
443 def RunNavigateSteps(self
, action_runner
):
444 self
.NavigateWait(action_runner
)
445 self
.ScrollKnowledgeCardToTop(action_runner
, 'kno-result')
448 class GwsBoogieExpansion(GwsExpansionPage
):
450 """ Why: Same case as Google expansion but text-heavy rather than image. """
452 def __init__(self
, page_set
):
453 super(GwsBoogieExpansion
, self
).__init
__(
454 url
='https://www.google.com/search?hl=en&q=define%3Aboogie',
457 def RunNavigateSteps(self
, action_runner
):
458 self
.NavigateWait(action_runner
)
459 self
.ScrollKnowledgeCardToTop(action_runner
, 'rso')
462 class Page22(KeySilkCasesPage
):
464 def __init__(self
, page_set
):
465 super(Page22
, self
).__init
__(
466 url
='http://plus.google.com/app/basic/stream',
469 self
.disabled
= 'Times out on Windows; crbug.com/338838'
470 self
.credentials
= 'google'
472 def RunNavigateSteps(self
, action_runner
):
473 action_runner
.NavigateToPage(self
)
474 action_runner
.WaitForJavaScriptCondition(
475 'document.getElementsByClassName("fHa").length > 0')
476 action_runner
.Wait(2)
478 def RunSmoothness(self
, action_runner
):
479 interaction
= action_runner
.BeginGestureInteraction(
480 'ScrollAction', is_smooth
=True)
481 action_runner
.ScrollElement(selector
='#mainContent')
485 class Page23(KeySilkCasesPage
):
488 Why: Physical simulation demo that does a lot of element.style mutation
489 triggering JS and recalc slowness
492 def __init__(self
, page_set
):
493 super(Page23
, self
).__init
__(
494 url
='http://jsbin.com/UVIgUTa/38/quiet',
497 def RunSmoothness(self
, action_runner
):
498 interaction
= action_runner
.BeginGestureInteraction(
499 'ScrollAction', is_smooth
=True)
500 action_runner
.ScrollPage(
501 distance_expr
='window.innerHeight / 2',
505 interaction
= action_runner
.BeginInteraction('Wait', is_smooth
=True)
506 action_runner
.Wait(1)
510 class Page24(KeySilkCasesPage
):
513 Why: Google News: this iOS version is slower than accelerated scrolling
516 def __init__(self
, page_set
):
517 super(Page24
, self
).__init
__(
518 url
='http://mobile-news.sandbox.google.com/news/pt0?scroll',
521 def RunNavigateSteps(self
, action_runner
):
522 action_runner
.NavigateToPage(self
)
523 action_runner
.WaitForJavaScriptCondition(
524 'document.getElementById(":h") != null')
525 action_runner
.Wait(1)
527 def RunSmoothness(self
, action_runner
):
528 interaction
= action_runner
.BeginGestureInteraction(
529 'ScrollAction', is_smooth
=True)
530 action_runner
.ScrollElement(
531 element_function
='document.getElementById(":5")',
537 class Page25(KeySilkCasesPage
):
539 def __init__(self
, page_set
):
540 super(Page25
, self
).__init
__(
541 url
='http://mobile-news.sandbox.google.com/news/pt0?swipe',
544 def RunNavigateSteps(self
, action_runner
):
545 action_runner
.NavigateToPage(self
)
546 action_runner
.WaitForJavaScriptCondition(
547 'document.getElementById(":h") != null')
548 action_runner
.Wait(1)
550 def RunSmoothness(self
, action_runner
):
551 interaction
= action_runner
.BeginGestureInteraction(
552 'SwipeAction', is_smooth
=True)
553 action_runner
.SwipeElement(
554 direction
='left', distance
=100,
555 element_function
='document.getElementById(":f")')
557 interaction
= action_runner
.BeginInteraction('Wait', is_smooth
=True)
558 action_runner
.Wait(1)
562 class Page26(KeySilkCasesPage
):
564 """ Why: famo.us twitter demo """
566 def __init__(self
, page_set
):
567 super(Page26
, self
).__init
__(
568 url
='http://s.codepen.io/befamous/fullpage/pFsqb?scroll',
571 def RunNavigateSteps(self
, action_runner
):
572 action_runner
.NavigateToPage(self
)
573 action_runner
.WaitForJavaScriptCondition(
574 'document.getElementsByClassName("tweet").length > 0')
575 action_runner
.Wait(1)
577 def RunSmoothness(self
, action_runner
):
578 interaction
= action_runner
.BeginGestureInteraction(
579 'ScrollAction', is_smooth
=True)
580 action_runner
.ScrollPage(distance
=5000)
584 class SVGIconRaster(KeySilkCasesPage
):
586 """ Why: Mutating SVG icons; these paint storm and paint slowly. """
588 def __init__(self
, page_set
):
589 super(SVGIconRaster
, self
).__init
__(
590 url
='http://wiltzius.github.io/shape-shifter/',
593 def RunNavigateSteps(self
, action_runner
):
594 action_runner
.NavigateToPage(self
)
595 action_runner
.WaitForJavaScriptCondition(
597 action_runner
.Wait(1)
599 def RunSmoothness(self
, action_runner
):
601 button_func
= ('document.getElementById("demo").$.'
602 'buttons.children[%d]') % i
603 interaction
= action_runner
.BeginInteraction(
604 'Action_TapAction', is_smooth
=True)
605 action_runner
.TapElement(element_function
=button_func
)
606 action_runner
.Wait(1)
610 class UpdateHistoryState(KeySilkCasesPage
):
612 """ Why: Modern apps often update history state, which currently is janky."""
614 def __init__(self
, page_set
):
615 super(UpdateHistoryState
, self
).__init
__(
616 url
='file://key_silk_cases/pushState.html',
619 def RunNavigateSteps(self
, action_runner
):
620 action_runner
.NavigateToPage(self
)
621 action_runner
.ExecuteJavaScript('''
622 window.requestAnimationFrame(function() {
623 window.__history_state_loaded = true;
626 action_runner
.WaitForJavaScriptCondition(
627 'window.__history_state_loaded == true;')
629 def RunSmoothness(self
, action_runner
):
630 interaction
= action_runner
.BeginInteraction('animation_interaction',
632 action_runner
.Wait(5) # JS runs the animation continuously on the page
636 class TextSizeAnimation(KeySilkCasesPage
):
638 """ Why: Scale animation with text. """
640 def __init__(self
, page_set
):
641 super(TextSizeAnimation
, self
).__init
__(
642 url
='http://jsbin.com/gikex/2/quiet',
645 self
.gpu_raster
= True
647 def RunSmoothness(self
, action_runner
):
648 action_runner
.Wait(4)
651 class KeySilkCasesPageSet(page_set_module
.PageSet
):
653 """ Pages hand-picked for project Silk. """
656 super(KeySilkCasesPageSet
, self
).__init
__(
657 credentials_path
='data/credentials.json',
658 user_agent_type
='mobile',
659 archive_data_file
='data/key_silk_cases.json',
660 bucket
=page_set_module
.PARTNER_BUCKET
)
662 self
.AddPage(Page1(self
))
663 self
.AddPage(Page2(self
))
664 self
.AddPage(Page3(self
))
665 self
.AddPage(Page4(self
))
666 self
.AddPage(Page5(self
))
667 self
.AddPage(Page6(self
))
668 self
.AddPage(Page7(self
))
669 self
.AddPage(Page8(self
))
670 self
.AddPage(Page9(self
))
671 self
.AddPage(Page10(self
))
672 self
.AddPage(Page11(self
))
673 self
.AddPage(Page12(self
))
674 self
.AddPage(Page13(self
))
675 self
.AddPage(Page14(self
))
676 self
.AddPage(Page15(self
))
677 self
.AddPage(Page16(self
))
678 self
.AddPage(Page17(self
))
679 self
.AddPage(Page18(self
))
681 # self.AddPage(Page19(self))
682 self
.AddPage(Page20(self
))
683 self
.AddPage(GwsGoogleExpansion(self
))
684 self
.AddPage(GwsBoogieExpansion(self
))
685 self
.AddPage(Page22(self
))
686 self
.AddPage(Page23(self
))
687 self
.AddPage(Page24(self
))
688 self
.AddPage(Page25(self
))
689 self
.AddPage(Page26(self
))
690 self
.AddPage(SVGIconRaster(self
))
691 self
.AddPage(UpdateHistoryState(self
))
692 self
.AddPage(TextSizeAnimation(self
))