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