| # Copyright 2016 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import six |
| |
| from page_sets.system_health import platforms |
| from page_sets.system_health import story_tags |
| |
| from telemetry.page import page as page_module |
| from telemetry.page import shared_page_state |
| from telemetry.util import wpr_modes |
| |
| |
| # Extra wait time after the page has loaded required by the loading metric. We |
| # use it in all benchmarks to avoid divergence between benchmarks. |
| # TODO(petrcermak): Switch the memory benchmarks to use it as well. |
| _WAIT_TIME_AFTER_LOAD = 10 |
| |
| |
| class _SystemHealthSharedState(shared_page_state.SharedPageState): |
| """Shared state which enables disabling stories on individual platforms. |
| This should be used only to disable the stories permanently. For |
| disabling stories temporarily use story expectations in ./expectations.py. |
| """ |
| |
| def CanRunOnBrowser(self, browser_info, page): |
| if (browser_info.browser_type.startswith('android-webview') |
| and page.WEBVIEW_NOT_SUPPORTED): |
| return False |
| |
| if page.TAGS and story_tags.WEBGL in page.TAGS: |
| return browser_info.HasWebGLSupport() |
| return True |
| |
| |
| class _MetaSystemHealthStory(type): |
| """Metaclass for SystemHealthStory.""" |
| |
| @property |
| def ABSTRACT_STORY(cls): |
| """Class field marking whether the class is abstract. |
| |
| If true, the story will NOT be instantiated and added to a System Health |
| story set. This field is NOT inherited by subclasses (that's why it's |
| defined on the metaclass). |
| """ |
| return cls.__dict__.get('ABSTRACT_STORY', False) |
| |
| |
| class SystemHealthStory( |
| six.with_metaclass(_MetaSystemHealthStory, page_module.Page)): |
| """Abstract base class for System Health user stories.""" |
| |
| # The full name of a single page story has the form CASE:GROUP:PAGE:[VERSION] |
| # (e.g. 'load:search:google' or 'load:search:google:2018'). |
| NAME = NotImplemented |
| URL = NotImplemented |
| ABSTRACT_STORY = True |
| # Skip the login flow in replay mode |
| # If you want to replay the login flow in your story, set SKIP_LOGIN to False |
| SKIP_LOGIN = True |
| SUPPORTED_PLATFORMS = platforms.ALL_PLATFORMS |
| TAGS = [] |
| PLATFORM_SPECIFIC = False |
| WEBVIEW_NOT_SUPPORTED = False |
| |
| def __init__(self, story_set, take_memory_measurement, |
| extra_browser_args=None): |
| case, group, _ = self.NAME.split(':', 2) |
| tags = [] |
| found_year_tag = False |
| for t in self.TAGS: # pylint: disable=not-an-iterable |
| assert t in story_tags.ALL_TAGS |
| tags.append(t.name) |
| if t in story_tags.YEAR_TAGS: |
| # Assert that this is the first year tag. |
| assert not found_year_tag, ( |
| "%s has more than one year tag found." % self.__class__.__name__) |
| found_year_tag = True |
| # Assert that there is one year tag. |
| assert found_year_tag, ( |
| "%s needs exactly one year tag." % self.__class__.__name__) |
| super(SystemHealthStory, self).__init__( |
| shared_page_state_class=_SystemHealthSharedState, |
| page_set=story_set, name=self.NAME, url=self.URL, tags=tags, |
| grouping_keys={'case': case, 'group': group}, |
| platform_specific=self.PLATFORM_SPECIFIC, |
| extra_browser_args=extra_browser_args) |
| self._take_memory_measurement = take_memory_measurement |
| |
| @classmethod |
| def GetStoryDescription(cls): |
| if cls.__doc__: |
| return cls.__doc__ |
| return cls.GenerateStoryDescription() |
| |
| @classmethod |
| def GenerateStoryDescription(cls): |
| """ Subclasses of SystemHealthStory can override this to auto generate |
| their story description. |
| However, it's recommended to use the Python docstring to describe the user |
| stories instead and this should only be used for very repetitive cases. |
| """ |
| return None |
| |
| def _Measure(self, action_runner): |
| if self._take_memory_measurement: |
| action_runner.MeasureMemory(deterministic_mode=True) |
| else: |
| action_runner.Wait(_WAIT_TIME_AFTER_LOAD) |
| |
| def _Login(self, action_runner): |
| pass |
| |
| def _DidLoadDocument(self, action_runner): |
| pass |
| |
| def RunNavigateSteps(self, action_runner): |
| if not (self.SKIP_LOGIN and self.wpr_mode == wpr_modes.WPR_REPLAY): |
| self._Login(action_runner) |
| super(SystemHealthStory, self).RunNavigateSteps(action_runner) |
| |
| def RunPageInteractions(self, action_runner): |
| action_runner.tab.WaitForDocumentReadyStateToBeComplete() |
| self._DidLoadDocument(action_runner) |
| self._Measure(action_runner) |