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 from page_sets.login_helpers import facebook_login | |
| 5 from page_sets.system_health import platforms | 6 from page_sets.system_health import platforms |
| 6 from page_sets.system_health import system_health_story | 7 from page_sets.system_health import system_health_story |
| 7 | 8 |
| 8 | 9 |
| 9 class _BrowsingStory(system_health_story.SystemHealthStory): | 10 class _BrowsingStory(system_health_story.SystemHealthStory): |
| 10 """Abstract base class for browsing stories. | 11 """Abstract base class for browsing stories. |
| 11 | 12 |
| 12 A browsing story visits items on the main page. Subclasses provide | 13 A browsing story visits items on the main page. Subclasses provide |
| 13 CSS selector to identify the items and implement interaction using | 14 CSS selector to identify the items and implement interaction using |
| 14 the helper methods of this class. | 15 the helper methods of this class. |
| 15 """ | 16 """ |
| 16 | 17 |
| 17 IS_SINGLE_PAGE_APP = False | 18 IS_SINGLE_PAGE_APP = False |
| 18 ITEM_SELECTOR = NotImplemented | 19 ITEM_SELECTOR = NotImplemented |
| 19 ITEMS_TO_VISIT = 4 | |
| 20 ABSTRACT_STORY = True | 20 ABSTRACT_STORY = True |
| 21 | 21 |
| 22 def _WaitForNavigation(self, action_runner): | 22 def _WaitForNavigation(self, action_runner): |
| 23 if not self.IS_SINGLE_PAGE_APP: | 23 if not self.IS_SINGLE_PAGE_APP: |
| 24 action_runner.WaitForNavigate() | 24 action_runner.WaitForNavigate() |
| 25 | 25 |
| 26 def _NavigateToItem(self, action_runner, index): | 26 def _NavigateToItem(self, action_runner, index): |
| 27 item_selector = 'document.querySelectorAll("%s")[%d]' % ( | 27 item_selector = 'document.querySelectorAll("%s")[%d]' % ( |
| 28 self.ITEM_SELECTOR, index) | 28 self.ITEM_SELECTOR, index) |
| 29 self._ClickLink(action_runner, item_selector) | 29 self._ClickLink(action_runner, item_selector) |
| 30 | 30 |
| 31 def _ClickLink(self, action_runner, element_function): | 31 def _ClickLink(self, action_runner, element_function): |
| 32 action_runner.WaitForElement(element_function=element_function) | 32 action_runner.WaitForElement(element_function=element_function) |
| 33 action_runner.ClickElement(element_function=element_function) | 33 action_runner.ClickElement(element_function=element_function) |
| 34 self._WaitForNavigation(action_runner) | 34 self._WaitForNavigation(action_runner) |
| 35 | 35 |
| 36 def _NavigateBack(self, action_runner): | 36 def _NavigateBack(self, action_runner): |
| 37 action_runner.ExecuteJavaScript('window.history.back()') | 37 action_runner.ExecuteJavaScript('window.history.back()') |
| 38 self._WaitForNavigation(action_runner) | 38 self._WaitForNavigation(action_runner) |
| 39 | 39 |
| 40 | 40 |
| 41 ############################################################################## | |
| 42 # News browsing stories. | |
| 43 ############################################################################## | |
| 44 | |
| 45 | |
| 41 class _NewsBrowsingStory(_BrowsingStory): | 46 class _NewsBrowsingStory(_BrowsingStory): |
| 42 """Abstract base class for news user stories. | 47 """Abstract base class for news user stories. |
| 43 | 48 |
| 44 A news story imitates browsing a news website: | 49 A news story imitates browsing a news website: |
| 45 1. Load the main page. | 50 1. Load the main page. |
| 46 2. Open and scroll the first news item. | 51 2. Open and scroll the first news item. |
| 47 3. Go back to the main page and scroll it. | 52 3. Go back to the main page and scroll it. |
| 48 4. Open and scroll the second news item. | 53 4. Open and scroll the second news item. |
| 49 5. Go back to the main page and scroll it. | 54 5. Go back to the main page and scroll it. |
| 50 6. etc. | 55 6. etc. |
| 51 """ | 56 """ |
| 52 | 57 |
| 53 ITEM_READ_TIME_IN_SECONDS = 3 | 58 ITEM_READ_TIME_IN_SECONDS = 3 |
| 54 ITEM_SCROLL_REPEAT = 2 | 59 ITEM_SCROLL_REPEAT = 2 |
| 60 ITEMS_TO_VISIT = 4 | |
| 55 MAIN_PAGE_SCROLL_REPEAT = 0 | 61 MAIN_PAGE_SCROLL_REPEAT = 0 |
| 56 ABSTRACT_STORY = True | 62 ABSTRACT_STORY = True |
| 57 | 63 |
| 58 def _DidLoadDocument(self, action_runner): | 64 def _DidLoadDocument(self, action_runner): |
| 59 for i in xrange(self.ITEMS_TO_VISIT): | 65 for i in xrange(self.ITEMS_TO_VISIT): |
| 60 self._NavigateToItem(action_runner, i) | 66 self._NavigateToItem(action_runner, i) |
| 61 self._ReadNewsItem(action_runner) | 67 self._ReadNewsItem(action_runner) |
| 62 self._NavigateBack(action_runner) | 68 self._NavigateBack(action_runner) |
| 63 self._ScrollMainPage(action_runner) | 69 self._ScrollMainPage(action_runner) |
| 64 | 70 |
| 65 def _ReadNewsItem(self, action_runner): | 71 def _ReadNewsItem(self, action_runner): |
| 66 action_runner.tab.WaitForDocumentReadyStateToBeComplete() | 72 action_runner.tab.WaitForDocumentReadyStateToBeComplete() |
| 67 action_runner.Wait(self.ITEM_READ_TIME_IN_SECONDS) | 73 action_runner.Wait(self.ITEM_READ_TIME_IN_SECONDS) |
| 68 action_runner.RepeatableBrowserDrivenScroll( | 74 action_runner.RepeatableBrowserDrivenScroll( |
| 69 repeat_count=self.ITEM_SCROLL_REPEAT) | 75 repeat_count=self.ITEM_SCROLL_REPEAT) |
| 70 | 76 |
| 71 def _ScrollMainPage(self, action_runner): | 77 def _ScrollMainPage(self, action_runner): |
| 72 action_runner.tab.WaitForDocumentReadyStateToBeComplete() | 78 action_runner.tab.WaitForDocumentReadyStateToBeComplete() |
| 73 action_runner.RepeatableBrowserDrivenScroll( | 79 action_runner.RepeatableBrowserDrivenScroll( |
| 74 repeat_count=self.MAIN_PAGE_SCROLL_REPEAT) | 80 repeat_count=self.MAIN_PAGE_SCROLL_REPEAT) |
| 75 | 81 |
| 76 | 82 |
| 77 ############################################################################## | |
| 78 # News browsing stories. | |
| 79 ############################################################################## | |
| 80 | |
| 81 | |
| 82 class CnnStory(_NewsBrowsingStory): | 83 class CnnStory(_NewsBrowsingStory): |
| 83 """The second top website in http://www.alexa.com/topsites/category/News""" | 84 """The second top website in http://www.alexa.com/topsites/category/News""" |
| 84 NAME = 'browse:news:cnn' | 85 NAME = 'browse:news:cnn' |
| 85 URL = 'http://edition.cnn.com/' | 86 URL = 'http://edition.cnn.com/' |
| 86 ITEM_SELECTOR = '.cd__content > h3 > a' | 87 ITEM_SELECTOR = '.cd__content > h3 > a' |
| 87 ITEMS_TO_VISIT = 2 | 88 ITEMS_TO_VISIT = 2 |
| 88 # TODO(ulan): Enable this story on mobile once it uses less memory and | 89 # TODO(ulan): Enable this story on mobile once it uses less memory and |
| 89 # does not crash with OOM. | 90 # does not crash with OOM. |
| 90 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY | 91 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY |
| 91 | 92 |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 205 def _DidLoadDocument(self, action_runner): | 206 def _DidLoadDocument(self, action_runner): |
| 206 # Close the popup window. On Nexus 9 (and probably other tables) the popup | 207 # Close the popup window. On Nexus 9 (and probably other tables) the popup |
| 207 # window does not have a "Close" button, instead it has only a "Send link | 208 # window does not have a "Close" button, instead it has only a "Send link |
| 208 # to phone" button. So on tablets we run with the popup window open. The | 209 # to phone" button. So on tablets we run with the popup window open. The |
| 209 # popup is transparent, so this is mostly an aesthetical issue. | 210 # popup is transparent, so this is mostly an aesthetical issue. |
| 210 has_button = action_runner.EvaluateJavaScript( | 211 has_button = action_runner.EvaluateJavaScript( |
| 211 '!!document.querySelector("%s")' % self._CLOSE_BUTTON_SELECTOR) | 212 '!!document.querySelector("%s")' % self._CLOSE_BUTTON_SELECTOR) |
| 212 if has_button: | 213 if has_button: |
| 213 action_runner.ClickElement(selector=self._CLOSE_BUTTON_SELECTOR) | 214 action_runner.ClickElement(selector=self._CLOSE_BUTTON_SELECTOR) |
| 214 super(WashingtonPostMobileStory, self)._DidLoadDocument(action_runner) | 215 super(WashingtonPostMobileStory, self)._DidLoadDocument(action_runner) |
| 216 | |
| 217 | |
| 218 ############################################################################## | |
| 219 # Media browsing stories. | |
| 220 ############################################################################## | |
| 221 | |
| 222 | |
| 223 class _MediaBrowsingStory(_BrowsingStory): | |
| 224 """Abstract base class for media user stories | |
| 225 | |
| 226 A media story imitates browsing a website with photo or video content: | |
| 227 1. Load a page showing a media item | |
| 228 2. Click on the next link to go to the next media item | |
| 229 3. etc. | |
| 230 """ | |
| 231 | |
| 232 ABSTRACT_STORY = True | |
| 233 ITEM_VIEW_TIME_IN_SECONDS = 3 | |
| 234 ITEMS_TO_VISIT = 15 | |
| 235 ITEM_SELECTOR_INDEX = 0 | |
| 236 | |
| 237 def _DidLoadDocument(self, action_runner): | |
| 238 for _ in xrange(self.ITEMS_TO_VISIT): | |
| 239 self._NavigateToItem(action_runner, self.ITEM_SELECTOR_INDEX) | |
| 240 self._ViewMediaItem(action_runner) | |
| 241 | |
| 242 def _ViewMediaItem(self, action_runner): | |
| 243 action_runner.tab.WaitForDocumentReadyStateToBeComplete() | |
| 244 action_runner.Wait(self.ITEM_VIEW_TIME_IN_SECONDS) | |
| 245 | |
| 246 | |
| 247 class ImgurMobileStory(_MediaBrowsingStory): | |
|
petrcermak
2016/08/04 13:32:42
Note that you could share common properties by def
Hannes Payer (out of office)
2016/08/05 10:21:05
Right on. I decided to keep the current structure
| |
| 248 NAME = 'browse:media:imgur' | |
| 249 URL = 'http://imgur.com/gallery/5UlBN' | |
| 250 ITEM_SELECTOR = '.Navbar-customAction' | |
| 251 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY | |
| 252 IS_SINGLE_PAGE_APP = True | |
| 253 | |
| 254 | |
| 255 class ImgurDesktopStory(_MediaBrowsingStory): | |
| 256 NAME = 'browse:media:imgur' | |
| 257 URL = 'http://imgur.com/gallery/5UlBN' | |
| 258 ITEM_SELECTOR = '.navNext' | |
| 259 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY | |
| 260 IS_SINGLE_PAGE_APP = True | |
| 261 | |
| 262 | |
| 263 class YoutubeMobileStory(_MediaBrowsingStory): | |
|
petrcermak
2016/08/04 13:32:42
nit: can you please change this to YouTubeMobileSt
Hannes Payer (out of office)
2016/08/05 10:21:05
Done.
| |
| 264 NAME = 'browse:media:youtube' | |
| 265 URL = 'https://m.youtube.com/watch?v=QGfhS1hfTWw&autoplay=false' | |
| 266 ITEM_SELECTOR = '._mhgb > a' | |
| 267 IS_SINGLE_PAGE_APP = True | |
|
petrcermak
2016/08/04 13:32:42
nit: Can you please order the class fields consist
Hannes Payer (out of office)
2016/08/05 10:21:05
Done.
| |
| 268 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY | |
| 269 ITEM_SELECTOR_INDEX = 3 | |
| 270 | |
| 271 | |
| 272 class YoutubeDesktopStory(_MediaBrowsingStory): | |
|
petrcermak
2016/08/04 13:32:42
ditto (capital "T")
Hannes Payer (out of office)
2016/08/05 10:21:05
Done.
| |
| 273 NAME = 'browse:media:youtube' | |
| 274 URL = 'https://www.youtube.com/watch?v=QGfhS1hfTWw&autoplay=false' | |
| 275 ITEM_SELECTOR = '.yt-uix-simple-thumb-related' | |
| 276 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY | |
| 277 IS_SINGLE_PAGE_APP = True | |
| 278 ITEM_VIEW_TIME_IN_SECONDS = 5 | |
|
petrcermak
2016/08/04 13:32:42
Could you please add a short comment why you overr
Hannes Payer (out of office)
2016/08/05 10:21:05
Done.
| |
| 279 ITEMS_TO_VISIT = 8 | |
| 280 ITEM_SELECTOR_INDEX = 3 | |
| 281 | |
| 282 | |
| 283 class FacebookMobileStory(_MediaBrowsingStory): | |
| 284 NAME = 'browse:media:facebookphotos' | |
|
petrcermak
2016/08/04 13:32:42
nit: I think facebook_photos would be better (cons
Hannes Payer (out of office)
2016/08/05 10:21:05
Done.
| |
| 285 URL = ( | |
| 286 'https://m.facebook.com/rihanna/photos/a.207477806675.138795.10092511675/1 0153911739606676/?type=3&source=54&ref=page_internal') | |
| 287 ITEM_SELECTOR = '._57-p > a' | |
| 288 IS_SINGLE_PAGE_APP = True | |
| 289 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY | |
| 290 ITEM_SELECTOR_INDEX = 1 | |
| 291 | |
| 292 def _Login(self, action_runner): | |
| 293 action_runner.Navigate('https://m.facebook.com/NASA') | |
|
petrcermak
2016/08/04 13:32:42
Why do you go to NASA and then back to Rihanna? If
Hannes Payer (out of office)
2016/08/05 10:21:05
Leftover, changed to rihanna.
| |
| 294 action_runner.tab.WaitForDocumentReadyStateToBeComplete() | |
| 295 | |
|
petrcermak
2016/08/04 13:32:42
nit: too many blank lines (should be 2)
Hannes Payer (out of office)
2016/08/05 10:21:05
Done.
| |
| 296 | |
| 297 | |
| 298 class FacebookDesktopStory(_MediaBrowsingStory): | |
| 299 NAME = 'browse:media:facebookphotos' | |
|
petrcermak
2016/08/04 13:32:42
ditto (facebook_photos)
Hannes Payer (out of office)
2016/08/05 10:21:05
Done.
| |
| 300 URL = ( | |
| 301 'https://www.facebook.com/rihanna/photos/a.207477806675.138795.10092511675 /10153911739606676/?type=3&theater') | |
| 302 ITEM_SELECTOR = '.snowliftPager.next' | |
| 303 IS_SINGLE_PAGE_APP = True | |
| 304 # Recording currently does not work. The page gets stuck in the | |
| 305 # theater viewer. | |
| 306 SUPPORTED_PLATFORMS = platforms.NO_PLATFORMS | |
| 307 | |
| 308 def _Login(self, action_runner): | |
| 309 facebook_login.LoginWithDesktopSite(action_runner, 'facebook3', | |
| 310 self.credentials_path) | |
| OLD | NEW |