Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 import logging | 5 import logging |
| 6 | 6 |
| 7 from page_sets.login_helpers import dropbox_login | 7 from page_sets.login_helpers import dropbox_login |
| 8 from page_sets.login_helpers import google_login | 8 from page_sets.login_helpers import google_login |
| 9 | 9 |
| 10 from telemetry import story | 10 from telemetry import story |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 26 # https://mail.google.com. | 26 # https://mail.google.com. |
| 27 action_runner.Navigate( | 27 action_runner.Navigate( |
| 28 'https://mail.google.com/mail/mu/mp/872/trigger_redirection_loop') | 28 'https://mail.google.com/mail/mu/mp/872/trigger_redirection_loop') |
| 29 action_runner.tab.WaitForDocumentReadyStateToBeComplete() | 29 action_runner.tab.WaitForDocumentReadyStateToBeComplete() |
| 30 | 30 |
| 31 | 31 |
| 32 def _LogIntoDropboxAccount(action_runner, credentials_path): | 32 def _LogIntoDropboxAccount(action_runner, credentials_path): |
| 33 dropbox_login.LoginAccount(action_runner, 'dropbox', credentials_path) | 33 dropbox_login.LoginAccount(action_runner, 'dropbox', credentials_path) |
| 34 | 34 |
| 35 | 35 |
| 36 def _CloseInboxInterstitialAndWaitUntilGmailReady(platform, action_runner): | 36 def _WaitUntilDesktopGmailReady(action_runner): |
| 37 if platform == 'desktop': | 37 # Wait until the UI loads. |
| 38 # Wait until the UI loads. | 38 action_runner.WaitForJavaScriptCondition( |
| 39 action_runner.WaitForJavaScriptCondition( | 39 'document.getElementById("loading").style.display === "none"') |
| 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 | 40 |
| 51 | 41 |
| 52 def _WaitUntilBubblesReady(_, action_runner): | 42 def _CloseInboxInterstitialAndWaitUntilMobileGmailReady(action_runner): |
| 43 # Close the "Get Inbox by Gmail" interstitial. | |
| 44 action_runner.WaitForJavaScriptCondition( | |
| 45 'document.querySelector("#isppromo a") !== null') | |
| 46 action_runner.ExecuteJavaScript( | |
| 47 'document.querySelector("#isppromo a").click()') | |
| 48 # Wait until the UI loads. | |
| 49 action_runner.WaitForJavaScriptCondition( | |
| 50 'document.getElementById("apploadingdiv").style.height === "0px"') | |
| 51 | |
| 52 | |
| 53 def _WaitUntilBubblesReady(action_runner): | |
| 53 # The #logo element is removed right before the main menu is displayed. | 54 # The #logo element is removed right before the main menu is displayed. |
| 54 action_runner.WaitForJavaScriptCondition( | 55 action_runner.WaitForJavaScriptCondition( |
| 55 'document.getElementById("logo") === null') | 56 'document.getElementById("logo") === null') |
| 56 | 57 |
| 57 | 58 |
| 58 def _WaitUntilSpyChaseReady(_, action_runner): | 59 def _WaitUntilSpyChaseReady(action_runner): |
| 59 # The background of the game canvas is set when the "Tap screen to play" | 60 # The background of the game canvas is set when the "Tap screen to play" |
| 60 # caption is displayed. | 61 # caption is displayed. |
| 61 action_runner.WaitForJavaScriptCondition( | 62 action_runner.WaitForJavaScriptCondition( |
| 62 'document.querySelector("#game canvas").style.background !== ""') | 63 'document.querySelector("#game canvas").style.background !== ""') |
| 63 | 64 |
| 64 | 65 |
| 65 def _WaitUntilFlickrReady(_, action_runner): | 66 def _WaitUntilFlickrReady(action_runner): |
| 66 # Wait until the 'Recently tagged' view loads. | 67 # Wait until the 'Recently tagged' view loads. |
| 67 action_runner.WaitForJavaScriptCondition(''' | 68 action_runner.WaitForJavaScriptCondition(''' |
| 68 document.querySelector( | 69 document.querySelector( |
| 69 '.search-photos-everyone-trending-view .photo-list-view') !== null''') | 70 '.search-photos-everyone-trending-view .photo-list-view') !== null''') |
| 70 | 71 |
| 71 | 72 |
| 72 class _PageSpec(object): | 73 class _PageSpec(object): |
| 73 | 74 |
| 74 def __init__(self, name, url, login_hook=None, post_load_hook=None): | 75 def __init__(self, name, url, login_hook=None, post_load_hook=None): |
| 75 assert isinstance(url, (dict, str)) | |
| 76 self._name = name | 76 self._name = name |
| 77 self._url = url | 77 self._url = url |
| 78 self._login_hook = login_hook | 78 self._login_hook = login_hook |
| 79 self._post_load_hook = post_load_hook | 79 self._post_load_hook = post_load_hook |
| 80 | 80 |
| 81 @property | 81 @property |
| 82 def name(self): | 82 def name(self): |
| 83 return self._name | 83 return self._name |
| 84 | 84 |
| 85 @property | 85 @property |
| 86 def url(self): | 86 def url(self): |
| 87 return self._url | 87 return self._url |
| 88 | 88 |
| 89 @property | 89 @property |
| 90 def login_hook(self): | 90 def login_hook(self): |
| 91 return self._login_hook | 91 return self._login_hook |
| 92 | 92 |
| 93 @property | 93 @property |
| 94 def post_load_hook(self): | 94 def post_load_hook(self): |
| 95 return self._post_load_hook | 95 return self._post_load_hook |
| 96 | 96 |
| 97 def Resolve(self, platform_name): | |
|
nednguyen
2016/06/24 17:08:26
It seems to me that we are going down to the path
petrcermak
2016/06/27 19:31:21
You're right. I rewrote the file completely ;-)
| |
| 98 return _PageSpec(self.name, | |
| 99 self._ResolveField(self._url, platform_name), | |
| 100 self._ResolveField(self._login_hook, platform_name), | |
| 101 self._ResolveField(self._post_load_hook, platform_name)) | |
| 102 | |
| 103 def _ResolveField(self, field, platform_name): | |
| 104 if isinstance(field, dict): | |
| 105 return field.get(platform_name) | |
| 106 return field | |
| 107 | |
| 97 | 108 |
| 98 _SINGLE_PAGE_SPECS = { | 109 _SINGLE_PAGE_SPECS = { |
| 99 # Search and e-commerce. | 110 # Search and e-commerce. |
| 100 'search': [ | 111 'search': [ |
| 101 _PageSpec( | 112 _PageSpec( |
| 102 name='google', | 113 name='google', |
| 103 url='https://www.google.com/#hl=en&q=science'), | 114 url='https://www.google.com/#hl=en&q=science'), |
| 104 _PageSpec( | 115 _PageSpec( |
| 105 name='baidu', | 116 name='baidu', |
| 106 url='https://www.baidu.com/s?word=google'), | 117 url='https://www.baidu.com/s?word=google'), |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 218 # Online tools (documents, emails, storage, ...). | 229 # Online tools (documents, emails, storage, ...). |
| 219 'tools': [ | 230 'tools': [ |
| 220 _PageSpec( | 231 _PageSpec( |
| 221 name='docs', | 232 name='docs', |
| 222 url=( | 233 url=( |
| 223 'https://docs.google.com/document/d/1GvzDP-tTLmJ0myRhUAfTYWs3ZUF ilUICg8psNHyccwQ/edit?usp=sharing')), | 234 'https://docs.google.com/document/d/1GvzDP-tTLmJ0myRhUAfTYWs3ZUF ilUICg8psNHyccwQ/edit?usp=sharing')), |
| 224 _PageSpec( | 235 _PageSpec( |
| 225 name='gmail', | 236 name='gmail', |
| 226 url='https://mail.google.com/mail/', | 237 url='https://mail.google.com/mail/', |
| 227 login_hook=_LogIntoGoogleAccountAndSetUpGmailSession, | 238 login_hook=_LogIntoGoogleAccountAndSetUpGmailSession, |
| 228 post_load_hook=_CloseInboxInterstitialAndWaitUntilGmailReady), | 239 post_load_hook={ |
| 240 'desktop': _WaitUntilDesktopGmailReady, | |
| 241 'mobile': _CloseInboxInterstitialAndWaitUntilMobileGmailReady}), | |
| 229 _PageSpec( | 242 _PageSpec( |
| 230 name='maps', | 243 name='maps', |
| 231 url='https://www.google.com/maps/place/London,+UK/'), | 244 url='https://www.google.com/maps/place/London,+UK/'), |
| 232 _PageSpec( | 245 _PageSpec( |
| 233 name='stackoverflow', | 246 name='stackoverflow', |
| 234 url=( | 247 url=( |
| 235 'https://stackoverflow.com/questions/36827659/compiling-an-appli cation-for-use-in-highly-radioactive-environments')), | 248 'https://stackoverflow.com/questions/36827659/compiling-an-appli cation-for-use-in-highly-radioactive-environments')), |
| 236 _PageSpec( | 249 _PageSpec( |
| 237 name='dropbox', | 250 name='dropbox', |
| 238 url='https://www.dropbox.com', | 251 url='https://www.dropbox.com', |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 271 _PageSpec( | 284 _PageSpec( |
| 272 name='alphabetty', | 285 name='alphabetty', |
| 273 url={'desktop': 'https://king.com/play/alphabetty'}), | 286 url={'desktop': 'https://king.com/play/alphabetty'}), |
| 274 ], | 287 ], |
| 275 } | 288 } |
| 276 | 289 |
| 277 | 290 |
| 278 DUMP_WAIT_TIME = 3 | 291 DUMP_WAIT_TIME = 3 |
| 279 | 292 |
| 280 | 293 |
| 281 class _LoadCase(page_module.Page): | 294 class _SinglePageCase(page_module.Page): |
| 282 """Generic System Health user story that loads a page and measures memory.""" | 295 """Abstract base class for single-page System Health user stories.""" |
| 296 CASE = NotImplemented | |
| 283 | 297 |
| 284 def __init__(self, story_set, group, url, page_spec): | 298 def __init__(self, story_set, group, page_spec): |
| 285 # For example, the name of the story for the |page_spec| with name | 299 # For example, the name of the load story for the |page_spec| with name |
| 286 # 'example' from the 'sample' URL |group| will be 'load:sample:example'. | 300 # 'example' from the 'sample' URL |group| will be 'load:sample:example'. |
| 287 name = 'load:%s:%s' % (group, page_spec.name) | 301 story_name = ':'.join((self.CASE, group, page_spec.name)) |
| 288 super(_LoadCase, self).__init__( | 302 super(_SinglePageCase, self).__init__( |
| 289 page_set=story_set, name=name, url=url, | 303 page_set=story_set, name=story_name, url=page_spec.url, |
| 290 credentials_path='../data/credentials.json', | 304 credentials_path='../data/credentials.json', |
| 291 grouping_keys={'case': 'load', 'group': group}) | 305 grouping_keys={'case': self.CASE, 'group': group}) |
| 292 self._page_spec = page_spec | 306 self._page_spec = page_spec |
| 293 | 307 |
| 294 @property | 308 @property |
| 295 def platform(self): | 309 def platform(self): |
| 296 return self.story_set.PLATFORM | 310 return self.story_set.PLATFORM |
| 297 | 311 |
| 298 def _TakeMemoryMeasurement(self, action_runner): | 312 def _TakeMemoryMeasurement(self, action_runner): |
| 299 # TODO(petrcermak): This method is essentially the same as | 313 # TODO(petrcermak): This method is essentially the same as |
| 300 # MemoryHealthPage._TakeMemoryMeasurement() in memory_health_story.py. | 314 # MemoryHealthPage._TakeMemoryMeasurement() in memory_health_story.py. |
| 301 # Consider sharing the common code. | 315 # Consider sharing the common code. |
| 302 action_runner.Wait(DUMP_WAIT_TIME) | 316 action_runner.Wait(DUMP_WAIT_TIME) |
| 303 action_runner.ForceGarbageCollection() | 317 action_runner.ForceGarbageCollection() |
| 304 action_runner.Wait(DUMP_WAIT_TIME) | 318 action_runner.Wait(DUMP_WAIT_TIME) |
| 305 tracing_controller = action_runner.tab.browser.platform.tracing_controller | 319 tracing_controller = action_runner.tab.browser.platform.tracing_controller |
| 306 if not tracing_controller.is_tracing_running: | 320 if not tracing_controller.is_tracing_running: |
| 307 return # Tracing is not running, e.g., when recording a WPR archive. | 321 return # Tracing is not running, e.g., when recording a WPR archive. |
| 308 if not action_runner.tab.browser.DumpMemory(): | 322 if not action_runner.tab.browser.DumpMemory(): |
| 309 logging.error('Unable to get a memory dump for %s.', self.name) | 323 logging.error('Unable to get a memory dump for %s.', self.name) |
| 310 | 324 |
| 311 def RunNavigateSteps(self, action_runner): | 325 def RunNavigateSteps(self, action_runner): |
| 312 if self._page_spec.login_hook: | 326 if self._page_spec.login_hook: |
| 313 self._page_spec.login_hook(action_runner, self.credentials_path) | 327 self._page_spec.login_hook(action_runner, self.credentials_path) |
| 314 super(_LoadCase, self).RunNavigateSteps(action_runner) | 328 super(_SinglePageCase, self).RunNavigateSteps(action_runner) |
| 315 | 329 |
| 316 def RunPageInteractions(self, action_runner): | 330 def RunPageInteractions(self, action_runner): |
| 317 action_runner.tab.WaitForDocumentReadyStateToBeComplete() | 331 action_runner.tab.WaitForDocumentReadyStateToBeComplete() |
| 318 if self._page_spec.post_load_hook: | 332 if self._page_spec.post_load_hook: |
| 319 self._page_spec.post_load_hook(self.platform, action_runner) | 333 self._page_spec.post_load_hook(action_runner) |
| 334 | |
| 335 | |
| 336 class _LoadCase(_SinglePageCase): | |
| 337 """Generic System Health user story that loads a page and measures memory.""" | |
| 338 CASE = 'load' | |
| 339 | |
| 340 def RunPageInteractions(self, action_runner): | |
| 341 super(_LoadCase, self).RunPageInteractions(action_runner) | |
| 320 self._TakeMemoryMeasurement(action_runner) | 342 self._TakeMemoryMeasurement(action_runner) |
| 321 | 343 |
| 322 | 344 |
| 323 class _MemorySystemHealthStorySet(story.StorySet): | 345 class _MemorySystemHealthStorySet(story.StorySet): |
| 324 """User stories for the System Health Plan. | 346 """User stories for the System Health Plan. |
| 325 | 347 |
| 326 See https://goo.gl/Jek2NL. | 348 See https://goo.gl/Jek2NL. |
| 327 """ | 349 """ |
| 328 PLATFORM = NotImplemented | 350 PLATFORM = NotImplemented |
| 329 | 351 |
| 330 def __init__(self): | 352 def __init__(self): |
| 331 super(_MemorySystemHealthStorySet, self).__init__( | 353 super(_MemorySystemHealthStorySet, self).__init__( |
| 332 archive_data_file=('../data/memory_system_health_%s.json' % | 354 archive_data_file=('../data/memory_system_health_%s.json' % |
| 333 self.PLATFORM), | 355 self.PLATFORM), |
| 334 cloud_storage_bucket=story.PARTNER_BUCKET) | 356 cloud_storage_bucket=story.PARTNER_BUCKET) |
| 335 | 357 |
| 336 for group_name, page_specs in _SINGLE_PAGE_SPECS.iteritems(): | 358 for group_name, page_specs in _SINGLE_PAGE_SPECS.iteritems(): |
| 337 for page_spec in page_specs: | 359 for page_spec in page_specs: |
| 338 url = page_spec.url | 360 resolved_page_spec = page_spec.Resolve(self.PLATFORM) |
| 339 if isinstance(url, dict): | 361 if not resolved_page_spec.url: |
| 340 url = url.get(self.PLATFORM) | 362 continue # URL not supported on the platform. |
| 341 if url is None: | 363 self.AddStory(_LoadCase(self, group_name, resolved_page_spec)) |
| 342 continue # URL not supported on the platform. | |
| 343 self.AddStory(_LoadCase(self, group_name, url, page_spec)) | |
| 344 | 364 |
| 345 | 365 |
| 346 class DesktopMemorySystemHealthStorySet(_MemorySystemHealthStorySet): | 366 class DesktopMemorySystemHealthStorySet(_MemorySystemHealthStorySet): |
| 347 """Desktop user stories for Chrome Memory System Health Plan.""" | 367 """Desktop user stories for Chrome Memory System Health Plan.""" |
| 348 PLATFORM = 'desktop' | 368 PLATFORM = 'desktop' |
| 349 | 369 |
| 350 | 370 |
| 351 class MobileMemorySystemHealthStorySet(_MemorySystemHealthStorySet): | 371 class MobileMemorySystemHealthStorySet(_MemorySystemHealthStorySet): |
| 352 """Mobile user stories for Chrome Memory System Health Plan.""" | 372 """Mobile user stories for Chrome Memory System Health Plan.""" |
| 353 PLATFORM = 'mobile' | 373 PLATFORM = 'mobile' |
| OLD | NEW |