dom/media/tests/mochitest/head.js

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/dom/media/tests/mochitest/head.js	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,260 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +var Cc = SpecialPowers.Cc;
     1.9 +var Ci = SpecialPowers.Ci;
    1.10 +var Cr = SpecialPowers.Cr;
    1.11 +
    1.12 +// Specifies whether we are using fake streams to run this automation
    1.13 +var FAKE_ENABLED = true;
    1.14 +
    1.15 +
    1.16 +/**
    1.17 + * Create the necessary HTML elements for head and body as used by Mochitests
    1.18 + *
    1.19 + * @param {object} meta
    1.20 + *        Meta information of the test
    1.21 + * @param {string} meta.title
    1.22 + *        Description of the test
    1.23 + * @param {string} [meta.bug]
    1.24 + *        Bug the test was created for
    1.25 + * @param {boolean} [meta.visible=false]
    1.26 + *        Visibility of the media elements
    1.27 + */
    1.28 +function createHTML(meta) {
    1.29 +  var test = document.getElementById('test');
    1.30 +
    1.31 +  // Create the head content
    1.32 +  var elem = document.createElement('meta');
    1.33 +  elem.setAttribute('charset', 'utf-8');
    1.34 +  document.head.appendChild(elem);
    1.35 +
    1.36 +  var title = document.createElement('title');
    1.37 +  title.textContent = meta.title;
    1.38 +  document.head.appendChild(title);
    1.39 +
    1.40 +  // Create the body content
    1.41 +  var anchor = document.createElement('a');
    1.42 +  anchor.setAttribute('target', '_blank');
    1.43 +
    1.44 +  if (meta.bug) {
    1.45 +    anchor.setAttribute('href', 'https://bugzilla.mozilla.org/show_bug.cgi?id=' + meta.bug);
    1.46 +  }
    1.47 +
    1.48 +  anchor.textContent = meta.title;
    1.49 +  document.body.insertBefore(anchor, test);
    1.50 +
    1.51 +  var display = document.createElement('p');
    1.52 +  display.setAttribute('id', 'display');
    1.53 +  document.body.insertBefore(display, test);
    1.54 +
    1.55 +  var content = document.createElement('div');
    1.56 +  content.setAttribute('id', 'content');
    1.57 +  content.style.display = meta.visible ? 'block' : "none";
    1.58 +  document.body.appendChild(content);
    1.59 +}
    1.60 +
    1.61 +
    1.62 +/**
    1.63 + * Create the HTML element if it doesn't exist yet and attach
    1.64 + * it to the content node.
    1.65 + *
    1.66 + * @param {string} type
    1.67 + *        Type of media element to create ('audio' or 'video')
    1.68 + * @param {string} label
    1.69 + *        Description to use for the element
    1.70 + * @return {HTMLMediaElement} The created HTML media element
    1.71 + */
    1.72 +function createMediaElement(type, label) {
    1.73 +  var id = label + '_' + type;
    1.74 +  var element = document.getElementById(id);
    1.75 +
    1.76 +  // Sanity check that we haven't created the element already
    1.77 +  if (element)
    1.78 +    return element;
    1.79 +
    1.80 +  element = document.createElement(type === 'audio' ? 'audio' : 'video');
    1.81 +  element.setAttribute('id', id);
    1.82 +  element.setAttribute('height', 100);
    1.83 +  element.setAttribute('width', 150);
    1.84 +  element.setAttribute('controls', 'controls');
    1.85 +  document.getElementById('content').appendChild(element);
    1.86 +
    1.87 +  return element;
    1.88 +}
    1.89 +
    1.90 +
    1.91 +/**
    1.92 + * Wrapper function for mozGetUserMedia to allow a singular area of control
    1.93 + * for determining whether we run this with fake devices or not.
    1.94 + *
    1.95 + * @param {Dictionary} constraints
    1.96 + *        The constraints for this mozGetUserMedia callback
    1.97 + * @param {Function} onSuccess
    1.98 + *        The success callback if the stream is successfully retrieved
    1.99 + * @param {Function} onError
   1.100 + *        The error callback if the stream fails to be retrieved
   1.101 + */
   1.102 +function getUserMedia(constraints, onSuccess, onError) {
   1.103 +  constraints["fake"] = FAKE_ENABLED;
   1.104 +
   1.105 +  info("Call getUserMedia for " + JSON.stringify(constraints));
   1.106 +  navigator.mozGetUserMedia(constraints, onSuccess, onError);
   1.107 +}
   1.108 +
   1.109 +
   1.110 +/**
   1.111 + * Setup any Mochitest for WebRTC by enabling the preference for
   1.112 + * peer connections. As by bug 797979 it will also enable mozGetUserMedia()
   1.113 + * and disable the mozGetUserMedia() permission checking.
   1.114 + *
   1.115 + * @param {Function} aCallback
   1.116 + *        Test method to execute after initialization
   1.117 + */
   1.118 +function runTest(aCallback) {
   1.119 +  if (window.SimpleTest) {
   1.120 +    // Running as a Mochitest.
   1.121 +    SimpleTest.waitForExplicitFinish();
   1.122 +    SpecialPowers.pushPrefEnv({'set': [
   1.123 +      ['dom.messageChannel.enabled', true],
   1.124 +      ['media.peerconnection.enabled', true],
   1.125 +      ['media.peerconnection.identity.enabled', true],
   1.126 +      ['media.peerconnection.identity.timeout', 12000],
   1.127 +      ['media.navigator.permission.disabled', true]]
   1.128 +    }, function () {
   1.129 +      try {
   1.130 +        aCallback();
   1.131 +      }
   1.132 +      catch (err) {
   1.133 +        generateErrorCallback()(err);
   1.134 +      }
   1.135 +    });
   1.136 +  } else {
   1.137 +    // Steeplechase, let it call the callback.
   1.138 +    window.run_test = function(is_initiator) {
   1.139 +      var options = {is_local: is_initiator,
   1.140 +                     is_remote: !is_initiator};
   1.141 +      aCallback(options);
   1.142 +    };
   1.143 +    // Also load the steeplechase test code.
   1.144 +    var s = document.createElement("script");
   1.145 +    s.src = "/test.js";
   1.146 +    document.head.appendChild(s);
   1.147 +  }
   1.148 +}
   1.149 +
   1.150 +/**
   1.151 + * Checks that the media stream tracks have the expected amount of tracks
   1.152 + * with the correct kind and id based on the type and constraints given.
   1.153 + *
   1.154 + * @param {Object} constraints specifies whether the stream should have
   1.155 + *                             audio, video, or both
   1.156 + * @param {String} type the type of media stream tracks being checked
   1.157 + * @param {sequence<MediaStreamTrack>} mediaStreamTracks the media stream
   1.158 + *                                     tracks being checked
   1.159 + */
   1.160 +function checkMediaStreamTracksByType(constraints, type, mediaStreamTracks) {
   1.161 +  if(constraints[type]) {
   1.162 +    is(mediaStreamTracks.length, 1, 'One ' + type + ' track shall be present');
   1.163 +
   1.164 +    if(mediaStreamTracks.length) {
   1.165 +      is(mediaStreamTracks[0].kind, type, 'Track kind should be ' + type);
   1.166 +      ok(mediaStreamTracks[0].id, 'Track id should be defined');
   1.167 +    }
   1.168 +  } else {
   1.169 +    is(mediaStreamTracks.length, 0, 'No ' + type + ' tracks shall be present');
   1.170 +  }
   1.171 +}
   1.172 +
   1.173 +/**
   1.174 + * Check that the given media stream contains the expected media stream
   1.175 + * tracks given the associated audio & video constraints provided.
   1.176 + *
   1.177 + * @param {Object} constraints specifies whether the stream should have
   1.178 + *                             audio, video, or both
   1.179 + * @param {MediaStream} mediaStream the media stream being checked
   1.180 + */
   1.181 +function checkMediaStreamTracks(constraints, mediaStream) {
   1.182 +  checkMediaStreamTracksByType(constraints, 'audio',
   1.183 +    mediaStream.getAudioTracks());
   1.184 +  checkMediaStreamTracksByType(constraints, 'video',
   1.185 +    mediaStream.getVideoTracks());
   1.186 +}
   1.187 +
   1.188 +/**
   1.189 + * Utility methods
   1.190 + */
   1.191 +
   1.192 +/**
   1.193 + * Returns the contents of a blob as text
   1.194 + *
   1.195 + * @param {Blob} blob
   1.196 +          The blob to retrieve the contents from
   1.197 + * @param {Function} onSuccess
   1.198 +          Callback with the blobs content as parameter
   1.199 + */
   1.200 +function getBlobContent(blob, onSuccess) {
   1.201 +  var reader = new FileReader();
   1.202 +
   1.203 +  // Listen for 'onloadend' which will always be called after a success or failure
   1.204 +  reader.onloadend = function (event) {
   1.205 +    onSuccess(event.target.result);
   1.206 +  };
   1.207 +
   1.208 +  reader.readAsText(blob);
   1.209 +}
   1.210 +
   1.211 +/**
   1.212 + * Generates a callback function fired only under unexpected circumstances
   1.213 + * while running the tests. The generated function kills off the test as well
   1.214 + * gracefully.
   1.215 + *
   1.216 + * @param {String} [message]
   1.217 + *        An optional message to show if no object gets passed into the
   1.218 + *        generated callback method.
   1.219 + */
   1.220 +function generateErrorCallback(message) {
   1.221 +  var stack = new Error().stack.split("\n");
   1.222 +  stack.shift(); // Don't include this instantiation frame
   1.223 +
   1.224 +  /**
   1.225 +   * @param {object} aObj
   1.226 +   *        The object fired back from the callback
   1.227 +   */
   1.228 +  return function (aObj) {
   1.229 +    if (aObj) {
   1.230 +      if (aObj.name && aObj.message) {
   1.231 +        ok(false, "Unexpected callback for '" + aObj.name +
   1.232 +           "' with message = '" + aObj.message + "' at " +
   1.233 +           JSON.stringify(stack));
   1.234 +      } else {
   1.235 +        ok(false, "Unexpected callback with = '" + aObj +
   1.236 +           "' at: " + JSON.stringify(stack));
   1.237 +      }
   1.238 +    } else {
   1.239 +      ok(false, "Unexpected callback with message = '" + message +
   1.240 +         "' at: " + JSON.stringify(stack));
   1.241 +    }
   1.242 +    SimpleTest.finish();
   1.243 +  }
   1.244 +}
   1.245 +
   1.246 +/**
   1.247 + * Generates a callback function fired only for unexpected events happening.
   1.248 + *
   1.249 + * @param {String} description
   1.250 +          Description of the object for which the event has been fired
   1.251 + * @param {String} eventName
   1.252 +          Name of the unexpected event
   1.253 + */
   1.254 +function unexpectedEventAndFinish(message, eventName) {
   1.255 +  var stack = new Error().stack.split("\n");
   1.256 +  stack.shift(); // Don't include this instantiation frame
   1.257 +
   1.258 +  return function () {
   1.259 +    ok(false, "Unexpected event '" + eventName + "' fired with message = '" +
   1.260 +       message + "' at: " + JSON.stringify(stack));
   1.261 +    SimpleTest.finish();
   1.262 +  }
   1.263 +}

mercurial