- add sources.
[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 json
6 import logging
7 import os
8 import sys
9 import tempfile
10 import time
11 import urlparse
12
13 from telemetry import test
14 from telemetry.core import browser_options
15 from telemetry.core import discover
16 from telemetry.core import util
17 from telemetry.core import wpr_modes
18 from telemetry.page import page_measurement
19 from telemetry.page import page_runner
20 from telemetry.page import page_set
21 from telemetry.page import page_test
22 from telemetry.page import test_expectations
23
24
25 class RecordPage(page_test.PageTest):
26   def __init__(self, measurements):
27     # This class overwrites PageTest.Run, so that the test method name is not
28     # really used (except for throwing an exception if it doesn't exist).
29     super(RecordPage, self).__init__('Run')
30     self._action_names = set(
31         [measurement().action_name_to_run
32          for measurement in measurements.values()
33          if measurement().action_name_to_run])
34
35   def CanRunForPage(self, page):
36     return page.url.startswith('http')
37
38   def CustomizeBrowserOptionsForPage(self, page, options):
39     for compound_action in self._CompoundActionsForPage(page):
40       for action in compound_action:
41         action.CustomizeBrowserOptions(options)
42
43   def WillNavigateToPage(self, _, tab):
44     """Override to ensure all resources are fetched from network."""
45     tab.ClearCache()
46
47   def Run(self, options, page, tab, results):
48     # When recording, sleep to catch any resources that load post-onload.
49     tab.WaitForDocumentReadyStateToBeComplete()
50     time.sleep(3)
51
52     # Run the actions for all measurements. Reload the page between
53     # actions.
54     should_reload = False
55     for compound_action in self._CompoundActionsForPage(page):
56       if should_reload:
57         self.RunNavigateSteps(page, tab)
58       self._RunCompoundAction(page, tab, compound_action)
59       should_reload = True
60
61   def _CompoundActionsForPage(self, page):
62     actions = []
63     for action_name in self._action_names:
64       if not hasattr(page, action_name):
65         continue
66       actions.append(page_test.GetCompoundActionFromPage(page, action_name))
67     return actions
68
69
70 def _CreatePageSetForUrl(url):
71   ps_name = urlparse.urlparse(url).hostname + '.json'
72   ps_path = os.path.join(util.GetBaseDir(), 'page_sets', ps_name)
73   ps = {'archive_data_file': '../data/%s' % ps_name,
74         'pages': [
75           { 'url': url }
76           ]
77         }
78   with open(ps_path, 'w') as f:
79     f.write(json.dumps(ps))
80   print 'Created new page set %s' % ps_path
81   return page_set.PageSet.FromFile(ps_path)
82
83
84 def Main(base_dir):
85   measurements = discover.DiscoverClasses(base_dir, base_dir,
86                                           page_measurement.PageMeasurement)
87   tests = discover.DiscoverClasses(base_dir, base_dir, test.Test,
88                                    index_by_class_name=True)
89   options = browser_options.BrowserFinderOptions()
90   parser = options.CreateParser('%prog <PageSet|Measurement|Test|URL>')
91   page_runner.AddCommandLineOptions(parser)
92
93   recorder = RecordPage(measurements)
94   recorder.AddCommandLineOptions(parser)
95
96   _, args = parser.parse_args()
97
98   if len(args) != 1:
99     parser.print_usage()
100     sys.exit(1)
101
102   if args[0].endswith('.json'):
103     ps = page_set.PageSet.FromFile(args[0])
104   elif args[0] in tests:
105     ps = tests[args[0]]().CreatePageSet(options)
106   elif args[0] in measurements:
107     ps = measurements[args[0]]().CreatePageSet(args, options)
108   elif args[0].startswith('http'):
109     ps = _CreatePageSetForUrl(args[0])
110   else:
111     parser.print_usage()
112     sys.exit(1)
113
114   expectations = test_expectations.TestExpectations()
115
116   # Set the archive path to something temporary.
117   temp_target_wpr_file_path = tempfile.mkstemp()[1]
118   ps.wpr_archive_info.AddNewTemporaryRecording(temp_target_wpr_file_path)
119
120   # Do the actual recording.
121   options.browser_options.wpr_mode = wpr_modes.WPR_RECORD
122   options.browser_options.no_proxy_server = True
123   recorder.CustomizeBrowserOptions(options)
124   results = page_runner.Run(recorder, ps, expectations, options)
125
126   if results.errors or results.failures:
127     logging.warning('Some pages failed. The recording has not been updated for '
128                     'these pages.')
129     logging.warning('Failed pages:\n%s',
130                     '\n'.join(zip(*results.errors + results.failures)[0]))
131
132   if results.skipped:
133     logging.warning('Some pages were skipped. The recording has not been '
134                     'updated for these pages.')
135     logging.warning('Skipped pages:\n%s', '\n'.join(zip(*results.skipped)[0]))
136
137   if results.successes:
138     # Update the metadata for the pages which were recorded.
139     ps.wpr_archive_info.AddRecordedPages(results.successes)
140   else:
141     os.remove(temp_target_wpr_file_path)
142
143   return min(255, len(results.failures))