summaryrefslogtreecommitdiffstats
path: root/testing/web-platform/tests/webrtc/RTCDTMFSender-helper.js
diff options
context:
space:
mode:
Diffstat (limited to 'testing/web-platform/tests/webrtc/RTCDTMFSender-helper.js')
-rw-r--r--testing/web-platform/tests/webrtc/RTCDTMFSender-helper.js149
1 files changed, 149 insertions, 0 deletions
diff --git a/testing/web-platform/tests/webrtc/RTCDTMFSender-helper.js b/testing/web-platform/tests/webrtc/RTCDTMFSender-helper.js
new file mode 100644
index 0000000000..4316c3804a
--- /dev/null
+++ b/testing/web-platform/tests/webrtc/RTCDTMFSender-helper.js
@@ -0,0 +1,149 @@
+'use strict';
+
+// Test is based on the following editor draft:
+// https://w3c.github.io/webrtc-pc/archives/20170605/webrtc.html
+
+// Code using this helper should also include RTCPeerConnection-helper.js
+// in the main HTML file
+
+// The following helper functions are called from RTCPeerConnection-helper.js:
+// getTrackFromUserMedia
+// exchangeOfferAnswer
+
+// Create a RTCDTMFSender using getUserMedia()
+// Connect the PeerConnection to another PC and wait until it is
+// properly connected, so that DTMF can be sent.
+function createDtmfSender(pc = new RTCPeerConnection()) {
+ let dtmfSender;
+ return getTrackFromUserMedia('audio')
+ .then(([track, mediaStream]) => {
+ const sender = pc.addTrack(track, mediaStream);
+ dtmfSender = sender.dtmf;
+ assert_true(dtmfSender instanceof RTCDTMFSender,
+ 'Expect audio sender.dtmf to be set to a RTCDTMFSender');
+ // Note: spec bug open - https://github.com/w3c/webrtc-pc/issues/1774
+ // on whether sending should be possible before negotiation.
+ const pc2 = new RTCPeerConnection();
+ Object.defineProperty(pc, 'otherPc', { value: pc2 });
+ exchangeIceCandidates(pc, pc2);
+ return exchangeOfferAnswer(pc, pc2);
+ }).then(() => {
+ if (!('canInsertDTMF' in dtmfSender)) {
+ return Promise.resolve();
+ }
+ // Wait until dtmfSender.canInsertDTMF becomes true.
+ // Up to 150 ms has been observed in test. Wait 1 second
+ // in steps of 10 ms.
+ // Note: Using a short timeout and rejected promise in order to
+ // make test return a clear error message on failure.
+ return new Promise((resolve, reject) => {
+ let counter = 0;
+ step_timeout(function checkCanInsertDTMF() {
+ if (dtmfSender.canInsertDTMF) {
+ resolve();
+ } else {
+ if (counter >= 100) {
+ reject('Waited too long for canInsertDTMF');
+ return;
+ }
+ ++counter;
+ step_timeout(checkCanInsertDTMF, 10);
+ }
+ }, 0);
+ });
+ }).then(() => {
+ return dtmfSender;
+ });
+}
+
+/*
+ Create an RTCDTMFSender and test tonechange events on it.
+ testFunc
+ Test function that is going to manipulate the DTMFSender.
+ It will be called with:
+ t - the test object
+ sender - the created RTCDTMFSender
+ pc - the associated RTCPeerConnection as second argument.
+ toneChanges
+ Array of expected tonechange events fired. The elements
+ are array of 3 items:
+ expectedTone
+ The expected character in event.tone
+ expectedToneBuffer
+ The expected new value of dtmfSender.toneBuffer
+ expectedDuration
+ The rough time since beginning or last tonechange event
+ was fired.
+ desc
+ Test description.
+ */
+function test_tone_change_events(testFunc, toneChanges, desc) {
+ // Convert to cumulative time
+ let cumulativeTime = 0;
+ const cumulativeToneChanges = toneChanges.map(c => {
+ cumulativeTime += c[2];
+ return [c[0], c[1], cumulativeTime];
+ });
+
+ // Wait for same duration as last expected duration + 100ms
+ // before passing test in case there are new tone events fired,
+ // in which case the test should fail.
+ const lastWait = toneChanges.pop()[2] + 100;
+
+ promise_test(async t => {
+ const pc = new RTCPeerConnection();
+ const dtmfSender = await createDtmfSender(pc);
+ const start = Date.now();
+
+ const allEventsReceived = new Promise(resolve => {
+ const onToneChange = t.step_func(ev => {
+ assert_true(ev instanceof RTCDTMFToneChangeEvent,
+ 'Expect tone change event object to be an RTCDTMFToneChangeEvent');
+
+ const { tone } = ev;
+ assert_equals(typeof tone, 'string',
+ 'Expect event.tone to be the tone string');
+
+ assert_greater_than(cumulativeToneChanges.length, 0,
+ 'More tonechange event is fired than expected');
+
+ const [
+ expectedTone, expectedToneBuffer, expectedTime
+ ] = cumulativeToneChanges.shift();
+
+ assert_equals(tone, expectedTone,
+ `Expect current event.tone to be ${expectedTone}`);
+
+ assert_equals(dtmfSender.toneBuffer, expectedToneBuffer,
+ `Expect dtmfSender.toneBuffer to be updated to ${expectedToneBuffer}`);
+
+ // We check that the cumulative delay is at least the expected one, but
+ // system load may cause random delays, so we do not put any
+ // realistic upper bound on the timing of the events.
+ assert_between_inclusive(Date.now() - start, expectedTime,
+ expectedTime + 4000,
+ `Expect tonechange event for "${tone}" to be fired approximately after ${expectedTime} milliseconds`);
+ if (cumulativeToneChanges.length === 0) {
+ resolve();
+ }
+ });
+
+ dtmfSender.addEventListener('tonechange', onToneChange);
+ });
+
+ testFunc(t, dtmfSender, pc);
+ await allEventsReceived;
+ const wait = ms => new Promise(resolve => t.step_timeout(resolve, ms));
+ await wait(lastWait);
+ }, desc);
+}
+
+// Get the one and only tranceiver from pc.getTransceivers().
+// Assumes that there is only one tranceiver in pc.
+function getTransceiver(pc) {
+ const transceivers = pc.getTransceivers();
+ assert_equals(transceivers.length, 1,
+ 'Expect there to be only one tranceiver in pc');
+
+ return transceivers[0];
+}