blob: e593dc62a3f076c991cf48225644b39c273595b4 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<title>RTCPeerConnection-ontrack</title>
<script src="../../resources/testharness.js"></script>
<script src="../../resources/testharnessreport.js"></script>
</head>
<body>
<script>
// TODO(hbos): Consider removing this file, it duplicates wpt tests.
promise_test(function() {
let pc = new RTCPeerConnection();
let pc2 = new RTCPeerConnection();
let eventSequence = [];
return createStreams({audio:true, video:false}, 1)
.then(function(streams) {
pc.addStream(streams[0]);
let resolvers = Resolver.createResolvers(2);
pc2.ontrack = function() {
eventSequence.push('ontrack');
resolvers.shift().resolve();
}
createAndSetRemoteDescription(pc, pc2).then(function() {
eventSequence.push('setRemoteDescription');
resolvers.shift().resolve();
});
return Promise.all(Resolver.promises(resolvers));
}).then(function() {
let expectedEventSequence = [ 'ontrack', 'setRemoteDescription' ];
assert_array_equals(expectedEventSequence, eventSequence);
});
}, 'ontrack fires before negotiation done.');
promise_test(function() {
let pc = new RTCPeerConnection();
let pc2 = new RTCPeerConnection();
let eventSequence = [];
return createStreams({audio:true, video:false}, 1)
.then(function(streams) {
pc.addStream(streams[0]);
let resolvers = Resolver.createResolvers(2);
pc2.onaddstream = function() {
eventSequence.push('onaddstream');
resolvers.shift().resolve();
}
createAndSetRemoteDescription(pc, pc2).then(function() {
eventSequence.push('setRemoteDescription');
resolvers.shift().resolve();
});
return Promise.all(Resolver.promises(resolvers));
}).then(function() {
let expectedEventSequence = [ 'onaddstream', 'setRemoteDescription' ];
assert_array_equals(eventSequence, expectedEventSequence);
});
}, 'onaddstream fires before negotation done.');
promise_test(function() {
let pc = new RTCPeerConnection();
let pc2 = new RTCPeerConnection();
let eventSequence = [];
return createStreams({audio:true, video:false}, 2)
.then(function(streams) {
pc.addStream(streams[0]);
pc.addStream(streams[1]);
let resolvers = Resolver.createResolvers(4);
pc2.onaddstream = function(event) {
eventSequence.push('stream:' + event.stream.id);
resolvers.shift().resolve();
};
pc2.ontrack = function(event) {
eventSequence.push('track:' + event.track.id);
resolvers.shift().resolve();
};
return Promise.all(
Resolver.promises(resolvers).concat(
createAndSetRemoteDescription(pc, pc2)));
}).then(function() {
let expectedEventSequence =
[ 'stream:' + pc2.getRemoteStreams()[0].id,
'track:' + pc2.getRemoteStreams()[0].getAudioTracks()[0].id,
'stream:' + pc2.getRemoteStreams()[1].id,
'track:' + pc2.getRemoteStreams()[1].getAudioTracks()[0].id ];
assert_array_equals(eventSequence, expectedEventSequence);
});
}, 'ontrack and onaddstream fires in the expected relative order.');
promise_test(function() {
let pc = new RTCPeerConnection();
let pc2 = new RTCPeerConnection();
let eventSequence = [];
return createStreams({audio:true, video:false}, 1)
.then(function(streams) {
pc.addStream(streams[0]);
let resolvers = Resolver.createResolvers(3);
let callback = function() {
if (eventSequence.length == 0) {
setTimeout(function() {
eventSequence.push('new task');
resolvers.shift().resolve();
}, 0);
}
eventSequence.push('track or stream fired');
resolvers.shift().resolve();
}
pc2.onaddstream = callback;
pc2.ontrack = callback;
return Promise.all(
Resolver.promises(resolvers).concat(
createAndSetRemoteDescription(pc, pc2)));
}).then(function() {
assert_array_equals(
eventSequence,
[ 'track or stream fired', 'track or stream fired', 'new task' ]);
});
}, 'ontrack and onaddstream fires in the same task.');
promise_test(function() {
let pc = new RTCPeerConnection();
let pc2 = new RTCPeerConnection();
return createStreams({audio:true, video:false}, 1)
.then(function(streams) {
pc.addStream(streams[0]);
let resolver = new Resolver();
pc2.ontrack = function(event) {
let remoteStream = pc2.getRemoteStreams()[0];
let remoteAudioTrack = remoteStream.getAudioTracks()[0];
assert_equals(event.track, remoteAudioTrack);
resolver.resolve();
};
return Promise.all([ resolver.promise,
createAndSetRemoteDescription(pc, pc2) ]);
});
}, 'ontrack event\'s track matches track in getRemoteStreams().');
promise_test(function() {
let pc = new RTCPeerConnection();
let pc2 = new RTCPeerConnection();
return createStreams({audio:true, video:false}, 1)
.then(function(streams) {
pc.addStream(streams[0]);
let resolver = new Resolver();
pc2.ontrack = function(event) {
let receiver = pc2.getReceivers()[0];
assert_equals(event.receiver, receiver);
resolver.resolve();
};
return Promise.all([ resolver.promise,
createAndSetRemoteDescription(pc, pc2) ]);
});
}, 'ontrack event\'s receiver matches getReceivers().');
promise_test(function() {
let pc = new RTCPeerConnection();
let pc2 = new RTCPeerConnection();
return createStreams({audio:true, video:false}, 1)
.then(function(streams) {
pc.addStream(streams[0]);
let resolver = new Resolver();
pc2.ontrack = function(event) {
assert_array_equals(event.streams, pc2.getRemoteStreams())
resolver.resolve();
};
return Promise.all([ resolver.promise,
createAndSetRemoteDescription(pc, pc2) ]);
});
}, 'ontrack event\'s streams match getRemoteStreams().');
promise_test(function() {
let pc = new RTCPeerConnection();
let pc2 = new RTCPeerConnection();
let firedForAudioTrack = false;
let firedForVideoTrack = false;
return createStreams({audio:true, video:true}, 1)
.then(function(streams) {
pc.addStream(streams[0]);
let resolvers = Resolver.createResolvers(2);
pc2.ontrack = function(event) {
let remoteStream = pc2.getRemoteStreams()[0];
if (event.track == remoteStream.getAudioTracks()[0])
firedForAudioTrack = true;
else if (event.track == remoteStream.getVideoTracks()[0])
firedForVideoTrack = true;
resolvers.shift().resolve();
};
return Promise.all(
Resolver.promises(resolvers).concat(
createAndSetRemoteDescription(pc, pc2)));
}).then(function() {
assert_true(firedForAudioTrack && firedForVideoTrack);
});
}, 'ontrack event fires twice for a stream containing two tracks.');
/**
* Helper functions.
*/
function createStreams(constraints, numStreams, streamsSoFar = []) {
if (numStreams == 0) {
return Promise.resolve(streamsSoFar);
}
return navigator.mediaDevices.getUserMedia(constraints)
.then(function(stream) {
return createStreams(constraints,
numStreams - 1,
streamsSoFar.concat([stream]));
});
}
/**
* Makes the setup step necessary to cause pc_b to emit events.
* Note: This does not set up a connection.
* Returns the promise resulting from pc_b.setRemoteDescription.
*/
function createAndSetRemoteDescription(pc_a, pc_b) {
return pc_a.createOffer()
.then(function(offer) {
return pc_b.setRemoteDescription(offer);
})
}
/**
* The resolver has a |promise| that can be resolved or rejected using |resolve|
* or |reject|.
*/
class Resolver {
constructor() {
let promiseResolve;
let promiseReject;
this.promise = new Promise(function(resolve, reject) {
promiseResolve = resolve;
promiseReject = reject;
});
this.resolve = promiseResolve;
this.reject = promiseReject;
}
static createResolvers(count) {
let result = [];
for (let i = 0; i < count; ++i)
result.push(new Resolver());
return result;
}
static promises(resolvers) {
let promises = [];
for (let i = 0; i < resolvers.length; ++i) {
promises.push(resolvers[i].promise);
}
return promises;
}
}
</script>
</body>
</html>