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.
4from telemetry.page import shared_page_state
5from telemetry import story
6
7from page_sets.rendering import rendering_story
8from page_sets.system_health import platforms
9from page_sets.rendering import story_tags
10
11
12class KeySilkPage(rendering_story.RenderingStory):
13  """ Base class for all key silk cases pages."""
14
15  ABSTRACT_STORY = True
16  SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
17  TAGS = [story_tags.KEY_SILK]
18
19  def __init__(self,
20               page_set,
21               shared_page_state_class=shared_page_state.SharedMobilePageState,
22               name_suffix='',
23               extra_browser_args=None):
24    super(KeySilkPage, self).__init__(
25        page_set=page_set,
26        shared_page_state_class=shared_page_state_class,
27        name_suffix=name_suffix,
28        extra_browser_args=extra_browser_args)
29
30  def RunNavigateSteps(self, action_runner):
31    super(KeySilkPage, self).RunNavigateSteps(action_runner)
32    action_runner.Wait(2)
33
34  def RunPageInteractions(self, action_runner):
35    # If a key silk case page wants to customize it actions, it should
36    # overrides the PerformPageInteractions method instead of this method.
37    self.PerformPageInteractions(action_runner)
38
39  def PerformPageInteractions(self, action_runner):
40    """ Perform interactions on page after navigate steps.
41    Override this to define custom actions to be run after navigate steps.
42    """
43    with action_runner.CreateGestureInteraction('ScrollAction'):
44      action_runner.ScrollPage()
45
46
47class Page1(KeySilkPage):
48
49  """ Why: Infinite scroll. Brings out all of our perf issues. """
50
51  BASE_NAME = 'list_recycle_transform'
52  URL = 'http://groupcloned.com/test/plain/list-recycle-transform.html'
53
54  def PerformPageInteractions(self, action_runner):
55    with action_runner.CreateGestureInteraction('ScrollAction'):
56      action_runner.ScrollElement(selector='#scrollable')
57
58
59class Page2(KeySilkPage):
60
61  """ Why: Brings out layer management bottlenecks. """
62
63  BASE_NAME = 'list_animation_simple'
64  URL = 'file://../key_silk_cases/list_animation_simple.html'
65
66  def PerformPageInteractions(self, action_runner):
67    with action_runner.CreateInteraction('SimpleAnimation'):
68      action_runner.Wait(2)
69
70
71class Page3(KeySilkPage):
72
73  """
74  Why: Best-known method for fake sticky. Janks sometimes. Interacts badly with
75  compositor scrolls.
76  """
77
78  BASE_NAME = 'sticky_using_webkit'
79  # pylint: disable=line-too-long
80  URL = 'http://groupcloned.com/test/plain/sticky-using-webkit-backface-visibility.html'
81
82  def PerformPageInteractions(self, action_runner):
83    with action_runner.CreateGestureInteraction('ScrollAction'):
84      action_runner.ScrollElement(selector='#container')
85
86
87class Page4(KeySilkPage):
88
89  """
90  Why: Card expansion: only the card should repaint, but in reality lots of
91  storms happen.
92  """
93
94  BASE_NAME = 'card_expansion'
95  URL = 'http://jsfiddle.net/3yDKh/15/show/'
96
97  def PerformPageInteractions(self, action_runner):
98    with action_runner.CreateInteraction('CardExpansionAnimation'):
99      action_runner.Wait(3)
100
101
102class Page5(KeySilkPage):
103
104  """
105  Why: Card expansion with animated contents, using will-change on the card
106  """
107
108  BASE_NAME = 'card_expansion_animated'
109  URL = 'http://jsfiddle.net/jx5De/14/show/'
110
111  def __init__(self,
112               page_set,
113               shared_page_state_class=shared_page_state.SharedMobilePageState,
114               name_suffix='',
115               extra_browser_args=None):
116    super(Page5, self).__init__(
117        page_set=page_set,
118        shared_page_state_class=shared_page_state_class,
119        name_suffix=name_suffix,
120        extra_browser_args=extra_browser_args)
121
122    self.gpu_raster = True
123
124  def PerformPageInteractions(self, action_runner):
125    with action_runner.CreateInteraction('CardExpansionAnimation'):
126      action_runner.Wait(4)
127
128
129class Page6(KeySilkPage):
130
131  """
132  Why: Card fly-in: It should be fast to animate in a bunch of cards using
133  margin-top and letting layout do the rest.
134  """
135
136  BASE_NAME = 'card_flying'
137  URL = 'http://jsfiddle.net/3yDKh/16/show/'
138
139  def PerformPageInteractions(self, action_runner):
140    with action_runner.CreateInteraction('CardFlyingAnimation'):
141      action_runner.Wait(3)
142
143
144class Page7(KeySilkPage):
145
146  """
147  Why: Image search expands a spacer div when you click an image to accomplish
148  a zoomin effect. Each image has a layer. Even so, this triggers a lot of
149  unnecessary repainting.
150  """
151
152  BASE_NAME = 'zoom_in_animation'
153  URL = 'http://jsfiddle.net/R8DX9/4/show/'
154
155  def PerformPageInteractions(self, action_runner):
156    with action_runner.CreateInteraction('ZoominAnimation'):
157      action_runner.Wait(3)
158
159
160class Page8(KeySilkPage):
161
162  """
163  Why: Swipe to dismiss of an element that has a fixed-position child that is
164  its pseudo-sticky header. Brings out issues with layer creation and
165  repainting.
166  """
167
168  BASE_NAME = 'swipe_to_dismiss'
169  URL = 'http://jsfiddle.net/rF9Gh/7/show/'
170
171  def PerformPageInteractions(self, action_runner):
172    with action_runner.CreateInteraction('SwipeToDismissAnimation'):
173      action_runner.Wait(3)
174
175
176class Page9(KeySilkPage):
177
178  """
179  Why: Horizontal and vertical expansion of a card that is cheap to layout but
180  costly to rasterize.
181  """
182
183  BASE_NAME = 'horizontal_vertical_expansion'
184  URL = 'http://jsfiddle.net/TLXLu/3/show/'
185
186  def __init__(self,
187               page_set,
188               shared_page_state_class=shared_page_state.SharedMobilePageState,
189               name_suffix='',
190               extra_browser_args=None):
191    super(Page9, self).__init__(
192        page_set=page_set,
193        shared_page_state_class=shared_page_state_class,
194        name_suffix=name_suffix,
195        extra_browser_args=extra_browser_args)
196
197    self.gpu_raster = True
198
199  def PerformPageInteractions(self, action_runner):
200    with action_runner.CreateInteraction('CardExpansionAnimation'):
201      action_runner.Wait(4)
202
203
204class Page10(KeySilkPage):
205
206  """
207  Why: Vertical Expansion of a card that is cheap to layout but costly to
208  rasterize.
209  """
210
211  BASE_NAME = 'vertical_expansion'
212  URL = 'http://jsfiddle.net/cKB9D/7/show/'
213
214  def __init__(self,
215               page_set,
216               shared_page_state_class=shared_page_state.SharedMobilePageState,
217               name_suffix='',
218               extra_browser_args=None):
219    super(Page10, self).__init__(
220        page_set=page_set,
221        shared_page_state_class=shared_page_state_class,
222        name_suffix=name_suffix,
223        extra_browser_args=extra_browser_args)
224
225    self.gpu_raster = True
226
227  def PerformPageInteractions(self, action_runner):
228    with action_runner.CreateInteraction('CardExpansionAnimation'):
229      action_runner.Wait(4)
230
231
232class Page11(KeySilkPage):
233
234  """
235  Why: Parallax effect is common on photo-viewer-like applications, overloading
236  software rasterization
237  """
238
239  BASE_NAME = 'parallax_effect'
240  URL = 'http://jsfiddle.net/vBQHH/11/show/'
241
242  def __init__(self,
243               page_set,
244               shared_page_state_class=shared_page_state.SharedMobilePageState,
245               name_suffix='',
246               extra_browser_args=None):
247    super(Page11, self).__init__(
248        page_set=page_set,
249        shared_page_state_class=shared_page_state_class,
250        name_suffix=name_suffix,
251        extra_browser_args=extra_browser_args)
252
253    self.gpu_raster = True
254
255  def PerformPageInteractions(self, action_runner):
256    with action_runner.CreateInteraction('ParallaxAnimation'):
257      action_runner.Wait(4)
258
259
260class Page12(KeySilkPage):
261
262  """ Why: Addressing paint storms during coordinated animations. """
263
264  BASE_NAME = 'coordinated_animation'
265  URL = 'http://jsfiddle.net/ugkd4/10/show/'
266
267  def PerformPageInteractions(self, action_runner):
268    with action_runner.CreateInteraction('CoordinatedAnimation'):
269      action_runner.Wait(5)
270
271
272class Page13(KeySilkPage):
273
274  """ Why: Mask transitions are common mobile use cases. """
275
276  BASE_NAME = 'mask_transition_animation'
277  URL = 'http://jsfiddle.net/xLuvC/1/show/'
278
279  def __init__(self,
280               page_set,
281               shared_page_state_class=shared_page_state.SharedMobilePageState,
282               name_suffix='',
283               extra_browser_args=None):
284    super(Page13, self).__init__(
285        page_set=page_set,
286        shared_page_state_class=shared_page_state_class,
287        name_suffix=name_suffix,
288        extra_browser_args=extra_browser_args)
289
290    self.gpu_raster = True
291
292  def PerformPageInteractions(self, action_runner):
293    with action_runner.CreateInteraction('MaskTransitionAnimation'):
294      action_runner.Wait(4)
295
296
297class Page14(KeySilkPage):
298
299  """ Why: Card expansions with images and text are pretty and common. """
300
301  BASE_NAME = 'card_expansion_images_text'
302  URL = 'http://jsfiddle.net/bNp2h/3/show/'
303
304  def __init__(self,
305               page_set,
306               shared_page_state_class=shared_page_state.SharedMobilePageState,
307               name_suffix='',
308               extra_browser_args=None):
309    super(Page14, self).__init__(
310        page_set=page_set,
311        shared_page_state_class=shared_page_state_class,
312        name_suffix=name_suffix,
313        extra_browser_args=extra_browser_args)
314
315    self.gpu_raster = True
316
317  def PerformPageInteractions(self, action_runner):
318    with action_runner.CreateInteraction('CardExpansionAnimation'):
319      action_runner.Wait(4)
320
321
322class Page15(KeySilkPage):
323
324  """ Why: Coordinated animations for expanding elements. """
325
326  BASE_NAME = 'font_wipe'
327  URL = 'file://../key_silk_cases/font_wipe.html'
328
329  def PerformPageInteractions(self, action_runner):
330    with action_runner.CreateInteraction('CoordinatedAnimation'):
331      action_runner.Wait(5)
332
333
334class Page16(KeySilkPage):
335
336  BASE_NAME = 'swipe_action'
337  URL = 'file://../key_silk_cases/inbox_app.html?swipe_to_dismiss'
338
339  def SwipeToDismiss(self, action_runner):
340    with action_runner.CreateGestureInteraction('SwipeAction'):
341      action_runner.SwipeElement(
342          left_start_ratio=0.8, top_start_ratio=0.2,
343          direction='left', distance=400, speed_in_pixels_per_second=5000,
344          element_function='document.getElementsByClassName("message")[2]')
345
346  def PerformPageInteractions(self, action_runner):
347    self.SwipeToDismiss(action_runner)
348
349
350class Page17(KeySilkPage):
351
352  BASE_NAME = 'stress_hidey_bars'
353  URL = 'file://../key_silk_cases/inbox_app.html?stress_hidey_bars'
354
355  def PerformPageInteractions(self, action_runner):
356    self.StressHideyBars(action_runner)
357
358  def StressHideyBars(self, action_runner):
359    with action_runner.CreateGestureInteraction(
360        'ScrollAction', repeatable=True):
361      action_runner.WaitForElement(selector='#messages')
362      action_runner.ScrollElement(
363        selector='#messages', direction='down', speed_in_pixels_per_second=200)
364    with action_runner.CreateGestureInteraction(
365        'ScrollAction', repeatable=True):
366      action_runner.WaitForElement(selector='#messages')
367      action_runner.ScrollElement(
368          selector='#messages', direction='up', speed_in_pixels_per_second=200)
369    with action_runner.CreateGestureInteraction(
370        'ScrollAction', repeatable=True):
371      action_runner.WaitForElement(selector='#messages')
372      action_runner.ScrollElement(
373          selector='#messages', direction='down',
374          speed_in_pixels_per_second=200)
375
376
377class Page18(KeySilkPage):
378
379  BASE_NAME = 'toggle_drawer'
380  URL = 'file://../key_silk_cases/inbox_app.html?toggle_drawer'
381
382  def PerformPageInteractions(self, action_runner):
383    for _ in xrange(6):
384      self.ToggleDrawer(action_runner)
385
386  def ToggleDrawer(self, action_runner):
387    with action_runner.CreateInteraction('Action_TapAction', repeatable=True):
388      action_runner.TapElement('#menu-button')
389      action_runner.Wait(1)
390
391
392class Page19(KeySilkPage):
393
394  BASE_NAME = 'slide_drawer'
395  URL = 'file://../key_silk_cases/inbox_app.html?slide_drawer'
396
397  def ToggleDrawer(self, action_runner):
398    with action_runner.CreateGestureInteraction('TapAction'):
399      action_runner.TapElement('#menu-button')
400
401    with action_runner.CreateInteraction('Wait'):
402      action_runner.WaitForJavaScriptCondition('''
403          document.getElementById("nav-drawer").active &&
404          document.getElementById("nav-drawer").children[0]
405              .getBoundingClientRect().left == 0''')
406
407  def RunNavigateSteps(self, action_runner):
408    super(Page19, self).RunNavigateSteps(action_runner)
409    action_runner.Wait(2)
410    self.ToggleDrawer(action_runner)
411
412  def PerformPageInteractions(self, action_runner):
413    self.SlideDrawer(action_runner)
414
415  def SlideDrawer(self, action_runner):
416    with action_runner.CreateInteraction('Action_SwipeAction'):
417      action_runner.SwipeElement(
418          left_start_ratio=0.8, top_start_ratio=0.2,
419          direction='left', distance=200,
420          element_function='document.getElementById("nav-drawer").children[0]')
421      action_runner.WaitForJavaScriptCondition(
422          '!document.getElementById("nav-drawer").active')
423
424
425class Page20(KeySilkPage):
426
427  """ Why: Shadow DOM infinite scrolling. """
428
429  BASE_NAME = 'infinite_scrolling'
430  URL = 'file://../key_silk_cases/infinite_scrolling.html'
431
432  def PerformPageInteractions(self, action_runner):
433    with action_runner.CreateGestureInteraction('ScrollAction'):
434      action_runner.ScrollElement(
435          selector='#container', speed_in_pixels_per_second=5000)
436
437
438class GwsExpansionPage(KeySilkPage):
439
440  """Abstract base class for pages that expand Google knowledge panels."""
441
442  ABSTRACT_STORY = True
443
444  def NavigateWait(self, action_runner):
445    super(GwsExpansionPage, self).RunNavigateSteps(action_runner)
446    action_runner.Wait(3)
447
448  def ExpandKnowledgeCard(self, action_runner):
449    # expand card
450    with action_runner.CreateInteraction('Action_TapAction'):
451      action_runner.TapElement(
452          element_function='document.getElementsByClassName("vk_arc")[0]')
453      action_runner.Wait(2)
454
455  def ScrollKnowledgeCardToTop(self, action_runner, card_id):
456    # scroll until the knowledge card is at the top
457    action_runner.ExecuteJavaScript(
458        "document.getElementById({{ card_id }}).scrollIntoView()",
459        card_id=card_id)
460
461  def PerformPageInteractions(self, action_runner):
462    self.ExpandKnowledgeCard(action_runner)
463
464
465class GwsGoogleExpansion(GwsExpansionPage):
466
467  """ Why: Animating height of a complex content card is common. """
468
469  BASE_NAME = 'gws_google_expansion'
470  URL = 'http://www.google.com/#q=google'
471
472  def RunNavigateSteps(self, action_runner):
473    self.NavigateWait(action_runner)
474    self.ScrollKnowledgeCardToTop(action_runner, 'kno-result')
475
476
477class GwsBoogieExpansion(GwsExpansionPage):
478
479  """ Why: Same case as Google expansion but text-heavy rather than image. """
480
481  BASE_NAME = 'gws_boogie_expansion'
482  URL = 'https://www.google.com/search?hl=en&q=define%3Aboogie'
483
484  def RunNavigateSteps(self, action_runner):
485    self.NavigateWait(action_runner)
486    self.ScrollKnowledgeCardToTop(action_runner, 'rso')
487
488
489class Page22(KeySilkPage):
490
491  BASE_NAME = 'basic_stream'
492  URL = 'http://plus.google.com/app/basic/stream'
493
494  def RunNavigateSteps(self, action_runner):
495    super(Page22, self).RunNavigateSteps(action_runner)
496    action_runner.WaitForJavaScriptCondition(
497        'document.getElementsByClassName("fHa").length > 0')
498    action_runner.Wait(2)
499
500  def PerformPageInteractions(self, action_runner):
501    with action_runner.CreateGestureInteraction('ScrollAction'):
502      action_runner.ScrollElement(selector='#mainContent')
503
504
505class Page23(KeySilkPage):
506
507  """
508  Why: Physical simulation demo that does a lot of element.style mutation
509  triggering JS and recalc slowness
510  """
511
512  BASE_NAME = 'physical_simulation'
513  URL = 'file://../key_silk_cases/physical_simulation.html'
514
515  def PerformPageInteractions(self, action_runner):
516    with action_runner.CreateGestureInteraction('ScrollAction',
517                                                repeatable=True):
518      action_runner.ScrollPage(
519          distance_expr='window.innerHeight / 2',
520          direction='down',
521          use_touch=True)
522    with action_runner.CreateGestureInteraction('ScrollAction',
523                                                repeatable=True):
524      action_runner.Wait(1)
525
526
527class Page24(KeySilkPage):
528
529  """
530  Why: Google News: this iOS version is slower than accelerated scrolling
531  """
532
533  BASE_NAME = 'google_news_ios'
534  URL = 'http://mobile-news.sandbox.google.com/news/pt0?scroll'
535
536  def RunNavigateSteps(self, action_runner):
537    super(Page24, self).RunNavigateSteps(action_runner)
538    action_runner.WaitForJavaScriptCondition(
539        'document.getElementById(":h") != null')
540    action_runner.Wait(1)
541
542  def PerformPageInteractions(self, action_runner):
543    with action_runner.CreateGestureInteraction('ScrollAction'):
544      action_runner.ScrollElement(
545          element_function='document.getElementById(":5")',
546          distance=2500,
547          use_touch=True)
548
549
550class Page25(KeySilkPage):
551
552  BASE_NAME = 'mobile_news_sandbox'
553  URL = 'http://mobile-news.sandbox.google.com/news/pt0?swipe'
554
555  def RunNavigateSteps(self, action_runner):
556    super(Page25, self).RunNavigateSteps(action_runner)
557    action_runner.WaitForJavaScriptCondition(
558        'document.getElementById(":h") != null')
559    action_runner.Wait(1)
560
561  def PerformPageInteractions(self, action_runner):
562    with action_runner.CreateGestureInteraction('SwipeAction', repeatable=True):
563      action_runner.SwipeElement(
564          direction='left', distance=100,
565          element_function='document.getElementById(":f")')
566    with action_runner.CreateGestureInteraction('SwipeAction', repeatable=True):
567      action_runner.Wait(1)
568
569
570class Page26(KeySilkPage):
571
572  """ Why: famo.us twitter demo """
573
574  BASE_NAME = 'famo_us_twitter_demo'
575  URL = 'http://s.codepen.io/befamous/fullpage/pFsqb?scroll'
576
577  def RunNavigateSteps(self, action_runner):
578    super(Page26, self).RunNavigateSteps(action_runner)
579    action_runner.WaitForJavaScriptCondition(
580        'document.getElementsByClassName("tweet").length > 0')
581    action_runner.Wait(1)
582
583  def PerformPageInteractions(self, action_runner):
584    # Add a touch-action: none because this page prevent defaults all
585    # touch moves.
586    action_runner.ExecuteJavaScript('''
587        var style = document.createElement("style");
588        document.head.appendChild(style);
589        style.sheet.insertRule("body { touch-action: none }", 0);
590        ''')
591    with action_runner.CreateGestureInteraction('ScrollAction'):
592      action_runner.ScrollPage(distance=5000)
593
594
595class SVGIconRaster(KeySilkPage):
596
597  """ Why: Mutating SVG icons; these paint storm and paint slowly. """
598
599  BASE_NAME = 'svg_icon_raster'
600  URL = 'http://wiltzius.github.io/shape-shifter/'
601
602  def RunNavigateSteps(self, action_runner):
603    super(SVGIconRaster, self).RunNavigateSteps(action_runner)
604    action_runner.WaitForJavaScriptCondition(
605        'loaded = true')
606    action_runner.Wait(1)
607
608  def PerformPageInteractions(self, action_runner):
609    for i in xrange(9):
610      button_func = ('document.getElementById("demo").$.'
611                     'buttons.children[%d]') % i
612      with action_runner.CreateInteraction('Action_TapAction', repeatable=True):
613        action_runner.TapElement(element_function=button_func)
614        action_runner.Wait(1)
615
616
617class UpdateHistoryState(KeySilkPage):
618
619  """ Why: Modern apps often update history state, which currently is janky."""
620
621  BASE_NAME = 'update_history_state'
622  URL = 'file://../key_silk_cases/pushState.html'
623
624  def RunNavigateSteps(self, action_runner):
625    super(UpdateHistoryState, self).RunNavigateSteps(action_runner)
626    action_runner.ExecuteJavaScript('''
627        window.requestAnimationFrame(function() {
628            window.__history_state_loaded = true;
629          });
630        ''')
631    action_runner.WaitForJavaScriptCondition(
632        'window.__history_state_loaded == true;')
633
634  def PerformPageInteractions(self, action_runner):
635    with action_runner.CreateInteraction('animation_interaction'):
636      action_runner.Wait(5) # JS runs the animation continuously on the page
637
638
639class SilkFinance(KeySilkPage):
640
641  """ Why: Some effects repaint the page, possibly including plenty of text. """
642
643  BASE_NAME = 'silk_finance'
644  URL = 'file://../key_silk_cases/silk_finance.html'
645
646  def PerformPageInteractions(self, action_runner):
647    with action_runner.CreateInteraction('animation_interaction'):
648      action_runner.Wait(10) # animation runs automatically
649
650
651class PolymerTopeka(KeySilkPage):
652
653  """ Why: Sample Polymer app. """
654
655  BASE_NAME = 'polymer_topeka'
656  URL = 'https://polymer-topeka.appspot.com/'
657
658  def PerformPageInteractions(self, action_runner):
659    profile = 'html /deep/ topeka-profile /deep/ '
660    first_name = profile + 'paper-input#first /deep/ input'
661    action_runner.WaitForElement(selector=first_name)
662    # Input First Name:
663    action_runner.ExecuteJavaScript('''
664        var fn = document.querySelector({{ first_name }});
665        fn.value = 'Chrome';
666        fn.fire('input');''',
667        first_name=first_name)
668    # Input Last Initial:
669    action_runner.ExecuteJavaScript('''
670        var li = document.querySelector({{ selector }});
671        li.value = 'E';
672        li.fire('input');''',
673        selector='%s paper-input#last /deep/ input' % profile)
674    with action_runner.CreateInteraction('animation_interaction'):
675      # Click the check-mark to login:
676      action_runner.ExecuteJavaScript('''
677          window.topeka_page_transitions = 0;
678          [].forEach.call(document.querySelectorAll(
679              'html /deep/ core-animated-pages'), function(p){
680                  p.addEventListener(
681                      'core-animated-pages-transition-end', function(e) {
682                          window.topeka_page_transitions++;
683                      });
684              });
685          document.querySelector({{ selector }}).fire('tap')''',
686          selector='%s paper-fab' % profile)
687      # Wait for category list to animate in:
688      action_runner.WaitForJavaScriptCondition('''
689          window.topeka_page_transitions === 1''')
690      # Click a category to start a quiz:
691      action_runner.ExecuteJavaScript('''
692          document.querySelector('\
693              html /deep/ core-selector.category-list').fire(
694              'tap',1,document.querySelector('html /deep/ \
695                      div.category-item.red-theme'));''')
696      # Wait for the category splash to animate in:
697      action_runner.WaitForJavaScriptCondition('''
698          window.topeka_page_transitions === 2''')
699      # Click to start the quiz:
700      action_runner.ExecuteJavaScript('''
701          document.querySelector('html /deep/ topeka-category-front-page /deep/\
702              paper-fab').fire('tap');''')
703      action_runner.WaitForJavaScriptCondition('''
704          window.topeka_page_transitions === 4''')
705      # Input a mostly correct answer:
706      action_runner.ExecuteJavaScript('''
707          document.querySelector('html /deep/ topeka-quiz-fill-blank /deep/\
708              input').value = 'arkinsaw';
709          document.querySelector('html /deep/ topeka-quiz-fill-blank /deep/\
710              input').fire('input');
711          document.querySelector('html /deep/ topeka-quizzes /deep/ \
712              paper-fab').fire('tap');''')
713      action_runner.WaitForJavaScriptCondition('''
714          window.topeka_page_transitions === 6''')
715
716class Masonry(KeySilkPage):
717
718  """ Why: Popular layout hack. """
719
720  BASE_NAME = 'masonry'
721  URL = 'file://../key_silk_cases/masonry.html'
722
723  def PerformPageInteractions(self, action_runner):
724    with action_runner.CreateInteraction('animation_interaction'):
725      action_runner.ExecuteJavaScript('window.brick()')
726      action_runner.WaitForJavaScriptCondition('window.done')
727
728
729# TODO(crbug.com/760553):remove this class after smoothness.key_silk_cases
730# benchmark is completely replaced by rendering benchmarks
731class KeySilkCasesPageSet(story.StorySet):
732
733  """ Pages hand-picked for project Silk. """
734
735  def __init__(self):
736    super(KeySilkCasesPageSet, self).__init__(
737      archive_data_file='../data/key_silk_cases.json',
738      cloud_storage_bucket=story.PARTNER_BUCKET)
739
740    page_classes = [
741      Page1,
742      Page2,
743      Page3,
744      Page4,
745      Page5,
746      Page6,
747      Page7,
748      Page8,
749      Page9,
750      Page10,
751      Page11,
752      Page12,
753      Page13,
754      Page14,
755      Page15,
756      Page16,
757      Page17,
758      # Missing frames during tap interaction; crbug.com/446332
759      Page18,
760      Page19,
761      Page20,
762      GwsGoogleExpansion,
763      GwsBoogieExpansion,
764      # Times out on Windows; crbug.com/338838,
765      Page22,
766      Page23,
767      Page24,
768      Page25,
769      Page26,
770      SVGIconRaster,
771      UpdateHistoryState,
772      SilkFinance,
773      # Flaky interaction steps on Android; crbug.com/507865,
774      PolymerTopeka,
775      Masonry
776    ]
777
778    for page_class in page_classes:
779      self.AddStory(page_class(self))
780
781    for page in self:
782      assert (page.__class__.RunPageInteractions ==
783              KeySilkPage.RunPageInteractions), (
784              'Pages in this page set must not override KeySilkPage\' '
785              'RunPageInteractions method.')
786