blob: 4e9941f5840ae6579e4625ab943bc277287351c2 [file] [log] [blame]
# Copyright 2014 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from telemetry.page import page as page_module
from telemetry.page import page_set as page_set_module
class KeySilkCasesPage(page_module.Page):
def __init__(self, url, page_set):
super(KeySilkCasesPage, self).__init__(url=url, page_set=page_set)
self.credentials_path = 'data/credentials.json'
self.user_agent_type = 'mobile'
self.archive_data_file = 'data/key_silk_cases.json'
def RunNavigateSteps(self, action_runner):
action_runner.NavigateToPage(self)
action_runner.Wait(2)
def RunSmoothness(self, action_runner):
interaction = action_runner.BeginGestureInteraction(
'ScrollAction', is_smooth=True)
action_runner.ScrollPage()
interaction.End()
class Page1(KeySilkCasesPage):
""" Why: Infinite scroll. Brings out all of our perf issues. """
def __init__(self, page_set):
super(Page1, self).__init__(
url='http://groupcloned.com/test/plain/list-recycle-transform.html',
page_set=page_set)
def RunSmoothness(self, action_runner):
interaction = action_runner.BeginGestureInteraction(
'ScrollAction', is_smooth=True)
action_runner.ScrollElement(selector='#scrollable')
interaction.End()
class Page2(KeySilkCasesPage):
""" Why: Brings out layer management bottlenecks. """
def __init__(self, page_set):
super(Page2, self).__init__(
url='http://groupcloned.com/test/plain/list-animation-simple.html',
page_set=page_set)
def RunSmoothness(self, action_runner):
action_runner.Wait(2)
class Page3(KeySilkCasesPage):
"""
Why: Best-known method for fake sticky. Janks sometimes. Interacts badly with
compositor scrolls.
"""
def __init__(self, page_set):
super(Page3, self).__init__(
# pylint: disable=C0301
url='http://groupcloned.com/test/plain/sticky-using-webkit-backface-visibility.html',
page_set=page_set)
def RunSmoothness(self, action_runner):
interaction = action_runner.BeginGestureInteraction(
'ScrollAction', is_smooth=True)
action_runner.ScrollElement(selector='#container')
interaction.End()
class Page4(KeySilkCasesPage):
"""
Why: Card expansion: only the card should repaint, but in reality lots of
storms happen.
"""
def __init__(self, page_set):
super(Page4, self).__init__(
url='http://jsfiddle.net/3yDKh/15/show/',
page_set=page_set)
def RunSmoothness(self, action_runner):
action_runner.Wait(3)
class Page5(KeySilkCasesPage):
"""
Why: Card expansion with animated contents, using will-change on the card
"""
def __init__(self, page_set):
super(Page5, self).__init__(
url='http://jsfiddle.net/jx5De/14/show/',
page_set=page_set)
self.gpu_raster = True
def RunSmoothness(self, action_runner):
action_runner.Wait(4)
class Page6(KeySilkCasesPage):
"""
Why: Card fly-in: It should be fast to animate in a bunch of cards using
margin-top and letting layout do the rest.
"""
def __init__(self, page_set):
super(Page6, self).__init__(
url='http://jsfiddle.net/3yDKh/16/show/',
page_set=page_set)
def RunSmoothness(self, action_runner):
action_runner.Wait(3)
class Page7(KeySilkCasesPage):
"""
Why: Image search expands a spacer div when you click an image to accomplish
a zoomin effect. Each image has a layer. Even so, this triggers a lot of
unnecessary repainting.
"""
def __init__(self, page_set):
super(Page7, self).__init__(
url='http://jsfiddle.net/R8DX9/4/show/',
page_set=page_set)
def RunSmoothness(self, action_runner):
action_runner.Wait(3)
class Page8(KeySilkCasesPage):
"""
Why: Swipe to dismiss of an element that has a fixed-position child that is
its pseudo-sticky header. Brings out issues with layer creation and
repainting.
"""
def __init__(self, page_set):
super(Page8, self).__init__(
url='http://jsfiddle.net/rF9Gh/7/show/',
page_set=page_set)
def RunSmoothness(self, action_runner):
action_runner.Wait(3)
class Page9(KeySilkCasesPage):
"""
Why: Horizontal and vertical expansion of a card that is cheap to layout but
costly to rasterize.
"""
def __init__(self, page_set):
super(Page9, self).__init__(
url='http://jsfiddle.net/TLXLu/3/show/',
page_set=page_set)
self.gpu_raster = True
def RunSmoothness(self, action_runner):
action_runner.Wait(4)
class Page10(KeySilkCasesPage):
"""
Why: Vertical Expansion of a card that is cheap to layout but costly to
rasterize.
"""
def __init__(self, page_set):
super(Page10, self).__init__(
url='http://jsfiddle.net/cKB9D/7/show/',
page_set=page_set)
self.gpu_raster = True
def RunSmoothness(self, action_runner):
action_runner.Wait(4)
class Page11(KeySilkCasesPage):
"""
Why: Parallax effect is common on photo-viewer-like applications, overloading
software rasterization
"""
def __init__(self, page_set):
super(Page11, self).__init__(
url='http://jsfiddle.net/vBQHH/11/show/',
page_set=page_set)
self.gpu_raster = True
def RunSmoothness(self, action_runner):
action_runner.Wait(4)
class Page12(KeySilkCasesPage):
""" Why: Addressing paint storms during coordinated animations. """
def __init__(self, page_set):
super(Page12, self).__init__(
url='http://jsfiddle.net/ugkd4/10/show/',
page_set=page_set)
def RunSmoothness(self, action_runner):
action_runner.Wait(5)
class Page13(KeySilkCasesPage):
""" Why: Mask transitions are common mobile use cases. """
def __init__(self, page_set):
super(Page13, self).__init__(
url='http://jsfiddle.net/xLuvC/1/show/',
page_set=page_set)
self.gpu_raster = True
def RunSmoothness(self, action_runner):
action_runner.Wait(4)
class Page14(KeySilkCasesPage):
""" Why: Card expansions with images and text are pretty and common. """
def __init__(self, page_set):
super(Page14, self).__init__(
url='http://jsfiddle.net/bNp2h/3/show/',
page_set=page_set)
self.gpu_raster = True
def RunSmoothness(self, action_runner):
action_runner.Wait(4)
class Page15(KeySilkCasesPage):
""" Why: Coordinated animations for expanding elements. """
def __init__(self, page_set):
super(Page15, self).__init__(
url='file://key_silk_cases/font_wipe.html',
page_set=page_set)
def RunSmoothness(self, action_runner):
action_runner.Wait(5)
class Page16(KeySilkCasesPage):
def __init__(self, page_set):
super(Page16, self).__init__(
url='file://key_silk_cases/inbox_app.html?swipe_to_dismiss',
page_set=page_set)
def RunNavigateSteps(self, action_runner):
action_runner.NavigateToPage(self)
action_runner.Wait(2)
def SwipeToDismiss(self, action_runner):
interaction = action_runner.BeginGestureInteraction(
'SwipeAction', is_smooth=True)
action_runner.SwipeElement(
left_start_ratio=0.8, top_start_ratio=0.2,
direction='left', distance=200, speed_in_pixels_per_second=5000,
element_function='document.getElementsByClassName("message")[2]')
interaction.End()
interaction = action_runner.BeginInteraction('Wait', is_smooth=True)
action_runner.WaitForJavaScriptCondition(
'document.getElementsByClassName("message").length < 18')
interaction.End()
def RunSmoothness(self, action_runner):
self.SwipeToDismiss(action_runner)
class Page17(KeySilkCasesPage):
def __init__(self, page_set):
super(Page17, self).__init__(
url='file://key_silk_cases/inbox_app.html?stress_hidey_bars',
page_set=page_set)
def RunNavigateSteps(self, action_runner):
action_runner.NavigateToPage(self)
action_runner.Wait(2)
def RunSmoothness(self, action_runner):
self.StressHideyBars(action_runner)
def StressHideyBars(self, action_runner):
interaction = action_runner.BeginGestureInteraction(
'ScrollAction', is_smooth=True)
action_runner.ScrollElement(
selector='#messages', direction='down', speed_in_pixels_per_second=200)
interaction.End()
interaction = action_runner.BeginGestureInteraction(
'ScrollAction', is_smooth=True)
action_runner.ScrollElement(
selector='#messages', direction='up', speed_in_pixels_per_second=200)
interaction.End()
interaction = action_runner.BeginGestureInteraction(
'ScrollAction', is_smooth=True)
action_runner.ScrollElement(
selector='#messages', direction='down', speed_in_pixels_per_second=200)
interaction.End()
class Page18(KeySilkCasesPage):
def __init__(self, page_set):
super(Page18, self).__init__(
url='file://key_silk_cases/inbox_app.html?toggle_drawer',
page_set=page_set)
def RunNavigateSteps(self, action_runner):
action_runner.NavigateToPage(self)
action_runner.Wait(2)
def RunSmoothness(self, action_runner):
for _ in xrange(6):
self.ToggleDrawer(action_runner)
def ToggleDrawer(self, action_runner):
interaction = action_runner.BeginInteraction(
'Action_TapAction', is_smooth=True)
action_runner.TapElement('#menu-button')
action_runner.Wait(1)
interaction.End()
class Page19(KeySilkCasesPage):
def __init__(self, page_set):
super(Page19, self).__init__(
url='file://key_silk_cases/inbox_app.html?slide_drawer',
page_set=page_set)
def ToggleDrawer(self, action_runner):
interaction = action_runner.BeginGestureInteraction(
'TapAction', is_smooth=True)
action_runner.TapElement('#menu-button')
interaction.End()
interaction = action_runner.BeginInteraction('Wait', is_smooth=True)
action_runner.WaitForJavaScriptCondition(
'document.getElementById("nav-drawer").active')
interaction.End()
def RunNavigateSteps(self, action_runner):
action_runner.NavigateToPage(self)
action_runner.Wait(2)
self.ToggleDrawer(action_runner)
def RunSmoothness(self, action_runner):
self.SlideDrawer(action_runner)
def SlideDrawer(self, action_runner):
interaction = action_runner.BeginInteraction(
'Action_SwipeAction', is_smooth=True)
action_runner.SwipeElement(
left_start_ratio=0.8, top_start_ratio=0.2,
direction='left', distance=200,
element_function='document.getElementById("nav-drawer").children[0]')
action_runner.WaitForJavaScriptCondition(
'!document.getElementById("nav-drawer").active')
interaction.End()
class Page20(KeySilkCasesPage):
""" Why: Shadow DOM infinite scrolling. """
def __init__(self, page_set):
super(Page20, self).__init__(
url='file://key_silk_cases/infinite_scrolling.html',
page_set=page_set)
def RunSmoothness(self, action_runner):
interaction = action_runner.BeginGestureInteraction(
'ScrollAction', is_smooth=True)
action_runner.ScrollElement(
selector='#container', speed_in_pixels_per_second=5000)
interaction.End()
class Page21(KeySilkCasesPage):
def __init__(self, page_set):
super(Page21, self).__init__(
url='http://www.google.com/#q=google',
page_set=page_set)
def ScrollKnowledgeCardToTop(self, action_runner):
# scroll until the knowledge card is at the top
action_runner.ScrollPage(
distance_expr='''
(function() {
var el = document.getElementById('kno-result');
var bound = el.getBoundingClientRect();
return bound.top - document.body.scrollTop;
})()''')
def ExpandKnowledgeCard(self, action_runner):
# expand card
interaction = action_runner.BeginInteraction(
'Action_TapAction', is_smooth=True)
action_runner.TapElement(
element_function='document.getElementsByClassName("vk_arc")[0]')
action_runner.Wait(2)
interaction.End()
def RunNavigateSteps(self, action_runner):
action_runner.NavigateToPage(self)
action_runner.Wait(3)
self.ScrollKnowledgeCardToTop(action_runner)
def RunSmoothness(self, action_runner):
self.ExpandKnowledgeCard(action_runner)
class Page22(KeySilkCasesPage):
def __init__(self, page_set):
super(Page22, self).__init__(
url='http://plus.google.com/app/basic/stream',
page_set=page_set)
self.disabled = 'Times out on Windows; crbug.com/338838'
self.credentials = 'google'
def RunNavigateSteps(self, action_runner):
action_runner.NavigateToPage(self)
action_runner.WaitForJavaScriptCondition(
'document.getElementsByClassName("fHa").length > 0')
action_runner.Wait(2)
def RunSmoothness(self, action_runner):
interaction = action_runner.BeginGestureInteraction(
'ScrollAction', is_smooth=True)
action_runner.ScrollElement(selector='#mainContent')
interaction.End()
class Page23(KeySilkCasesPage):
"""
Why: Physical simulation demo that does a lot of element.style mutation
triggering JS and recalc slowness
"""
def __init__(self, page_set):
super(Page23, self).__init__(
url='http://jsbin.com/UVIgUTa/38/quiet',
page_set=page_set)
def RunSmoothness(self, action_runner):
interaction = action_runner.BeginGestureInteraction(
'ScrollAction', is_smooth=True)
action_runner.ScrollPage(
distance_expr='window.innerHeight / 2',
direction='down',
use_touch=True)
interaction.End()
interaction = action_runner.BeginInteraction('Wait', is_smooth=True)
action_runner.Wait(1)
interaction.End()
class Page24(KeySilkCasesPage):
"""
Why: Google News: this iOS version is slower than accelerated scrolling
"""
def __init__(self, page_set):
super(Page24, self).__init__(
url='http://mobile-news.sandbox.google.com/news/pt0?scroll',
page_set=page_set)
def RunNavigateSteps(self, action_runner):
action_runner.NavigateToPage(self)
action_runner.WaitForJavaScriptCondition(
'document.getElementById(":h") != null')
action_runner.Wait(1)
def RunSmoothness(self, action_runner):
interaction = action_runner.BeginGestureInteraction(
'ScrollAction', is_smooth=True)
action_runner.ScrollElement(
element_function='document.getElementById(":5")',
distance=2500,
use_touch=True)
interaction.End()
class Page25(KeySilkCasesPage):
def __init__(self, page_set):
super(Page25, self).__init__(
url='http://mobile-news.sandbox.google.com/news/pt0?swipe',
page_set=page_set)
def RunNavigateSteps(self, action_runner):
action_runner.NavigateToPage(self)
action_runner.WaitForJavaScriptCondition(
'document.getElementById(":h") != null')
action_runner.Wait(1)
def RunSmoothness(self, action_runner):
interaction = action_runner.BeginGestureInteraction(
'SwipeAction', is_smooth=True)
action_runner.SwipeElement(
direction='left', distance=100,
element_function='document.getElementById(":f")')
interaction.End()
interaction = action_runner.BeginInteraction('Wait', is_smooth=True)
action_runner.Wait(1)
interaction.End()
class Page26(KeySilkCasesPage):
""" Why: famo.us twitter demo """
def __init__(self, page_set):
super(Page26, self).__init__(
url='http://s.codepen.io/befamous/fullpage/pFsqb?scroll',
page_set=page_set)
def RunNavigateSteps(self, action_runner):
action_runner.NavigateToPage(self)
action_runner.WaitForJavaScriptCondition(
'document.getElementsByClassName("tweet").length > 0')
action_runner.Wait(1)
def RunSmoothness(self, action_runner):
interaction = action_runner.BeginGestureInteraction(
'ScrollAction', is_smooth=True)
action_runner.ScrollPage(distance=5000)
interaction.End()
class SVGIconRaster(KeySilkCasesPage):
""" Why: Mutating SVG icons; these paint storm and paint slowly. """
def __init__(self, page_set):
super(SVGIconRaster, self).__init__(
url='http://wiltzius.github.io/shape-shifter/',
page_set=page_set)
def RunNavigateSteps(self, action_runner):
action_runner.NavigateToPage(self)
action_runner.WaitForJavaScriptCondition(
'loaded = true')
action_runner.Wait(1)
def RunSmoothness(self, action_runner):
for i in xrange(9):
button_func = ('document.getElementById("demo").$.'
'buttons.children[%d]') % i
interaction = action_runner.BeginInteraction(
'Action_TapAction', is_smooth=True)
action_runner.TapElement(element_function=button_func)
action_runner.Wait(1)
interaction.End()
class UpdateHistoryState(KeySilkCasesPage):
""" Why: Modern apps often update history state, which currently is janky."""
def __init__(self, page_set):
super(UpdateHistoryState, self).__init__(
url='file://key_silk_cases/pushState.html',
page_set=page_set)
def RunNavigateSteps(self, action_runner):
action_runner.NavigateToPage(self)
action_runner.ExecuteJavaScript('''
window.requestAnimationFrame(function() {
window.__history_state_loaded = true;
});
''')
action_runner.WaitForJavaScriptCondition(
'window.__history_state_loaded == true;')
def RunSmoothness(self, action_runner):
interaction = action_runner.BeginInteraction('animation_interaction',
is_smooth=True)
action_runner.Wait(5) # JS runs the animation continuously on the page
interaction.End()
class KeySilkCasesPageSet(page_set_module.PageSet):
""" Pages hand-picked for project Silk. """
def __init__(self):
super(KeySilkCasesPageSet, self).__init__(
credentials_path='data/credentials.json',
user_agent_type='mobile',
archive_data_file='data/key_silk_cases.json',
bucket=page_set_module.PARTNER_BUCKET)
self.AddPage(Page1(self))
self.AddPage(Page2(self))
self.AddPage(Page3(self))
self.AddPage(Page4(self))
self.AddPage(Page5(self))
self.AddPage(Page6(self))
self.AddPage(Page7(self))
self.AddPage(Page8(self))
self.AddPage(Page9(self))
self.AddPage(Page10(self))
self.AddPage(Page11(self))
self.AddPage(Page12(self))
self.AddPage(Page13(self))
self.AddPage(Page14(self))
self.AddPage(Page15(self))
self.AddPage(Page16(self))
self.AddPage(Page17(self))
self.AddPage(Page18(self))
self.AddPage(Page19(self))
self.AddPage(Page20(self))
self.AddPage(Page21(self))
self.AddPage(Page22(self))
self.AddPage(Page23(self))
self.AddPage(Page24(self))
self.AddPage(Page25(self))
self.AddPage(Page26(self))
self.AddPage(SVGIconRaster(self))
self.AddPage(UpdateHistoryState(self))