15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#!/usr/bin/env python
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import time
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# This little construct ensures we can run even if we have a bad version of
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# psutil installed. If so, we'll just skip the test that needs it.
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)_HAS_CORRECT_PSUTIL_VERSION = False
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)try:
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  import psutil
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if 'version_info' in dir(psutil):
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # If psutil has any version info at all, it's recent enough.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    _HAS_CORRECT_PSUTIL_VERSION = True
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)except ImportError, e:
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pass
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Note: pyauto_functional must come before pyauto.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import pyauto_functional
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import pyauto
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import pyauto_utils
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import webrtc_test_base
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class WebrtcCallTest(webrtc_test_base.WebrtcTestBase):
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """Test we can set up a WebRTC call and disconnect it.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Prerequisites: This test case must run on a machine with a webcam, either
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fake or real, and with some kind of audio device. You must make the
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  peerconnection_server target before you run.
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  The test case will launch a custom binary
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  (peerconnection_server) which will allow two WebRTC clients to find each
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  other. For more details, see the source code which is available at the site
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  http://code.google.com/p/libjingle/source/browse/ (make sure to browse to
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  trunk/talk/examples/peerconnection/server).
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def setUp(self):
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pyauto.PyUITest.setUp(self)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.StartPeerConnectionServer()
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def tearDown(self):
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.StopPeerConnectionServer()
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pyauto.PyUITest.tearDown(self)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEquals('', self.CheckErrorsAndCrashes())
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def _SimpleWebrtcCall(self, request_video, request_audio, duration_seconds=0):
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Tests we can call and hang up with WebRTC.
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    This test exercises pretty much the whole happy-case for the WebRTC
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    JavaScript API. Currently, it exercises a normal call setup using the API
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    defined at http://dev.w3.org/2011/webrtc/editor/webrtc.html. The API is
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    still evolving.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    The test will load the supplied HTML file, which in turn will load different
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    javascript files depending on which version of the signaling protocol
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    we are running.
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    The supplied HTML file will be loaded in two tabs and tell the web
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pages to start up WebRTC, which will acquire video and audio devices on the
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    system. This will launch a dialog in Chrome which we click past using the
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    automation controller. Then, we will order both tabs to connect the server,
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    which will make the two tabs aware of each other. Once that is done we order
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    one tab to call the other.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    We make sure that the javascript tells us that the call succeeded, lets it
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    run for a while and try to hang up the call after that. We verify video is
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    playing by using the video detector.
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Args:
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_video: Whether to request video.
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_audio: Whether to request audio.
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      duration_seconds: The number of seconds to keep the call up before
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        shutting it down.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._SetupCall(request_video=request_video, request_audio=request_audio)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if duration_seconds:
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      print 'Call up: sleeping %d seconds...' % duration_seconds
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      time.sleep(duration_seconds);
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # The hang-up will automatically propagate to the second tab.
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.HangUp(from_tab_with_index=0)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.WaitUntilHangUpVerified(tab_index=1)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.Disconnect(tab_index=0)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.Disconnect(tab_index=1)
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Ensure we didn't miss any errors.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.AssertNoFailures(tab_index=0)
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.AssertNoFailures(tab_index=1)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def testWebrtcCall(self):
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.LoadTestPageInTwoTabs()
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._SimpleWebrtcCall(request_video=True, request_audio=True)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def testWebrtcVideoOnlyCall(self):
1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.LoadTestPageInTwoTabs()
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._SimpleWebrtcCall(request_video=True, request_audio=False)
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def testWebrtcAudioOnlyCall(self):
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.LoadTestPageInTwoTabs()
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._SimpleWebrtcCall(request_video=False, request_audio=True)
1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def testWebrtcJsep01CallAndMeasureCpu20Seconds(self):
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not _HAS_CORRECT_PSUTIL_VERSION:
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      print ('WARNING: Can not run cpu/mem measurements with this version of '
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             'psutil. You must have at least psutil 0.4.1 installed for the '
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             'version of python you are running this test with.')
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.LoadTestPageInTwoTabs(test_page='webrtc_jsep01_test.html')
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Prepare CPU measurements.
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    renderer_process = self._GetChromeRendererProcess(tab_index=0)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    renderer_process.get_cpu_percent()
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self._SimpleWebrtcCall(request_video=True,
1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           request_audio=True,
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                           duration_seconds=20)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    cpu_usage = renderer_process.get_cpu_percent(interval=0)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mem_usage_bytes = renderer_process.get_memory_info()[0]
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    mem_usage_kb = float(mem_usage_bytes) / 1024
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pyauto_utils.PrintPerfResult('cpu', 'jsep01_call', cpu_usage, '%')
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pyauto_utils.PrintPerfResult('memory', 'jsep01_call', mem_usage_kb, 'KiB')
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testLocalPreview(self):
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Brings up a local preview and ensures video is playing.
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    This test will launch a window with a single tab and run a getUserMedia call
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    which will give us access to the webcam and microphone. Then the javascript
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    code will hook up the webcam data to the local-view video tag. We will
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    detect video in that tag using the video detector, and if we see video
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    moving the test passes.
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.LoadTestPageInOneTab()
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEquals('ok-got-stream', self.GetUserMedia(tab_index=0))
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._StartDetectingVideo(tab_index=0, video_element='local-view')
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self._WaitForVideo(tab_index=0, expect_playing=True)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def testHandlesNewGetUserMediaRequestSeparately(self):
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Ensures WebRTC doesn't allow new requests to piggy-back on old ones."""
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.LoadTestPageInTwoTabs()
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.GetUserMedia(tab_index=0)
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.GetUserMedia(tab_index=1)
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.Connect("user_1", tab_index=0)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.Connect("user_2", tab_index=1)
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.CreatePeerConnection(tab_index=0)
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.AddUserMediaLocalStream(tab_index=0)
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.EstablishCall(from_tab_with_index=0, to_tab_with_index=1)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    self.assertEquals('failed-with-error-PERMISSION_DENIED',
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                      self.GetUserMedia(tab_index=0, action='cancel'))
161868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)    self.assertEquals('failed-with-error-PERMISSION_DENIED',
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      self.GetUserMedia(tab_index=0, action='dismiss'))
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def _SetupCall(self, request_video, request_audio):
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Gets user media and establishes a call.
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Assumes that two tabs are already opened with a suitable test page.
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Args:
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_video: Whether to request video.
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      request_audio: Whether to request audio.
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.assertEquals('ok-got-stream', self.GetUserMedia(
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tab_index=0, request_video=request_video, request_audio=request_audio))
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.assertEquals('ok-got-stream', self.GetUserMedia(
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tab_index=1, request_video=request_video, request_audio=request_audio))
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.Connect('user_1', tab_index=0)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.Connect('user_2', tab_index=1)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.CreatePeerConnection(tab_index=0)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.AddUserMediaLocalStream(tab_index=0)
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.EstablishCall(from_tab_with_index=0, to_tab_with_index=1)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if request_video:
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self._StartDetectingVideo(tab_index=0, video_element='remote-view')
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self._StartDetectingVideo(tab_index=1, video_element='remote-view')
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self._WaitForVideo(tab_index=0, expect_playing=True)
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self._WaitForVideo(tab_index=1, expect_playing=True)
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def _StartDetectingVideo(self, tab_index, video_element):
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertEquals('ok-started', self.ExecuteJavascript(
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'startDetection("%s", "frame-buffer", 320, 240)' % video_element,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tab_index=tab_index));
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def _WaitForVideo(self, tab_index, expect_playing):
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    # TODO(phoglund): Remove this hack if we manage to get a more stable Linux
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    # bot to run these tests.
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if self.IsLinux():
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      print "Linux; pretending to wait for video..."
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      time.sleep(1)
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      return
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    expect_retval='video-playing' if expect_playing else 'video-not-playing'
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    video_playing = self.WaitUntil(
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        function=lambda: self.ExecuteJavascript('isVideoPlaying()',
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                tab_index=tab_index),
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        expect_retval=expect_retval)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.assertTrue(video_playing,
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                    msg= 'Timed out while waiting for isVideoPlaying to ' +
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         'return ' + expect_retval + '.')
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def _GetChromeRendererProcess(self, tab_index):
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    """Returns the Chrome renderer process as a psutil process wrapper."""
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    tab_info = self.GetBrowserInfo()['windows'][0]['tabs'][tab_index]
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    renderer_id = tab_info['renderer_pid']
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if not renderer_id:
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      self.fail('Can not find the tab renderer process.')
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return psutil.Process(renderer_id)
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)if __name__ == '__main__':
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  pyauto_functional.Main()
225