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
.credentials
= 'google'
471 def RunNavigateSteps(self
, action_runner
):
472 action_runner
.NavigateToPage(self
)
473 action_runner
.WaitForJavaScriptCondition(
474 'document.getElementsByClassName("fHa").length > 0')
475 action_runner
.Wait(2)
477 def RunSmoothness(self
, action_runner
):
478 interaction
= action_runner
.BeginGestureInteraction(
479 'ScrollAction', is_smooth
=True)
480 action_runner
.ScrollElement(selector
='#mainContent')
484 class Page23(KeySilkCasesPage
):
487 Why: Physical simulation demo that does a lot of element.style mutation
488 triggering JS and recalc slowness
491 def __init__(self
, page_set
):
492 super(Page23
, self
).__init
__(
493 url
='http://jsbin.com/UVIgUTa/38/quiet',
496 def RunSmoothness(self
, action_runner
):
497 interaction
= action_runner
.BeginGestureInteraction(
498 'ScrollAction', is_smooth
=True)
499 action_runner
.ScrollPage(
500 distance_expr
='window.innerHeight / 2',
504 interaction
= action_runner
.BeginInteraction('Wait', is_smooth
=True)
505 action_runner
.Wait(1)
509 class Page24(KeySilkCasesPage
):
512 Why: Google News: this iOS version is slower than accelerated scrolling
515 def __init__(self
, page_set
):
516 super(Page24
, self
).__init
__(
517 url
='http://mobile-news.sandbox.google.com/news/pt0?scroll',
520 def RunNavigateSteps(self
, action_runner
):
521 action_runner
.NavigateToPage(self
)
522 action_runner
.WaitForJavaScriptCondition(
523 'document.getElementById(":h") != null')
524 action_runner
.Wait(1)
526 def RunSmoothness(self
, action_runner
):
527 interaction
= action_runner
.BeginGestureInteraction(
528 'ScrollAction', is_smooth
=True)
529 action_runner
.ScrollElement(
530 element_function
='document.getElementById(":5")',
536 class Page25(KeySilkCasesPage
):
538 def __init__(self
, page_set
):
539 super(Page25
, self
).__init
__(
540 url
='http://mobile-news.sandbox.google.com/news/pt0?swipe',
543 def RunNavigateSteps(self
, action_runner
):
544 action_runner
.NavigateToPage(self
)
545 action_runner
.WaitForJavaScriptCondition(
546 'document.getElementById(":h") != null')
547 action_runner
.Wait(1)
549 def RunSmoothness(self
, action_runner
):
550 interaction
= action_runner
.BeginGestureInteraction(
551 'SwipeAction', is_smooth
=True)
552 action_runner
.SwipeElement(
553 direction
='left', distance
=100,
554 element_function
='document.getElementById(":f")')
556 interaction
= action_runner
.BeginInteraction('Wait', is_smooth
=True)
557 action_runner
.Wait(1)
561 class Page26(KeySilkCasesPage
):
563 """ Why: famo.us twitter demo """
565 def __init__(self
, page_set
):
566 super(Page26
, self
).__init
__(
567 url
='http://s.codepen.io/befamous/fullpage/pFsqb?scroll',
570 def RunNavigateSteps(self
, action_runner
):
571 action_runner
.NavigateToPage(self
)
572 action_runner
.WaitForJavaScriptCondition(
573 'document.getElementsByClassName("tweet").length > 0')
574 action_runner
.Wait(1)
576 def RunSmoothness(self
, action_runner
):
577 interaction
= action_runner
.BeginGestureInteraction(
578 'ScrollAction', is_smooth
=True)
579 action_runner
.ScrollPage(distance
=5000)
583 class SVGIconRaster(KeySilkCasesPage
):
585 """ Why: Mutating SVG icons; these paint storm and paint slowly. """
587 def __init__(self
, page_set
):
588 super(SVGIconRaster
, self
).__init
__(
589 url
='http://wiltzius.github.io/shape-shifter/',
592 def RunNavigateSteps(self
, action_runner
):
593 action_runner
.NavigateToPage(self
)
594 action_runner
.WaitForJavaScriptCondition(
596 action_runner
.Wait(1)
598 def RunSmoothness(self
, action_runner
):
600 button_func
= ('document.getElementById("demo").$.'
601 'buttons.children[%d]') % i
602 interaction
= action_runner
.BeginInteraction(
603 'Action_TapAction', is_smooth
=True)
604 action_runner
.TapElement(element_function
=button_func
)
605 action_runner
.Wait(1)
609 class UpdateHistoryState(KeySilkCasesPage
):
611 """ Why: Modern apps often update history state, which currently is janky."""
613 def __init__(self
, page_set
):
614 super(UpdateHistoryState
, self
).__init
__(
615 url
='file://key_silk_cases/pushState.html',
618 def RunNavigateSteps(self
, action_runner
):
619 action_runner
.NavigateToPage(self
)
620 action_runner
.ExecuteJavaScript('''
621 window.requestAnimationFrame(function() {
622 window.__history_state_loaded = true;
625 action_runner
.WaitForJavaScriptCondition(
626 'window.__history_state_loaded == true;')
628 def RunSmoothness(self
, action_runner
):
629 interaction
= action_runner
.BeginInteraction('animation_interaction',
631 action_runner
.Wait(5) # JS runs the animation continuously on the page
635 class TextSizeAnimation(KeySilkCasesPage
):
637 """ Why: Scale animation with text. """
639 def __init__(self
, page_set
):
640 super(TextSizeAnimation
, self
).__init
__(
641 url
='http://jsbin.com/gikex/2/quiet',
644 self
.gpu_raster
= True
646 def RunSmoothness(self
, action_runner
):
647 action_runner
.Wait(4)
650 class KeySilkCasesPageSet(page_set_module
.PageSet
):
652 """ Pages hand-picked for project Silk. """
655 super(KeySilkCasesPageSet
, self
).__init
__(
656 credentials_path
='data/credentials.json',
657 user_agent_type
='mobile',
658 archive_data_file
='data/key_silk_cases.json',
659 bucket
=page_set_module
.PARTNER_BUCKET
)
661 self
.AddPage(Page1(self
))
662 self
.AddPage(Page2(self
))
663 self
.AddPage(Page3(self
))
664 self
.AddPage(Page4(self
))
665 self
.AddPage(Page5(self
))
666 self
.AddPage(Page6(self
))
667 self
.AddPage(Page7(self
))
668 self
.AddPage(Page8(self
))
669 self
.AddPage(Page9(self
))
670 self
.AddPage(Page10(self
))
671 self
.AddPage(Page11(self
))
672 self
.AddPage(Page12(self
))
673 self
.AddPage(Page13(self
))
674 self
.AddPage(Page14(self
))
675 self
.AddPage(Page15(self
))
676 self
.AddPage(Page16(self
))
677 self
.AddPage(Page17(self
))
678 self
.AddPage(Page18(self
))
680 # self.AddPage(Page19(self))
681 self
.AddPage(Page20(self
))
682 self
.AddPage(GwsGoogleExpansion(self
))
683 self
.AddPage(GwsBoogieExpansion(self
))
684 # Times out on Windows; crbug.com/338838
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
))