2 # Copyright (c) 2012 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
11 from telemetry import test
12 from telemetry.core import browser_options
13 from telemetry.core import discover
14 from telemetry.core import wpr_modes
15 from telemetry.page import page_measurement
16 from telemetry.page import page_measurement_results
17 from telemetry.page import page_runner
18 from telemetry.page import page_set
19 from telemetry.page import page_test
20 from telemetry.page import profile_creator
21 from telemetry.page import test_expectations
22 from telemetry.page.actions import action_runner as action_runner_module
23 from telemetry.page.actions import interact
26 class RecordPage(page_test.PageTest): # pylint: disable=W0223
27 def __init__(self, measurements):
28 # This class overwrites PageTest.Run, so that the test method name is not
29 # really used (except for throwing an exception if it doesn't exist).
30 super(RecordPage, self).__init__('Run')
31 self._action_names = set(
32 [measurement().action_name_to_run
33 for measurement in measurements.values()
34 if measurement().action_name_to_run])
37 def CanRunForPage(self, page):
38 return page.url.startswith('http')
40 def WillNavigateToPage(self, page, tab):
41 """Override to ensure all resources are fetched from network."""
42 tab.ClearCache(force=False)
44 self.test.WillNavigateToPage(page, tab)
46 def DidNavigateToPage(self, page, tab):
47 """Forward the call to the test."""
49 self.test.DidNavigateToPage(page, tab)
51 def RunPage(self, page, tab, results):
52 # When recording, sleep to catch any resources that load post-onload.
53 tab.WaitForDocumentReadyStateToBeComplete()
56 dummy_results = page_measurement_results.PageMeasurementResults()
57 dummy_results.WillMeasurePage(page)
58 self.test.MeasurePage(page, tab, dummy_results)
59 dummy_results.DidMeasurePage()
61 # TODO(tonyg): This should probably monitor resource timing for activity
62 # and sleep until 2s since the last network event with some timeout like
63 # 20s. We could wrap this up as WaitForNetworkIdle() and share with the
67 # Run the actions for all measurements. Reload the page between
70 interactive = self.options and self.options.interactive
71 for action_name in self._action_names:
72 if not hasattr(page, action_name):
75 self.RunNavigateSteps(page, tab)
76 action_runner = action_runner_module.ActionRunner(page, tab, self)
78 action_runner.RunAction(interact.InteractAction())
80 self._RunMethod(page, action_name, action_runner)
86 n: cls for n, cls in discover.DiscoverClasses(
87 base_dir, base_dir, page_measurement.PageMeasurement).items()
88 # Filter out unneeded ProfileCreators (crbug.com/319573).
89 if not issubclass(cls, profile_creator.ProfileCreator)
91 tests = discover.DiscoverClasses(base_dir, base_dir, test.Test,
92 index_by_class_name=True)
94 options = browser_options.BrowserFinderOptions()
95 parser = options.CreateParser('%prog <PageSet|Test|URL>')
96 page_runner.AddCommandLineArgs(parser)
98 recorder = RecordPage(measurements)
99 recorder.AddCommandLineArgs(parser)
101 quick_args = [a for a in sys.argv[1:] if not a.startswith('-')]
102 if len(quick_args) != 1:
105 target = quick_args[0]
107 recorder.test = tests[target]().test()
108 recorder.test.AddCommandLineArgs(parser)
109 recorder.test.SetArgumentDefaults(parser)
111 recorder.test.ProcessCommandLineArgs(parser, options)
112 ps = tests[target]().CreatePageSet(options)
113 elif discover.IsPageSetFile(target):
115 ps = page_set.PageSet.FromFile(target)
120 page_runner.ProcessCommandLineArgs(parser, options)
121 recorder.ProcessCommandLineArgs(parser, options)
123 expectations = test_expectations.TestExpectations()
125 # Set the archive path to something temporary.
126 temp_target_wpr_file_path = tempfile.mkstemp()[1]
127 ps.wpr_archive_info.AddNewTemporaryRecording(temp_target_wpr_file_path)
129 # Do the actual recording.
130 options.browser_options.wpr_mode = wpr_modes.WPR_RECORD
131 options.browser_options.no_proxy_server = True
132 recorder.CustomizeBrowserOptions(options)
133 results = page_runner.Run(recorder, ps, expectations, options)
135 if results.errors or results.failures:
136 logging.warning('Some pages failed. The recording has not been updated for '
138 logging.warning('Failed pages:\n%s',
139 '\n'.join(zip(*results.errors + results.failures)[0]))
142 logging.warning('Some pages were skipped. The recording has not been '
143 'updated for these pages.')
144 logging.warning('Skipped pages:\n%s', '\n'.join(zip(*results.skipped)[0]))
146 if results.successes:
147 # Update the metadata for the pages which were recorded.
148 ps.wpr_archive_info.AddRecordedPages(results.successes)
150 os.remove(temp_target_wpr_file_path)
152 return min(255, len(results.failures))