Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / page / page.py
1 # Copyright 2012 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 import inspect
6 import os
7 import re
8 import urlparse
9
10 _next_page_id = 0
11
12 class Page(object):
13
14   def __init__(self, url, page_set=None, base_dir=None, name=''):
15     self._url = url
16     self._page_set = page_set
17     # Default value of base_dir is the directory of the file that defines the
18     # class of this page instance.
19     if base_dir is None:
20       base_dir = os.path.dirname(inspect.getfile(self.__class__))
21     self._base_dir = base_dir
22     self._name = name
23
24     global _next_page_id
25     self._id = _next_page_id
26     _next_page_id += 1
27
28     # These attributes can be set dynamically by the page.
29     self.synthetic_delays = dict()
30     self.startup_url = page_set.startup_url if page_set else ''
31     self.credentials = None
32     self.disabled = False
33     self.skip_waits = False
34     self.script_to_evaluate_on_commit = None
35     self._SchemeErrorCheck()
36
37   def _SchemeErrorCheck(self):
38     if not self._scheme:
39       raise ValueError('Must prepend the URL with scheme (e.g. file://)')
40
41     if self.startup_url:
42       startup_url_scheme = urlparse.urlparse(self.startup_url).scheme
43       if not startup_url_scheme:
44         raise ValueError('Must prepend the URL with scheme (e.g. http://)')
45       if startup_url_scheme == 'file':
46         raise ValueError('startup_url with local file scheme is not supported')
47
48   def TransferToPageSet(self, another_page_set):
49     """ Transfer this page to another page set.
50     Args:
51       another_page_set: an instance of telemetry.page.PageSet to transfer this
52           page to.
53     Note:
54       This method removes this page instance from the pages list of its current
55       page_set, so one should be careful not to iterate through the list of
56       pages of a page_set and calling this method.
57       For example, the below loop is erroneous:
58         for p in page_set_A.pages:
59           p.TransferToPageSet(page_set_B.pages)
60     """
61     assert self._page_set
62     if another_page_set is self._page_set:
63       return
64     self._page_set.pages.remove(self)
65     self._page_set = another_page_set
66     self._page_set.AddPage(self)
67
68   def RunNavigateSteps(self, action_runner):
69     action_runner.NavigateToPage(self)
70
71   def CanRunOnBrowser(self, browser_info):
72     """Override this to returns whether this page can be run on specific
73     browser.
74
75     Args:
76       browser_info: an instance of telemetry.core.browser_info.BrowserInfo
77     """
78     assert browser_info
79     return True
80
81   def AsDict(self):
82     """Converts a page object to a dict suitable for JSON output."""
83     d = {
84       'id': self._id,
85       'url': self._url,
86     }
87     if self._name:
88       d['name'] = self._name
89     return d
90
91   @property
92   def page_set(self):
93     return self._page_set
94
95   @property
96   def name(self):
97     return self._name
98
99   @property
100   def url(self):
101     return self._url
102
103   @property
104   def id(self):
105     return self._id
106
107   def GetSyntheticDelayCategories(self):
108     result = []
109     for delay, options in self.synthetic_delays.items():
110       options = '%f;%s' % (options.get('target_duration', 0),
111                            options.get('mode', 'static'))
112       result.append('DELAY(%s;%s)' % (delay, options))
113     return result
114
115   def __lt__(self, other):
116     return self.url < other.url
117
118   def __cmp__(self, other):
119     x = cmp(self.name, other.name)
120     if x != 0:
121       return x
122     return cmp(self.url, other.url)
123
124   def __str__(self):
125     return self.url
126
127   def AddCustomizeBrowserOptions(self, options):
128     """ Inherit page overrides this to add customized browser options."""
129     pass
130
131   @property
132   def _scheme(self):
133     return urlparse.urlparse(self.url).scheme
134
135   @property
136   def is_file(self):
137     """Returns True iff this URL points to a file."""
138     return self._scheme == 'file'
139
140   @property
141   def is_local(self):
142     """Returns True iff this URL is local. This includes chrome:// URLs."""
143     return self._scheme in ['file', 'chrome', 'about']
144
145   @property
146   def file_path(self):
147     """Returns the path of the file, stripping the scheme and query string."""
148     assert self.is_file
149     # Because ? is a valid character in a filename,
150     # we have to treat the url as a non-file by removing the scheme.
151     parsed_url = urlparse.urlparse(self.url[7:])
152     return os.path.normpath(os.path.join(
153         self._base_dir, parsed_url.netloc + parsed_url.path))
154
155   @property
156   def file_path_url(self):
157     """Returns the file path, including the params, query, and fragment."""
158     assert self.is_file
159     file_path_url = os.path.normpath(os.path.join(self._base_dir, self.url[7:]))
160     # Preserve trailing slash or backslash.
161     # It doesn't matter in a file path, but it does matter in a URL.
162     if self.url.endswith('/'):
163       file_path_url += os.sep
164     return file_path_url
165
166   @property
167   def serving_dir(self):
168     file_path = os.path.realpath(self.file_path)
169     if os.path.isdir(file_path):
170       return file_path
171     else:
172       return os.path.dirname(file_path)
173
174   @property
175   def file_safe_name(self):
176     """A version of display_name that's safe to use as a filename."""
177     # Just replace all special characters in the url with underscore.
178     return re.sub('[^a-zA-Z0-9]', '_', self.display_name)
179
180   @property
181   def display_name(self):
182     if self.name:
183       return self.name
184     if not self.is_file:
185       return self.url
186     all_urls = [p.url.rstrip('/') for p in self.page_set if p.is_file]
187     common_prefix = os.path.dirname(os.path.commonprefix(all_urls))
188     return self.url[len(common_prefix):].strip('/')
189
190   @property
191   def archive_path(self):
192     return self.page_set.WprFilePathForPage(self)