Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / page / record_wpr.py
1 #!/usr/bin/env python
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.
5 import logging
6 import os
7 import sys
8 import tempfile
9 import time
10
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
24
25
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])
35     self.test = None
36
37   def CanRunForPage(self, page):
38     return page.url.startswith('http')
39
40   def WillNavigateToPage(self, page, tab):
41     """Override to ensure all resources are fetched from network."""
42     tab.ClearCache(force=False)
43     if self.test:
44       self.test.WillNavigateToPage(page, tab)
45
46   def DidNavigateToPage(self, page, tab):
47     """Forward the call to the test."""
48     if self.test:
49       self.test.DidNavigateToPage(page, tab)
50
51   def RunPage(self, page, tab, results):
52     # When recording, sleep to catch any resources that load post-onload.
53     tab.WaitForDocumentReadyStateToBeComplete()
54
55     if self.test:
56       dummy_results = page_measurement_results.PageMeasurementResults()
57       dummy_results.WillMeasurePage(page)
58       self.test.MeasurePage(page, tab, dummy_results)
59       dummy_results.DidMeasurePage()
60     else:
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
64       # speed index metric.
65       time.sleep(3)
66
67     # Run the actions for all measurements. Reload the page between
68     # actions.
69     should_reload = False
70     interactive = self.options and self.options.interactive
71     for action_name in self._action_names:
72       if not hasattr(page, action_name):
73         continue
74       if should_reload:
75         self.RunNavigateSteps(page, tab)
76       action_runner = action_runner_module.ActionRunner(page, tab, self)
77       if interactive:
78         action_runner.RunAction(interact.InteractAction())
79       else:
80         self._RunMethod(page, action_name, action_runner)
81       should_reload = True
82
83
84 def Main(base_dir):
85   measurements = {
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)
90       }
91   tests = discover.DiscoverClasses(base_dir, base_dir, test.Test,
92                                    index_by_class_name=True)
93
94   options = browser_options.BrowserFinderOptions()
95   parser = options.CreateParser('%prog <PageSet|Test|URL>')
96   page_runner.AddCommandLineArgs(parser)
97
98   recorder = RecordPage(measurements)
99   recorder.AddCommandLineArgs(parser)
100
101   quick_args = [a for a in sys.argv[1:] if not a.startswith('-')]
102   if len(quick_args) != 1:
103     parser.print_usage()
104     sys.exit(1)
105   target = quick_args[0]
106   if target in tests:
107     recorder.test = tests[target]().test()
108     recorder.test.AddCommandLineArgs(parser)
109     recorder.test.SetArgumentDefaults(parser)
110     parser.parse_args()
111     recorder.test.ProcessCommandLineArgs(parser, options)
112     ps = tests[target]().CreatePageSet(options)
113   elif discover.IsPageSetFile(target):
114     parser.parse_args()
115     ps = page_set.PageSet.FromFile(target)
116   else:
117     parser.print_usage()
118     sys.exit(1)
119
120   page_runner.ProcessCommandLineArgs(parser, options)
121   recorder.ProcessCommandLineArgs(parser, options)
122
123   expectations = test_expectations.TestExpectations()
124
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)
128
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)
134
135   if results.errors or results.failures:
136     logging.warning('Some pages failed. The recording has not been updated for '
137                     'these pages.')
138     logging.warning('Failed pages:\n%s',
139                     '\n'.join(zip(*results.errors + results.failures)[0]))
140
141   if results.skipped:
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]))
145
146   if results.successes:
147     # Update the metadata for the pages which were recorded.
148     ps.wpr_archive_info.AddRecordedPages(results.successes)
149   else:
150     os.remove(temp_target_wpr_file_path)
151
152   return min(255, len(results.failures))