1*9c5db199SXin Li# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2*9c5db199SXin Li# Use of this source code is governed by a BSD-style license that can be 3*9c5db199SXin Li# found in the LICENSE file. 4*9c5db199SXin Li 5*9c5db199SXin Liimport logging 6*9c5db199SXin Liimport time 7*9c5db199SXin Li 8*9c5db199SXin Lifrom autotest_lib.client.bin import utils 9*9c5db199SXin Lifrom autotest_lib.client.common_lib import error 10*9c5db199SXin Lifrom autotest_lib.client.cros.graphics import graphics_utils 11*9c5db199SXin Li 12*9c5db199SXin Li 13*9c5db199SXin LiPLAYBACK_TEST_TIME_S = 10 14*9c5db199SXin LiPLAYER_ENDED_STATE = 'Ended' 15*9c5db199SXin LiPLAYER_PAUSE_STATE = 'Paused' 16*9c5db199SXin LiPLAYER_PLAYING_STATE = 'Playing' 17*9c5db199SXin LiWAIT_TIMEOUT_S = 20 18*9c5db199SXin Li 19*9c5db199SXin Li 20*9c5db199SXin Liclass YouTubeHelper(object): 21*9c5db199SXin Li """A helper class contains YouTube related utility functions. 22*9c5db199SXin Li 23*9c5db199SXin Li To use this class, please call wait_for_player_state(playing) as below 24*9c5db199SXin Li before calling set_video_duration. Please note that set_video_duration 25*9c5db199SXin Li must be called in order to access few functions which uses the video 26*9c5db199SXin Li length member variable. 27*9c5db199SXin Li 28*9c5db199SXin Li yh = youtube_helper.YouTubeHelper(tab) 29*9c5db199SXin Li yh.wait_for_player_state(PLAYER_PLAYING_STATE) 30*9c5db199SXin Li yh.set_video_duration() 31*9c5db199SXin Li 32*9c5db199SXin Li """ 33*9c5db199SXin Li 34*9c5db199SXin Li def __init__(self, youtube_tab): 35*9c5db199SXin Li self._tab = youtube_tab 36*9c5db199SXin Li self._video_duration = 0 37*9c5db199SXin Li 38*9c5db199SXin Li 39*9c5db199SXin Li def set_video_duration(self): 40*9c5db199SXin Li """Sets the video duration.""" 41*9c5db199SXin Li self._video_duration = (int(self._tab.EvaluateJavaScript( 42*9c5db199SXin Li 'player.getDuration()'))) 43*9c5db199SXin Li 44*9c5db199SXin Li def video_current_time(self): 45*9c5db199SXin Li """Returns video's current playback time. 46*9c5db199SXin Li 47*9c5db199SXin Li Returns: 48*9c5db199SXin Li returns the current playback location in seconds (int). 49*9c5db199SXin Li 50*9c5db199SXin Li """ 51*9c5db199SXin Li return int(self._tab.EvaluateJavaScript('player.getCurrentTime()')) 52*9c5db199SXin Li 53*9c5db199SXin Li def get_player_status(self): 54*9c5db199SXin Li """Returns the player status.""" 55*9c5db199SXin Li return self._tab.EvaluateJavaScript( 56*9c5db199SXin Li '(typeof playerStatus !== \'undefined\') && ' 57*9c5db199SXin Li 'playerStatus.innerHTML') 58*9c5db199SXin Li 59*9c5db199SXin Li def get_playback_quality(self): 60*9c5db199SXin Li """Returns the playback quality.""" 61*9c5db199SXin Li return self._tab.EvaluateJavaScript('player.getPlaybackQuality()') 62*9c5db199SXin Li 63*9c5db199SXin Li def wait_for_player_state(self, expected_status): 64*9c5db199SXin Li """Wait till the player status changes to expected_status. 65*9c5db199SXin Li 66*9c5db199SXin Li If the status doesn't change for long, the test will time out after 67*9c5db199SXin Li WAIT_TIMEOUT_S and fails. 68*9c5db199SXin Li 69*9c5db199SXin Li @param expected_status: status which is expected for the test 70*9c5db199SXin Li to continue. 71*9c5db199SXin Li 72*9c5db199SXin Li """ 73*9c5db199SXin Li utils.poll_for_condition( 74*9c5db199SXin Li lambda: self.get_player_status() == expected_status, 75*9c5db199SXin Li exception=error.TestError( 76*9c5db199SXin Li 'Video failed to load. Player expected status: %s' 77*9c5db199SXin Li ' and current status: %s.' 78*9c5db199SXin Li % (expected_status, self.get_player_status())), 79*9c5db199SXin Li timeout=WAIT_TIMEOUT_S, 80*9c5db199SXin Li sleep_interval=1) 81*9c5db199SXin Li 82*9c5db199SXin Li def verify_video_playback(self): 83*9c5db199SXin Li """Verify the video playback.""" 84*9c5db199SXin Li logging.info('Verifying the YouTube video playback.') 85*9c5db199SXin Li playback = 0 # seconds 86*9c5db199SXin Li prev_playback = 0 87*9c5db199SXin Li count = 0 88*9c5db199SXin Li while (self.video_current_time() < self._video_duration 89*9c5db199SXin Li and playback < PLAYBACK_TEST_TIME_S): 90*9c5db199SXin Li time.sleep(1) 91*9c5db199SXin Li if self.video_current_time() <= prev_playback: 92*9c5db199SXin Li if count < 2: 93*9c5db199SXin Li logging.info('Retrying to video playback test.') 94*9c5db199SXin Li self._tab.ExecuteJavaScript( 95*9c5db199SXin Li 'player.seekTo(%d, true)' 96*9c5db199SXin Li % (self.video_current_time() + 2)) 97*9c5db199SXin Li time.sleep(1) 98*9c5db199SXin Li count = count + 1 99*9c5db199SXin Li else: 100*9c5db199SXin Li player_status = self.get_player_status() 101*9c5db199SXin Li raise error.TestError( 102*9c5db199SXin Li 'Video is not playing. Player status: %s.' % 103*9c5db199SXin Li player_status) 104*9c5db199SXin Li prev_playback = self.video_current_time() 105*9c5db199SXin Li playback = playback + 1 106*9c5db199SXin Li 107*9c5db199SXin Li def verify_player_states(self): 108*9c5db199SXin Li """Verify the player states like play, pause, ended and seek.""" 109*9c5db199SXin Li logging.info('Verifying the player states.') 110*9c5db199SXin Li self._tab.ExecuteJavaScript('player.pauseVideo()') 111*9c5db199SXin Li self.wait_for_player_state(PLAYER_PAUSE_STATE) 112*9c5db199SXin Li self._tab.ExecuteJavaScript('player.playVideo()') 113*9c5db199SXin Li self.wait_for_player_state(PLAYER_PLAYING_STATE) 114*9c5db199SXin Li # We are seeking the player position to (video length - 2 seconds). 115*9c5db199SXin Li # Since the player waits for WAIT_TIMEOUT_S for the status change, 116*9c5db199SXin Li # the video should be ended before we hit the timeout. 117*9c5db199SXin Li video_end_test_duration = (self._video_duration - 118*9c5db199SXin Li self.video_current_time() - 2) 119*9c5db199SXin Li if video_end_test_duration >= WAIT_TIMEOUT_S: 120*9c5db199SXin Li self._tab.ExecuteJavaScript( 121*9c5db199SXin Li 'player.seekTo(%d, true)' % (self._video_duration - 5)) 122*9c5db199SXin Li self.wait_for_player_state(PLAYER_ENDED_STATE) 123*9c5db199SXin Li else: 124*9c5db199SXin Li raise error.TestError( 125*9c5db199SXin Li 'Test video is not long enough for the video end test.') 126*9c5db199SXin Li # Verifying seek back from the end position. 127*9c5db199SXin Li self._tab.ExecuteJavaScript('player.seekTo(%d, true)' 128*9c5db199SXin Li % (self._video_duration / 2)) 129*9c5db199SXin Li self.wait_for_player_state(PLAYER_PLAYING_STATE) 130*9c5db199SXin Li # So the playback doesn't stay at the mid. 131*9c5db199SXin Li seek_test = False 132*9c5db199SXin Li for _ in range(WAIT_TIMEOUT_S): 133*9c5db199SXin Li logging.info('Waiting for seek position to change.') 134*9c5db199SXin Li time.sleep(1) 135*9c5db199SXin Li seek_position = self.video_current_time() 136*9c5db199SXin Li if (seek_position > self._video_duration / 2 137*9c5db199SXin Li and seek_position < self._video_duration): 138*9c5db199SXin Li seek_test = True 139*9c5db199SXin Li break 140*9c5db199SXin Li if not seek_test: 141*9c5db199SXin Li raise error.TestError( 142*9c5db199SXin Li 'Seek location is wrong. ' 143*9c5db199SXin Li 'Video length: %d, seek position: %d.' % 144*9c5db199SXin Li (self._video_duration, seek_position)) 145