Home | History | Annotate | Download | only in functional
      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