node-datachannel 0.11.0 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -27,6 +27,7 @@
27
27
  "@electron-forge/plugin-webpack": "^6.4.2",
28
28
  "@electron/rebuild": "^3.3.0",
29
29
  "@vercel/webpack-asset-relocator-loader": "^1.7.3",
30
+ "copy-webpack-plugin": "^12.0.2",
30
31
  "css-loader": "^6.8.1",
31
32
  "electron": "26.2.4",
32
33
  "node-loader": "^2.0.0",
@@ -40,4 +41,4 @@
40
41
  "runtime": "electron",
41
42
  "runtimeVersion": "26.2.0"
42
43
  }
43
- }
44
+ }
@@ -1,3 +1,5 @@
1
+ const CopyPlugin = require('copy-webpack-plugin');
2
+
1
3
  module.exports = {
2
4
  /**
3
5
  * This is the main entry point for your application, it's the first file
@@ -8,4 +10,12 @@ module.exports = {
8
10
  module: {
9
11
  rules: require('./webpack.rules'),
10
12
  },
13
+ externals: {
14
+ 'node-datachannel': 'node-datachannel',
15
+ },
16
+ plugins: [
17
+ new CopyPlugin({
18
+ patterns: [{ from: 'node_modules/node-datachannel', to: 'node_modules/node-datachannel' }],
19
+ }),
20
+ ],
11
21
  };
package/jest.config.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  /** @type {import('jest').Config} */
2
2
  const config = {
3
3
  verbose: true,
4
- testPathIgnorePatterns: ['<rootDir>/node_modules/', 'multiple-run.test'],
4
+ testPathIgnorePatterns: ['node_modules', 'multiple-run.test', 'wpt-tests'],
5
5
  };
6
6
 
7
7
  module.exports = config;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-datachannel",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "libdatachannel node bindings",
5
5
  "type": "module",
6
6
  "types": "./lib/index.d.ts",
@@ -100,4 +100,4 @@
100
100
  "node-domexception": "^2.0.1",
101
101
  "prebuild-install": "^7.0.1"
102
102
  }
103
- }
103
+ }
@@ -0,0 +1,11 @@
1
+ /// <reference lib="dom" />
2
+
3
+ export class _RTCError extends DOMException implements RTCError {
4
+ constructor(init: RTCErrorInit, message?: string);
5
+ // type RTCErrorDetailType = "data-channel-failure" | "dtls-failure" | "fingerprint-failure" | "hardware-encoder-error" | "hardware-encoder-not-available" | "sctp-failure" | "sdp-syntax-error";
6
+ readonly errorDetail: RTCErrorDetailType;
7
+ readonly receivedAlert: number | null;
8
+ readonly sctpCauseCode: number | null;
9
+ readonly sdpLineNumber: number | null;
10
+ readonly sentAlert: number | null;
11
+ }
@@ -0,0 +1,65 @@
1
+ export default class RTCError extends DOMException {
2
+ constructor(init, message = '') {
3
+ super(message, 'OperationError');
4
+
5
+ if (!init || !init.errorDetail) throw new TypeError('Cannot construct RTCError, errorDetail is required');
6
+ if (
7
+ [
8
+ 'data-channel-failure',
9
+ 'dtls-failure',
10
+ 'fingerprint-failure',
11
+ 'hardware-encoder-error',
12
+ 'hardware-encoder-not-available',
13
+ 'sctp-failure',
14
+ 'sdp-syntax-error',
15
+ ].indexOf(init.errorDetail) === -1
16
+ )
17
+ throw new TypeError('Cannot construct RTCError, errorDetail is invalid');
18
+
19
+ this._errorDetail = init.errorDetail;
20
+ this._receivedAlert = init.receivedAlert ?? null;
21
+ this._sctpCauseCode = init.sctpCauseCode ?? null;
22
+ this._sdpLineNumber = init.sdpLineNumber ?? null;
23
+ this._sentAlert = init.sentAlert ?? null;
24
+ }
25
+
26
+ get errorDetail() {
27
+ return this._errorDetail;
28
+ }
29
+
30
+ set errorDetail(value) {
31
+ throw new TypeError('Cannot set errorDetail, it is read-only');
32
+ }
33
+
34
+ get receivedAlert() {
35
+ return this._receivedAlert;
36
+ }
37
+
38
+ set receivedAlert(value) {
39
+ throw new TypeError('Cannot set receivedAlert, it is read-only');
40
+ }
41
+
42
+ get sctpCauseCode() {
43
+ return this._sctpCauseCode;
44
+ }
45
+
46
+ set sctpCauseCode(value) {
47
+ throw new TypeError('Cannot set sctpCauseCode, it is read-only');
48
+ }
49
+
50
+ get sdpLineNumber() {
51
+ return this._sdpLineNumber;
52
+ }
53
+
54
+ set sdpLineNumber(value) {
55
+ throw new TypeError('Cannot set sdpLineNumber, it is read-only');
56
+ }
57
+
58
+ get sentAlert() {
59
+ return this._sentAlert;
60
+ }
61
+
62
+ set sentAlert(value) {
63
+ throw new TypeError('Cannot set sentAlert, it is read-only');
64
+ }
65
+ }
@@ -2,7 +2,7 @@
2
2
  //
