diff options
Diffstat (limited to 'testing/web-platform/tests/webrtc/RTCDTMFSender-helper.js')
-rw-r--r-- | testing/web-platform/tests/webrtc/RTCDTMFSender-helper.js | 149 |
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]; +} |