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 logging 7 import os 8 import time 9 10 import pyauto_functional 11 import pyauto 12 import test_utils 13 14 15 class NetflixTestHelper(): 16 """Helper functions for Netflix tests. 17 18 For sample usage, look at class NetflixTest. 19 """ 20 21 # Netflix player states. 22 IS_GUEST_MODE_ERROR = '0' 23 IS_PLAYING = '4' 24 25 TITLE_HOMEPAGE = 'http://movies.netflix.com/WiHome' 26 SIGNOUT_PAGE = 'https://account.netflix.com/Logout' 27 # 30 Rock. 28 VIDEO_URL = 'https://movies.netflix.com/WiPlayer?movieid=70136124' 29 ALT_VIDEO_URL = 'https://movies.netflix.com/WiPlayer?movieid=70133713' 30 _pyauto = None 31 32 def __init__(self, pyauto): 33 self._pyauto = pyauto 34 35 def _IsNetflixPluginEnabled(self): 36 """Determine Netflix plugin availability and its state.""" 37 return [x for x in self._pyauto.GetPluginsInfo().Plugins() \ 38 if x['name'] == 'Netflix' and x['enabled']] 39 40 def _LoginToNetflix(self): 41 """Login to Netflix.""" 42 credentials = self._pyauto.GetPrivateInfo()['test_netflix_acct'] 43 board_name = self._pyauto.ChromeOSBoard() 44 assert credentials.get(board_name), \ 45 'No netflix credentials for %s.' % board_name 46 self._pyauto.NavigateToURL(credentials['login_url']) 47 login_js = """ 48 document.getElementById('email').value='%s'; 49 document.getElementById('password').value='%s'; 50 window.domAutomationController.send('ok'); 51 """ % (credentials[board_name], credentials['password']) 52 self._pyauto.assertEqual(self._pyauto.ExecuteJavascript(login_js), 'ok', 53 msg='Failed to set login credentials.') 54 self._pyauto.assertTrue(self._pyauto.SubmitForm('login-form'), 55 msg='Login to Netflix failed. We think this is an authetication ' 56 'problem from the Netflix side. Sometimes we also see this while ' 57 'login in manually.') 58 59 def _GetVideoDroppedFrames(self, tab_index=0, windex=0): 60 """Returns total Netflix video dropped frames.""" 61 js = """ 62 var frames = nrdp.video.droppedFrames; 63 window.domAutomationController.send(frames + ''); 64 """ 65 return int(self._pyauto.ExecuteJavascript(js, tab_index=tab_index, 66 windex=windex)) 67 68 def _GetVideoFrames(self, tab_index=0, windex=0): 69 """Returns Netflix video total frames.""" 70 js = """ 71 var frames = nrdp.video.totalFrames; 72 window.domAutomationController.send(frames + ''); 73 """ 74 return int(self._pyauto.ExecuteJavascript(js, tab_index=tab_index, 75 windex=windex)) 76 77 def _HandleInfobars(self, err_msg): 78 """Manage infobars that come up during the test.""" 79 def _HandleNetflixInfobar(): 80 tab_info = self._pyauto.GetBrowserInfo()['windows'][0]['tabs'][0] 81 infobars = tab_info['infobars'] 82 index = 0 83 for infobar in infobars: 84 if 'netflix' in infobar['text']: 85 # After storage infobar pops up, clicking the Ok button immediately 86 # returns the Storage error on faster machines like Stumpy/Lumpy so 87 # adding a delay of 1 second here. 88 time.sleep(1) 89 self._pyauto.PerformActionOnInfobar('accept', infobar_index=index) 90 return True 91 index = index + 1 92 return False 93 self._pyauto.assertTrue(self._pyauto.WaitUntil(_HandleNetflixInfobar), 94 msg=err_msg) 95 96 def CurrentPlaybackTime(self): 97 """Returns the current playback time in seconds.""" 98 time = self._pyauto.ExecuteJavascript(""" 99 time = nrdp.video.currentTime; 100 window.domAutomationController.send(time + ''); 101 """) 102 return int(float(time)) 103 104 def SignOut(self): 105 """Sign out from Netflix Login.""" 106 self._pyauto.NavigateToURL(self.SIGNOUT_PAGE) 107 108 def LoginAndStartPlaying(self): 109 """Login and start playing the video.""" 110 self._pyauto.assertTrue(self._pyauto._IsNetflixPluginEnabled(), 111 msg='Netflix plugin is disabled or not available.') 112 self._pyauto._LoginToNetflix() 113 self._pyauto.assertTrue(self._pyauto.WaitUntil( 114 lambda: self._pyauto.GetActiveTabURL().spec(), 115 expect_retval=self.TITLE_HOMEPAGE), 116 msg='Login to Netflix failed.') 117 self._pyauto.NavigateToURL(self.VIDEO_URL) 118 self._pyauto._HandleInfobars(err_msg='Netflix infobar did not show up') 119 120 def CheckNetflixPlaying(self, expected_result, error_msg): 121 """Check if Netflix is playing the video or not. 122 123 Args: 124 expected_result: expected return value from Netflix player. 125 error_msg: If expected value isn't matching, error message to throw. 126 """ 127 self._pyauto.assertTrue(self._pyauto.WaitUntil( 128 lambda: self._pyauto.ExecuteJavascript(""" 129 if (typeof nrdp == 'undefined') { 130 window.domAutomationController.send('not ready'); 131 } 132 player_status = nrdp.video.readyState; 133 window.domAutomationController.send(player_status + ''); 134 """), expect_retval=expected_result), 135 msg=error_msg) 136 137 138 class NetflixTest(pyauto.PyUITest, NetflixTestHelper): 139 """Test case for Netflix player.""" 140 141 def __init__(self, methodName='runTest', **kwargs): 142 pyauto.PyUITest.__init__(self, methodName, **kwargs) 143 NetflixTestHelper.__init__(self, self) 144 145 def ShouldAutoLogin(self): 146 return False 147 148 def _Login(self): 149 """Perform login""" 150 credentials = self.GetPrivateInfo()['test_google_account'] 151 self.Login(credentials['username'], credentials['password']) 152 logging.info('Logged in as %s' % credentials['username']) 153 login_info = self.GetLoginInfo() 154 self.assertTrue(login_info['is_logged_in'], msg='Login failed.') 155 self.assertFalse(login_info['is_guest'], 156 msg='Should not be logged in as guest.') 157 158 def setUp(self): 159 assert os.geteuid() == 0, 'Run test as root since we might need to logout' 160 pyauto.PyUITest.setUp(self) 161 if self.GetLoginInfo()['is_logged_in']: 162 self.Logout() 163 self._Login() 164 165 def tearDown(self): 166 self.SignOut() 167 pyauto.PyUITest.tearDown(self) 168 169 def testPlayerLoadsAndPlays(self): 170 """Test that Netflix player loads and plays the title.""" 171 self.LoginAndStartPlaying() 172 self._HandleInfobars(err_msg='Netflix plugin access infobar did not show up') 173 self.CheckNetflixPlaying(self.IS_PLAYING, 174 'Player did not start playing the title.') 175 176 def testMultiplePlayback(self): 177 """Test that playing two titles, Netflix returns multiple play error.""" 178 self.LoginAndStartPlaying() 179 self._HandleInfobars(err_msg='Netflix plugin access infobar did not show up') 180 self.CheckNetflixPlaying(self.IS_PLAYING, 181 'Player did not start playing the title.') 182 self.AppendTab(self.ALT_VIDEO_URL) 183 self.assertTrue('Multiple Play Error' in self.GetTabContents(), 184 msg='Multiple Play Error is not found on the page.') 185 186 def testPlaying(self): 187 """Test that title playing progresses.""" 188 self.LoginAndStartPlaying() 189 self._HandleInfobars(err_msg='Netflix plugin access infobar did not show up') 190 self.CheckNetflixPlaying(self.IS_PLAYING, 191 'Player did not start playing the title.') 192 title_length = self.ExecuteJavascript(""" 193 time = nrdp.video.duration; 194 window.domAutomationController.send(time + ''); 195 """) 196 title_length = int(float(title_length)) 197 prev_time = 0 198 current_time = 0 199 count = 0 200 while current_time < title_length: 201 # We want to test playing only for ten seconds. 202 count = count + 1 203 if count == 10: 204 break 205 current_time = self.CurrentPlaybackTime() 206 self.assertTrue(prev_time <= current_time, 207 msg='Prev playing time %s is greater than current time %s.' 208 % (prev_time, current_time)) 209 prev_time = current_time 210 # play video for some time 211 time.sleep(1) 212 # In case player doesn't start playing at all, above while loop may 213 # still pass. So re-verifying and assuming that player did play something 214 # during last 10 seconds. 215 self.assertTrue(current_time > 0, 216 msg='Netflix player did not start playing.') 217 218 219 class NetflixGuestModeTest(pyauto.PyUITest, NetflixTestHelper): 220 """Netflix in guest mode.""" 221 222 def __init__(self, methodName='runTest', **kwargs): 223 pyauto.PyUITest.__init__(self, methodName, **kwargs) 224 NetflixTestHelper.__init__(self, self) 225 226 def setUp(self): 227 assert os.geteuid() == 0, 'Run test as root since we might need to logout' 228 pyauto.PyUITest.setUp(self) 229 if self.GetLoginInfo()['is_logged_in']: 230 self.Logout() 231 self.LoginAsGuest() 232 login_info = self.GetLoginInfo() 233 self.assertTrue(login_info['is_logged_in'], msg='Not logged in at all.') 234 self.assertTrue(login_info['is_guest'], msg='Not logged in as guest.') 235 236 def ShouldAutoLogin(self): 237 return False 238 239 def tearDown(self): 240 self.AppendTab(self.SIGNOUT_PAGE) 241 self.Logout() 242 pyauto.PyUITest.tearDown(self) 243 244 def testGuestMode(self): 245 """Test that Netflix doesn't play in guest mode login.""" 246 self.LoginAndStartPlaying() 247 self.CheckNetflixPlaying( 248 self.IS_GUEST_MODE_ERROR, 249 'Netflix player did not return a Guest mode error.') 250 # crosbug.com/p/14009 251 self.assertTrue('Netflix Video Player Unavailable' in self.GetTabContents(), 252 msg='Guest Mode error is not found on the page.') 253 254 255 if __name__ == '__main__': 256 pyauto_functional.Main() 257