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