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 6 7 8 class KeySilkCasesPage(page_module.Page): 9 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' 15 16 def RunNavigateSteps(self, action_runner): 17 action_runner.NavigateToPage(self) 18 action_runner.Wait(2) 19 20 def RunSmoothness(self, action_runner): 21 interaction = action_runner.BeginGestureInteraction( 22 'ScrollAction', is_smooth=True) 23 action_runner.ScrollPage() 24 interaction.End() 25 26 27 class Page1(KeySilkCasesPage): 28 29 """ Why: Infinite scroll. Brings out all of our perf issues. """ 30 31 def __init__(self, page_set): 32 super(Page1, self).__init__( 33 url='http://groupcloned.com/test/plain/list-recycle-transform.html', 34 page_set=page_set) 35 36 def RunSmoothness(self, action_runner): 37 interaction = action_runner.BeginGestureInteraction( 38 'ScrollAction', is_smooth=True) 39 action_runner.ScrollElement(selector='#scrollable') 40 interaction.End() 41 42 43 class Page2(KeySilkCasesPage): 44 45 """ Why: Brings out layer management bottlenecks. """ 46 47 def __init__(self, page_set): 48 super(Page2, self).__init__( 49 url='http://groupcloned.com/test/plain/list-animation-simple.html', 50 page_set=page_set) 51 52 def RunSmoothness(self, action_runner): 53 action_runner.Wait(2) 54 55 56 class Page3(KeySilkCasesPage): 57 58 """ 59 Why: Best-known method for fake sticky. Janks sometimes. Interacts badly with 60 compositor scrolls. 61 """ 62 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', 67 page_set=page_set) 68 69 def RunSmoothness(self, action_runner): 70 interaction = action_runner.BeginGestureInteraction( 71 'ScrollAction', is_smooth=True) 72 action_runner.ScrollElement(selector='#container') 73 interaction.End() 74 75 76 class Page4(KeySilkCasesPage): 77 78 """ 79 Why: Card expansion: only the card should repaint, but in reality lots of 80 storms happen. 81 """ 82 83 def __init__(self, page_set): 84 super(Page4, self).__init__( 85 url='http://jsfiddle.net/3yDKh/15/show/', 86 page_set=page_set) 87 88 def RunSmoothness(self, action_runner): 89 action_runner.Wait(3) 90 91 92 class Page5(KeySilkCasesPage): 93 94 """ 95 Why: Card expansion with animated contents, using will-change on the card 96 """ 97 98 def __init__(self, page_set): 99 super(Page5, self).__init__( 100 url='http://jsfiddle.net/jx5De/14/show/', 101 page_set=page_set) 102 103 self.gpu_raster = True 104 105 def RunSmoothness(self, action_runner): 106 action_runner.Wait(4) 107 108 109 class Page6(KeySilkCasesPage): 110 111 """ 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. 114 """ 115 116 def __init__(self, page_set): 117 super(Page6, self).__init__( 118 url='http://jsfiddle.net/3yDKh/16/show/', 119 page_set=page_set) 120 121 def RunSmoothness(self, action_runner): 122 action_runner.Wait(3) 123 124 125 class Page7(KeySilkCasesPage): 126 127 """ 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. 131 """ 132 133 def __init__(self, page_set): 134 super(Page7, self).__init__( 135 url='http://jsfiddle.net/R8DX9/4/show/', 136 page_set=page_set) 137 138 def RunSmoothness(self, action_runner): 139 action_runner.Wait(3) 140 141 142 class Page8(KeySilkCasesPage): 143 144 """ 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 147 repainting. 148 """ 149 150 def __init__(self, page_set): 151 super(Page8, self).__init__( 152 url='http://jsfiddle.net/rF9Gh/7/show/', 153 page_set=page_set) 154 155 def RunSmoothness(self, action_runner): 156 action_runner.Wait(3) 157 158 159 class Page9(KeySilkCasesPage): 160 161 """ 162 Why: Horizontal and vertical expansion of a card that is cheap to layout but 163 costly to rasterize. 164 """ 165 166 def __init__(self, page_set): 167 super(Page9, self).__init__( 168 url='http://jsfiddle.net/TLXLu/3/show/', 169 page_set=page_set) 170 171 self.gpu_raster = True 172 173 def RunSmoothness(self, action_runner): 174 action_runner.Wait(4) 175 176 177 class Page10(KeySilkCasesPage): 178 179 """ 180 Why: Vertical Expansion of a card that is cheap to layout but costly to 181 rasterize. 182 """ 183 184 def __init__(self, page_set): 185 super(Page10, self).__init__( 186 url='http://jsfiddle.net/cKB9D/7/show/', 187 page_set=page_set) 188 189 self.gpu_raster = True 190 191 def RunSmoothness(self, action_runner): 192 action_runner.Wait(4) 193 194 195 class Page11(KeySilkCasesPage): 196 197 """ 198 Why: Parallax effect is common on photo-viewer-like applications, overloading 199 software rasterization 200 """ 201 202 def __init__(self, page_set): 203 super(Page11, self).__init__( 204 url='http://jsfiddle.net/vBQHH/11/show/', 205 page_set=page_set) 206 207 self.gpu_raster = True 208 209 def RunSmoothness(self, action_runner): 210 action_runner.Wait(4) 211 212 213 class Page12(KeySilkCasesPage): 214 215 """ Why: Addressing paint storms during coordinated animations. """ 216 217 def __init__(self, page_set): 218 super(Page12, self).__init__( 219 url='http://jsfiddle.net/ugkd4/10/show/', 220 page_set=page_set) 221 222 def RunSmoothness(self, action_runner): 223 action_runner.Wait(5) 224 225 226 class Page13(KeySilkCasesPage): 227 228 """ Why: Mask transitions are common mobile use cases. """ 229 230 def __init__(self, page_set): 231 super(Page13, self).__init__( 232 url='http://jsfiddle.net/xLuvC/1/show/', 233 page_set=page_set) 234 235 self.gpu_raster = True 236 237 def RunSmoothness(self, action_runner): 238 action_runner.Wait(4) 239 240 241 class Page14(KeySilkCasesPage): 242 243 """ Why: Card expansions with images and text are pretty and common. """ 244 245 def __init__(self, page_set): 246 super(Page14, self).__init__( 247 url='http://jsfiddle.net/bNp2h/3/show/', 248 page_set=page_set) 249 250 self.gpu_raster = True 251 252 def RunSmoothness(self, action_runner): 253 action_runner.Wait(4) 254 255 256 class Page15(KeySilkCasesPage): 257 258 """ Why: Coordinated animations for expanding elements. """ 259 260 def __init__(self, page_set): 261 super(Page15, self).__init__( 262 url='file://key_silk_cases/font_wipe.html', 263 page_set=page_set) 264 265 def RunSmoothness(self, action_runner): 266 action_runner.Wait(5) 267 268 269 class Page16(KeySilkCasesPage): 270 271 def __init__(self, page_set): 272 super(Page16, self).__init__( 273 url='file://key_silk_cases/inbox_app.html?swipe_to_dismiss', 274 page_set=page_set) 275 276 def RunNavigateSteps(self, action_runner): 277 action_runner.NavigateToPage(self) 278 action_runner.Wait(2) 279 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]') 287 interaction.End() 288 interaction = action_runner.BeginInteraction('Wait', is_smooth=True) 289 action_runner.WaitForJavaScriptCondition( 290 'document.getElementsByClassName("message").length < 18') 291 interaction.End() 292 293 def RunSmoothness(self, action_runner): 294 self.SwipeToDismiss(action_runner) 295 296 297 class Page17(KeySilkCasesPage): 298 299 def __init__(self, page_set): 300 super(Page17, self).__init__( 301 url='file://key_silk_cases/inbox_app.html?stress_hidey_bars', 302 page_set=page_set) 303 304 def RunNavigateSteps(self, action_runner): 305 action_runner.NavigateToPage(self) 306 action_runner.Wait(2) 307 308 def RunSmoothness(self, action_runner): 309 self.StressHideyBars(action_runner) 310 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) 316 interaction.End() 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) 321 interaction.End() 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) 326 interaction.End() 327 328 329 class Page18(KeySilkCasesPage): 330 331 def __init__(self, page_set): 332 super(Page18, self).__init__( 333 url='file://key_silk_cases/inbox_app.html?toggle_drawer', 334 page_set=page_set) 335 336 def RunNavigateSteps(self, action_runner): 337 action_runner.NavigateToPage(self) 338 action_runner.Wait(2) 339 340 def RunSmoothness(self, action_runner): 341 for _ in xrange(6): 342 self.ToggleDrawer(action_runner) 343 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) 349 interaction.End() 350 351 352 class Page19(KeySilkCasesPage): 353 354 def __init__(self, page_set): 355 super(Page19, self).__init__( 356 url='file://key_silk_cases/inbox_app.html?slide_drawer', 357 page_set=page_set) 358 359 def ToggleDrawer(self, action_runner): 360 interaction = action_runner.BeginGestureInteraction( 361 'TapAction', is_smooth=True) 362 action_runner.TapElement('#menu-button') 363 interaction.End() 364 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''') 370 interaction.End() 371 372 def RunNavigateSteps(self, action_runner): 373 action_runner.NavigateToPage(self) 374 action_runner.Wait(2) 375 self.ToggleDrawer(action_runner) 376 377 def RunSmoothness(self, action_runner): 378 self.SlideDrawer(action_runner) 379 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') 389 interaction.End() 390 391 392 class Page20(KeySilkCasesPage): 393 394 """ Why: Shadow DOM infinite scrolling. """ 395 396 def __init__(self, page_set): 397 super(Page20, self).__init__( 398 url='file://key_silk_cases/infinite_scrolling.html', 399 page_set=page_set) 400 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) 406 interaction.End() 407 408 409 class GwsExpansionPage(KeySilkCasesPage): 410 """Abstract base class for pages that expand Google knowledge panels.""" 411 412 def NavigateWait(self, action_runner): 413 action_runner.NavigateToPage(self) 414 action_runner.Wait(3) 415 416 def ExpandKnowledgeCard(self, action_runner): 417 # expand card 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) 423 interaction.End() 424 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) 429 430 def RunSmoothness(self, action_runner): 431 self.ExpandKnowledgeCard(action_runner) 432 433 434 class GwsGoogleExpansion(GwsExpansionPage): 435 436 """ Why: Animating height of a complex content card is common. """ 437 438 def __init__(self, page_set): 439 super(GwsGoogleExpansion, self).__init__( 440 url='http://www.google.com/#q=google', 441 page_set=page_set) 442 443 def RunNavigateSteps(self, action_runner): 444 self.NavigateWait(action_runner) 445 self.ScrollKnowledgeCardToTop(action_runner, 'kno-result') 446 447 448 class GwsBoogieExpansion(GwsExpansionPage): 449 450 """ Why: Same case as Google expansion but text-heavy rather than image. """ 451 452 def __init__(self, page_set): 453 super(GwsBoogieExpansion, self).__init__( 454 url='https://www.google.com/search?hl=en&q=define%3Aboogie', 455 page_set=page_set) 456 457 def RunNavigateSteps(self, action_runner): 458 self.NavigateWait(action_runner) 459 self.ScrollKnowledgeCardToTop(action_runner, 'rso') 460 461 462 class Page22(KeySilkCasesPage): 463 464 def __init__(self, page_set): 465 super(Page22, self).__init__( 466 url='http://plus.google.com/app/basic/stream', 467 page_set=page_set) 468 469 self.disabled = 'Times out on Windows; crbug.com/338838' 470 self.credentials = 'google' 471 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) 477 478 def RunSmoothness(self, action_runner): 479 interaction = action_runner.BeginGestureInteraction( 480 'ScrollAction', is_smooth=True) 481 action_runner.ScrollElement(selector='#mainContent') 482 interaction.End() 483 484 485 class Page23(KeySilkCasesPage): 486 487 """ 488 Why: Physical simulation demo that does a lot of element.style mutation 489 triggering JS and recalc slowness 490 """ 491 492 def __init__(self, page_set): 493 super(Page23, self).__init__( 494 url='http://jsbin.com/UVIgUTa/38/quiet', 495 page_set=page_set) 496 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', 502 direction='down', 503 use_touch=True) 504 interaction.End() 505 interaction = action_runner.BeginInteraction('Wait', is_smooth=True) 506 action_runner.Wait(1) 507 interaction.End() 508 509 510 class Page24(KeySilkCasesPage): 511 512 """ 513 Why: Google News: this iOS version is slower than accelerated scrolling 514 """ 515 516 def __init__(self, page_set): 517 super(Page24, self).__init__( 518 url='http://mobile-news.sandbox.google.com/news/pt0?scroll', 519 page_set=page_set) 520 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) 526 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")', 532 distance=2500, 533 use_touch=True) 534 interaction.End() 535 536 537 class Page25(KeySilkCasesPage): 538 539 def __init__(self, page_set): 540 super(Page25, self).__init__( 541 url='http://mobile-news.sandbox.google.com/news/pt0?swipe', 542 page_set=page_set) 543 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) 549 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")') 556 interaction.End() 557 interaction = action_runner.BeginInteraction('Wait', is_smooth=True) 558 action_runner.Wait(1) 559 interaction.End() 560 561 562 class Page26(KeySilkCasesPage): 563 564 """ Why: famo.us twitter demo """ 565 566 def __init__(self, page_set): 567 super(Page26, self).__init__( 568 url='http://s.codepen.io/befamous/fullpage/pFsqb?scroll', 569 page_set=page_set) 570 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) 576 577 def RunSmoothness(self, action_runner): 578 interaction = action_runner.BeginGestureInteraction( 579 'ScrollAction', is_smooth=True) 580 action_runner.ScrollPage(distance=5000) 581 interaction.End() 582 583 584 class SVGIconRaster(KeySilkCasesPage): 585 586 """ Why: Mutating SVG icons; these paint storm and paint slowly. """ 587 588 def __init__(self, page_set): 589 super(SVGIconRaster, self).__init__( 590 url='http://wiltzius.github.io/shape-shifter/', 591 page_set=page_set) 592 593 def RunNavigateSteps(self, action_runner): 594 action_runner.NavigateToPage(self) 595 action_runner.WaitForJavaScriptCondition( 596 'loaded = true') 597 action_runner.Wait(1) 598 599 def RunSmoothness(self, action_runner): 600 for i in xrange(9): 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) 607 interaction.End() 608 609 610 class UpdateHistoryState(KeySilkCasesPage): 611 612 """ Why: Modern apps often update history state, which currently is janky.""" 613 614 def __init__(self, page_set): 615 super(UpdateHistoryState, self).__init__( 616 url='file://key_silk_cases/pushState.html', 617 page_set=page_set) 618 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; 624 }); 625 ''') 626 action_runner.WaitForJavaScriptCondition( 627 'window.__history_state_loaded == true;') 628 629 def RunSmoothness(self, action_runner): 630 interaction = action_runner.BeginInteraction('animation_interaction', 631 is_smooth=True) 632 action_runner.Wait(5) # JS runs the animation continuously on the page 633 interaction.End() 634 635 636 class TextSizeAnimation(KeySilkCasesPage): 637 638 """ Why: Scale animation with text. """ 639 640 def __init__(self, page_set): 641 super(TextSizeAnimation, self).__init__( 642 url='http://jsbin.com/gikex/2/quiet', 643 page_set=page_set) 644 645 self.gpu_raster = True 646 647 def RunSmoothness(self, action_runner): 648 action_runner.Wait(4) 649 650 651 class KeySilkCasesPageSet(page_set_module.PageSet): 652 653 """ Pages hand-picked for project Silk. """ 654 655 def __init__(self): 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) 661 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)) 680 # crbug.com/404317 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)) 693