blob: 973691c5b87f808663fd4858e3f7a0ee8710e78d [file] [log] [blame]
#!/usr/bin/env python
# Copyright (c) 2012 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
import os
import platform
import re
import subprocess
import pyauto
class MissingRequiredBinaryException(Exception):
pass
class WebrtcTestBase(pyauto.PyUITest):
"""This base class provides helpers for WebRTC calls."""
DEFAULT_TEST_PAGE = 'webrtc_jsep01_test.html'
def ExtraChromeFlags(self):
"""Adds flags to the Chrome command line."""
extra_flags = ['--enable-data-channels', '--enable-dcheck']
return pyauto.PyUITest.ExtraChromeFlags(self) + extra_flags
def LoadTestPageInTwoTabs(self, test_page=DEFAULT_TEST_PAGE):
url = self.GetFileURLForDataPath('webrtc', test_page)
self.NavigateToURL(url)
self.AppendTab(pyauto.GURL(url))
def LoadTestPageInOneTab(self, test_page=DEFAULT_TEST_PAGE):
url = self.GetFileURLForDataPath('webrtc', test_page)
self.NavigateToURL(url)
def GetUserMedia(self, tab_index, action='accept',
request_video=True, request_audio=True):
"""Acquires webcam or mic for one tab and returns the result.
Args:
tab_index: The tab to request user media on.
action: The action to take on the info bar. Can be 'accept', 'cancel' or
'dismiss'.
request_video: Whether to request video.
request_audio: Whether to request audio.
Returns:
A string as specified by the getUserMedia javascript function.
"""
constraints = '{ video: %s, audio: %s }' % (str(request_video).lower(),
str(request_audio).lower())
self.assertEquals('ok-requested', self.ExecuteJavascript(
'getUserMedia("%s")' % constraints, tab_index=tab_index))
self.WaitForInfobarCount(1, tab_index=tab_index)
self.PerformActionOnInfobar(action, infobar_index=0, tab_index=tab_index)
self.WaitForGetUserMediaResult(tab_index=0)
result = self.GetUserMediaResult(tab_index=0)
self.AssertNoFailures(tab_index)
return result
def WaitForGetUserMediaResult(self, tab_index):
"""Waits until WebRTC has responded to a getUserMedia query.
Fails an assert if WebRTC doesn't respond within the default timeout.
Args:
tab_index: the tab to query.
"""
def HasResult():
return self.GetUserMediaResult(tab_index) != 'not-called-yet'
self.assertTrue(self.WaitUntil(HasResult),
msg='Timed out while waiting for getUserMedia callback.')
def GetUserMediaResult(self, tab_index):
"""Retrieves WebRTC's answer to a user media query.
Args:
tab_index: the tab to query.
Returns:
Specified in obtainGetUserMediaResult() in getusermedia.js.
"""
return self.ExecuteJavascript(
'obtainGetUserMediaResult()', tab_index=tab_index)
def AssertNoFailures(self, tab_index):
"""Ensures the javascript hasn't registered any asynchronous errors.
Args:
tab_index: The tab to check.
"""
self.assertEquals('ok-no-errors', self.ExecuteJavascript(
'getAnyTestFailures()', tab_index=tab_index))
def Connect(self, user_name, tab_index):
self.assertEquals('ok-connected', self.ExecuteJavascript(
'connect("http://localhost:8888", "%s")' % user_name,
tab_index=tab_index))
self.AssertNoFailures(tab_index)
def CreatePeerConnection(self, tab_index):
self.assertEquals('ok-peerconnection-created', self.ExecuteJavascript(
'preparePeerConnection()', tab_index=tab_index))
def AddUserMediaLocalStream(self, tab_index):
self.assertEquals('ok-added', self.ExecuteJavascript(
'addLocalStream()', tab_index=tab_index))
def AddWebAudioFile(self, tab_index, input_relative_path):
"""The path must be relative to where the javascript is.
This call just loads and adds a file to a peer connection, but it doesn't
start to play it until you call PlayWebAudioFile.
"""
self.assertEquals('ok-added', self.ExecuteJavascript(
'addAudioFile("%s")' % re.escape(input_relative_path),
tab_index=tab_index))
def PlayWebAudioFile(self, tab_index):
"""Plays a web audio file which was added earlier."""
self.assertEquals('ok-playing', self.ExecuteJavascript(
'playAudioFile()', tab_index=tab_index))
def EstablishCall(self, from_tab_with_index, to_tab_with_index):
self.WaitUntilPeerConnects(tab_index=from_tab_with_index)
self.assertEquals('ok-negotiating', self.ExecuteJavascript(
'negotiateCall()', tab_index=from_tab_with_index))
self.AssertNoFailures(from_tab_with_index)
self.WaitUntilReadyState(ready_state='active',
tab_index=from_tab_with_index)
# Double-check the call reached the other side.
self.WaitUntilReadyState(ready_state='active',
tab_index=to_tab_with_index)
def HangUp(self, from_tab_with_index):
self.assertEquals('ok-call-hung-up', self.ExecuteJavascript(
'hangUp()', tab_index=from_tab_with_index))
self.WaitUntilHangUpVerified(tab_index=from_tab_with_index)
self.AssertNoFailures(tab_index=from_tab_with_index)
def WaitUntilPeerConnects(self, tab_index):
peer_connected = self.WaitUntil(
function=lambda: self.ExecuteJavascript('remotePeerIsConnected()',
tab_index=tab_index),
expect_retval='peer-connected')
self.assertTrue(peer_connected,
msg='Timed out while waiting for peer to connect.')
def WaitUntilReadyState(self, ready_state, tab_index):
got_ready_state = self.WaitUntil(
function=lambda: self.ExecuteJavascript('getPeerConnectionReadyState()',
tab_index=tab_index),
expect_retval=ready_state)
self.assertTrue(got_ready_state,
msg=('Timed out while waiting for peer connection ready '
'state to change to %s for tab %d.' % (ready_state,
tab_index)))
def WaitUntilHangUpVerified(self, tab_index):
self.WaitUntilReadyState('no-peer-connection', tab_index=tab_index)
def Disconnect(self, tab_index):
self.assertEquals('ok-disconnected', self.ExecuteJavascript(
'disconnect()', tab_index=tab_index))
def BinPathForPlatform(self, path):
"""Form a platform specific path to a binary.
Args:
path(string): The path to the binary without an extension.
Return:
(string): The platform-specific bin path.
"""
if self.IsWin():
path += '.exe'
return path
def PlatformIsWinXP(self):
"""Check if the executing platform is Windows XP.
Return:
True if the platform is Windows XP.
"""
return platform.system() == 'Windows' and platform.release() == 'XP'
def StartPeerConnectionServer(self):
"""Starts peerconnection_server.
Peerconnection_server is a custom binary allowing two WebRTC clients to find
each other. For more details, see the source code which is available at the
site http://code.google.com/p/libjingle/source/browse/ (make sure to browse
to trunk/talk/examples/peerconnection/server).
"""
# Start the peerconnection_server. It should be next to chrome.
binary_path = os.path.join(self.BrowserPath(), 'peerconnection_server')
binary_path = self.BinPathForPlatform(binary_path)
if not os.path.exists(binary_path):
raise MissingRequiredBinaryException(
'Could not locate peerconnection_server. Have you built the '
'peerconnection_server target? We expect to have a '
'peerconnection_server binary next to the chrome binary.')
self._server_process = subprocess.Popen(binary_path)
def StopPeerConnectionServer(self):
"""Stops the peerconnection_server."""
assert self._server_process
self._server_process.kill()