| OLD | NEW |
| (Empty) |
| 1 # Copyright 2016 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 logging | |
| 6 | |
| 7 from page_sets.login_helpers import dropbox_login | |
| 8 from page_sets.login_helpers import google_login | |
| 9 | |
| 10 from telemetry import story | |
| 11 from telemetry.page import page as page_module | |
| 12 | |
| 13 | |
| 14 def _LogIntoGoogleAccount(action_runner, credentials_path): | |
| 15 google_login.LoginGoogleAccount(action_runner, 'googletest', credentials_path) | |
| 16 | |
| 17 | |
| 18 def _LogIntoGoogleAccountAndSetUpGmailSession(action_runner, credentials_path): | |
| 19 _LogIntoGoogleAccount(action_runner, credentials_path) | |
| 20 | |
| 21 # Navigating to https://mail.google.com immediately leads to an infinite | |
| 22 # redirection loop due to a bug in WPR (see | |
| 23 # https://github.com/chromium/web-page-replay/issues/70). We therefore first | |
| 24 # navigate to a sub-URL to set up the session and hit the resulting | |
| 25 # redirection loop. Afterwards, we can safely navigate to | |
| 26 # https://mail.google.com. | |
| 27 action_runner.Navigate( | |
| 28 'https://mail.google.com/mail/mu/mp/872/trigger_redirection_loop') | |
| 29 action_runner.tab.WaitForDocumentReadyStateToBeComplete() | |
| 30 | |
| 31 | |
| 32 def _LogIntoDropboxAccount(action_runner, credentials_path): | |
| 33 dropbox_login.LoginAccount(action_runner, 'dropbox', credentials_path) | |
| 34 | |
| 35 | |
| 36 def _CloseInboxInterstitialAndWaitUntilGmailReady(platform, action_runner): | |
| 37 if platform == 'desktop': | |
| 38 # Wait until the UI loads. | |
| 39 action_runner.WaitForJavaScriptCondition( | |
| 40 'document.getElementById("loading").style.display === "none"') | |
| 41 elif platform == 'mobile': | |
| 42 # Close the "Get Inbox by Gmail" interstitial. | |
| 43 action_runner.WaitForJavaScriptCondition( | |
| 44 'document.querySelector("#isppromo a") !== null') | |
| 45 action_runner.ExecuteJavaScript( | |
| 46 'document.querySelector("#isppromo a").click()') | |
| 47 # Wait until the UI loads. | |
| 48 action_runner.WaitForJavaScriptCondition( | |
| 49 'document.getElementById("apploadingdiv").style.height === "0px"') | |
| 50 | |
| 51 | |
| 52 def _WaitUntilBubblesReady(_, action_runner): | |
| 53 # The #logo element is removed right before the main menu is displayed. | |
| 54 action_runner.WaitForJavaScriptCondition( | |
| 55 'document.getElementById("logo") === null') | |
| 56 | |
| 57 | |
| 58 def _WaitUntilSpyChaseReady(_, action_runner): | |
| 59 # The background of the game canvas is set when the "Tap screen to play" | |
| 60 # caption is displayed. | |
| 61 action_runner.WaitForJavaScriptCondition( | |
| 62 'document.querySelector("#game canvas").style.background !== ""') | |
| 63 | |
| 64 | |
| 65 def _WaitUntilFlickrReady(_, action_runner): | |
| 66 # Wait until the 'Recently tagged' view loads. | |
| 67 action_runner.WaitForJavaScriptCondition(''' | |
| 68 document.querySelector( | |
| 69 '.search-photos-everyone-trending-view .photo-list-view') !== null''') | |
| 70 | |
| 71 | |
| 72 class _PageSpec(object): | |
| 73 | |
| 74 def __init__(self, name, url, login_hook=None, post_load_hook=None): | |
| 75 assert isinstance(url, (dict, str)) | |
| 76 self._name = name | |
| 77 self._url = url | |
| 78 self._login_hook = login_hook | |
| 79 self._post_load_hook = post_load_hook | |
| 80 | |
| 81 @property | |
| 82 def name(self): | |
| 83 return self._name | |
| 84 | |
| 85 @property | |
| 86 def url(self): | |
| 87 return self._url | |
| 88 | |
| 89 @property | |
| 90 def login_hook(self): | |
| 91 return self._login_hook | |
| 92 | |
| 93 @property | |
| 94 def post_load_hook(self): | |
| 95 return self._post_load_hook | |
| 96 | |
| 97 | |
| 98 _SINGLE_PAGE_SPECS = { | |
| 99 # Search and e-commerce. | |
| 100 'search': [ | |
| 101 _PageSpec( | |
| 102 name='google', | |
| 103 url='https://www.google.com/#hl=en&q=science'), | |
| 104 _PageSpec( | |
| 105 name='baidu', | |
| 106 url='https://www.baidu.com/s?word=google'), | |
| 107 _PageSpec( | |
| 108 name='yahoo', | |
| 109 url='https://search.yahoo.com/search;_ylt=?p=google'), | |
| 110 _PageSpec( | |
| 111 name='amazon', | |
| 112 url='https://www.amazon.com/s/?field-keywords=nexus'), | |
| 113 # "ali_trackid" in the URL suppresses "Download app" interstitial. | |
| 114 _PageSpec( | |
| 115 name='taobao', | |
| 116 url={'desktop': 'https://world.taobao.com/', | |
| 117 'mobile': 'http://m.intl.taobao.com/?ali_trackid'}), | |
| 118 _PageSpec( | |
| 119 name='yandex', | |
| 120 url='https://yandex.ru/touchsearch?text=science'), | |
| 121 # Redirects to the "http://" version. | |
| 122 _PageSpec( | |
| 123 name='ebay', | |
| 124 url='https://www.ebay.com/sch/i.html?_nkw=headphones'), | |
| 125 # Using "https://" forces mobile version on desktop. The mobile page | |
| 126 # (https://www.flipkart.com/search?q=nexus+5x) almost always freezes | |
| 127 # due to crbug.com/611390. | |
| 128 _PageSpec( | |
| 129 name='flipkart', | |
| 130 url={'desktop': 'http://www.flipkart.com/search?q=nexus+5x'}), | |
| 131 ], | |
| 132 | |
| 133 # Social networks. | |
| 134 'social': [ | |
| 135 # Using Facebook login often causes "404 Not Found" with WPR. | |
| 136 _PageSpec( | |
| 137 name='facebook', | |
| 138 url='https://www.facebook.com/rihanna'), | |
| 139 _PageSpec( | |
| 140 name='twitter', | |
| 141 url='https://www.twitter.com/justinbieber?skip_interstitial=true'), | |
| 142 # Due to the deterministic date injected by WPR (February 2008), the | |
| 143 # cookie set by https://vk.com immediately expires, so the page keeps | |
| 144 # refreshing indefinitely on mobile | |
| 145 # (see https://github.com/chromium/web-page-replay/issues/71). | |
| 146 _PageSpec( | |
| 147 name='vk', | |
| 148 url={'desktop': 'https://vk.com/sbeatles'}), | |
| 149 _PageSpec( | |
| 150 name='instagram', | |
| 151 url='https://www.instagram.com/selenagomez/'), | |
| 152 _PageSpec( | |
| 153 name='pinterest', | |
| 154 url='https://uk.pinterest.com/categories/popular/'), | |
| 155 # Redirects to the "http://" version. | |
| 156 _PageSpec( | |
| 157 name='tumblr', | |
| 158 url='https://50thousand.tumblr.com/'), | |
| 159 ], | |
| 160 | |
| 161 # News, discussion and knowledge portals and blogs. | |
| 162 'news': [ | |
| 163 # Redirects to the "http://" version. | |
| 164 _PageSpec( | |
| 165 name='bbc', | |
| 166 url='https://www.bbc.co.uk/news/world-asia-china-36189636'), | |
| 167 # Using "https://" shows "Your connection is not private". | |
| 168 _PageSpec( | |
| 169 name='cnn', | |
| 170 url=( | |
| 171 'http://edition.cnn.com/2016/05/02/health/three-habitable-planet
s-earth-dwarf-star/index.html')), | |
| 172 _PageSpec( | |
| 173 name='reddit', | |
| 174 url={'desktop': ( | |
| 175 'https://www.reddit.com/r/AskReddit/comments/4hi90e/whats_y
our_best_wedding_horror_story/'), | |
| 176 'mobile': ( | |
| 177 'https://m.reddit.com/r/AskReddit/comments/4hi90e/whats_you
r_best_wedding_horror_story/')}), | |
| 178 # Using "https://" hangs and shows "This site can't be reached". | |
| 179 _PageSpec( | |
| 180 name='qq', | |
| 181 url='http://news.qq.com/a/20160503/003186.htm'), | |
| 182 # Using "https://" leads to missing images and scripts on mobile (due | |
| 183 # to mixed content). The desktop page | |
| 184 # (http://news.sohu.com/20160503/n447433356.shtml) almost always fails | |
| 185 # to completely load due to | |
| 186 # https://github.com/chromium/web-page-replay/issues/74. | |
| 187 _PageSpec( | |
| 188 name='sohu', | |
| 189 url={'mobile': 'http://m.sohu.com/n/447433356/'}), | |
| 190 _PageSpec( | |
| 191 name='wikipedia', | |
| 192 url='https://en.wikipedia.org/wiki/Science'), | |
| 193 ], | |
| 194 | |
| 195 # Audio and video. | |
| 196 'media': [ | |
| 197 # No way to disable autoplay on desktop. | |
| 198 _PageSpec( | |
| 199 name='youtube', | |
| 200 url='https://www.youtube.com/watch?v=QGfhS1hfTWw&autoplay=false'), | |
| 201 # The side panel with related videos doesn't show on desktop due to | |
| 202 # https://github.com/chromium/web-page-replay/issues/74. | |
| 203 _PageSpec( | |
| 204 name='dailymotion', | |
| 205 url=( | |
| 206 'https://www.dailymotion.com/video/x489k7d_street-performer-show
s-off-slinky-skills_fun?autoplay=false')), | |
| 207 _PageSpec( | |
| 208 name='google_images', | |
| 209 url='https://www.google.co.uk/search?tbm=isch&q=love'), | |
| 210 # No way to disable autoplay on desktop. Album artwork doesn't load due | |
| 211 # to https://github.com/chromium/web-page-replay/issues/73. | |
| 212 _PageSpec( | |
| 213 name='soundcloud', | |
| 214 url='https://soundcloud.com/lifeofdesiigner/desiigner-panda'), | |
| 215 _PageSpec( | |
| 216 name='9gag', | |
| 217 url='https://www.9gag.com/'), | |
| 218 _PageSpec( | |
| 219 name='flickr', | |
| 220 url='https://www.flickr.com/photos/tags/farm', | |
| 221 post_load_hook=_WaitUntilFlickrReady), | |
| 222 ], | |
| 223 | |
| 224 # Online tools (documents, emails, storage, ...). | |
| 225 'tools': [ | |
| 226 _PageSpec( | |
| 227 name='docs', | |
| 228 url=( | |
| 229 'https://docs.google.com/document/d/1GvzDP-tTLmJ0myRhUAfTYWs3ZUF
ilUICg8psNHyccwQ/edit?usp=sharing')), | |
| 230 _PageSpec( | |
| 231 name='gmail', | |
| 232 url='https://mail.google.com/mail/', | |
| 233 login_hook=_LogIntoGoogleAccountAndSetUpGmailSession, | |
| 234 post_load_hook=_CloseInboxInterstitialAndWaitUntilGmailReady), | |
| 235 _PageSpec( | |
| 236 name='maps', | |
| 237 url='https://www.google.com/maps/place/London,+UK/'), | |
| 238 _PageSpec( | |
| 239 name='stackoverflow', | |
| 240 url=( | |
| 241 'https://stackoverflow.com/questions/36827659/compiling-an-appli
cation-for-use-in-highly-radioactive-environments')), | |
| 242 _PageSpec( | |
| 243 name='dropbox', | |
| 244 url='https://www.dropbox.com', | |
| 245 login_hook=_LogIntoDropboxAccount), | |
| 246 _PageSpec( | |
| 247 name='weather', | |
| 248 url='https://weather.com/en-GB/weather/today/l/USCA0286:1:US'), | |
| 249 _PageSpec( | |
| 250 name='drive', | |
| 251 url='https://drive.google.com/drive/my-drive', | |
| 252 login_hook=_LogIntoGoogleAccount), | |
| 253 ], | |
| 254 | |
| 255 # In-browser games (HTML5 and Flash). | |
| 256 'games': [ | |
| 257 _PageSpec( | |
| 258 name='bubbles', | |
| 259 url=( | |
| 260 'https://games.cdn.famobi.com/html5games/s/smarty-bubbles/v010/?
fg_domain=play.famobi.com&fg_uid=d8f24956-dc91-4902-9096-a46cb1353b6f&fg_pid=463
8e320-4444-4514-81c4-d80a8c662371&fg_beat=620'), | |
| 261 post_load_hook=_WaitUntilBubblesReady), | |
| 262 # Using "https://" hangs and shows "This site can't be reached". | |
| 263 _PageSpec( | |
| 264 name='lazors', | |
| 265 url='http://www8.games.mobi/games/html5/lazors/lazors.html'), | |
| 266 # Using "https://" shows "Your connection is not private". | |
| 267 _PageSpec( | |
| 268 name='spychase', | |
| 269 url='http://playstar.mobi/games/spychase/index.php', | |
| 270 post_load_hook=_WaitUntilSpyChaseReady), | |
| 271 # Desktop only (requires Flash). Using "https://" causes | |
| 272 # "404 Not Found" during WPR recording. | |
| 273 _PageSpec( | |
| 274 name='miniclip', | |
| 275 url={'desktop': 'http://www.miniclip.com/games/en/'}), | |
| 276 # Desktop only (requires Flash). | |
| 277 _PageSpec( | |
| 278 name='alphabetty', | |
| 279 url={'desktop': 'https://king.com/play/alphabetty'}), | |
| 280 ], | |
| 281 } | |
| 282 | |
| 283 | |
| 284 DUMP_WAIT_TIME = 3 | |
| 285 | |
| 286 | |
| 287 class _LoadCase(page_module.Page): | |
| 288 """Generic System Health user story that loads a page and measures memory.""" | |
| 289 | |
| 290 def __init__(self, story_set, group, url, page_spec): | |
| 291 # For example, the name of the story for the |page_spec| with name | |
| 292 # 'example' from the 'sample' URL |group| will be 'load:sample:example'. | |
| 293 name = 'load:%s:%s' % (group, page_spec.name) | |
| 294 super(_LoadCase, self).__init__( | |
| 295 page_set=story_set, name=name, url=url, | |
| 296 credentials_path='data/credentials.json', | |
| 297 grouping_keys={'case': 'load', 'group': group}) | |
| 298 self._page_spec = page_spec | |
| 299 | |
| 300 @property | |
| 301 def platform(self): | |
| 302 return self.story_set.PLATFORM | |
| 303 | |
| 304 def _TakeMemoryMeasurement(self, action_runner): | |
| 305 # TODO(petrcermak): This method is essentially the same as | |
| 306 # MemoryHealthPage._TakeMemoryMeasurement() in memory_health_story.py. | |
| 307 # Consider sharing the common code. | |
| 308 action_runner.Wait(DUMP_WAIT_TIME) | |
| 309 action_runner.ForceGarbageCollection() | |
| 310 action_runner.Wait(DUMP_WAIT_TIME) | |
| 311 tracing_controller = action_runner.tab.browser.platform.tracing_controller | |
| 312 if not tracing_controller.is_tracing_running: | |
| 313 return # Tracing is not running, e.g., when recording a WPR archive. | |
| 314 if not action_runner.tab.browser.DumpMemory(): | |
| 315 logging.error('Unable to get a memory dump for %s.', self.name) | |
| 316 | |
| 317 def RunNavigateSteps(self, action_runner): | |
| 318 if self._page_spec.login_hook: | |
| 319 self._page_spec.login_hook(action_runner, self.credentials_path) | |
| 320 super(_LoadCase, self).RunNavigateSteps(action_runner) | |
| 321 | |
| 322 def RunPageInteractions(self, action_runner): | |
| 323 action_runner.tab.WaitForDocumentReadyStateToBeComplete() | |
| 324 if self._page_spec.post_load_hook: | |
| 325 self._page_spec.post_load_hook(self.platform, action_runner) | |
| 326 self._TakeMemoryMeasurement(action_runner) | |
| 327 | |
| 328 | |
| 329 class _MemorySystemHealthStorySet(story.StorySet): | |
| 330 """User stories for the System Health Plan. | |
| 331 | |
| 332 See https://goo.gl/Jek2NL. | |
| 333 """ | |
| 334 PLATFORM = NotImplemented | |
| 335 | |
| 336 def __init__(self): | |
| 337 super(_MemorySystemHealthStorySet, self).__init__( | |
| 338 archive_data_file='data/memory_system_health_%s.json' % self.PLATFORM, | |
| 339 cloud_storage_bucket=story.PARTNER_BUCKET) | |
| 340 | |
| 341 for group_name, page_specs in _SINGLE_PAGE_SPECS.iteritems(): | |
| 342 for page_spec in page_specs: | |
| 343 url = page_spec.url | |
| 344 if isinstance(url, dict): | |
| 345 url = url.get(self.PLATFORM) | |
| 346 if url is None: | |
| 347 continue # URL not supported on the platform. | |
| 348 self.AddStory(_LoadCase(self, group_name, url, page_spec)) | |
| 349 | |
| 350 | |
| 351 class DesktopMemorySystemHealthStorySet(_MemorySystemHealthStorySet): | |
| 352 """Desktop user stories for Chrome Memory System Health Plan.""" | |
| 353 PLATFORM = 'desktop' | |
| 354 | |
| 355 | |
| 356 class MobileMemorySystemHealthStorySet(_MemorySystemHealthStorySet): | |
| 357 """Mobile user stories for Chrome Memory System Health Plan.""" | |
| 358 PLATFORM = 'mobile' | |
| OLD | NEW |