node-datachannel 0.10.1 → 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.
- package/.github/workflows/build-linux.yml +7 -2
- package/.github/workflows/build-win.yml +3 -3
- package/.gitmodules +3 -0
- package/CMakeLists.txt +1 -1
- package/README.md +18 -4
- package/cmake/toolchain/ci.cmake +1 -1
- package/examples/client-server/client-benchmark.js +7 -9
- package/examples/client-server/client-periodic.js +7 -9
- package/examples/client-server/client.js +7 -9
- package/examples/client-server/package-lock.json +0 -27
- package/examples/client-server/package.json +0 -1
- package/examples/client-server/signaling-server.js +21 -10
- package/examples/electron-demo/README.md +1 -1
- package/examples/electron-demo/package-lock.json +316 -372
- package/examples/electron-demo/package.json +2 -1
- package/examples/electron-demo/webpack.main.config.js +10 -0
- package/examples/websocket/websocket-client.js +20 -0
- package/examples/websocket/websocket-server.js +22 -0
- package/jest.config.cjs +1 -1
- package/lib/index.cjs +52 -9
- package/lib/index.js +22 -15
- package/lib/node-datachannel.js +7 -0
- package/lib/websocket-server.js +34 -0
- package/package.json +3 -3
- package/polyfill/Events.js +5 -3
- package/polyfill/Exception.js +23 -0
- package/polyfill/README.md +4 -0
- package/polyfill/RTCDataChannel.js +19 -11
- package/polyfill/RTCError.d.ts +11 -0
- package/polyfill/RTCError.js +65 -0
- package/polyfill/RTCIceCandidate.js +22 -23
- package/polyfill/RTCPeerConnection.js +157 -42
- package/polyfill/index.cjs +350 -82
- package/polyfill/index.js +3 -0
- package/src/peer-connection-wrapper.cpp +11 -3
- package/src/web-socket-server-wrapper.cpp +23 -23
- package/src/web-socket-server-wrapper.h +8 -6
- package/src/web-socket-wrapper.cpp +7 -1
- package/test/connectivity.js +1 -23
- package/test/wpt-tests/README.md +46 -0
- package/test/wpt-tests/chrome-failed-tests.js +42 -0
- package/test/wpt-tests/index.js +96 -0
- package/test/wpt-tests/last-test-results.md +301 -0
- package/test/wpt-tests/package-lock.json +1712 -0
- package/test/wpt-tests/package.json +19 -0
- package/test/wpt-tests/wpt-test-list.js +139 -0
- package/test/wpt-tests/wpt.js +131 -0
- package/test/wpt.js +0 -50
|
@@ -100,8 +100,17 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
100
100
|
Napi::Array iceServers = config.Get("iceServers").As<Napi::Array>();
|
|
101
101
|
for (uint32_t i = 0; i < iceServers.Length(); i++)
|
|
102
102
|
{
|
|
103
|
-
if (iceServers.Get(i).IsString())
|
|
104
|
-
|
|
103
|
+
if (iceServers.Get(i).IsString()){
|
|
104
|
+
try
|
|
105
|
+
{
|
|
106
|
+
rtcConfig.iceServers.emplace_back(iceServers.Get(i).As<Napi::String>().ToString());
|
|
107
|
+
}
|
|
108
|
+
catch(std::exception &ex)
|
|
109
|
+
{
|
|
110
|
+
Napi::TypeError::New(env, "SyntaxError: IceServer config error: " + std::string(ex.what())).ThrowAsJavaScriptException();
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
105
114
|
else
|
|
106
115
|
{
|
|
107
116
|
if (!iceServers.Get(i).IsObject())
|
|
@@ -116,7 +125,6 @@ PeerConnectionWrapper::PeerConnectionWrapper(const Napi::CallbackInfo &info) : N
|
|
|
116
125
|
Napi::TypeError::New(env, "IceServer config error (hostname OR/AND port is not suitable)").ThrowAsJavaScriptException();
|
|
117
126
|
return;
|
|
118
127
|
}
|
|
119
|
-
|
|
120
128
|
if (iceServer.Get("relayType").IsString() &&
|
|
121
129
|
(!iceServer.Get("username").IsString() || !iceServer.Get("password").IsString()))
|
|
122
130
|
{
|
|
@@ -2,6 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
#include "plog/Log.h"
|
|
4
4
|
|
|
5
|
+
Napi::FunctionReference WebSocketServerWrapper::constructor;
|
|
6
|
+
std::unordered_set<WebSocketServerWrapper *> WebSocketServerWrapper::instances;
|
|
7
|
+
|
|
5
8
|
void WebSocketServerWrapper::StopAll()
|
|
6
9
|
{
|
|
7
10
|
PLOG_DEBUG << "StopAll() called";
|
|
@@ -10,9 +13,6 @@ void WebSocketServerWrapper::StopAll()
|
|
|
10
13
|
inst->doStop();
|
|
11
14
|
}
|
|
12
15
|
|
|
13
|
-
Napi::FunctionReference WebSocketServerWrapper::constructor;
|
|
14
|
-
std::unordered_set<WebSocketServerWrapper *> WebSocketServerWrapper::instances;
|
|
15
|
-
|
|
16
16
|
Napi::Object WebSocketServerWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
17
17
|
{
|
|
18
18
|
Napi::HandleScope scope(env);
|
|
@@ -36,7 +36,6 @@ Napi::Object WebSocketServerWrapper::Init(Napi::Env env, Napi::Object exports)
|
|
|
36
36
|
WebSocketServerWrapper::WebSocketServerWrapper(const Napi::CallbackInfo &info) : Napi::ObjectWrap<WebSocketServerWrapper>(info)
|
|
37
37
|
{
|
|
38
38
|
PLOG_DEBUG << "Constructor called";
|
|
39
|
-
|
|
40
39
|
Napi::Env env = info.Env();
|
|
41
40
|
|
|
42
41
|
// Create WebSocketServer without config
|
|
@@ -52,7 +51,7 @@ WebSocketServerWrapper::WebSocketServerWrapper(const Napi::CallbackInfo &info) :
|
|
|
52
51
|
Napi::Error::New(env, std::string("libdatachannel error while creating WebSocketServer without config: ") + ex.what()).ThrowAsJavaScriptException();
|
|
53
52
|
return;
|
|
54
53
|
}
|
|
55
|
-
|
|
54
|
+
|
|
56
55
|
PLOG_DEBUG << "WebSocketServer created without config";
|
|
57
56
|
|
|
58
57
|
instances.insert(this);
|
|
@@ -60,14 +59,14 @@ WebSocketServerWrapper::WebSocketServerWrapper(const Napi::CallbackInfo &info) :
|
|
|
60
59
|
}
|
|
61
60
|
|
|
62
61
|
// Create WebSocketServer with config
|
|
63
|
-
|
|
64
|
-
Napi::Object config = info[0].As<Napi::Object>();
|
|
62
|
+
|
|
63
|
+
Napi::Object config = info[0].As<Napi::Object>();
|
|
65
64
|
rtc::WebSocketServerConfiguration webSocketServerConfig;
|
|
66
65
|
|
|
67
66
|
// Port
|
|
68
67
|
if (config.Has("port"))
|
|
69
68
|
{
|
|
70
|
-
if (!config.Get("port").IsNumber())
|
|
69
|
+
if (!config.Get("port").IsNumber())
|
|
71
70
|
{
|
|
72
71
|
Napi::TypeError::New(info.Env(), "port must be a number").ThrowAsJavaScriptException();
|
|
73
72
|
return;
|
|
@@ -78,7 +77,7 @@ WebSocketServerWrapper::WebSocketServerWrapper(const Napi::CallbackInfo &info) :
|
|
|
78
77
|
// Enable TLS
|
|
79
78
|
if (config.Has("enableTls"))
|
|
80
79
|
{
|
|
81
|
-
if (!config.Get("enableTls").IsBoolean())
|
|
80
|
+
if (!config.Get("enableTls").IsBoolean())
|
|
82
81
|
{
|
|
83
82
|
Napi::TypeError::New(info.Env(), "enableTls must be boolean").ThrowAsJavaScriptException();
|
|
84
83
|
return;
|
|
@@ -89,7 +88,7 @@ WebSocketServerWrapper::WebSocketServerWrapper(const Napi::CallbackInfo &info) :
|
|
|
89
88
|
// Certificate PEM File
|
|
90
89
|
if (config.Has("certificatePemFile"))
|
|
91
90
|
{
|
|
92
|
-
if (!config.Get("certificatePemFile").IsString())
|
|
91
|
+
if (!config.Get("certificatePemFile").IsString())
|
|
93
92
|
{
|
|
94
93
|
Napi::TypeError::New(info.Env(), "certificatePemFile must be a string").ThrowAsJavaScriptException();
|
|
95
94
|
return;
|
|
@@ -100,7 +99,7 @@ WebSocketServerWrapper::WebSocketServerWrapper(const Napi::CallbackInfo &info) :
|
|
|
100
99
|
// Key PEM File
|
|
101
100
|
if (config.Has("keyPemFile"))
|
|
102
101
|
{
|
|
103
|
-
if (!config.Get("keyPemFile").IsString())
|
|
102
|
+
if (!config.Get("keyPemFile").IsString())
|
|
104
103
|
{
|
|
105
104
|
Napi::TypeError::New(info.Env(), "keyPemFile must be a string").ThrowAsJavaScriptException();
|
|
106
105
|
return;
|
|
@@ -111,7 +110,7 @@ WebSocketServerWrapper::WebSocketServerWrapper(const Napi::CallbackInfo &info) :
|
|
|
111
110
|
// Key PEM Pass
|
|
112
111
|
if (config.Has("keyPemPass"))
|
|
113
112
|
{
|
|
114
|
-
if (!config.Get("keyPemPass").IsString())
|
|
113
|
+
if (!config.Get("keyPemPass").IsString())
|
|
115
114
|
{
|
|
116
115
|
Napi::TypeError::New(info.Env(), "keyPemPass must be a string").ThrowAsJavaScriptException();
|
|
117
116
|
return;
|
|
@@ -122,7 +121,7 @@ WebSocketServerWrapper::WebSocketServerWrapper(const Napi::CallbackInfo &info) :
|
|
|
122
121
|
// Bind Address
|
|
123
122
|
if (config.Has("bindAddress"))
|
|
124
123
|
{
|
|
125
|
-
if (!config.Get("bindAddress").IsString())
|
|
124
|
+
if (!config.Get("bindAddress").IsString())
|
|
126
125
|
{
|
|
127
126
|
Napi::TypeError::New(info.Env(), "bindAddress must be a string").ThrowAsJavaScriptException();
|
|
128
127
|
return;
|
|
@@ -133,7 +132,7 @@ WebSocketServerWrapper::WebSocketServerWrapper(const Napi::CallbackInfo &info) :
|
|
|
133
132
|
// Connection Timeout
|
|
134
133
|
if (config.Has("connectionTimeout"))
|
|
135
134
|
{
|
|
136
|
-
if (!config.Get("connectionTimeout").IsNumber())
|
|
135
|
+
if (!config.Get("connectionTimeout").IsNumber())
|
|
137
136
|
{
|
|
138
137
|
Napi::TypeError::New(info.Env(), "connectionTimeout must be a number").ThrowAsJavaScriptException();
|
|
139
138
|
return;
|
|
@@ -144,7 +143,7 @@ WebSocketServerWrapper::WebSocketServerWrapper(const Napi::CallbackInfo &info) :
|
|
|
144
143
|
// Max Message Size
|
|
145
144
|
if (config.Has("maxMessageSize"))
|
|
146
145
|
{
|
|
147
|
-
if (!config.Get("maxMessageSize").IsNumber())
|
|
146
|
+
if (!config.Get("maxMessageSize").IsNumber())
|
|
148
147
|
{
|
|
149
148
|
Napi::TypeError::New(info.Env(), "maxMessageSize must be a number").ThrowAsJavaScriptException();
|
|
150
149
|
return;
|
|
@@ -163,7 +162,7 @@ WebSocketServerWrapper::WebSocketServerWrapper(const Napi::CallbackInfo &info) :
|
|
|
163
162
|
Napi::Error::New(env, std::string("libdatachannel error while creating WebSocketServer: ") + ex.what()).ThrowAsJavaScriptException();
|
|
164
163
|
return;
|
|
165
164
|
}
|
|
166
|
-
|
|
165
|
+
|
|
167
166
|
PLOG_DEBUG << "WebSocketServer created";
|
|
168
167
|
instances.insert(this);
|
|
169
168
|
}
|
|
@@ -179,7 +178,7 @@ void WebSocketServerWrapper::doStop()
|
|
|
179
178
|
PLOG_DEBUG << "doStop() called";
|
|
180
179
|
if (mWebSocketServerPtr)
|
|
181
180
|
{
|
|
182
|
-
PLOG_DEBUG << "
|
|
181
|
+
PLOG_DEBUG << "Stopping...";
|
|
183
182
|
try
|
|
184
183
|
{
|
|
185
184
|
mWebSocketServerPtr->stop();
|
|
@@ -187,13 +186,12 @@ void WebSocketServerWrapper::doStop()
|
|
|
187
186
|
}
|
|
188
187
|
catch (std::exception &ex)
|
|
189
188
|
{
|
|
190
|
-
std::cerr << std::string("
|
|
189
|
+
std::cerr << std::string("libdatachannel error while closing WebSocketServer: ") + ex.what() << std::endl;
|
|
191
190
|
return;
|
|
192
191
|
}
|
|
193
192
|
}
|
|
194
193
|
|
|
195
194
|
mOnClientCallback.reset();
|
|
196
|
-
|
|
197
195
|
instances.erase(this);
|
|
198
196
|
}
|
|
199
197
|
|
|
@@ -238,7 +236,7 @@ void WebSocketServerWrapper::onClient(const Napi::CallbackInfo &info)
|
|
|
238
236
|
|
|
239
237
|
if (length < 1 || !info[0].IsFunction())
|
|
240
238
|
{
|
|
241
|
-
Napi::TypeError::New(env, "Function expected as onClient
|
|
239
|
+
Napi::TypeError::New(env, "Function expected as onClient callback").ThrowAsJavaScriptException();
|
|
242
240
|
return;
|
|
243
241
|
}
|
|
244
242
|
|
|
@@ -246,7 +244,7 @@ void WebSocketServerWrapper::onClient(const Napi::CallbackInfo &info)
|
|
|
246
244
|
mOnClientCallback = std::make_unique<ThreadSafeCallback>(info[0].As<Napi::Function>());
|
|
247
245
|
|
|
248
246
|
mWebSocketServerPtr->onClient([&](std::shared_ptr<rtc::WebSocket> ws)
|
|
249
|
-
|
|
247
|
+
{
|
|
250
248
|
PLOG_DEBUG << "onClient ws received from WebSocketServer";
|
|
251
249
|
if (mOnClientCallback)
|
|
252
250
|
mOnClientCallback->call([this, ws](Napi::Env env, std::vector<napi_value> &args) {
|
|
@@ -258,8 +256,10 @@ void WebSocketServerWrapper::onClient(const Napi::CallbackInfo &info)
|
|
|
258
256
|
// This will run in main thread and needs to construct the
|
|
259
257
|
// arguments for the call
|
|
260
258
|
std::shared_ptr<rtc::WebSocket> webSocket = ws;
|
|
261
|
-
|
|
259
|
+
// First argument is just a placeholder
|
|
260
|
+
auto instance = WebSocketWrapper::constructor.New({Napi::Boolean::New(env, false), Napi::External<std::shared_ptr<rtc::WebSocket>>::New(env, &webSocket)});
|
|
262
261
|
args = {instance};
|
|
263
262
|
PLOG_DEBUG << "mOnClientCallback call(2)";
|
|
264
|
-
});
|
|
263
|
+
});
|
|
264
|
+
});
|
|
265
265
|
}
|
|
@@ -16,13 +16,11 @@
|
|
|
16
16
|
class WebSocketServerWrapper : public Napi::ObjectWrap<WebSocketServerWrapper>
|
|
17
17
|
{
|
|
18
18
|
public:
|
|
19
|
-
static Napi::FunctionReference constructor;
|
|
20
19
|
static Napi::Object Init(Napi::Env env, Napi::Object exports);
|
|
21
20
|
WebSocketServerWrapper(const Napi::CallbackInfo &info);
|
|
22
21
|
~WebSocketServerWrapper();
|
|
23
22
|
|
|
24
23
|
// Functions
|
|
25
|
-
|
|
26
24
|
void stop(const Napi::CallbackInfo &info);
|
|
27
25
|
Napi::Value port(const Napi::CallbackInfo &info);
|
|
28
26
|
|
|
@@ -31,13 +29,17 @@ public:
|
|
|
31
29
|
|
|
32
30
|
// Close all existing WebSocketServers
|
|
33
31
|
static void StopAll();
|
|
34
|
-
|
|
32
|
+
|
|
35
33
|
private:
|
|
36
|
-
static
|
|
37
|
-
std::
|
|
38
|
-
std::unique_ptr<ThreadSafeCallback> mOnClientCallback = nullptr;
|
|
34
|
+
static Napi::FunctionReference constructor;
|
|
35
|
+
static std::unordered_set<WebSocketServerWrapper *> instances;
|
|
39
36
|
|
|
40
37
|
void doStop();
|
|
38
|
+
|
|
39
|
+
std::unique_ptr<rtc::WebSocketServer> mWebSocketServerPtr = nullptr;
|
|
40
|
+
|
|
41
|
+
// Callback Ptrs
|
|
42
|
+
std::unique_ptr<ThreadSafeCallback> mOnClientCallback = nullptr;
|
|
41
43
|
};
|
|
42
44
|
|
|
43
45
|
#endif // WEB_SOCKET_SERVER_WRAPPER_H
|
|
@@ -65,6 +65,9 @@ WebSocketWrapper::WebSocketWrapper(const Napi::CallbackInfo &info) : Napi::Objec
|
|
|
65
65
|
mWebSocketPtr = *(info[1].As<Napi::External<std::shared_ptr<rtc::WebSocket>>>().Data());
|
|
66
66
|
PLOG_DEBUG << "Using WebSocket got from WebSocketServer";
|
|
67
67
|
instances.insert(this);
|
|
68
|
+
|
|
69
|
+
// Closed callback must be set to trigger cleanup
|
|
70
|
+
mOnClosedCallback = std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo &) {}));
|
|
68
71
|
return;
|
|
69
72
|
}
|
|
70
73
|
|
|
@@ -82,6 +85,9 @@ WebSocketWrapper::WebSocketWrapper(const Napi::CallbackInfo &info) : Napi::Objec
|
|
|
82
85
|
return;
|
|
83
86
|
}
|
|
84
87
|
instances.insert(this);
|
|
88
|
+
|
|
89
|
+
// Closed callback must be set to trigger cleanup
|
|
90
|
+
mOnClosedCallback = std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo &) {}));
|
|
85
91
|
return;
|
|
86
92
|
}
|
|
87
93
|
|
|
@@ -240,7 +246,7 @@ WebSocketWrapper::WebSocketWrapper(const Napi::CallbackInfo &info) : Napi::Objec
|
|
|
240
246
|
PLOG_DEBUG << "WebSocket created";
|
|
241
247
|
|
|
242
248
|
// Closed callback must set to trigger cleanup
|
|
243
|
-
mOnClosedCallback = std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo&){}));
|
|
249
|
+
mOnClosedCallback = std::make_unique<ThreadSafeCallback>(Napi::Function::New(info.Env(), [](const Napi::CallbackInfo &) {}));
|
|
244
250
|
|
|
245
251
|
instances.insert(this);
|
|
246
252
|
}
|
package/test/connectivity.js
CHANGED
|
@@ -1,30 +1,16 @@
|
|
|
1
1
|
import nodeDataChannel from '../lib/index.js';
|
|
2
2
|
|
|
3
3
|
nodeDataChannel.initLogger('Debug');
|
|
4
|
-
nodeDataChannel.preload();
|
|
5
4
|
|
|
6
5
|
let dc1 = null;
|
|
7
6
|
let dc2 = null;
|
|
8
7
|
|
|
9
|
-
// Config options
|
|
10
|
-
// export interface RtcConfig {
|
|
11
|
-
// iceServers: string[];
|
|
12
|
-
// proxyServer?: ProxyServer;
|
|
13
|
-
// bindAddress?: string;
|
|
14
|
-
// enableIceTcp?: boolean;
|
|
15
|
-
// portRangeBegin?: number;
|
|
16
|
-
// portRangeEnd?: number;
|
|
17
|
-
// maxMessageSize?: number;
|
|
18
|
-
// iceTransportPolicy?: TransportPolicy;
|
|
19
|
-
// }
|
|
20
|
-
//
|
|
21
8
|
// "iceServers" option is an array of stun/turn server urls
|
|
22
9
|
// Examples;
|
|
23
10
|
// STUN Server Example : stun:stun.l.google.com:19302
|
|
24
11
|
// TURN Server Example : turn:USERNAME:PASSWORD@TURN_IP_OR_ADDRESS:PORT
|
|
25
12
|
// TURN Server Example (TCP) : turn:USERNAME:PASSWORD@TURN_IP_OR_ADDRESS:PORT?transport=tcp
|
|
26
13
|
// TURN Server Example (TLS) : turns:USERNAME:PASSWORD@TURN_IP_OR_ADDRESS:PORT
|
|
27
|
-
|
|
28
14
|
let peer1 = new nodeDataChannel.PeerConnection('Peer1', { iceServers: ['stun:stun.l.google.com:19302'] });
|
|
29
15
|
|
|
30
16
|
// Set Callbacks
|
|
@@ -78,15 +64,7 @@ peer2.onDataChannel((dc) => {
|
|
|
78
64
|
});
|
|
79
65
|
});
|
|
80
66
|
|
|
81
|
-
// DataChannel
|
|
82
|
-
// export interface DataChannelInitConfig {
|
|
83
|
-
// protocol?: string;
|
|
84
|
-
// negotiated?: boolean;
|
|
85
|
-
// id?: number;
|
|
86
|
-
// ordered?: boolean;
|
|
87
|
-
// maxPacketLifeTime?: number;
|
|
88
|
-
// maxRetransmits?: number;
|
|
89
|
-
// }
|
|
67
|
+
// Create DataChannel
|
|
90
68
|
dc1 = peer1.createDataChannel('test');
|
|
91
69
|
dc1.onOpen(() => {
|
|
92
70
|
dc1.sendMessage('Hello from Peer1');
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Setup (First time usage)
|
|
2
|
+
|
|
3
|
+
> cd test/wpt-tests
|
|
4
|
+
|
|
5
|
+
> npm i
|
|
6
|
+
|
|
7
|
+
> git submodule update --init --recursive --depth 1
|
|
8
|
+
|
|
9
|
+
> cd wpt
|
|
10
|
+
|
|
11
|
+
> ./wpt make-hosts-file | sudo tee -a /etc/hosts
|
|
12
|
+
|
|
13
|
+
After your hosts file is configured, the servers will be locally accessible at:
|
|
14
|
+
|
|
15
|
+
http://web-platform.test:8000/
|
|
16
|
+
|
|
17
|
+
https://web-platform.test:8443/ \*
|
|
18
|
+
|
|
19
|
+
To use the web-based runner point your browser to:
|
|
20
|
+
|
|
21
|
+
http://web-platform.test:8000/tools/runner/index.html
|
|
22
|
+
|
|
23
|
+
https://web-platform.test:8443/tools/runner/index.html \*
|
|
24
|
+
|
|
25
|
+
# Running Tests
|
|
26
|
+
|
|
27
|
+
> npm run test
|
|
28
|
+
|
|
29
|
+
OR
|
|
30
|
+
|
|
31
|
+
> npm run:wpt (Let this run)
|
|
32
|
+
|
|
33
|
+
> npm run:test (In an other console)
|
|
34
|
+
|
|
35
|
+
The files that tested are listed in `wpt-test-list.js`. The commented lines need still to be one-by-one tested and uncommented.
|
|
36
|
+
|
|
37
|
+
Contributions are welcome!
|
|
38
|
+
|
|
39
|
+
# Run a test for Chrome
|
|
40
|
+
|
|
41
|
+
./wpt run chrome /webrtc/RTCPeerConnection-addIceCandidate.html
|
|
42
|
+
|
|
43
|
+
# Latest Test Results
|
|
44
|
+
|
|
45
|
+
Please check [last-test-results.md](./last-test-results.md) page
|
|
46
|
+
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { runWptTests } from './wpt.js';
|
|
2
|
+
|
|
3
|
+
// Some tests also fail in Chrome
|
|
4
|
+
// We don't also care of them
|
|
5
|
+
let chromeFailedTests = [];
|
|
6
|
+
let totalNumberOfTests = 0;
|
|
7
|
+
|
|
8
|
+
export async function runChromeTests(wptTestList) {
|
|
9
|
+
chromeFailedTests = [];
|
|
10
|
+
totalNumberOfTests = 0;
|
|
11
|
+
let results = await runWptTests(wptTestList, true);
|
|
12
|
+
for (let i = 0; i < results.length; i++) {
|
|
13
|
+
totalNumberOfTests += results[i].result?.length || 0;
|
|
14
|
+
if (results[i].result && results[i].result.some((test) => test.status === 1)) {
|
|
15
|
+
chromeFailedTests.push({
|
|
16
|
+
test: results[i].test,
|
|
17
|
+
result: results[i].result.filter((test) => test.status === 1),
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function getChromeFailedTests() {
|
|
24
|
+
return chromeFailedTests;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function isTestForChromeFailed(testPath, testName) {
|
|
28
|
+
return chromeFailedTests.some(
|
|
29
|
+
(test) =>
|
|
30
|
+
test.test === testPath && test.result.some((result) => result.name === testName && result.status === 1),
|
|
31
|
+
);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function getTotalNumberOfTests() {
|
|
35
|
+
return totalNumberOfTests;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Test
|
|
39
|
+
// (async () => {
|
|
40
|
+
// await runChromeTests();
|
|
41
|
+
// console.log(getChromeFailedTests());
|
|
42
|
+
// })();
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import ndc from '../../lib/index.js';
|
|
2
|
+
import wptTestList from './wpt-test-list.js';
|
|
3
|
+
import { runWptTests } from './wpt.js';
|
|
4
|
+
import { runChromeTests, isTestForChromeFailed, getTotalNumberOfTests } from './chrome-failed-tests.js';
|
|
5
|
+
|
|
6
|
+
// Set the log level, for debugging purposes
|
|
7
|
+
// ndc.initLogger('Debug');
|
|
8
|
+
|
|
9
|
+
// Catch unhandled exceptions
|
|
10
|
+
process.on('unhandledRejection', (reason, promise) => {
|
|
11
|
+
console.error('Unhandled Rejection at:', promise, 'reason:', reason);
|
|
12
|
+
process.exit(1);
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
// Run tests for Chrome
|
|
16
|
+
console.log('# Running tests for Chrome...');
|
|
17
|
+
await runChromeTests(wptTestList);
|
|
18
|
+
//console.log(JSON.stringify(getChromeFailedTests(), null, 2));
|
|
19
|
+
|
|
20
|
+
// Run tests for node-datachannel
|
|
21
|
+
console.log('');
|
|
22
|
+
console.log('# Running tests for node-datachannel...');
|
|
23
|
+
let results = await runWptTests(wptTestList);
|
|
24
|
+
|
|
25
|
+
// Calc total number of tests
|
|
26
|
+
let totalTests = 0;
|
|
27
|
+
results.forEach((result) => {
|
|
28
|
+
totalTests += result.result.length;
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// Compare results
|
|
32
|
+
// Filter failed tests for node-datachannel
|
|
33
|
+
let failedTestsLibrary = [];
|
|
34
|
+
results.forEach((result) => {
|
|
35
|
+
if (result.result.some((test) => test.status === 1)) {
|
|
36
|
+
failedTestsLibrary.push({
|
|
37
|
+
test: result.test,
|
|
38
|
+
result: result.result.filter((test) => test.status === 1),
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
let totalFailedTestsLibrary = 0;
|
|
43
|
+
failedTestsLibrary.forEach((result) => {
|
|
44
|
+
totalFailedTestsLibrary += result.result.length;
|
|
45
|
+
});
|
|
46
|
+
// console.log(JSON.stringify(failedTestsLibrary, null, 2));
|
|
47
|
+
|
|
48
|
+
// Filter out any failed tests that also failed in Chrome
|
|
49
|
+
let failedTests = [];
|
|
50
|
+
failedTestsLibrary.forEach((result) => {
|
|
51
|
+
if (result.result.some((test) => !isTestForChromeFailed(result.test, test.name))) {
|
|
52
|
+
failedTests.push({
|
|
53
|
+
test: result.test,
|
|
54
|
+
result: result.result.filter((test) => !isTestForChromeFailed(result.test, test.name)),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
});
|
|
58
|
+
let totalFailedTests = 0;
|
|
59
|
+
failedTests.forEach((result) => {
|
|
60
|
+
totalFailedTests += result.result.length;
|
|
61
|
+
});
|
|
62
|
+
// console.log(JSON.stringify(failedTests, null, 2));
|
|
63
|
+
|
|
64
|
+
// Print Report
|
|
65
|
+
// Print Test Names
|
|
66
|
+
console.log('');
|
|
67
|
+
console.log('# Tests Report');
|
|
68
|
+
// Total number of tests
|
|
69
|
+
console.log('Total Tests [Chrome]: ', getTotalNumberOfTests(), ' ');
|
|
70
|
+
console.log('Total Tests [Library]: ', totalTests, ' (We expect this to be equal to Total Tests [Chrome]) ');
|
|
71
|
+
// Number of passed tests
|
|
72
|
+
console.log('Passed Tests: ', totalTests - totalFailedTestsLibrary, ' ');
|
|
73
|
+
// Number of failed tests for chrome + node-datachannel
|
|
74
|
+
console.log(
|
|
75
|
+
'Failed Tests (Chrome + Library): ',
|
|
76
|
+
totalFailedTestsLibrary - totalFailedTests,
|
|
77
|
+
" (We don't care about these tests) ",
|
|
78
|
+
);
|
|
79
|
+
// Number of failed tests
|
|
80
|
+
console.log('Failed Tests: ', totalFailedTests, ' ');
|
|
81
|
+
|
|
82
|
+
// Print Failed Tests
|
|
83
|
+
console.log('');
|
|
84
|
+
console.log('## Failed Tests');
|
|
85
|
+
for (let i = 0; i < failedTests.length; i++) {
|
|
86
|
+
console.log(`### ${failedTests[i].test}`);
|
|
87
|
+
for (let j = 0; j < failedTests[i].result.length; j++) {
|
|
88
|
+
console.log(`- name: ${failedTests[i].result[j].name} `);
|
|
89
|
+
console.log(` message: ${failedTests[i].result[j].message} `);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
// Sometimes failed tests are not cleaned up
|
|
94
|
+
// This can prevent the process from exiting
|
|
95
|
+
ndc.cleanup();
|
|
96
|
+
console.log('End of tests');
|