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
5import os
6import sys
7
8from telemetry import benchmark
9from telemetry import decorators
10from telemetry.core import util
11from telemetry.core import wpr_modes
12from telemetry.page import page as page_module
13from telemetry.page import page_set as page_set_module
14from telemetry.page import page_test
15from telemetry.page import record_wpr
16from telemetry.unittest import tab_test_case
17
18
19class MockPage(page_module.Page):
20  def __init__(self, page_set, url):
21    super(MockPage, self).__init__(url=url,
22                                   page_set=page_set,
23                                   base_dir=util.GetUnittestDataDir())
24    self.func_calls = []
25
26  def RunNavigateSteps(self, action_runner):
27    self.func_calls.append('RunNavigateSteps')
28    super(MockPage, self).RunNavigateSteps(action_runner)
29
30  def RunFoo(self, _):
31    self.func_calls.append('RunFoo')
32
33  def RunBar(self, _):
34    self.func_calls.append('RunBar')
35
36  def RunBaz(self, _):
37    self.func_calls.append('RunBaz')
38
39
40class MockPageSet(page_set_module.PageSet):
41  def __init__(self, url=''):
42    super(MockPageSet, self).__init__(archive_data_file='data/test.json')
43    self.AddPage(MockPage(self, url))
44
45
46class MockPageTest(page_test.PageTest):
47  def __init__(self):
48    super(MockPageTest, self).__init__()
49    self._action_name_to_run = "RunBaz"
50    self.func_calls = []
51
52  @classmethod
53  def AddCommandLineArgs(cls, parser):
54    parser.add_option('--mock-page-test-option', action="store_true")
55
56  def WillNavigateToPage(self, page, tab):
57    self.func_calls.append('WillNavigateToPage')
58
59  def DidNavigateToPage(self, page, tab):
60    self.func_calls.append('DidNavigateToPage')
61
62  def WillRunActions(self, page, tab):
63    self.func_calls.append('WillRunActions')
64
65  def DidRunActions(self, page, tab):
66    self.func_calls.append('DidRunActions')
67
68  def ValidatePage(self, page, tab, results):
69    self.func_calls.append('ValidatePage')
70
71  def WillStartBrowser(self, platform):
72    self.func_calls.append('WillStartBrowser')
73
74  def DidStartBrowser(self, browser):
75    self.func_calls.append('DidStartBrowser')
76
77class MockBenchmark(benchmark.Benchmark):
78  test = MockPageTest
79  mock_page_set = None
80
81  @classmethod
82  def AddTestCommandLineArgs(cls, group):
83    group.add_option('', '--mock-benchmark-url', action='store', type='string')
84
85  def CreatePageSet(self, options):
86    kwargs = {}
87    if (options.mock_benchmark_url):
88      kwargs['url'] = options.mock_benchmark_url
89    self.mock_page_set = MockPageSet(**kwargs)
90    return self.mock_page_set
91
92
93class RecordWprUnitTests(tab_test_case.TabTestCase):
94
95  _base_dir = util.GetUnittestDataDir()
96  _test_data_dir = os.path.join(util.GetUnittestDataDir(), 'page_tests')
97
98  @classmethod
99  def setUpClass(cls):
100    sys.path.extend([cls._base_dir, cls._test_data_dir])
101    super(RecordWprUnitTests, cls).setUpClass()
102    cls._url = cls.UrlOfUnittestFile('blank.html')
103
104  # When the RecorderPageTest is created from a PageSet, we do not have a
105  # PageTest to use. In this case, we will record every available action.
106  def testRunPage_AllActions(self):
107    record_page_test = record_wpr.RecorderPageTest(["RunFoo", "RunBar"])
108    page = MockPage(page_set=MockPageSet(url=self._url), url=self._url)
109    record_page_test.RunPage(page, self._tab, results=None)
110    self.assertTrue('RunFoo' in page.func_calls)
111    self.assertTrue('RunBar' in page.func_calls)
112    self.assertFalse('RunBaz' in page.func_calls)
113
114  def testRunPage_DontReloadSingleActions(self):
115    record_page_test = record_wpr.RecorderPageTest(["RunFoo"])
116    page = MockPage(page_set=MockPageSet(url=self._url), url=self._url)
117    record_page_test.RunPage(page, self._tab, results=None)
118    self.assertFalse('RunNavigateSteps' in page.func_calls)
119
120  def testRunPage_ReloadPageBetweenActions(self):
121    record_page_test = record_wpr.RecorderPageTest(["RunFoo", "RunBar"])
122    page = MockPage(page_set=MockPageSet(url=self._url), url=self._url)
123    record_page_test.RunPage(page, self._tab, results=None)
124    self.assertTrue('RunNavigateSteps' in page.func_calls)
125
126  # When the RecorderPageTest is created from a Benchmark, the benchmark will
127  # have a PageTest, specified by its test attribute.
128  def testRunPage_OnlyRunBenchmarkAction(self):
129    record_page_test = record_wpr.RecorderPageTest(["RunFoo"])
130    record_page_test.page_test = MockBenchmark().test()
131    page = MockPage(page_set=MockPageSet(url=self._url), url=self._url)
132    record_page_test.RunPage(page, self._tab, results=None)
133    self.assertFalse('RunFoo' in page.func_calls)
134    self.assertTrue('RunBaz' in page.func_calls)
135
136  def testRunPage_CallBenchmarksPageTestsFunctions(self):
137    record_page_test = record_wpr.RecorderPageTest([])
138    record_page_test.page_test = MockBenchmark().test()
139    page = MockPage(page_set=MockPageSet(url=self._url), url=self._url)
140    record_page_test.RunPage(page, self._tab, results=None)
141    self.assertEqual(3, len(record_page_test.page_test.func_calls))
142    self.assertEqual('WillRunActions', record_page_test.page_test.func_calls[0])
143    self.assertEqual('DidRunActions', record_page_test.page_test.func_calls[1])
144    self.assertEqual('ValidatePage', record_page_test.page_test.func_calls[2])
145
146  @decorators.Disabled('chromeos') # crbug.com/404868.
147  def testWprRecorderWithPageSet(self):
148    flags = []
149    mock_page_set = MockPageSet(url=self._url)
150    wpr_recorder = record_wpr.WprRecorder(self._test_data_dir,
151                                          mock_page_set, flags)
152    results = wpr_recorder.CreateResults()
153    wpr_recorder.Record(results)
154    self.assertEqual(set(mock_page_set.pages), results.pages_that_succeeded)
155
156  def testWprRecorderWithBenchmark(self):
157    flags = ['--mock-benchmark-url', self._url]
158    mock_benchmark = MockBenchmark()
159    wpr_recorder = record_wpr.WprRecorder(self._test_data_dir, mock_benchmark,
160                                          flags)
161    results = wpr_recorder.CreateResults()
162    wpr_recorder.Record(results)
163    self.assertEqual(set(mock_benchmark.mock_page_set.pages),
164                     results.pages_that_succeeded)
165
166  def testCommandLineFlags(self):
167    flags = [
168        '--page-repeat', '2',
169        '--mock-benchmark-url', self._url,
170        '--mock-page-test-option',
171    ]
172    wpr_recorder = record_wpr.WprRecorder(self._test_data_dir, MockBenchmark(),
173                                          flags)
174    # page_runner command-line args
175    self.assertEquals(2, wpr_recorder.options.page_repeat)
176    # benchmark command-line args
177    self.assertEquals(self._url, wpr_recorder.options.mock_benchmark_url)
178    # benchmark's page_test command-line args
179    self.assertTrue(wpr_recorder.options.mock_page_test_option)
180    # invalid command-line args
181    self.assertFalse(hasattr(wpr_recorder.options, 'not_a_real_option'))
182
183  def testRecordingEnabled(self):
184    flags = ['--mock-benchmark-url', self._url]
185    wpr_recorder = record_wpr.WprRecorder(self._test_data_dir, MockBenchmark(),
186                                          flags)
187    self.assertEqual(wpr_modes.WPR_RECORD,
188                     wpr_recorder.options.browser_options.wpr_mode)
189
190  def testFindAllActionNames(self):
191    # The src/tools/telemetry/unittest_data/page_tests/ has been
192    # populated with three simple Page Measurement classes, the first two of
193    # which have action_name_to_run defined.
194    action_names_to_run = record_wpr.FindAllActionNames(self._test_data_dir)
195    self.assertTrue('RunFoo' in action_names_to_run)
196    self.assertTrue('RunBar' in action_names_to_run)
197    self.assertFalse('RunBaz' in action_names_to_run)
198
199  # When the RecorderPageTest WillStartBrowser/DidStartBrowser function is
200  # called, it forwards the call to the PageTest
201  def testRecorderPageTest_BrowserMethods(self):
202    record_page_test = record_wpr.RecorderPageTest([])
203    record_page_test.page_test = MockBenchmark().test()
204    record_page_test.WillStartBrowser(self._tab.browser.platform)
205    record_page_test.DidStartBrowser(self._tab.browser)
206    self.assertTrue('WillStartBrowser' in record_page_test.page_test.func_calls)
207    self.assertTrue('DidStartBrowser' in record_page_test.page_test.func_calls)
208