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
5"""Provide a TestCase base class for PageTest subclasses' unittests."""
6
7import unittest
8
9from telemetry import benchmark
10from telemetry.core import exceptions
11from telemetry.core import util
12from telemetry.page import page as page_module
13from telemetry.page import page_runner
14from telemetry.page import page_set as page_set_module
15from telemetry.page import page_test
16from telemetry.page import test_expectations
17from telemetry.results import results_options
18from telemetry.unittest import options_for_unittests
19
20
21class BasicTestPage(page_module.Page):
22  def __init__(self, url, page_set, base_dir):
23    super(BasicTestPage, self).__init__(url, page_set, base_dir)
24
25  def RunSmoothness(self, action_runner):
26    interaction = action_runner.BeginGestureInteraction(
27        'ScrollAction', is_smooth=True)
28    action_runner.ScrollPage()
29    interaction.End()
30
31
32class EmptyMetadataForTest(benchmark.BenchmarkMetadata):
33  def __init__(self):
34    super(EmptyMetadataForTest, self).__init__('')
35
36
37class PageTestTestCase(unittest.TestCase):
38  """A base class to simplify writing unit tests for PageTest subclasses."""
39
40  def CreatePageSetFromFileInUnittestDataDir(self, test_filename):
41    ps = self.CreateEmptyPageSet()
42    page = BasicTestPage('file://' + test_filename, ps, base_dir=ps.base_dir)
43    ps.AddPage(page)
44    return ps
45
46  def CreateEmptyPageSet(self):
47    base_dir = util.GetUnittestDataDir()
48    ps = page_set_module.PageSet(file_path=base_dir)
49    return ps
50
51  def RunMeasurement(self, measurement, ps,
52      expectations=test_expectations.TestExpectations(),
53      options=None):
54    """Runs a measurement against a pageset, returning the rows its outputs."""
55    if options is None:
56      options = options_for_unittests.GetCopy()
57    assert options
58    temp_parser = options.CreateParser()
59    page_runner.AddCommandLineArgs(temp_parser)
60    measurement.AddCommandLineArgs(temp_parser)
61    measurement.SetArgumentDefaults(temp_parser)
62    defaults = temp_parser.get_default_values()
63    for k, v in defaults.__dict__.items():
64      if hasattr(options, k):
65        continue
66      setattr(options, k, v)
67
68    measurement.CustomizeBrowserOptions(options.browser_options)
69    options.output_file = None
70    options.output_formats = ['none']
71    options.suppress_gtest_report = True
72    options.output_trace_tag = None
73    page_runner.ProcessCommandLineArgs(temp_parser, options)
74    measurement.ProcessCommandLineArgs(temp_parser, options)
75    results = results_options.CreateResults(EmptyMetadataForTest(), options)
76    page_runner.Run(measurement, ps, expectations, options, results)
77    return results
78
79  def TestTracingCleanedUp(self, measurement_class, options=None):
80    ps = self.CreatePageSetFromFileInUnittestDataDir('blank.html')
81    start_tracing_called = [False]
82    stop_tracing_called = [False]
83
84    class BuggyMeasurement(measurement_class):
85      def __init__(self, *args, **kwargs):
86        measurement_class.__init__(self, *args, **kwargs)
87
88      # Inject fake tracing methods to tracing_controller
89      def TabForPage(self, page, browser):
90        ActualStartTracing = browser.platform.tracing_controller.Start
91        def FakeStartTracing(*args, **kwargs):
92          ActualStartTracing(*args, **kwargs)
93          start_tracing_called[0] = True
94          raise exceptions.IntentionalException
95        browser.StartTracing = FakeStartTracing
96
97        ActualStopTracing = browser.platform.tracing_controller.Stop
98        def FakeStopTracing(*args, **kwargs):
99          result = ActualStopTracing(*args, **kwargs)
100          stop_tracing_called[0] = True
101          return result
102        browser.platform.tracing_controller.Stop = FakeStopTracing
103
104        return measurement_class.TabForPage(self, page, browser)
105
106    measurement = BuggyMeasurement()
107    try:
108      self.RunMeasurement(measurement, ps, options=options)
109    except page_test.TestNotSupportedOnPlatformFailure:
110      pass
111    if start_tracing_called[0]:
112      self.assertTrue(stop_tracing_called[0])
113