| # Copyright 2018 The Chromium Authors |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| from telemetry.page import page as page_module |
| |
| |
| class PressStory(page_module.Page): |
| """Base class for Press stories. |
| |
| Override ExecuteTest to execute javascript on the page and |
| ParseTestResults to obtain javascript metrics from page. |
| |
| Example Implementation: |
| |
| class FooPressStory: |
| URL = 'http://example.com/foo_story' |
| NAME = 'FooStory' |
| |
| def ExecuteTest(self, action_runner): |
| // Execute some javascript |
| |
| def ParseTestResults(self, action_runner): |
| js_code = 'some_js_expression;' |
| self.AddJavaScriptMeasurement(name, unit, js_code) |
| |
| """ |
| URL = None |
| DETERMINISTIC_JS = False |
| NAME = None |
| |
| def __init__(self, |
| page_set, |
| tags=None, |
| extra_browser_args=None, |
| url=None, |
| name=None): |
| super(PressStory, |
| self).__init__(url or self.URL, |
| page_set, |
| base_dir=page_set.base_dir, |
| make_javascript_deterministic=self.DETERMINISTIC_JS, |
| name=name or self.NAME or self.URL, |
| tags=self.PreprocessTags(tags), |
| extra_browser_args=extra_browser_args) |
| self._measurements = [] |
| self._action_runner = None |
| |
| def PreprocessTags(self, tags=None): |
| if tags is None: |
| tags = [] |
| else: |
| assert 'all' not in tags |
| tags.append('all') |
| return tags |
| |
| def AddMeasurement(self, name, unit, samples, description=None): |
| """Record an ad-hoc measurement. |
| |
| Args: |
| name: A string with the name of the measurement (e.g. 'score', 'runtime', |
| etc). |
| unit: A string specifying the unit used for measurements (e.g. 'ms', |
| 'count', etc). |
| samples: Either a single numeric value or a list of numeric values to |
| record as part of this measurement. |
| description: An optional string with a short human readable description |
| of the measurement. |
| """ |
| # TODO(crbug.com/40642835): Ideally, these should be recorded directly into |
| # the results object, rather than held on this temporary list. That needs, |
| # however, another slight refactor to make the results object available at |
| # this point. |
| self._measurements.append({'name': name, 'unit': unit, 'samples': samples, |
| 'description': description}) |
| |
| def AddJavaScriptMeasurement(self, name, unit, code, **kwargs): |
| """Run some JavaScript to obtain and record an ad-hoc measurements. |
| |
| Args: |
| name: A string with the name of the measurement (e.g. 'score', 'runtime', |
| etc). |
| unit: A string specifying the unit used for measurements (e.g. 'ms', |
| 'count', etc). |
| code: A piece of JavaScript code to run on the current tab, it must |
| return either a single or a list of numeric values. These are the |
| values for the measurement to be recorded. |
| description: An optional string with a short human readable description |
| of the measurement. |
| Other keyword arguments provide values to be interpolated within |
| the JavaScript code. See telemetry.util.js_template for details. |
| """ |
| description = kwargs.pop('description', None) |
| samples = self._action_runner.EvaluateJavaScript(code, **kwargs) |
| self.AddMeasurement(name, unit, samples, description) |
| |
| def GetMeasurements(self): |
| return self._measurements |
| |
| def Run(self, shared_state): |
| self._measurements = [] |
| super(PressStory, self).Run(shared_state) |
| |
| def ExecuteTest(self, action_runner): |
| pass |
| |
| def ParseTestResults(self, action_runner): |
| pass |
| |
| def RunPageInteractions(self, action_runner): |
| self._action_runner = action_runner |
| try: |
| self.ExecuteTest(action_runner) |
| self.ParseTestResults(action_runner) |
| finally: |
| self._action_runner = None |