summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/test/data/media/csv/testscenario.csv1
-rw-r--r--chrome/test/data/media/html/media_event.html42
-rw-r--r--chrome/test/data/media/html/player.js34
-rwxr-xr-xchrome/test/functional/media/media_event_test_base.py33
-rwxr-xr-xchrome/test/functional/media/media_test_base.py35
-rw-r--r--chrome/test/functional/media/media_test_env_names.py6
-rwxr-xr-xchrome/test/functional/media/media_test_runner.py21
7 files changed, 143 insertions, 29 deletions
diff --git a/chrome/test/data/media/csv/testscenario.csv b/chrome/test/data/media/csv/testscenario.csv
new file mode 100644
index 0000000..9e6363c
--- /dev/null
+++ b/chrome/test/data/media/csv/testscenario.csv
@@ -0,0 +1 @@
+100,pause,0,5000,play,0 \ No newline at end of file
diff --git a/chrome/test/data/media/html/media_event.html b/chrome/test/data/media/html/media_event.html
index a7e3b24..654669c 100644
--- a/chrome/test/data/media/html/media_event.html
+++ b/chrome/test/data/media/html/media_event.html
@@ -1,31 +1,39 @@
-<!--
+<!--
This HTML file contains a player div which is used for event testing
-(chrome/test/functional/media_event_*.py).
+(chrome/test/functional/media_event_*.py).
The query string should contain the following information:
- tag (required): HTML video/audio tag.
+ tag (required): HTML video/audio tag.
video file (required): video file name.
- t (optional): add the "t" parameter to disable the media cache.
+ t (optional): add the "t" parameter to disable the media cache.
+ actions (optional): add a list of triples (time, action, action_argument)
+ delimited by '|'. For example, '3000|seek|5000' means 'at second 3, seek
+ to second 5'. Possible actions are 'play', 'pause', 'seek', or
+ 'ratechange'. Time and action_arugment is in milliseconds. 'play' and
+ 'pause' should have dummy action_argument, which is ignored.
-Example: "media_event.html?tag=video&media=foo.webm&t=t"
--->
+Example: "media_event.html?tag=video&media=foo.webm&t=t&actions=3000|seek|5000"
+-->
<html>
<body>
<div id='player_container'></div>
<script type='text/javascript' src='player.js'></script>
<script>
-var events = ['loadstart', 'ratechange', 'waiting', 'ratechange',
- 'durationchange', 'loadedmetadata', 'loadeddata',
- 'canplay', 'canplaythrough', 'play', 'timeupdate',
- 'pause', 'ended'];
+var events = ['abort', 'canplay', 'canplaythrough', 'durationchange', 'emptied',
+ 'ended', 'error', 'load', 'loadeddata', 'loadedmetadata',
+ 'loadstart', 'pause', 'play', 'playing', 'progress',
+ 'ratechange', 'seeked', 'seeking', 'stalled', 'suspend',
+ 'timeupdate', 'volumechange', 'waiting']
+
+var startTime = 0
var table = document.createElement('table');
table.id = 'event';
document.body.appendChild(table);
-function incrementCounterForEvent(evt) {
- // Convert the string to an integer.
- var currentValue = document.getElementById(evt.type).innerHTML - 0;
- document.getElementById(evt.type).innerHTML = currentValue + 1;
+function recordEventTime(evt) {
+ // Record the time when an event happens.
+ var time = new Date().getTime() - startTime
+ document.getElementById(evt.type).innerHTML += time + ' '
}
var player = document.getElementById('player');
@@ -35,17 +43,19 @@ for (var event in events) {
var eventNameColumn = document.createElement('td');
eventNameColumn.innerHTML = events[event];
var eventValueColumn = document.createElement('td');
- eventValueColumn.innerHTML = 0;
+ eventValueColumn.innerHTML = '';
eventValueColumn.id = events[event];
row.appendChild(eventNameColumn);
row.appendChild(eventValueColumn);
table.appendChild(row)
- player.addEventListener(events[event], incrementCounterForEvent, false);
+ player.addEventListener(events[event], recordEventTime, false);
}
if (ok) {
+ startTime = new Date().getTime();
player.play();
}
</script>
</body>
</html>
+
diff --git a/chrome/test/data/media/html/player.js b/chrome/test/data/media/html/player.js
index 064c0ab..8f28f44 100644
--- a/chrome/test/data/media/html/player.js
+++ b/chrome/test/data/media/html/player.js
@@ -50,6 +50,39 @@ if (tag != 'audio' && tag != 'video') {
ok = false;
}
+function translateCommand(command, arg) {
+ // Translate command in 'actions' query string into corresponding JavaScript
+ // code.
+ if (command == 'seek') {
+ return 'player.currentTime=' + arg + ';';
+ } else if (command == 'ratechange') {
+ return 'player.playbackRate=' + arg + ';';
+ } else if (command == 'play' || command == 'pause') {
+ return 'player.' + command + '();';
+ } else {
+ return 'ERROR - ' + command + ' is not a valid command.'
+ }
+}
+
+if (queryString('actions')) {
+ // Action query string is a list of actions. An action consists of a
+ // time, action, action_argument triple (delimited by '|').
+ // For example, '1000|seek|4000' means 'At second 1, seek to second 4.'
+ // Or '1000|pause|0|2000|play|0' means 'At second 1, pause the video.
+ // At second 2, play the video.'
+ var original_actions = queryString('actions').split('|');
+ if ((original_actions.length % 3) != 0) {
+ // The action list is a list of triples. Otherwise, it fails.
+ document.title = 'FAIL';
+ ok = false;
+ }
+ for (i = 0; i < original_actions.length / 3; i++) {
+ setTimeout(translateCommand(original_actions[3 * i + 1],
+ original_actions[3 * i + 2]),
+ parseInt(original_actions[3 * i]));
+ }
+}
+
var container = document.getElementById('player_container');
container.innerHTML = '<' + tag + ' controls id="player"></' + tag + '>';
player = document.getElementById('player');
@@ -60,5 +93,4 @@ InstallEventHandler('error',
InstallEventHandler('playing', 'document.title = "PLAYING"');
InstallEventHandler('ended', 'document.title = "END"');
-// Starts the player.
player.src = media_url; \ No newline at end of file
diff --git a/chrome/test/functional/media/media_event_test_base.py b/chrome/test/functional/media/media_event_test_base.py
index 6a59c49..18b0d69 100755
--- a/chrome/test/functional/media/media_event_test_base.py
+++ b/chrome/test/functional/media/media_event_test_base.py
@@ -17,16 +17,27 @@ from media_test_base import MediaTestBase
class MediaEventTestBase(MediaTestBase):
"""Event test base for the HTML5 media tag."""
# This is a list of events to test during media playback.
- EVENT_LIST = ['loadstart', 'ratechange', 'waiting',
- 'ratechange', 'durationchange', 'loadedmetadata',
- 'loadeddata', 'canplay', 'canplaythrough',
- 'play', 'timeupdate', 'pause', 'ended']
+ EVENT_LIST = ['abort', 'canplay', 'canplaythrough', 'durationchange',
+ 'emptied', 'ended', 'error', 'load', 'loadeddata',
+ 'loadedmetadata', 'loadstart', 'pause', 'play', 'playing',
+ 'progress', 'ratechange', 'seeked', 'seeking', 'stalled',
+ 'suspend', 'timeupdate', 'volumechange', 'waiting']
# These are event types that are not 1 at the end of video playback.
# There are two types of events listed here:
# 0: event occurrence is 0.
# None: event occurrence is more than 1.
+ # The following are default values that may be overridden.
event_expected_values = {'ratechange': 0,
'pause': 0,
+ 'suspend': 0,
+ 'load': 0,
+ 'abort': 0,
+ 'error': 0,
+ 'emptied': 0,
+ 'stalled': 0,
+ 'seeking': 0,
+ 'seeked': 0,
+ 'volumechange': 0,
'timeupdate': None}
def _GetEventLog(self):
@@ -38,8 +49,7 @@ class MediaEventTestBase(MediaTestBase):
all_event_infos = {}
for event_name in self.EVENT_LIST:
loc = 'document.getElementById(\'%s\').innerHTML' % event_name
- value = self.GetDOMValue(loc).strip()
- all_event_infos[event_name] = int(value)
+ all_event_infos[event_name] = self.GetDOMValue(loc).strip()
return all_event_infos
def AssertEvent(self, all_event_infos):
@@ -52,21 +62,22 @@ class MediaEventTestBase(MediaTestBase):
occurrence counts.
"""
for event_name in self.EVENT_LIST:
+ event_occurrence = len(all_event_infos[event_name].split())
if event_name in self.event_expected_values:
if self.event_expected_values[event_name] is None:
self.assertTrue(
- all_event_infos[event_name] > 1,
+ event_occurrence > 1,
msg='the number of events should be more than 1 for %s' %
event_name)
else:
self.assertEqual(
- all_event_infos[event_name],
+ event_occurrence,
self.event_expected_values[event_name],
msg='the number of events is wrong for %s' % event_name)
else:
# Make sure the value is one.
self.assertEqual(
- all_event_infos[event_name], 1,
+ event_occurrence, 1,
msg='the number of events should be 1 for %s' % event_name)
def PostEachRunProcess(self, run_counter):
@@ -80,7 +91,9 @@ class MediaEventTestBase(MediaTestBase):
"""
MediaTestBase.PostEachRunProcess(self, run_counter)
all_event_infos = self._GetEventLog()
- self.AssertEvent(all_event_infos)
+ # TODO(imasaki@chromium.org): adjust events based on actions.
+ if not self._test_scenarios:
+ self.AssertEvent(all_event_infos)
def GetPlayerHTMLFileName(self):
"""A method to get the player HTML file name."""
diff --git a/chrome/test/functional/media/media_test_base.py b/chrome/test/functional/media/media_test_base.py
index f9cf5b7..bd3a40e 100755
--- a/chrome/test/functional/media/media_test_base.py
+++ b/chrome/test/functional/media/media_test_base.py
@@ -13,6 +13,7 @@ media_test_runner.py is used for generating these variables
(PyAuto does not support direct parameters).
"""
+import csv
import os
import time
@@ -47,6 +48,7 @@ class MediaTestBase(pyauto.PyUITest):
times = []
media_filename = ''
media_filename_nickname = ''
+ _test_scenarios = []
def _GetMediaURLAndParameterString(self, media_filename):
"""Get media url and parameter string.
@@ -97,6 +99,23 @@ class MediaTestBase(pyauto.PyUITest):
extra_nickname)
return url, parameter_str
+ def ReadTestScenarioFiles(self, test_scenario_filename):
+ """Read a test scenario CSV file with actions such as 'play'.
+
+ In the CSV file, each row is a test scenario which consists of one
+ or more (time, action, action_argument) triples (time and action_argument
+ are in milliseconds). For example, the following CSV file contains 3 test
+ scenarios to be tested.
+ 500, pause, 0
+ 1000, pause, 0, 2000, play, 0
+ 1000, seek, 0, 2000, ratechange, 2
+ """
+ test_scenarios = []
+ rows = csv.reader(open(test_scenario_filename))
+ for row in rows:
+ test_scenarios.append('|'.join(row))
+ return test_scenarios
+
def ExecuteTest(self):
"""Test HTML5 Media Tag."""
@@ -111,9 +130,23 @@ class MediaTestBase(pyauto.PyUITest):
return self.GetDOMValue('document.title').strip() == 'END'
self.PreAllRunsProcess()
+ test_scenario_filename = os.getenv(
+ MediaTestEnvNames.TEST_SCENARIO_FILE_ENV_NAME, '')
+ test_scenario = os.getenv(
+ MediaTestEnvNames.TEST_SCENARIO_ENV_NAME, '')
+ if test_scenario:
+ # Run test with the same action several times.
+ self._test_scenarios = [test_scenario] * self.number_of_runs
+ if test_scenario_filename:
+ self._test_scenarios = self.ReadTestScenarioFiles(test_scenario_filename)
+ # One run per test scenario.
+ self.number_of_runs = len(self._test_scenarios)
for run_counter in range(self.number_of_runs):
self.PreEachRunProcess(run_counter)
- self.NavigateToURL(self.url)
+ url = self.url
+ if self._test_scenarios:
+ url += '&actions=' + self.test_scenarios[run_counter]
+ self.NavigateToURL(url)
self.WaitUntil(lambda: _VideoEnded(),
self.TIMEOUT)
self.PostEachRunProcess(run_counter)
diff --git a/chrome/test/functional/media/media_test_env_names.py b/chrome/test/functional/media/media_test_env_names.py
index 43b3a24..6667f43 100644
--- a/chrome/test/functional/media/media_test_env_names.py
+++ b/chrome/test/functional/media/media_test_env_names.py
@@ -49,3 +49,9 @@ class MediaTestEnvNames:
# Define the interval for the measurement.
MEASURE_INTERVAL_ENV_NAME = 'MEASURE_INTERVALS'
+
+ # Define the test scenario file, which contains all operations during tests.
+ TEST_SCENARIO_FILE_ENV_NAME = 'TEST_SCENARIO_FILE'
+
+ # Define the test scenario, which contains operations during tests.
+ TEST_SCENARIO_ENV_NAME = 'TEST_SCENARIO'
diff --git a/chrome/test/functional/media/media_test_runner.py b/chrome/test/functional/media/media_test_runner.py
index 7348724..1af348f 100755
--- a/chrome/test/functional/media/media_test_runner.py
+++ b/chrome/test/functional/media/media_test_runner.py
@@ -98,15 +98,30 @@ def main():
default=True, # Currently default is True
# since we want to test only 1 combination.
help='Run only one parameter combination')
+ parser.add_option(
+ '-w', '--test_scenario_input_filename',
+ dest='test_scenario_input_filename',
+ default='', help='Test scenario file (CSV form)', metavar='FILE')
+ parser.add_option(
+ '-c', '--test_scenario', dest='test_scenario',
+ default='', help='Test scenario (action triples delimited by \'|\')')
parser.add_option('-s', '--suite', dest='suite',
help='Suite file')
+ parser.add_option('-e', '--media_file', dest='media_file',
+ default='',
+ help=('Media file to be played using player.html. ',
+ 'The relative path needs to be specified starting ',
+ 'from data/html/ directory.'))
+
options, args = parser.parse_args()
if args:
parser.print_help()
sys.exit(1)
test_data_list = []
- if options.input_matrix_filename is None:
+ if options.media_file:
+ test_data_list.append(['video', options.media_file, options.media_file])
+ elif options.input_matrix_filename is None:
file = open(options.input_filename, 'rb')
test_data_list = csv.reader(file)
# First line contains headers that can be skipped.
@@ -151,6 +166,10 @@ def main():
REMOVE_FIRST_RESULT,
MediaTestEnvNames.MEASURE_INTERVAL_ENV_NAME:
str(options.measure_intervals),
+ MediaTestEnvNames.TEST_SCENARIO_FILE_ENV_NAME:
+ options.test_scenario_input_filename,
+ MediaTestEnvNames.TEST_SCENARIO_ENV_NAME:
+ options.test_scenario,
}
envs.update(parent_envs)
if options.suite is None and options.test_prog_name is not None: