| 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 |