- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / test / functional / youtube.py
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()