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