1# Copyright 2016 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 5from page_sets.system_health import platforms 6from page_sets.system_health import story_tags 7 8from telemetry.page import page 9from telemetry.page import shared_page_state 10from telemetry.util import wpr_modes 11 12 13# Extra wait time after the page has loaded required by the loading metric. We 14# use it in all benchmarks to avoid divergence between benchmarks. 15# TODO(petrcermak): Switch the memory benchmarks to use it as well. 16_WAIT_TIME_AFTER_LOAD = 10 17 18 19class _SystemHealthSharedState(shared_page_state.SharedPageState): 20 """Shared state which enables disabling stories on individual platforms. 21 This should be used only to disable the stories permanently. For 22 disabling stories temporarily use story expectations in ./expectations.py. 23 """ 24 25 def CanRunOnBrowser(self, browser_info, story): 26 if (browser_info.browser_type.startswith('android-webview') and 27 story.WEBVIEW_NOT_SUPPORTED): 28 return False 29 30 if story.TAGS and story_tags.WEBGL in story.TAGS: 31 return browser_info.HasWebGLSupport() 32 return True 33 34 35class _MetaSystemHealthStory(type): 36 """Metaclass for SystemHealthStory.""" 37 38 @property 39 def ABSTRACT_STORY(cls): 40 """Class field marking whether the class is abstract. 41 42 If true, the story will NOT be instantiated and added to a System Health 43 story set. This field is NOT inherited by subclasses (that's why it's 44 defined on the metaclass). 45 """ 46 return cls.__dict__.get('ABSTRACT_STORY', False) 47 48 49class SystemHealthStory(page.Page): 50 """Abstract base class for System Health user stories.""" 51 __metaclass__ = _MetaSystemHealthStory 52 53 # The full name of a single page story has the form CASE:GROUP:PAGE:[VERSION] 54 # (e.g. 'load:search:google' or 'load:search:google:2018'). 55 NAME = NotImplemented 56 URL = NotImplemented 57 ABSTRACT_STORY = True 58 # Skip the login flow in replay mode 59 # If you want to replay the login flow in your story, set SKIP_LOGIN to False 60 SKIP_LOGIN = True 61 SUPPORTED_PLATFORMS = platforms.ALL_PLATFORMS 62 TAGS = [] 63 PLATFORM_SPECIFIC = False 64 WEBVIEW_NOT_SUPPORTED = False 65 66 def __init__(self, story_set, take_memory_measurement, 67 extra_browser_args=None): 68 case, group, _ = self.NAME.split(':', 2) 69 tags = [] 70 found_year_tag = False 71 for t in self.TAGS: # pylint: disable=not-an-iterable 72 assert t in story_tags.ALL_TAGS 73 tags.append(t.name) 74 if t in story_tags.YEAR_TAGS: 75 # Assert that this is the first year tag. 76 assert not found_year_tag, ( 77 "%s has more than one year tag found." % self.__class__.__name__) 78 found_year_tag = True 79 # Assert that there is one year tag. 80 assert found_year_tag, ( 81 "%s needs exactly one year tag." % self.__class__.__name__) 82 super(SystemHealthStory, self).__init__( 83 shared_page_state_class=_SystemHealthSharedState, 84 page_set=story_set, name=self.NAME, url=self.URL, tags=tags, 85 grouping_keys={'case': case, 'group': group}, 86 platform_specific=self.PLATFORM_SPECIFIC, 87 extra_browser_args=extra_browser_args) 88 self._take_memory_measurement = take_memory_measurement 89 90 @classmethod 91 def GetStoryDescription(cls): 92 if cls.__doc__: 93 return cls.__doc__ 94 return cls.GenerateStoryDescription() 95 96 @classmethod 97 def GenerateStoryDescription(cls): 98 """ Subclasses of SystemHealthStory can override this to auto generate 99 their story description. 100 However, it's recommended to use the Python docstring to describe the user 101 stories instead and this should only be used for very repetitive cases. 102 """ 103 return None 104 105 def _Measure(self, action_runner): 106 if self._take_memory_measurement: 107 action_runner.MeasureMemory(deterministic_mode=True) 108 else: 109 action_runner.Wait(_WAIT_TIME_AFTER_LOAD) 110 111 def _Login(self, action_runner): 112 pass 113 114 def _DidLoadDocument(self, action_runner): 115 pass 116 117 def RunNavigateSteps(self, action_runner): 118 if not (self.SKIP_LOGIN and self.wpr_mode == wpr_modes.WPR_REPLAY): 119 self._Login(action_runner) 120 super(SystemHealthStory, self).RunNavigateSteps(action_runner) 121 122 def RunPageInteractions(self, action_runner): 123 action_runner.tab.WaitForDocumentReadyStateToBeComplete() 124 self._DidLoadDocument(action_runner) 125 self._Measure(action_runner) 126 127