Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(71)

Side by Side Diff: tools/perf/page_sets/system_health/media_stories.py

Issue 2787103003: Add System health stories for Emerging market (Closed)
Patch Set: nits. Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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.system_health import platforms 5 from page_sets.system_health import platforms
6 from page_sets.system_health import story_tags
6 from page_sets.system_health import system_health_story 7 from page_sets.system_health import system_health_story
8 from page_sets.system_health import browsing_stories
7 9
8 from page_sets.login_helpers import google_login 10 from page_sets.login_helpers import google_login
9 from page_sets.login_helpers import pandora_login 11 from page_sets.login_helpers import pandora_login
12 from page_sets.login_helpers import pinterest_login
10 13
11 from telemetry import benchmark 14 from telemetry import benchmark
12 from telemetry import decorators 15 from telemetry import decorators
13 16
14 17
15 class _MediaStory(system_health_story.SystemHealthStory): 18 ################################################################################
19 # Audio and Video stories.
20 ################################################################################
21
22
23 class _PlayMediaStory(system_health_story.SystemHealthStory):
16 """Abstract base class for media System Health user stories.""" 24 """Abstract base class for media System Health user stories."""
17 25
18 ABSTRACT_STORY = True 26 ABSTRACT_STORY = True
19 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY 27 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY
20 PLAY_DURATION = 20 28 PLAY_DURATION = 20
21 PLAY_SELECTOR = NotImplemented 29 PLAY_SELECTOR = NotImplemented
22 STOP_SELECTOR = NotImplemented 30 STOP_SELECTOR = NotImplemented
23 TIME_SELECTOR = NotImplemented 31 TIME_SELECTOR = NotImplemented
24 32
25 def RunPageInteractions(self, action_runner): 33 def RunPageInteractions(self, action_runner):
(...skipping 18 matching lines...) Expand all
44 action_runner.Wait( 52 action_runner.Wait(
45 self.PLAY_DURATION - self._GetTimeInSeconds(action_runner)) 53 self.PLAY_DURATION - self._GetTimeInSeconds(action_runner))
46 54
47 def _GetTimeInSeconds(self, action_runner): 55 def _GetTimeInSeconds(self, action_runner):
48 minutes, seconds = action_runner.EvaluateJavaScript( 56 minutes, seconds = action_runner.EvaluateJavaScript(
49 'document.querySelector({{ selector }}).textContent', 57 'document.querySelector({{ selector }}).textContent',
50 selector=self.TIME_SELECTOR).split(':') 58 selector=self.TIME_SELECTOR).split(':')
51 return int(minutes * 60 + seconds) 59 return int(minutes * 60 + seconds)
52 60
53 61
54 ################################################################################ 62 # TODO(ssid): Rename the play stories to browse stories crbug.com/708300.
55 # Audio stories.
56 ################################################################################
57
58
59 @benchmark.Disabled('all') # crbug.com/649392 63 @benchmark.Disabled('all') # crbug.com/649392
60 class GooglePlayMusicDesktopStory(_MediaStory): 64 class GooglePlayMusicDesktopStory(_PlayMediaStory):
61 NAME = 'play:media:google_play_music' 65 NAME = 'play:media:google_play_music'
62 URL = 'https://music.google.com' 66 URL = 'https://music.google.com'
63 67
64 PLAY_SELECTOR = '.x-scope.paper-fab-0' 68 PLAY_SELECTOR = '.x-scope.paper-fab-0'
65 STOP_SELECTOR = '.style-scope.sj-play-button' 69 STOP_SELECTOR = '.style-scope.sj-play-button'
66 TIME_SELECTOR = '#time-container-current' 70 TIME_SELECTOR = '#time-container-current'
67 SEARCH_SELECTOR = '.title.fade-out.tooltip' 71 SEARCH_SELECTOR = '.title.fade-out.tooltip'
68 NAVIGATE_SELECTOR = '.description.tooltip.fade-out' 72 NAVIGATE_SELECTOR = '.description.tooltip.fade-out'
69 73
70 def _Login(self, action_runner): 74 def _Login(self, action_runner):
71 google_login.LoginGoogleAccount(action_runner, 'googletest', 75 google_login.LoginGoogleAccount(action_runner, 'googletest',
72 self.credentials_path) 76 self.credentials_path)
73 77
74 def _NavigateToMedia(self, action_runner): 78 def _NavigateToMedia(self, action_runner):
75 # Clicks on Today's top hits. 79 # Clicks on Today's top hits.
76 action_runner.Wait(1) # Add 1 second wait to make the browsing realistic. 80 action_runner.Wait(1) # Add 1 second wait to make the browsing realistic.
77 self._WaitForAndClickElementBySelector(action_runner, self.SEARCH_SELECTOR) 81 self._WaitForAndClickElementBySelector(action_runner, self.SEARCH_SELECTOR)
78 # Clicks on playlist. 82 # Clicks on playlist.
79 action_runner.Wait(1) # Add 1 second wait to make the browsing realistic. 83 action_runner.Wait(1) # Add 1 second wait to make the browsing realistic.
80 self._WaitForAndClickElementBySelector(action_runner, 84 self._WaitForAndClickElementBySelector(action_runner,
81 self.NAVIGATE_SELECTOR) 85 self.NAVIGATE_SELECTOR)
82 86
83 87
84 @benchmark.Disabled('win') # crbug.com/649392 88 @benchmark.Disabled('win') # crbug.com/649392
85 class SoundCloudDesktopStory(_MediaStory): 89 class SoundCloudDesktopStory(_PlayMediaStory):
86 NAME = 'play:media:soundcloud' 90 NAME = 'play:media:soundcloud'
87 URL = 'https://soundcloud.com' 91 URL = 'https://soundcloud.com'
88 92
89 PLAY_SELECTOR = '.sc-button-play.playButton.sc-button.sc-button-xlarge' 93 PLAY_SELECTOR = '.sc-button-play.playButton.sc-button.sc-button-xlarge'
90 STOP_SELECTOR = '.playControl.playControls__icon.sc-ir.playing' 94 STOP_SELECTOR = '.playControl.playControls__icon.sc-ir.playing'
91 TIME_SELECTOR = '.playbackTimeline__timePassed>span[aria-hidden=true]' 95 TIME_SELECTOR = '.playbackTimeline__timePassed>span[aria-hidden=true]'
92 SEARCH_SELECTOR = '.headerSearch' 96 SEARCH_SELECTOR = '.headerSearch'
93 SEARCH_QUERY = 'SSmooth Jazz' # First S for some reason gets ommited. 97 SEARCH_QUERY = 'SSmooth Jazz' # First S for some reason gets ommited.
94 98
95 def _NavigateToMedia(self, action_runner): 99 def _NavigateToMedia(self, action_runner):
96 self._WaitForAndClickElementBySelector(action_runner, self.SEARCH_SELECTOR) 100 self._WaitForAndClickElementBySelector(action_runner, self.SEARCH_SELECTOR)
97 action_runner.Wait(1) # Add 1 second wait to make the browsing realistic. 101 action_runner.Wait(1) # Add 1 second wait to make the browsing realistic.
98 action_runner.EnterText(self.SEARCH_QUERY) 102 action_runner.EnterText(self.SEARCH_QUERY)
99 action_runner.PressKey('Return') 103 action_runner.PressKey('Return')
100 104
101 105
102 @decorators.Disabled('all') # crbug.com/649392 106 @decorators.Disabled('all') # crbug.com/649392
103 class PandoraDesktopStory(_MediaStory): 107 class PandoraDesktopStory(_PlayMediaStory):
104 NAME = 'play:media:pandora' 108 NAME = 'play:media:pandora'
105 URL = 'https://pandora.com' 109 URL = 'https://pandora.com'
106 110
107 PLAY_SELECTOR = None 111 PLAY_SELECTOR = None
108 STOP_SELECTOR = '.pauseButton' 112 STOP_SELECTOR = '.pauseButton'
109 TIME_SELECTOR = '.elapsedTime' 113 TIME_SELECTOR = '.elapsedTime'
110 SEARCH_SELECTOR = '.searchInput' 114 SEARCH_SELECTOR = '.searchInput'
111 115
112 def _Login(self, action_runner): 116 def _Login(self, action_runner):
113 pandora_login.LoginAccount(action_runner, 'pandora', self.credentials_path) 117 pandora_login.LoginAccount(action_runner, 'pandora', self.credentials_path)
114 118
115 def _NavigateToMedia(self, action_runner): 119 def _NavigateToMedia(self, action_runner):
116 pass # Audio autoplays on Pandora, no need to search. 120 pass # Audio autoplays on Pandora, no need to search.
121
122
123 class YoutubeMobileStory(_PlayMediaStory):
124 NAME = 'play:media:youtube'
125 URL = 'https://m.youtube.in/watch?v=OnhXkCPMeMc'
126 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
127 TAGS = [story_tags.EMERGING_MARKET]
128
129 PLAYER_FUNCTION = 'document.getElementById("player")'
130 STOP_FUNCTION = 'document.getElementsByTagName("video")[0].pause()'
131 TIME_FUNCTION = 'document.getElementsByTagName("video")[0].currentTime'
132
133 def RunPageInteractions(self, action_runner):
134 app_ui = action_runner.tab.browser.app_ui
135 action_runner.WaitForElement(element_function=self.PLAYER_FUNCTION)
136
137 # Simulate user click in system ui since youtube play can be initialied only
138 # by user gesture.
139 renderer_view_id = 'compositor_view_holder'
140 app_ui.WaitForUiNode(resource_id=renderer_view_id)
141 renderer_view = app_ui.GetUiNode(resource_id=renderer_view_id)
142 # Click on the top half of the renderer view to start video.
143 shifted_center = 0.5 * (
144 renderer_view.bounds.center + renderer_view.bounds.top_left)
145 renderer_view.Tap(point=shifted_center)
146
147 self._WaitForPlayTime(action_runner)
148 action_runner.EvaluateJavaScript(self.STOP_FUNCTION)
149 self._Measure(action_runner)
150
151
152 def _GetTimeInSeconds(self, action_runner):
153 return int(action_runner.EvaluateJavaScript(self.TIME_FUNCTION))
154
155 def _NavigateToMedia(self, action_runner):
156 pass # Users usually open youtube links directly, skip searching.
157
158
159 ################################################################################
160 # Photos browsing stories.
161 ################################################################################
162
163
164 class _PhotoBrowsingStory(browsing_stories.BrowsingStory):
165 """Abstract base class for media user stories
166
167 A media story imitates browsing a website with photo or video content:
168 1. Load a page showing a media item
169 2. Click on the next link to go to the next media item
170 3. etc.
171 """
172
173 ABSTRACT_STORY = True
174 ITEM_VIEW_TIME_IN_SECONDS = 3
175 ITEMS_TO_VISIT = 15
176 ITEM_SELECTOR_INDEX = 0
177 INCREMENT_INDEX_AFTER_EACH_ITEM = False
178
179 def _DidLoadDocument(self, action_runner):
180 index = self.ITEM_SELECTOR_INDEX
181 for _ in xrange(self.ITEMS_TO_VISIT):
182 self._NavigateToItem(action_runner, index)
183 self._ViewMediaItem(action_runner, index)
184 if self.INCREMENT_INDEX_AFTER_EACH_ITEM:
185 index += 1
186
187
188 def _ViewMediaItem(self, action_runner, index):
189 del index # Unused.
190 action_runner.tab.WaitForDocumentReadyStateToBeComplete()
191 action_runner.Wait(self.ITEM_VIEW_TIME_IN_SECONDS)
192
193
194 class ImgurMobileStory(_PhotoBrowsingStory):
195 NAME = 'browse:media:imgur'
196 URL = 'http://imgur.com/gallery/5UlBN'
197 ITEM_SELECTOR = '.Navbar-customAction'
198 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
199 IS_SINGLE_PAGE_APP = True
200 TAGS = [story_tags.EMERGING_MARKET]
201
202
203 # crbug.com/704197 for win and mac
204 @decorators.Disabled('win', 'mac')
205 class ImgurDesktopStory(_PhotoBrowsingStory):
206 NAME = 'browse:media:imgur'
207 URL = 'http://imgur.com/gallery/5UlBN'
208 ITEM_SELECTOR = '.navNext'
209 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY
210 IS_SINGLE_PAGE_APP = True
211
212
213 # TODO(ssid): Remove this story since we have play youtube story
214 # crbug.com/708300.
215 class YouTubeMobileStory(_PhotoBrowsingStory):
216 NAME = 'browse:media:youtube'
217 URL = 'https://m.youtube.com/watch?v=QGfhS1hfTWw&autoplay=false'
218 ITEM_SELECTOR = '._mhgb > a'
219 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
220 IS_SINGLE_PAGE_APP = True
221 ITEM_SELECTOR_INDEX = 3
222 TAGS = [story_tags.JAVASCRIPT_HEAVY]
223
224
225 class YouTubeDesktopStory(_PhotoBrowsingStory):
226 NAME = 'browse:media:youtube'
227 URL = 'https://www.youtube.com/watch?v=QGfhS1hfTWw&autoplay=false'
228 ITEM_SELECTOR = '.yt-uix-simple-thumb-related'
229 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY
230 IS_SINGLE_PAGE_APP = True
231 # A longer view time allows videos to load and play.
232 ITEM_VIEW_TIME_IN_SECONDS = 5
233 ITEMS_TO_VISIT = 8
234 ITEM_SELECTOR_INDEX = 3
235 PLATFORM_SPECIFIC = True
236 TAGS = [story_tags.JAVASCRIPT_HEAVY]
237
238
239 class FacebookPhotosMobileStory(_PhotoBrowsingStory):
240 NAME = 'browse:media:facebook_photos'
241 URL = (
242 'https://m.facebook.com/rihanna/photos/a.207477806675.138795.10092511675/1 0153911739606676/?type=3&source=54&ref=page_internal')
243 ITEM_SELECTOR = '._57-r.touchable'
244 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
245 IS_SINGLE_PAGE_APP = True
246 ITEM_SELECTOR_INDEX = 0
247 TAGS = [story_tags.EMERGING_MARKET]
248
249
250 class FacebookPhotosDesktopStory(_PhotoBrowsingStory):
251 NAME = 'browse:media:facebook_photos'
252 URL = (
253 'https://www.facebook.com/rihanna/photos/a.207477806675.138795.10092511675 /10153911739606676/?type=3&theater')
254 ITEM_SELECTOR = '.snowliftPager.next'
255 # Recording currently does not work. The page gets stuck in the
256 # theater viewer.
257 SUPPORTED_PLATFORMS = platforms.NO_PLATFORMS
258 IS_SINGLE_PAGE_APP = True
259
260
261 class TumblrDesktopStory(_PhotoBrowsingStory):
262 NAME = 'browse:media:tumblr'
263 URL = 'https://tumblr.com/search/gifs'
264 ITEM_SELECTOR = '.photo'
265 IS_SINGLE_PAGE_APP = True
266 ITEMS_TO_VISIT = 8
267 INCREMENT_INDEX_AFTER_EACH_ITEM = True
268 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY
269
270 def _ViewMediaItem(self, action_runner, index):
271 super(TumblrDesktopStory, self)._ViewMediaItem(action_runner, index)
272 action_runner.MouseClick(selector='#tumblr_lightbox_center_image')
273 action_runner.Wait(1) # To make browsing more realistic.
274
275
276 class PinterestDesktopStory(_PhotoBrowsingStory):
277 NAME = 'browse:media:pinterest'
278 URL = 'https://pinterest.com'
279 ITEM_SELECTOR = '.pinImageDim'
280 IS_SINGLE_PAGE_APP = True
281 ITEMS_TO_VISIT = 8
282 INCREMENT_INDEX_AFTER_EACH_ITEM = True
283 SUPPORTED_PLATFORMS = platforms.DESKTOP_ONLY
284
285 def _Login(self, action_runner):
286 pinterest_login.LoginDesktopAccount(action_runner, 'googletest',
287 self.credentials_path)
288
289 def _ViewMediaItem(self, action_runner, index):
290 super(PinterestDesktopStory, self)._ViewMediaItem(action_runner, index)
291 # To imitate real user interaction, we do not want to pin every post.
292 # We will only pin every other post.
293 if index % 2 == 0:
294 # Pin the selection.
295 save_function = ('document.querySelector('
296 '".Button.Module.ShowModalButton.btn.hasIcon.hasText.'
297 'isBrioFlat.medium.primary.primaryOnHover.repin.'
298 'pinActionBarButton.isBrioFlat.rounded")')
299 action_runner.ClickElement(element_function=save_function)
300 action_runner.Wait(1) # Wait to make navigation realistic.
301 # Select which board to pin to.
302 inner_save_function = 'document.querySelector(".nameAndIcons")'
303 action_runner.WaitForElement(element_function=inner_save_function)
304 action_runner.ClickElement(element_function=inner_save_function)
305 action_runner.Wait(1) # Wait to make navigation realistic.
306
307 # Close selection.
308 x_element_function = ('document.querySelector('
309 '".Button.borderless.close.visible")')
310 action_runner.ClickElement(element_function=x_element_function)
311 action_runner.Wait(1) # Wait to make navigation realistic.
312
313
314 # Instagram requires navigate back to view next photo So, use
315 # ArticleBrowsingStory.
316 class InstagramMobileStory(browsing_stories.ArticleBrowsingStory):
317 NAME = 'browse:media:instagram'
318 URL = 'https://www.instagram.com/badgalriri/'
319 ITEM_SELECTOR = '[class=\\"_8mlbc _vbtk2 _t5r8b\\"]'
320 ITEMS_TO_VISIT = 8
321 IS_SINGLE_PAGE_APP = True
322
323 SUPPORTED_PLATFORMS = platforms.MOBILE_ONLY
324 TAGS = [story_tags.EMERGING_MARKET]
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698