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 sys |
| 6 |
| 7 from page_sets.system_health import platforms |
| 8 from page_sets.system_health import system_health_story |
| 9 |
| 10 from telemetry import story |
| 11 |
| 12 |
| 13 class _BrowsingStory(system_health_story.SystemHealthStory): |
| 14 """Abstract base class for browsing stories. |
| 15 |
| 16 A browsing story visits items on the main page. Subclasses provide |
| 17 CSS selector to identify the items and implement interaction using |
| 18 the helper methods of this class. |
| 19 """ |
| 20 |
| 21 IS_SINGLE_PAGE_APP = False |
| 22 ITEM_SELECTOR = NotImplemented |
| 23 ITEMS_TO_VISIT = 4 |
| 24 |
| 25 def __init__(self, story_set): |
| 26 super(_BrowsingStory, self).__init__( |
| 27 story_set, take_memory_measurement=False) |
| 28 |
| 29 def _WaitForNavigation(self, action_runner): |
| 30 if not self.IS_SINGLE_PAGE_APP: |
| 31 action_runner.WaitForNavigate() |
| 32 |
| 33 def _NavigateToItem(self, action_runner, index): |
| 34 item_selector = 'document.querySelectorAll("%s")[%d]' % ( |
| 35 self.ITEM_SELECTOR, index) |
| 36 action_runner.WaitForElement(element_function=item_selector) |
| 37 action_runner.ClickElement(element_function=item_selector) |
| 38 self._WaitForNavigation(action_runner) |
| 39 |
| 40 def _NavigateBack(self, action_runner): |
| 41 action_runner.ExecuteJavaScript('window.history.back()') |
| 42 self._WaitForNavigation(action_runner) |
| 43 |
| 44 |
| 45 class _NewsBrowsingStory(_BrowsingStory): |
| 46 """Abstract base class for news user stories. |
| 47 |
| 48 A news story imitates browsing a news website: |
| 49 1. Load the main page. |
| 50 2. Open and scroll the first news item. |
| 51 3. Go back to the main page and scroll it. |
| 52 4. Open and scroll the second news item. |
| 53 5. Go back to the main page and scroll it. |
| 54 6. etc. |
| 55 """ |
| 56 |
| 57 ITEM_READ_TIME_IN_SECONDS = 3 |
| 58 ITEM_SCROLL_REPEAT = 2 |
| 59 MAIN_PAGE_SCROLL_REPEAT = 0 |
| 60 |
| 61 def _DidLoadDocument(self, action_runner): |
| 62 for i in xrange(self.ITEMS_TO_VISIT): |
| 63 self._NavigateToItem(action_runner, i) |
| 64 self._ReadNewsItem(action_runner) |
| 65 self._NavigateBack(action_runner) |
| 66 self._ScrollMainPage(action_runner) |
| 67 |
| 68 def _ReadNewsItem(self, action_runner): |
| 69 action_runner.tab.WaitForDocumentReadyStateToBeComplete() |
| 70 action_runner.Wait(self.ITEM_READ_TIME_IN_SECONDS) |
| 71 action_runner.RepeatableBrowserDrivenScroll( |
| 72 repeat_count=self.ITEM_SCROLL_REPEAT) |
| 73 |
| 74 def _ScrollMainPage(self, action_runner): |
| 75 action_runner.tab.WaitForDocumentReadyStateToBeComplete() |
| 76 action_runner.RepeatableBrowserDrivenScroll( |
| 77 repeat_count=self.MAIN_PAGE_SCROLL_REPEAT) |
| 78 |
| 79 |
| 80 ############################################################################## |
| 81 # News browsing stories. |
| 82 ############################################################################## |
| 83 |
| 84 |
| 85 class CnnStory(_NewsBrowsingStory): |
| 86 """The second top website in http://www.alexa.com/topsites/category/News""" |
| 87 NAME = 'browse:news:cnn' |
| 88 URL = 'http://edition.cnn.com/' |
| 89 ITEM_SELECTOR = '.cd__content > h3 > a' |
| 90 # TODO(ulan): Enable this story on mobile once it uses less memory and |
| 91 # does not crash with OOM. |
| 92 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY |
| 93 |
| 94 |
| 95 class FacebookMobileStory(_NewsBrowsingStory): |
| 96 NAME = 'browse:social:facebook' |
| 97 URL = 'https://www.facebook.com/rihanna' |
| 98 ITEM_SELECTOR = 'article ._5msj' |
| 99 # Facebook on desktop is not interesting because it embeds post comments |
| 100 # directly in the main timeline. |
| 101 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY |
| 102 |
| 103 |
| 104 class HackerNewsStory(_NewsBrowsingStory): |
| 105 NAME = 'browse:news:hackernews' |
| 106 URL = 'https://news.ycombinator.com' |
| 107 ITEM_SELECTOR = '.athing .title > a' |
| 108 |
| 109 |
| 110 class NytimesMobileStory(_NewsBrowsingStory): |
| 111 """The third top website in http://www.alexa.com/topsites/category/News""" |
| 112 NAME = 'browse:news:nytimes' |
| 113 URL = 'http://mobile.nytimes.com' |
| 114 ITEM_SELECTOR = '.sfgAsset-link' |
| 115 # Visiting more items causes OOM. |
| 116 ITEMS_TO_VISIT = 2 |
| 117 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY |
| 118 |
| 119 |
| 120 class NytimesDesktopStory(_NewsBrowsingStory): |
| 121 """The third top website in http://www.alexa.com/topsites/category/News""" |
| 122 NAME = 'browse:news:nytimes' |
| 123 URL = 'http://www.nytimes.com' |
| 124 ITEM_SELECTOR = '.story-heading > a' |
| 125 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY |
| 126 |
| 127 |
| 128 class QqMobileStory(_NewsBrowsingStory): |
| 129 NAME = 'browse:news:qq' |
| 130 URL = 'http://news.qq.com' |
| 131 # Desktop qq.com opens a news item in a separate tab, for which the back |
| 132 # button does not work. |
| 133 # Mobile qq.com is disabled due to crbug.com/627166 |
| 134 ITEM_SELECTOR = '.list .full a' |
| 135 SUPPORTED_PLATFORMS = platforms.NO_PLATFORMS |
| 136 |
| 137 |
| 138 class RedditDesktopStory(_NewsBrowsingStory): |
| 139 """The top website in http://www.alexa.com/topsites/category/News""" |
| 140 NAME = 'browse:news:reddit' |
| 141 URL = 'https://www.reddit.com/top/?sort=top&t=week' |
| 142 ITEM_SELECTOR = '.thing .title > a' |
| 143 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY |
| 144 |
| 145 |
| 146 class RedditMobileStory(_NewsBrowsingStory): |
| 147 """The top website in http://www.alexa.com/topsites/category/News""" |
| 148 NAME = 'browse:news:reddit' |
| 149 URL = 'https://m.reddit.com/?sort=top&time=week' |
| 150 IS_SINGLE_PAGE_APP = True |
| 151 ITEM_SELECTOR = '.PostHeader__post-title-line' |
| 152 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY |
| 153 |
| 154 |
| 155 class TwitterMobileStory(_NewsBrowsingStory): |
| 156 NAME = 'browse:social:twitter' |
| 157 URL = 'https://www.twitter.com/justinbieber?skip_interstitial=true' |
| 158 ITEM_SELECTOR = '.Tweet-text' |
| 159 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY |
| 160 |
| 161 |
| 162 class TwitterDesktopStory(_NewsBrowsingStory): |
| 163 NAME = 'browse:social:twitter' |
| 164 URL = 'https://www.twitter.com/justinbieber?skip_interstitial=true' |
| 165 IS_SINGLE_PAGE_APP = True |
| 166 ITEM_SELECTOR = '.tweet-text' |
| 167 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY |
| 168 |
| 169 |
| 170 class WashingtonPostMobileStory(_NewsBrowsingStory): |
| 171 """Progressive website""" |
| 172 NAME = 'browse:news:washingtonpost' |
| 173 URL = 'https://www.washingtonpost.com/pwa' |
| 174 IS_SINGLE_PAGE_APP = True |
| 175 ITEM_SELECTOR = '.hed > a' |
| 176 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY |
| 177 |
| 178 def _DidLoadDocument(self, action_runner): |
| 179 # Close the popup window. |
| 180 action_runner.ClickElement(selector='.close') |
| 181 super(WashingtonPostMobileStory, self)._DidLoadDocument(action_runner) |
| 182 |
| 183 |
| 184 ############################################################################## |
| 185 # Browsing story sets. |
| 186 ############################################################################## |
| 187 |
| 188 |
| 189 def _IterAllNewsBrowsingStoryClasses(): |
| 190 return system_health_story.IterAllStoryClasses( |
| 191 sys.modules[__name__], _NewsBrowsingStory) |
| 192 |
| 193 |
| 194 class _NewsBrowsingStorySet(story.StorySet): |
| 195 PLATFORM = NotImplemented |
| 196 |
| 197 def __init__(self): |
| 198 super(_NewsBrowsingStorySet, self).__init__( |
| 199 archive_data_file=('../data/news_%s.json' % self.PLATFORM), |
| 200 cloud_storage_bucket=story.PARTNER_BUCKET) |
| 201 for story_class in _IterAllNewsBrowsingStoryClasses(): |
| 202 if self.PLATFORM not in story_class.SUPPORTED_PLATFORMS: |
| 203 continue |
| 204 self.AddStory(story_class(self)) |
| 205 |
| 206 |
| 207 class DesktopNewsStorySet(_NewsBrowsingStorySet): |
| 208 PLATFORM = platforms.DESKTOP |
| 209 |
| 210 |
| 211 class MobileNewsStorySet(_NewsBrowsingStorySet): |
| 212 PLATFORM = platforms.MOBILE |
OLD | NEW |