3
3
  // Example: candidate:123456 1 UDP 123456 192.168.1.1 12345 typ host raddr=10.0.0.1 rport=54321 generation 0
4
4
 
5
- import DOMException from 'node-domexception';
5
+ import 'node-domexception';
6
6
 
7
7
  export default class _RTCIceCandidate {
8
8
  #address;
@@ -19,41 +19,40 @@ export default class _RTCIceCandidate {
19
19
  #tcpType;
20
20
  #type;
21
21
  #usernameFragment;
22
- #ip;
23
22
 
24
23
  constructor({ candidate, sdpMLineIndex, sdpMid, usernameFragment }) {
25
- if (candidate == null) {
26
- throw new DOMException('candidate must be specified');
27
- }
24
+ if (sdpMLineIndex == null && sdpMid == null)
25
+ throw new TypeError('At least one of sdpMLineIndex or sdpMid must be specified');
28
26
 
29
- this.#candidate = candidate;
30
- this.#sdpMLineIndex = sdpMLineIndex || null;
31
- this.#sdpMid = sdpMid || null;
32
- this.#usernameFragment = usernameFragment || null;
27
+ this.#candidate = candidate === null ? 'null' : candidate ?? '';
28
+ this.#sdpMLineIndex = sdpMLineIndex ?? null;
29
+ this.#sdpMid = sdpMid ?? null;
30
+ this.#usernameFragment = usernameFragment ?? null;
33
31
 
34
32
  if (candidate) {
35
33
  const fields = candidate.split(' ');
36
- this.#foundation = fields[0];
34
+ this.#foundation = fields[0].replace('candidate:', ''); // remove text candidate:
37
35
  this.#component = fields[1] == '1' ? 'rtp' : 'rtcp';
38
36
  this.#protocol = fields[2];
39
37
  this.#priority = parseInt(fields[3], 10);
40
- this.#ip = fields[4];
38
+ this.#address = fields[4];
41
39
  this.#port = parseInt(fields[5], 10);
42
40
  this.#type = fields[7];
43
- if (fields[6] === 'typ') {
44
- this.#tcpType = null;
45
- } else if (fields[6] === 'tcp') {
46
- this.#tcpType = fields[7];
47
- this.#type = fields[8];
48
- }
41
+ this.#tcpType = null;
42
+ this.#relatedAddress = null;
43
+ this.#relatedPort = null;
49
44
 
50
45
  // Parse the candidate string to extract relatedPort and relatedAddress
51
- for (let i = 9; i < fields.length; i++) {
46
+ for (let i = 8; i < fields.length; i++) {
52
47
  const field = fields[i];
53
- if (field.startsWith('raddr')) {
54
- this.#relatedAddress = field.split('=')[1];
55
- } else if (field.startsWith('rport')) {
56
- this.#relatedPort = parseInt(field.split('=')[1], 10);
48
+ if (field === 'raddr') {
49
+ this.#relatedAddress = fields[i + 1];
50
+ } else if (field === 'rport') {
51
+ this.#relatedPort = parseInt(fields[i + 1], 10);
52
+ }
53
+
54
+ if (this.#protocol === 'tcp' && field === 'tcptype') {
55
+ this.#tcpType = fields[i + 1];
57
56
  }
58
57
  }
59
58
  }
@@ -64,7 +63,7 @@ export default class _RTCIceCandidate {
64
63
  }
65
64
 
66
65
  get candidate() {
67
- return this.#candidate || '';
66
+ return this.#candidate;
68
67
  }
69
68
 
70
69
  get component() {
@@ -1,10 +1,10 @@
1
+ import 'node-domexception';
1
2
  import NodeDataChannel from '../lib/index.js';
2
3
  import RTCSessionDescription from './RTCSessionDescription.js';
3
4
  import RTCDataChannel from './RTCDataChannel.js';
4
5
  import RTCIceCandidate from './RTCIceCandidate.js';
5
6
  import { RTCDataChannelEvent, RTCPeerConnectionIceEvent } from './Events.js';
6
7
  import RTCSctpTransport from './RTCSctpTransport.js';
7
- import 'node-domexception';
8
8
  import * as exceptions from './Exception.js';
9
9
 
10
10
  export default class _RTCPeerConnection extends EventTarget {
@@ -55,10 +55,18 @@ export default class _RTCPeerConnection extends EventTarget {
55
55
  if (config.iceServers[i].urls?.some((url) => url == ''))
56
56
  throw exceptions.SyntaxError('IceServers urls cannot be empty');
57
57
 
58
- // urls should match the regex "stun\:\w*|turn\:\w*|turns\:\w*"
58
+ // urls should be valid URLs and match the protocols "stun:|turn:|turns:"
59
59
  if (
60
60
  config.iceServers[i].urls?.some(
61
- (url) => !/^(stun:[\w,\.,:]*|turn:[\w,\.,:]*|turns:[\w,\.,:]*)$/.test(url),
61
+ (url) => {
62
+ try {
63
+ const parsedURL = new URL(url)
64
+
65
+ return !/^(stun:|turn:|turns:)$/.test(parsedURL.protocol)
66
+ } catch (error) {
67
+ return true
68
+ }
69
+ },
62
70
  )
63
71
  )
64
72
  throw exceptions.SyntaxError('IceServers urls wrong format');
@@ -2,7 +2,7 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var DOMException$1 = require('node-domexception');
5
+ require('node-domexception');
6
6
  var module$1 = require('module');
7
7
  var stream = require('stream');
8
8
  var events = require('events');
@@ -247,41 +247,40 @@ class _RTCIceCandidate {
247
247
  #tcpType;
248
248
  #type;
249
249
  #usernameFragment;
250
- #ip;
251
250
 
252
251
  constructor({ candidate, sdpMLineIndex, sdpMid, usernameFragment }) {
253
- if (candidate == null) {
254
- throw new DOMException$1('candidate must be specified');
255
- }
252
+ if (sdpMLineIndex == null && sdpMid == null)
253
+ throw new TypeError('At least one of sdpMLineIndex or sdpMid must be specified');
256
254
 
257
- this.#candidate = candidate;
258
- this.#sdpMLineIndex = sdpMLineIndex || null;
259
- this.#sdpMid = sdpMid || null;
260
- this.#usernameFragment = usernameFragment || null;
255
+ this.#candidate = candidate === null ? 'null' : candidate ?? '';
256
+ this.#sdpMLineIndex = sdpMLineIndex ?? null;
257
+ this.#sdpMid = sdpMid ?? null;
258
+ this.#usernameFragment = usernameFragment ?? null;
261
259
 
262
260
  if (candidate) {
263
261
  const fields = candidate.split(' ');
264
- this.#foundation = fields[0];
262
+ this.#foundation = fields[0].replace('candidate:', ''); // remove text candidate:
265
263
  this.#component = fields[1] == '1' ? 'rtp' : 'rtcp';
266
264
  this.#protocol = fields[2];
267
265
  this.#priority = parseInt(fields[3], 10);
268
- this.#ip = fields[4];
266
+ this.#address = fields[4];
269
267
  this.#port = parseInt(fields[5], 10);
270
268
  this.#type = fields[7];
271
- if (fields[6] === 'typ') {
272
- this.#tcpType = null;
273
- } else if (fields[6] === 'tcp') {
274
- this.#tcpType = fields[7];
275
- this.#type = fields[8];
276
- }
269
+ this.#tcpType = null;
270
+ this.#relatedAddress = null;
271
+ this.#relatedPort = null;
277
272
 
278
273
  // Parse the candidate string to extract relatedPort and relatedAddress
279
- for (let i = 9; i < fields.length; i++) {
274
+ for (let i = 8; i < fields.length; i++) {
280
275
  const field = fields[i];
281
- if (field.startsWith('raddr')) {
282
- this.#relatedAddress = field.split('=')[1];
283
- } else if (field.startsWith('rport')) {
284
- this.#relatedPort = parseInt(field.split('=')[1], 10);
276
+ if (field === 'raddr') {
277
+ this.#relatedAddress = fields[i + 1];
278
+ } else if (field === 'rport') {
279
+ this.#relatedPort = parseInt(fields[i + 1], 10);
280
+ }
281
+
282
+ if (this.#protocol === 'tcp' && field === 'tcptype') {
283
+ this.#tcpType = fields[i + 1];
285
284
  }
286
285
  }
287
286
  }
@@ -292,7 +291,7 @@ class _RTCIceCandidate {
292
291
  }
293
292
 
294
293
  get candidate() {
295
- return this.#candidate || '';
294
+ return this.#candidate;
296
295
  }
297
296
 
298
297
  get component() {
@@ -809,10 +808,18 @@ class _RTCPeerConnection extends EventTarget {
809
808
  if (config.iceServers[i].urls?.some((url) => url == ''))
810
809
  throw SyntaxError('IceServers urls cannot be empty');
811
810
 
812
- // urls should match the regex "stun\:\w*|turn\:\w*|turns\:\w*"
811
+ // urls should be valid URLs and match the protocols "stun:|turn:|turns:"
813
812
  if (
814
813
  config.iceServers[i].urls?.some(
815
- (url) => !/^(stun:[\w,\.,:]*|turn:[\w,\.,:]*|turns:[\w,\.,:]*)$/.test(url),
814
+ (url) => {
815
+ try {
816
+ const parsedURL = new URL(url);
817
+
818
+ return !/^(stun:|turn:|turns:)$/.test(parsedURL.protocol)
819
+ } catch (error) {
820
+ return true
821
+ }
822
+ },
816
823
  )
817
824
  )
818
825
  throw SyntaxError('IceServers urls wrong format');
@@ -1232,6 +1239,72 @@ function getRandomString(length) {
1232
1239
  .substring(2, 2 + length);
1233
1240
  }
1234
1241
 
1242
+ let RTCError$1 = class RTCError extends DOMException {
1243
+ constructor(init, message = '') {
1244
+ super(message, 'OperationError');
1245
+
1246
+ if (!init || !init.errorDetail) throw new TypeError('Cannot construct RTCError, errorDetail is required');
1247
+ if (
1248
+ [
1249
+ 'data-channel-failure',
1250
+ 'dtls-failure',
1251
+ 'fingerprint-failure',
1252
+ 'hardware-encoder-error',
1253
+ 'hardware-encoder-not-available',
1254
+ 'sctp-failure',
1255
+ 'sdp-syntax-error',
1256
+ ].indexOf(init.errorDetail) === -1
1257
+ )
1258
+ throw new TypeError('Cannot construct RTCError, errorDetail is invalid');
1259
+
1260
+ this._errorDetail = init.errorDetail;
1261
+ this._receivedAlert = init.receivedAlert ?? null;
1262
+ this._sctpCauseCode = init.sctpCauseCode ?? null;
1263
+ this._sdpLineNumber = init.sdpLineNumber ?? null;
1264
+ this._sentAlert = init.sentAlert ?? null;
1265
+ }
1266
+
1267
+ get errorDetail() {
1268
+ return this._errorDetail;
1269
+ }
1270
+
1271
+ set errorDetail(value) {
1272
+ throw new TypeError('Cannot set errorDetail, it is read-only');
1273
+ }
1274
+
1275
+ get receivedAlert() {
1276
+ return this._receivedAlert;
1277
+ }
1278
+
1279
+ set receivedAlert(value) {
1280
+ throw new TypeError('Cannot set receivedAlert, it is read-only');
1281
+ }
1282
+
1283
+ get sctpCauseCode() {
1284
+ return this._sctpCauseCode;
1285
+ }
1286
+
1287
+ set sctpCauseCode(value) {
1288
+ throw new TypeError('Cannot set sctpCauseCode, it is read-only');
1289
+ }
1290
+
1291
+ get sdpLineNumber() {
1292
+ return this._sdpLineNumber;
1293
+ }
1294
+
1295
+ set sdpLineNumber(value) {
1296
+ throw new TypeError('Cannot set sdpLineNumber, it is read-only');
1297
+ }
1298
+
1299
+ get sentAlert() {
1300
+ return this._sentAlert;
1301
+ }
1302
+
1303
+ set sentAlert(value) {
1304
+ throw new TypeError('Cannot set sentAlert, it is read-only');
1305
+ }
1306
+ };
1307
+
1235
1308
  var index = {
1236
1309
  RTCCertificate,
1237
1310
  RTCDataChannel: _RTCDataChannel,
@@ -1243,12 +1316,14 @@ var index = {
1243
1316
  RTCSessionDescription: _RTCSessionDescription,
1244
1317
  RTCDataChannelEvent,
1245
1318
  RTCPeerConnectionIceEvent,
1319
+ RTCError: RTCError$1,
1246
1320
  };
1247
1321
 
1248
1322
  exports.RTCCertificate = RTCCertificate;
1249
1323
  exports.RTCDataChannel = _RTCDataChannel;
1250
1324
  exports.RTCDataChannelEvent = RTCDataChannelEvent;
1251
1325
  exports.RTCDtlsTransport = _RTCDtlsTransport;
1326
+ exports.RTCError = RTCError$1;
1252
1327
  exports.RTCIceCandidate = _RTCIceCandidate;
1253
1328
  exports.RTCIceTransport = _RTCIceTransport;
1254
1329
  exports.RTCPeerConnection = _RTCPeerConnection;
package/polyfill/index.js CHANGED
@@ -7,6 +7,7 @@ import RTCPeerConnection from './RTCPeerConnection.js';
7
7
  import RTCSctpTransport from './RTCSctpTransport.js';
8
8
  import RTCSessionDescription from './RTCSessionDescription.js';
9
9
  import { RTCDataChannelEvent, RTCPeerConnectionIceEvent } from './Events.js';
10
+ import RTCError from './RTCError.js';
10
11
 
11
12
  export {
12
13
  RTCCertificate,
@@ -19,6 +20,7 @@ export {
19
20
  RTCSessionDescription,
20
21
  RTCDataChannelEvent,
21
22
  RTCPeerConnectionIceEvent,
23
+ RTCError,
22
24
  };
23
25
 
24
26
  export default {
@@ -32,4 +34,5 @@ export default {
32
34
  RTCSessionDescription,
33
35
  RTCDataChannelEvent,
34
36
  RTCPeerConnectionIceEvent,
37
+ RTCError,
35
38
  };
@@ -22,6 +22,15 @@ Running test: /webrtc/RTCDataChannelEvent-constructor.html
22
22
  Running test: /webrtc/RTCDataChannel-iceRestart.html
23
23
  Running test: /webrtc/RTCDataChannel-id.html
24
24
  Running test: /webrtc/RTCDataChannel-send-blob-order.html
25
+ Running test: /webrtc/RTCDtlsTransport-getRemoteCertificates.html
26
+ Running test: /webrtc/RTCDtlsTransport-state.html
27
+ Running test: /webrtc/RTCDTMFSender-insertDTMF.https.html
28
+ Running test: /webrtc/RTCDTMFSender-ontonechange.https.html
29
+ Running test: /webrtc/RTCDTMFSender-ontonechange-long.https.html
30
+ Running test: /webrtc/RTCError.html
31
+ Running test: /webrtc/RTCIceCandidate-constructor.html
32
+ Running test: /webrtc/RTCIceConnectionState-candidate-pair.https.html
33
+ Running test: /webrtc/RTCIceTransport.html
25
34
  Running test: /webrtc/RTCPeerConnection-addIceCandidate.html
26
35
  Running test: /webrtc/RTCPeerConnection-addTcpIceCandidate.html
27
36
 
@@ -45,15 +54,24 @@ Running test: /webrtc/RTCDataChannelEvent-constructor.html
45
54
  Running test: /webrtc/RTCDataChannel-iceRestart.html
46
55
  Running test: /webrtc/RTCDataChannel-id.html
47
56
  Running test: /webrtc/RTCDataChannel-send-blob-order.html
57
+ Running test: /webrtc/RTCDtlsTransport-getRemoteCertificates.html
58
+ Running test: /webrtc/RTCDtlsTransport-state.html
59
+ Running test: /webrtc/RTCDTMFSender-insertDTMF.https.html
60
+ Running test: /webrtc/RTCDTMFSender-ontonechange.https.html
61
+ Running test: /webrtc/RTCDTMFSender-ontonechange-long.https.html
62
+ Running test: /webrtc/RTCError.html
63
+ Running test: /webrtc/RTCIceCandidate-constructor.html
64
+ Running test: /webrtc/RTCIceConnectionState-candidate-pair.https.html
65
+ Running test: /webrtc/RTCIceTransport.html
48
66
  Running test: /webrtc/RTCPeerConnection-addIceCandidate.html
49
67
  Running test: /webrtc/RTCPeerConnection-addTcpIceCandidate.html
50
68
 
51
69
  # Tests Report
52
- Total Tests [Chrome]: 316
53
- Total Tests [Library]: 316 (We expect this to be equal to Total Tests [Chrome])
54
- Passed Tests: 228
55
- Failed Tests (Chrome + Library): 35 (We don't care about these tests)
56
- Failed Tests: 53
70
+ Total Tests [Chrome]: 398
71
+ Total Tests [Library]: 398 (We expect this to be equal to Total Tests [Chrome])
72
+ Passed Tests: 269
73
+ Failed Tests (Chrome + Library): 41 (We don't care about these tests)
74
+ Failed Tests: 88
57
75
 
58
76
  ## Failed Tests
59
77
  ### /webrtc/historical.html
@@ -189,6 +207,85 @@ Failed Tests: 53
189
207
  message: assert_equals: expected (object) null but got (number) 42
190
208
  - name: Odd/even role should not be violated when mixing with negotiated channels
191
209
  message: assert_equals: Channel id must be null before DTLS role has been determined expected (object) null but got (number) 65535
210
+ ### /webrtc/RTCDtlsTransport-getRemoteCertificates.html
211
+ - name: RTCDtlsTransport.prototype.getRemoteCertificates
212
+ message: AudioContext is not defined
213
+ ### /webrtc/RTCDtlsTransport-state.html
214
+ - name: DTLS transport goes to connected state
215
+ message: promise_test: Unhandled rejection with value: object "ReferenceError: AudioContext is not defined"
216
+ - name: close() causes the other end's DTLS transport to close
217
+ message: promise_test: Unhandled rejection with value: object "ReferenceError: AudioContext is not defined"
218
+ - name: stop bundled transceiver retains dtls transport state
219
+ message: promise_test: Unhandled rejection with value: object "Error: Not implemented"
220
+ ### /webrtc/RTCDTMFSender-insertDTMF.https.html
221
+ - name: insertDTMF() should succeed if tones contains valid DTMF characters
222
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
223
+ - name: insertDTMF() should throw InvalidCharacterError if tones contains invalid DTMF characters
224
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
225
+ - name: insertDTMF() should throw InvalidStateError if transceiver is stopped
226
+ message: Not implemented
227
+ - name: insertDTMF() should throw InvalidStateError if transceiver.currentDirection is recvonly
228
+ message: promise_test: Unhandled rejection with value: object "Error: Not implemented"
229
+ - name: insertDTMF() should throw InvalidStateError if transceiver.currentDirection is inactive
230
+ message: promise_test: Unhandled rejection with value: object "Error: Not implemented"
231
+ - name: insertDTMF() should set toneBuffer to provided tones normalized, with old tones overridden
232
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
233
+ - name: insertDTMF() after remove and close should reject
234
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
235
+ ### /webrtc/RTCDTMFSender-ontonechange.https.html
236
+ - name: insertDTMF() with default duration and intertoneGap should fire tonechange events at the expected time
237
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
238
+ - name: insertDTMF() with explicit duration and intertoneGap should fire tonechange events at the expected time
239
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
240
+ - name: insertDTMF('') should not fire any tonechange event, including for '' tone
241
+ message: assert_unreached: Unexpected promise rejection: TypeError: Cannot read properties of undefined (reading 'getUserMedia') Reached unreachable code
242
+ - name: insertDTMF() with duration less than 40 should be clamped to 40
243
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
244
+ - name: insertDTMF() with interToneGap less than 30 should be clamped to 30
245
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
246
+ - name: insertDTMF with comma should delay next tonechange event for a constant 2000ms
247
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
248
+ - name: insertDTMF() with transceiver stopped in the middle should stop future tonechange events from firing
249
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
250
+ - name: Calling insertDTMF() in the middle of tonechange events should cause future tonechanges to be updated to new tones
251
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
252
+ - name: Calling insertDTMF() multiple times in the middle of tonechange events should cause future tonechanges to be updated the last provided tones
253
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
254
+ - name: Calling insertDTMF('') in the middle of tonechange events should stop future tonechange events from firing
255
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
256
+ - name: Setting transceiver.currentDirection to recvonly in the middle of tonechange events should stop future tonechange events from firing
257
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
258
+ - name: Tone change event constructor works
259
+ message: RTCDTMFToneChangeEvent is not defined
260
+ - name: Tone change event with unexpected name should not crash
261
+ message: RTCDTMFToneChangeEvent is not defined
262
+ ### /webrtc/RTCDTMFSender-ontonechange-long.https.html
263
+ - name: insertDTMF with duration greater than 6000 should be clamped to 6000
264
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
265
+ ### /webrtc/RTCIceConnectionState-candidate-pair.https.html
266
+ - name: On ICE connected, getStats() contains a connected candidate-pair
267
+ message: promise_test: Unhandled rejection with value: object "TypeError: Cannot read properties of undefined (reading 'getUserMedia')"
268
+ ### /webrtc/RTCIceTransport.html
269
+ - name: RTCIceTransport should be in state "new" initially
270
+ message: promise_test: Unhandled rejection with value: object "Error: Not implemented"
271
+ - name: RTCIceTransport should not transition to "checking" until after the answer is set _and_ the first remote candidate is received
272
+ message: promise_test: Unhandled rejection with value: object "Error: Not implemented"
273
+ - name: RTCIceTransport should transition to "disconnected" if packets stop flowing
274
+ message: promise_test: Unhandled rejection with value: object "Error: Not implemented"
275
+ - name: RTCIceTransport should transition to "disconnected" if packets stop flowing (DataChannel case)
276
+ message: assert_equals: expected "checking" but got "connected"
277
+ - name: Local ICE restart should not result in a different ICE transport
278
+ message: promise_test: Unhandled rejection with value: object "Error: Not implemented"
279
+ - name: Local ICE restart should not result in a different ICE transport (DataChannel case)
280
+ message: promise_test: Unhandled rejection with value: object "Error: Not implemented"
281
+ - name: Remote ICE restart should not result in a different ICE transport
282
+ message: promise_test: Unhandled rejection with value: object "Error: Not implemented"
283
+ - name: Remote ICE restart should not result in a different ICE transport (DataChannel case)
284
+ message: promise_test: Unhandled rejection with value: object "Error: Not implemented"
285
+ - name: RTCIceTransport should transition to "closed" if the underlying transport is closed because the answer used bundle
286
+ message: promise_test: Unhandled rejection with value: object "Error: Not implemented"
287
+ - name: RTCIceTransport should synchronously transition to "closed" with no event if the underlying transport is closed due to PC.close()
288
+ message: promise_test: Unhandled rejection with value: object "Error: Not implemented"
192
289
  ### /webrtc/RTCPeerConnection-addIceCandidate.html
193
290
  - name: addIceCandidate with second sdpMid and sdpMLineIndex should add candidate to second media stream
194
291
  message: assert_true: Expect candidate line to be found after media line m=video expected true got false
@@ -201,5 +298,4 @@ Failed Tests: 53
201
298
  message: promise_test: Unhandled rejection with value: undefined
202
299
  - name: TCP addIceCandidate aimed at port 8001 accepted
203
300
  message: promise_test: Unhandled rejection with value: object "OperationError: Invalid sdpMid format"
204
- - name: TCP candidate aimed at Fetch bad port 119 ignored
205
- message: assert_unreached: Reached unreachable code
301
+ End of tests
@@ -5,7 +5,7 @@
5
5
  "type": "module",
6
6
  "main": "wpt.js",
7
7
  "scripts": {
8
- "test": "npm run run:wpt & (sleep 8 && (npm run run:test > last-test-results.md) )",
8
+ "test": "npm run run:wpt & (sleep 8 && (npm run run:test | tee last-test-results.md) )",
9
9
  "run:wpt": "cd wpt && ./wpt serve",
10
10
  "run:test": "node index.js"
11
11
  },