OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
3 # Use of this source code is governed by a BSD-style license that can be | |
4 # found in the LICENSE file. | |
5 | |
6 import re | |
7 import time | |
8 | |
9 import pyauto_functional | |
10 import pyauto | |
11 import pyauto_errors | |
12 import test_utils | |
13 | |
14 | |
15 class YoutubeTestHelper(): | |
16 """Helper functions for Youtube tests. | |
17 | |
18 For sample usage, look at class YoutubeTest. | |
19 """ | |
20 | |
21 # YouTube player states | |
22 is_unstarted = '-1' | |
23 is_playing = '1' | |
24 is_paused = '2' | |
25 has_ended = '0' | |
26 _pyauto = None | |
27 | |
28 def __init__(self, pyauto): | |
29 self._pyauto = pyauto | |
30 | |
31 def IsFlashPluginEnabled(self): | |
32 """Verify flash plugin availability and its state.""" | |
33 return [x for x in self._pyauto.GetPluginsInfo().Plugins() \ | |
34 if x['name'] == 'Shockwave Flash' and x['enabled']] | |
35 | |
36 def AssertPlayerState(self, state, msg): | |
37 expected_regex = '^%s$' % state | |
38 self.WaitForDomNode('id("playerState")', expected_value=expected_regex, | |
39 msg=msg) | |
40 | |
41 def WaitUntilPlayerReady(self): | |
42 """Verify that player is ready.""" | |
43 self.AssertPlayerState(state=self.is_unstarted, | |
44 msg='Failed to load youtube player.') | |
45 | |
46 def GetPlayerState(self): | |
47 """Returns a player state.""" | |
48 js = """ | |
49 var val = ytplayer.getPlayerState(); | |
50 window.domAutomationController.send(val + ''); | |
51 """ | |
52 return self._pyauto.ExecuteJavascript(js) | |
53 | |
54 def GetVideoInfo(self): | |
55 """Returns Youtube video info.""" | |
56 youtube_apis = self._pyauto.GetPrivateInfo()['youtube_api'] | |
57 youtube_debug_text = youtube_apis['GetDebugText'] | |
58 return self._pyauto.ExecuteJavascript( | |
59 'window.domAutomationController.send(%s);' % youtube_debug_text) | |
60 | |
61 def GetVideoDroppedFrames(self): | |
62 """Returns total Youtube video dropped frames. | |
63 | |
64 Returns: | |
65 -1 if failed to get video frames from the video data | |
66 """ | |
67 video_data = self._pyauto.GetVideoInfo() | |
68 matched = re.search('droppedFrames=([\d\.]+)', video_data) | |
69 if matched: | |
70 return int(matched.group(1)) | |
71 else: | |
72 return -1 | |
73 | |
74 def GetVideoFrames(self): | |
75 """Returns Youtube video frames/second. | |
76 | |
77 Returns: | |
78 -1 if failed to get droppd frames from the video data. | |
79 """ | |
80 video_data = self._pyauto.GetVideoInfo() | |
81 matched = re.search('videoFps=([\d\.]+)', video_data) | |
82 if matched: | |
83 return int(matched.group(1)) | |
84 else: | |
85 return -1 | |
86 | |
87 def GetVideoTotalBytes(self): | |
88 """Returns video total size in bytes. | |
89 | |
90 To call this function, video must be in the paying state, | |
91 or this returns 0. | |
92 """ | |
93 total_bytes = 0 | |
94 total_bytes = self._pyauto.ExecuteJavascript(""" | |
95 bytesTotal = document.getElementById("bytesTotal"); | |
96 window.domAutomationController.send(bytesTotal.innerHTML); | |
97 """) | |
98 return int(total_bytes) | |
99 | |
100 def GetVideoLoadedBytes(self): | |
101 """Returns video size in bytes.""" | |
102 loaded_bytes = 0 | |
103 loaded_bytes = self.ExecuteJavascript(""" | |
104 bytesLoaded = document.getElementById("bytesLoaded"); | |
105 window.domAutomationController.send(bytesLoaded.innerHTML); | |
106 """) | |
107 return int(loaded_bytes) | |
108 | |
109 def GetCurrentVideoTime(self): | |
110 """Returns the current time of the video in seconds.""" | |
111 current_time = 0 | |
112 current_time = self.ExecuteJavascript(""" | |
113 videoCurrentTime = document.getElementById("videoCurrentTime"); | |
114 window.domAutomationController.send(videoCurrentTime.innerHTML); | |
115 """) | |
116 return int(current_time) | |
117 | |
118 def PlayVideo(self): | |
119 """Plays the loaded video.""" | |
120 self._pyauto.ExecuteJavascript(""" | |
121 ytplayer.playVideo(); | |
122 window.domAutomationController.send(''); | |
123 """) | |
124 | |
125 def StopVideo(self): | |
126 """Stops the video and cancels loading.""" | |
127 self._pyauto.ExecuteJavascript(""" | |
128 ytplayer.stopVideo(); | |
129 window.domAutomationController.send(''); | |
130 """) | |
131 | |
132 def PauseVideo(self): | |
133 """Pause the video.""" | |
134 self.ExecuteJavascript(""" | |
135 ytplayer.pauseVideo(); | |
136 window.domAutomationController.send(''); | |
137 """) | |
138 | |
139 def PlayVideoAndAssert(self, youtube_video='zuzaxlddWbk', | |
140 ignore_assert=False): | |
141 """Start video and assert the playing state. | |
142 | |
143 By default test uses http://www.youtube.com/watch?v=zuzaxlddWbki. | |
144 | |
145 Args: | |
146 youtube_video: The string ID of the youtube video to play. | |
147 ignore_assert: flag to ignore the assertion and continue the test. | |
148 """ | |
149 self._pyauto.assertTrue(self._pyauto.IsFlashPluginEnabled(), | |
150 msg='From here Flash plugin is disabled or not available.') | |
151 url = self._pyauto.GetHttpURLForDataPath( | |
152 'media', 'youtube.html?video=' + youtube_video) | |
153 self._pyauto.NavigateToURL(url) | |
154 self.WaitUntilPlayerReady() | |
155 i = 0 | |
156 # The YouTube player will get in a state where it does not return the | |
157 # number of loaded bytes. When this happens we need to reload the page | |
158 # before starting the test. | |
159 while self.GetVideoLoadedBytes() == 1 and i < 30: | |
160 self._pyauto.NavigateToURL(url) | |
161 self.WaitUntilPlayerReady() | |
162 i = i + 1 | |
163 self.PlayVideo() | |
164 if ignore_assert: | |
165 return self.is_playing | |
166 self.AssertPlayerState(state=self.is_playing, | |
167 msg='Player did not enter the playing state.') | |
168 | |
169 def VideoBytesLoadingAndAssert(self): | |
170 """Assert the video loading.""" | |
171 total_bytes = self.GetVideoTotalBytes() | |
172 prev_loaded_bytes = 0 | |
173 loaded_bytes = 0 | |
174 count = 0 | |
175 while loaded_bytes < total_bytes: | |
176 # We want to test bytes loading only twice | |
177 count = count + 1 | |
178 if count == 2: | |
179 break | |
180 loaded_bytes = self.GetVideoLoadedBytes() | |
181 self.assertTrue(prev_loaded_bytes <= loaded_bytes) | |
182 prev_loaded_bytes = loaded_bytes | |
183 # Give some time to load a video | |
184 time.sleep(1) | |
185 | |
186 def PlayFAVideo(self): | |
187 """Play and assert FA video playing. | |
188 | |
189 We are using multiple test videos in case any FA video playback fails | |
190 becuase other tests are palying the same video and the test gets the | |
191 simultaneous playback error. | |
192 """ | |
193 fa_videos = ('APRpcscmbY0', 'yQqvrED-np0', 'KJuFw6hQdNY', | |
194 'BeFQbgxr_9g', 'L6JwlOudqA4') | |
195 credentials = self.GetPrivateInfo()['test_fa_account'] | |
196 test_utils.GoogleAccountsLogin(self, | |
197 credentials['username'], credentials['password']) | |
198 for video in fa_videos: | |
199 result = self.PlayVideoAndAssert(video, ignore_assert=True) | |
200 if result is self.is_playing: | |
201 return | |
202 self.assertTrue(False, msg='Player did not enter the playing state.') | |
203 | |
204 | |
205 class YoutubeTest(pyauto.PyUITest, YoutubeTestHelper): | |
206 """Test case for Youtube videos.""" | |
207 | |
208 def __init__(self, methodName='runTest', **kwargs): | |
209 pyauto.PyUITest.__init__(self, methodName, **kwargs) | |
210 YoutubeTestHelper.__init__(self, self) | |
211 | |
212 def testPlayerStatus(self): | |
213 """Test that YouTube loads a player and changes player states. | |
214 | |
215 Test verifies various player states like unstarted, playing, paused | |
216 and ended. | |
217 """ | |
218 # Navigating to Youtube video. This video is 122 seconds long. | |
219 # During tests, we are not goinig to play this video full. | |
220 self.PlayVideoAndAssert() | |
221 self.PauseVideo() | |
222 self.AssertPlayerState(state=self.is_paused, | |
223 msg='Player did not enter the paused state.') | |
224 # Seek to the end of video | |
225 self.ExecuteJavascript(""" | |
226 val = ytplayer.getDuration(); | |
227 ytplayer.seekTo(val, true); | |
228 window.domAutomationController.send(''); | |
229 """) | |
230 self.PlayVideo() | |
231 # We've seeked to almost the end of the video but not quite. | |
232 # Wait until the end. | |
233 self.AssertPlayerState(state=self.has_ended, | |
234 msg='Player did not reach the stopped state.') | |
235 | |
236 def testPlayerResolution(self): | |
237 """Test various video resolutions.""" | |
238 self.PlayVideoAndAssert() | |
239 resolutions = self.ExecuteJavascript(""" | |
240 res = ytplayer.getAvailableQualityLevels(); | |
241 window.domAutomationController.send(res.toString()); | |
242 """) | |
243 resolutions = resolutions.split(',') | |
244 for res in resolutions: | |
245 self.ExecuteJavascript(""" | |
246 ytplayer.setPlaybackQuality('%s'); | |
247 window.domAutomationController.send(''); | |
248 """ % res) | |
249 curr_res = self.ExecuteJavascript(""" | |
250 res = ytplayer.getPlaybackQuality(); | |
251 window.domAutomationController.send(res + ''); | |
252 """) | |
253 self.assertEqual(res, curr_res, msg='Resolution is not set to %s.' % res) | |
254 | |
255 def testPlayerBytes(self): | |
256 """Test that player downloads video bytes.""" | |
257 self.PlayVideoAndAssert() | |
258 self.VideoBytesLoadingAndAssert() | |
259 | |
260 def testFAVideo(self): | |
261 """Test that FlashAccess/DRM video plays.""" | |
262 self.PlayFAVideo() | |
263 self.StopVideo() | |
264 | |
265 def testFAVideoBytes(self): | |
266 """Test FlashAccess/DRM video bytes loading.""" | |
267 self.PlayFAVideo() | |
268 self.VideoBytesLoadingAndAssert() | |
269 self.StopVideo() | |
270 | |
271 | |
272 if __name__ == '__main__': | |
273 pyauto_functional.Main() | |
OLD | NEW |