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# pylint: disable=W0401,W0614 5from telemetry.page.actions.all_page_actions import * 6from telemetry.page import page as page_module 7from telemetry.page import page_set as page_set_module 8 9 10class KeySilkCasesPage(page_module.Page): 11 12 def __init__(self, url, page_set): 13 super(KeySilkCasesPage, self).__init__(url=url, page_set=page_set) 14 self.credentials_path = 'data/credentials.json' 15 self.user_agent_type = 'mobile' 16 self.archive_data_file = 'data/key_silk_cases.json' 17 18 def RunNavigateSteps(self, action_runner): 19 action_runner.NavigateToPage(self) 20 action_runner.Wait(2) 21 22 def RunSmoothness(self, action_runner): 23 action_runner.RunAction(ScrollAction()) 24 25 26class Page1(KeySilkCasesPage): 27 28 """ Why: Infinite scroll. Brings out all of our perf issues. """ 29 30 def __init__(self, page_set): 31 super(Page1, self).__init__( 32 url='http://groupcloned.com/test/plain/list-recycle-transform.html', 33 page_set=page_set) 34 35 def RunSmoothness(self, action_runner): 36 action_runner.RunAction(ScrollAction( 37 { 38 'scrollable_element_function': ''' 39 function(callback) { 40 callback(document.getElementById('scrollable')); 41 }''' 42 })) 43 44 45class Page2(KeySilkCasesPage): 46 47 """ Why: Brings out layer management bottlenecks. """ 48 49 def __init__(self, page_set): 50 super(Page2, self).__init__( 51 url='http://groupcloned.com/test/plain/list-animation-simple.html', 52 page_set=page_set) 53 54 def RunSmoothness(self, action_runner): 55 action_runner.Wait(2) 56 57 58class Page3(KeySilkCasesPage): 59 60 """ 61 Why: Best-known method for fake sticky. Janks sometimes. Interacts badly with 62 compositor scrolls. 63 """ 64 65 def __init__(self, page_set): 66 super(Page3, self).__init__( 67 # pylint: disable=C0301 68 url='http://groupcloned.com/test/plain/sticky-using-webkit-backface-visibility.html', 69 page_set=page_set) 70 71 def RunSmoothness(self, action_runner): 72 action_runner.RunAction(ScrollAction( 73 { 74 'scrollable_element_function': ''' 75 function(callback) { 76 callback(document.getElementById('container')); 77 }''' 78 })) 79 80 81class Page4(KeySilkCasesPage): 82 83 """ 84 Why: Card expansion: only the card should repaint, but in reality lots of 85 storms happen. 86 """ 87 88 def __init__(self, page_set): 89 super(Page4, self).__init__( 90 url='http://jsfiddle.net/3yDKh/15/show/', 91 page_set=page_set) 92 93 def RunSmoothness(self, action_runner): 94 action_runner.Wait(3) 95 96 97class Page5(KeySilkCasesPage): 98 99 """ 100 Why: Card expansion with animated contents, using will-change on the card 101 """ 102 103 def __init__(self, page_set): 104 super(Page5, self).__init__( 105 url='http://jsfiddle.net/jx5De/14/show/', 106 page_set=page_set) 107 108 self.gpu_raster = True 109 110 def RunSmoothness(self, action_runner): 111 action_runner.Wait(4) 112 113 114class Page6(KeySilkCasesPage): 115 116 """ 117 Why: Card fly-in: It should be fast to animate in a bunch of cards using 118 margin-top and letting layout do the rest. 119 """ 120 121 def __init__(self, page_set): 122 super(Page6, self).__init__( 123 url='http://jsfiddle.net/3yDKh/16/show/', 124 page_set=page_set) 125 126 def RunSmoothness(self, action_runner): 127 action_runner.Wait(3) 128 129 130class Page7(KeySilkCasesPage): 131 132 """ 133 Why: Image search expands a spacer div when you click an image to accomplish 134 a zoomin effect. Each image has a layer. Even so, this triggers a lot of 135 unnecessary repainting. 136 """ 137 138 def __init__(self, page_set): 139 super(Page7, self).__init__( 140 url='http://jsfiddle.net/R8DX9/4/show/', 141 page_set=page_set) 142 143 def RunSmoothness(self, action_runner): 144 action_runner.Wait(3) 145 146 147class Page8(KeySilkCasesPage): 148 149 """ 150 Why: Swipe to dismiss of an element that has a fixed-position child that is 151 its pseudo-sticky header. Brings out issues with layer creation and 152 repainting. 153 """ 154 155 def __init__(self, page_set): 156 super(Page8, self).__init__( 157 url='http://jsfiddle.net/rF9Gh/7/show/', 158 page_set=page_set) 159 160 def RunSmoothness(self, action_runner): 161 action_runner.Wait(3) 162 163 164class Page9(KeySilkCasesPage): 165 166 """ 167 Why: Horizontal and vertical expansion of a card that is cheap to layout but 168 costly to rasterize. 169 """ 170 171 def __init__(self, page_set): 172 super(Page9, self).__init__( 173 url='http://jsfiddle.net/TLXLu/3/show/', 174 page_set=page_set) 175 176 self.gpu_raster = True 177 178 def RunSmoothness(self, action_runner): 179 action_runner.Wait(4) 180 181 182class Page10(KeySilkCasesPage): 183 184 """ 185 Why: Vertical Expansion of a card that is cheap to layout but costly to 186 rasterize. 187 """ 188 189 def __init__(self, page_set): 190 super(Page10, self).__init__( 191 url='http://jsfiddle.net/cKB9D/7/show/', 192 page_set=page_set) 193 194 self.gpu_raster = True 195 196 def RunSmoothness(self, action_runner): 197 action_runner.Wait(4) 198 199 200class Page11(KeySilkCasesPage): 201 202 """ 203 Why: Parallax effect is common on photo-viewer-like applications, overloading 204 software rasterization 205 """ 206 207 def __init__(self, page_set): 208 super(Page11, self).__init__( 209 url='http://jsfiddle.net/vBQHH/11/show/', 210 page_set=page_set) 211 212 self.gpu_raster = True 213 214 def RunSmoothness(self, action_runner): 215 action_runner.Wait(4) 216 217 218class Page12(KeySilkCasesPage): 219 220 """ Why: Addressing paint storms during coordinated animations. """ 221 222 def __init__(self, page_set): 223 super(Page12, self).__init__( 224 url='http://jsfiddle.net/ugkd4/10/show/', 225 page_set=page_set) 226 227 def RunSmoothness(self, action_runner): 228 action_runner.Wait(5) 229 230 231class Page13(KeySilkCasesPage): 232 233 """ Why: Mask transitions are common mobile use cases. """ 234 235 def __init__(self, page_set): 236 super(Page13, self).__init__( 237 url='http://jsfiddle.net/xLuvC/1/show/', 238 page_set=page_set) 239 240 self.gpu_raster = True 241 242 def RunSmoothness(self, action_runner): 243 action_runner.Wait(4) 244 245 246class Page14(KeySilkCasesPage): 247 248 """ Why: Card expansions with images and text are pretty and common. """ 249 250 def __init__(self, page_set): 251 super(Page14, self).__init__( 252 url='http://jsfiddle.net/bNp2h/3/show/', 253 page_set=page_set) 254 255 self.gpu_raster = True 256 257 def RunSmoothness(self, action_runner): 258 action_runner.Wait(4) 259 260 261class Page15(KeySilkCasesPage): 262 263 """ Why: Coordinated animations for expanding elements. """ 264 265 def __init__(self, page_set): 266 super(Page15, self).__init__( 267 url='file://key_silk_cases/font_wipe.html', 268 page_set=page_set) 269 270 def RunSmoothness(self, action_runner): 271 action_runner.Wait(5) 272 273 274class Page16(KeySilkCasesPage): 275 276 def __init__(self, page_set): 277 super(Page16, self).__init__( 278 url='file://key_silk_cases/inbox_app.html?swipe_to_dismiss', 279 page_set=page_set) 280 281 def RunNavigateSteps(self, action_runner): 282 action_runner.NavigateToPage(self) 283 action_runner.Wait(2) 284 285 def SwipeToDismiss(self, action_runner): 286 interaction = action_runner.BeginGestureInteraction( 287 'SwipeAction', is_smooth=True) 288 action_runner.SwipeElement( 289 left_start_ratio=0.8, top_start_ratio=0.2, 290 direction='left', distance=200, speed=5000, 291 element_function='document.getElementsByClassName("message")[2]') 292 interaction.End() 293 interaction = action_runner.BeginInteraction('Wait', is_smooth=True) 294 action_runner.WaitForJavaScriptCondition( 295 'document.getElementsByClassName("message").length < 18') 296 interaction.End() 297 298 def RunSmoothness(self, action_runner): 299 self.SwipeToDismiss(action_runner) 300 301 302class Page17(KeySilkCasesPage): 303 304 def __init__(self, page_set): 305 super(Page17, self).__init__( 306 url='file://key_silk_cases/inbox_app.html?stress_hidey_bars', 307 page_set=page_set) 308 309 def RunNavigateSteps(self, action_runner): 310 action_runner.NavigateToPage(self) 311 action_runner.Wait(2) 312 313 def RunSmoothness(self, action_runner): 314 self.StressHideyBars(action_runner) 315 316 def StressHideyBars(self, action_runner): 317 action_runner.RunAction(ScrollAction( 318 { 319 'direction': 'down', 320 'speed': 200, 321 'scrollable_element_function': ''' 322 function(callback) { 323 callback(document.getElementById('messages')); 324 }''' 325 })) 326 action_runner.RunAction(ScrollAction( 327 { 328 'direction': 'up', 329 'speed': 200, 330 'scrollable_element_function': ''' 331 function(callback) { 332 callback(document.getElementById('messages')); 333 }''' 334 })) 335 action_runner.RunAction(ScrollAction( 336 { 337 'direction': 'down', 338 'speed': 200, 339 'scrollable_element_function': ''' 340 function(callback) { 341 callback(document.getElementById('messages')); 342 }''' 343 })) 344 345 346class Page18(KeySilkCasesPage): 347 348 def __init__(self, page_set): 349 super(Page18, self).__init__( 350 url='file://key_silk_cases/inbox_app.html?toggle_drawer', 351 page_set=page_set) 352 353 def RunNavigateSteps(self, action_runner): 354 action_runner.NavigateToPage(self) 355 action_runner.Wait(2) 356 357 def RunSmoothness(self, action_runner): 358 for _ in xrange(6): 359 self.ToggleDrawer(action_runner) 360 361 def ToggleDrawer(self, action_runner): 362 interaction = action_runner.BeginInteraction( 363 'Action_TapAction', is_smooth=True) 364 action_runner.TapElement('#menu-button') 365 action_runner.Wait(1) 366 interaction.End() 367 368 369class Page19(KeySilkCasesPage): 370 371 def __init__(self, page_set): 372 super(Page19, self).__init__( 373 url='file://key_silk_cases/inbox_app.html?slide_drawer', 374 page_set=page_set) 375 376 def ToggleDrawer(self, action_runner): 377 interaction = action_runner.BeginGestureInteraction( 378 'TapAction', is_smooth=True) 379 action_runner.TapElement('#menu-button') 380 interaction.End() 381 382 interaction = action_runner.BeginInteraction('Wait', is_smooth=True) 383 action_runner.WaitForJavaScriptCondition( 384 'document.getElementById("nav-drawer").active') 385 interaction.End() 386 387 388 def RunNavigateSteps(self, action_runner): 389 action_runner.NavigateToPage(self) 390 action_runner.Wait(2) 391 self.ToggleDrawer(action_runner) 392 393 def RunSmoothness(self, action_runner): 394 self.SlideDrawer(action_runner) 395 396 def SlideDrawer(self, action_runner): 397 interaction = action_runner.BeginInteraction( 398 'Action_SwipeAction', is_smooth=True) 399 action_runner.SwipeElement( 400 left_start_ratio=0.8, top_start_ratio=0.2, 401 direction='left', distance=200, 402 element_function='document.getElementById("nav-drawer").children[0]') 403 action_runner.WaitForJavaScriptCondition( 404 '!document.getElementById("nav-drawer").active') 405 interaction.End() 406 407 408class Page20(KeySilkCasesPage): 409 410 """ Why: Shadow DOM infinite scrolling. """ 411 412 def __init__(self, page_set): 413 super(Page20, self).__init__( 414 url='file://key_silk_cases/infinite_scrolling.html', 415 page_set=page_set) 416 417 def RunSmoothness(self, action_runner): 418 action_runner.RunAction(ScrollAction( 419 { 420 'speed': 5000, 421 'scrollable_element_function': ''' 422 function(callback) { 423 callback(document.getElementById('container')); 424 }''' 425 })) 426 427 428class Page21(KeySilkCasesPage): 429 430 def __init__(self, page_set): 431 super(Page21, self).__init__( 432 url='http://www.google.com/#q=google', 433 page_set=page_set) 434 435 def ScrollKnowledgeCardToTop(self, action_runner): 436 # scroll until the knowledge card is at the top 437 action_runner.RunAction(ScrollAction( 438 { 439 'scroll_distance_function': ''' 440 function() { 441 var el = document.getElementById('kno-result'); 442 var bound = el.getBoundingClientRect(); 443 return bound.top - document.body.scrollTop; 444 } 445 ''' 446 })) 447 448 def ExpandKnowledgeCard(self, action_runner): 449 # expand card 450 interaction = action_runner.BeginInteraction( 451 'Action_TapAction', is_smooth=True) 452 action_runner.TapElement( 453 element_function='document.getElementsByClassName("vk_arc")[0]') 454 action_runner.Wait(2) 455 interaction.End() 456 457 458 def RunNavigateSteps(self, action_runner): 459 action_runner.NavigateToPage(self) 460 action_runner.Wait(3) 461 self.ScrollKnowledgeCardToTop(action_runner) 462 463 def RunSmoothness(self, action_runner): 464 self.ExpandKnowledgeCard(action_runner) 465 466 467class Page22(KeySilkCasesPage): 468 469 def __init__(self, page_set): 470 super(Page22, self).__init__( 471 url='http://plus.google.com/app/basic/stream', 472 page_set=page_set) 473 474 self.disabled = 'Times out on Windows; crbug.com/338838' 475 self.credentials = 'google' 476 477 def RunNavigateSteps(self, action_runner): 478 action_runner.NavigateToPage(self) 479 action_runner.WaitForJavaScriptCondition( 480 'document.getElementsByClassName("fHa").length > 0') 481 action_runner.Wait(2) 482 483 def RunSmoothness(self, action_runner): 484 action_runner.RunAction(ScrollAction( 485 { 486 'scrollable_element_function': ''' 487 function(callback) { 488 callback(document.getElementById('mainContent')); 489 }''' 490 })) 491 492 493class Page23(KeySilkCasesPage): 494 495 """ 496 Why: Physical simulation demo that does a lot of element.style mutation 497 triggering JS and recalc slowness 498 """ 499 500 def __init__(self, page_set): 501 super(Page23, self).__init__( 502 url='http://jsbin.com/UVIgUTa/38/quiet', 503 page_set=page_set) 504 505 def RunSmoothness(self, action_runner): 506 action_runner.RunAction(ScrollAction( 507 { 508 'direction': 'down', 509 'scroll_requires_touch': True, 510 'scroll_distance_function': 511 'function() { return window.innerHeight / 2; }' 512 })) 513 interaction = action_runner.BeginInteraction('Wait', is_smooth=True) 514 action_runner.Wait(1) 515 interaction.End() 516 517 518class Page24(KeySilkCasesPage): 519 520 """ 521 Why: Google News: this iOS version is slower than accelerated scrolling 522 """ 523 524 def __init__(self, page_set): 525 super(Page24, self).__init__( 526 url='http://mobile-news.sandbox.google.com/news/pt0?scroll', 527 page_set=page_set) 528 529 def RunNavigateSteps(self, action_runner): 530 action_runner.NavigateToPage(self) 531 action_runner.WaitForJavaScriptCondition( 532 'document.getElementById(":h") != null') 533 action_runner.Wait(1) 534 535 def RunSmoothness(self, action_runner): 536 action_runner.RunAction(ScrollAction( 537 { 538 'scroll_distance_function': 'function() { return 2500; }', 539 'scrollable_element_function': 540 'function(callback) { callback(document.getElementById(":5")); }', 541 'scroll_requires_touch': True 542 })) 543 544 545class Page25(KeySilkCasesPage): 546 547 def __init__(self, page_set): 548 super(Page25, self).__init__( 549 url='http://mobile-news.sandbox.google.com/news/pt0?swipe', 550 page_set=page_set) 551 552 def RunNavigateSteps(self, action_runner): 553 action_runner.NavigateToPage(self) 554 action_runner.WaitForJavaScriptCondition( 555 'document.getElementById(":h") != null') 556 action_runner.Wait(1) 557 558 def RunSmoothness(self, action_runner): 559 interaction = action_runner.BeginGestureInteraction( 560 'SwipeAction', is_smooth=True) 561 action_runner.SwipeElement( 562 direction='left', distance=100, 563 element_function='document.getElementById(":f")') 564 interaction.End() 565 interaction = action_runner.BeginInteraction('Wait', is_smooth=True) 566 action_runner.Wait(1) 567 interaction.End() 568 569 570class Page26(KeySilkCasesPage): 571 572 """ Why: famo.us twitter demo """ 573 574 def __init__(self, page_set): 575 super(Page26, self).__init__( 576 url='http://s.codepen.io/befamous/fullpage/pFsqb?scroll', 577 page_set=page_set) 578 579 def RunNavigateSteps(self, action_runner): 580 action_runner.NavigateToPage(self) 581 action_runner.WaitForJavaScriptCondition( 582 'document.getElementsByClassName("tweet").length > 0') 583 action_runner.Wait(1) 584 585 def RunSmoothness(self, action_runner): 586 action_runner.RunAction(ScrollAction( 587 { 588 'scroll_distance_function': 'function() { return 5000; }' 589 })) 590 591 592class KeySilkCasesPageSet(page_set_module.PageSet): 593 594 """ Pages hand-picked for project Silk. """ 595 596 def __init__(self): 597 super(KeySilkCasesPageSet, self).__init__( 598 credentials_path='data/credentials.json', 599 user_agent_type='mobile', 600 archive_data_file='data/key_silk_cases.json', 601 bucket=page_set_module.PARTNER_BUCKET) 602 603 self.AddPage(Page1(self)) 604 self.AddPage(Page2(self)) 605 self.AddPage(Page3(self)) 606 self.AddPage(Page4(self)) 607 self.AddPage(Page5(self)) 608 self.AddPage(Page6(self)) 609 self.AddPage(Page7(self)) 610 self.AddPage(Page8(self)) 611 self.AddPage(Page9(self)) 612 self.AddPage(Page10(self)) 613 self.AddPage(Page11(self)) 614 self.AddPage(Page12(self)) 615 self.AddPage(Page13(self)) 616 self.AddPage(Page14(self)) 617 self.AddPage(Page15(self)) 618 self.AddPage(Page16(self)) 619 self.AddPage(Page17(self)) 620 self.AddPage(Page18(self)) 621 self.AddPage(Page19(self)) 622 self.AddPage(Page20(self)) 623 self.AddPage(Page21(self)) 624 self.AddPage(Page22(self)) 625 self.AddPage(Page23(self)) 626 self.AddPage(Page24(self)) 627 self.AddPage(Page25(self)) 628 self.AddPage(Page26(self)) 629