ep_webrtc 2.5.35 → 2.5.37
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/backend-tests.yml +4 -0
- package/.github/workflows/frontend-tests.yml +19 -41
- package/package.json +1 -1
- package/static/css/styles.css +19 -0
- package/static/js/index.js +56 -2
- package/static/tests/frontend-new/helper/utils.ts +145 -0
- package/static/tests/frontend-new/specs/audio_video_on_start.spec.ts +37 -0
- package/static/tests/frontend-new/specs/checkbox.spec.ts +154 -0
- package/static/tests/frontend-new/specs/enable_disable.spec.ts +81 -0
- package/static/tests/frontend-new/specs/errors.spec.ts +165 -0
- package/static/tests/frontend-new/specs/interface_buttons.spec.ts +271 -0
- package/static/tests/frontend-new/specs/race_conditions.spec.ts +301 -0
- package/static/tests/frontend-new/specs/setStream.spec.ts +185 -0
- package/static/tests/frontend/specs/audio_video_on_start.js +0 -35
- package/static/tests/frontend/specs/checkbox.js +0 -107
- package/static/tests/frontend/specs/enable_disable.js +0 -50
- package/static/tests/frontend/specs/errors.js +0 -58
- package/static/tests/frontend/specs/interface_buttons.js +0 -251
- package/static/tests/frontend/specs/race_conditions.js +0 -206
- package/static/tests/frontend/specs/setStream.js +0 -138
- package/static/tests/frontend/utils.js +0 -44
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
describe('error handling', function () {
|
|
4
|
-
let chrome$;
|
|
5
|
-
let $videoBtn;
|
|
6
|
-
let getUserMediaBackup;
|
|
7
|
-
|
|
8
|
-
const testCases = [
|
|
9
|
-
// Hard to test the version of NotAllowedError that is the SSL error
|
|
10
|
-
// because it requires changing window.location
|
|
11
|
-
['NotAllowedError', 'Failed to get permission to access'],
|
|
12
|
-
['NotFoundError', 'Failed to access'],
|
|
13
|
-
['NotReadableError', 'hardware error occurred'],
|
|
14
|
-
['AbortError', 'not a hardware error'],
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
before(async function () {
|
|
18
|
-
this.timeout(60000);
|
|
19
|
-
await helper.aNewPad({params: {
|
|
20
|
-
av: true,
|
|
21
|
-
webrtcaudioenabled: false,
|
|
22
|
-
webrtcvideoenabled: false,
|
|
23
|
-
}});
|
|
24
|
-
chrome$ = helper.padChrome$;
|
|
25
|
-
await helper.waitForPromise(() => chrome$('#rtcbox').data('initialized'));
|
|
26
|
-
const ownUserId = chrome$.window.ep_webrtc.getUserId();
|
|
27
|
-
const ownVideoId = `video_${ownUserId.replace(/\./g, '_')}`;
|
|
28
|
-
const ownInterfaceId = `interface_${ownVideoId}`;
|
|
29
|
-
$videoBtn = chrome$(`#${ownInterfaceId} .video-btn`);
|
|
30
|
-
getUserMediaBackup = chrome$.window.navigator.mediaDevices.getUserMedia;
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
after(async function () {
|
|
34
|
-
chrome$.window.navigator.mediaDevices.getUserMedia = getUserMediaBackup;
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
beforeEach(async function () {
|
|
38
|
-
// No idea why but this needs to be called twice to actually make #gritter-container hidden
|
|
39
|
-
chrome$.gritter.removeAll({fade: false});
|
|
40
|
-
chrome$.gritter.removeAll({fade: false});
|
|
41
|
-
expect($videoBtn.hasClass('off')).to.equal(true);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
for (const [errName, checkString] of testCases) {
|
|
45
|
-
it(errName, async function () {
|
|
46
|
-
chrome$.window.navigator.mediaDevices.getUserMedia = async () => {
|
|
47
|
-
const err = new Error();
|
|
48
|
-
err.name = errName;
|
|
49
|
-
throw err;
|
|
50
|
-
};
|
|
51
|
-
await helper.waitForPromise(() => chrome$('#gritter-container:visible').length === 0, 1000);
|
|
52
|
-
$videoBtn.click();
|
|
53
|
-
await helper.waitForPromise(() => chrome$('#gritter-container:visible').length === 1, 1000);
|
|
54
|
-
expect(chrome$('.gritter-title').html()).to.be('Error');
|
|
55
|
-
expect(chrome$('.gritter-content p').html()).to.contain(checkString);
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
});
|
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const {fakeGetUserMedia} = require('ep_webrtc/static/tests/frontend/utils');
|
|
4
|
-
|
|
5
|
-
describe('Test the behavior of the interface buttons: Mute, Video Disable, Enlarge', function () {
|
|
6
|
-
let audioTrack;
|
|
7
|
-
let videoTrack;
|
|
8
|
-
|
|
9
|
-
const installFakeGetUserMedia = () => {
|
|
10
|
-
const chrome$ = helper.padChrome$;
|
|
11
|
-
chrome$.window.navigator.mediaDevices.getUserMedia = async (constraints) => {
|
|
12
|
-
const stream = await fakeGetUserMedia(constraints);
|
|
13
|
-
audioTrack = stream.getAudioTracks()[0];
|
|
14
|
-
videoTrack = stream.getVideoTracks()[0];
|
|
15
|
-
return stream;
|
|
16
|
-
};
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
describe('audio and video on by default', function () {
|
|
20
|
-
beforeEach(async function () {
|
|
21
|
-
this.timeout(60000);
|
|
22
|
-
audioTrack = null;
|
|
23
|
-
videoTrack = null;
|
|
24
|
-
|
|
25
|
-
// Make sure webrtc starts disabled so we have time to wrap getUserMedia
|
|
26
|
-
await helper.aNewPad({
|
|
27
|
-
padPrefs: {
|
|
28
|
-
rtcEnabled: false,
|
|
29
|
-
audioEnabledOnStart: true,
|
|
30
|
-
videoEnabledOnStart: true,
|
|
31
|
-
},
|
|
32
|
-
});
|
|
33
|
-
const chrome$ = helper.padChrome$;
|
|
34
|
-
installFakeGetUserMedia();
|
|
35
|
-
// Clicking $('#options-enablertc') also activates, but calling activate() directly blocks
|
|
36
|
-
// until activation is complete.
|
|
37
|
-
await chrome$.window.ep_webrtc.activate();
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('enlarges then shrinks', async function () {
|
|
41
|
-
const chrome$ = helper.padChrome$;
|
|
42
|
-
|
|
43
|
-
this.timeout(60000);
|
|
44
|
-
|
|
45
|
-
// i.e., "160.25px" -> 160.25 the number
|
|
46
|
-
const numFromCssSize = (size) => {
|
|
47
|
-
expect(size.slice(-2)).to.be('px');
|
|
48
|
-
return Number(size.slice(0, -2));
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
// All of these sizes have to allow for tolerances.
|
|
52
|
-
// I.e. it has come back a quarter pixel off before.
|
|
53
|
-
const $video = chrome$('video');
|
|
54
|
-
await helper.waitForPromise(() => {
|
|
55
|
-
const w = numFromCssSize($video.css('width'));
|
|
56
|
-
const h = numFromCssSize($video.css('height'));
|
|
57
|
-
return 159 < w && w < 161 && 119 < h && h < 121;
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
const $enlargeBtn = chrome$('.enlarge-btn');
|
|
61
|
-
$enlargeBtn.click();
|
|
62
|
-
|
|
63
|
-
// Expect it to grow to 260, 190
|
|
64
|
-
await helper.waitForPromise(
|
|
65
|
-
() => (numFromCssSize($video.css('width')) > 259 &&
|
|
66
|
-
numFromCssSize($video.css('height')) > 194),
|
|
67
|
-
1000);
|
|
68
|
-
$enlargeBtn.click();
|
|
69
|
-
// Expect it to shrink to 160, 116
|
|
70
|
-
await helper.waitForPromise(
|
|
71
|
-
() => (numFromCssSize($video.css('width')) < 161 &&
|
|
72
|
-
numFromCssSize($video.css('height')) < 121),
|
|
73
|
-
1000);
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('mutes then unmutes', async function () {
|
|
77
|
-
this.timeout(60000);
|
|
78
|
-
|
|
79
|
-
const chrome$ = helper.padChrome$;
|
|
80
|
-
|
|
81
|
-
expect(audioTrack.enabled).to.be(true);
|
|
82
|
-
expect(chrome$('.audio-btn.muted').length).to.be(0);
|
|
83
|
-
expect(chrome$('.audio-btn').attr('title')).to.be('Mute');
|
|
84
|
-
|
|
85
|
-
const $audioBtn = chrome$('.audio-btn');
|
|
86
|
-
$audioBtn.click();
|
|
87
|
-
|
|
88
|
-
await helper.waitForPromise(
|
|
89
|
-
() => chrome$('.audio-btn.muted').length === 1 && audioTrack.enabled === false, 3000);
|
|
90
|
-
expect(chrome$('.audio-btn').attr('title')).to.be('Unmute');
|
|
91
|
-
$audioBtn.click();
|
|
92
|
-
await helper.waitForPromise(
|
|
93
|
-
() => chrome$('.audio-btn.muted').length === 0 && audioTrack.enabled === true, 3000);
|
|
94
|
-
expect(chrome$('.audio-btn').attr('title')).to.be('Mute');
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it('disables then enables video', async function () {
|
|
98
|
-
this.timeout(60000);
|
|
99
|
-
|
|
100
|
-
const chrome$ = helper.padChrome$;
|
|
101
|
-
|
|
102
|
-
expect(videoTrack.enabled).to.be(true);
|
|
103
|
-
expect(chrome$('.video-btn.off').length).to.be(0);
|
|
104
|
-
expect(chrome$('.video-btn').attr('title')).to.contain('Disable');
|
|
105
|
-
|
|
106
|
-
const $videoBtn = chrome$('.video-btn');
|
|
107
|
-
$videoBtn.click();
|
|
108
|
-
|
|
109
|
-
await helper.waitForPromise(
|
|
110
|
-
() => chrome$('.video-btn.off').length === 1 && videoTrack.enabled === false, 3000);
|
|
111
|
-
expect(chrome$('.video-btn').attr('title')).to.contain('Enable');
|
|
112
|
-
$videoBtn.click();
|
|
113
|
-
await helper.waitForPromise(
|
|
114
|
-
() => chrome$('.video-btn.off').length === 0 && videoTrack.enabled === true, 3000);
|
|
115
|
-
expect(chrome$('.video-btn').attr('title')).to.contain('Disable');
|
|
116
|
-
});
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
context('audio and video off by default', function () {
|
|
120
|
-
beforeEach(async function () {
|
|
121
|
-
this.timeout(60000);
|
|
122
|
-
audioTrack = null;
|
|
123
|
-
videoTrack = null;
|
|
124
|
-
|
|
125
|
-
// Make sure webrtc starts disabled so we have time to wrap getUserMedia
|
|
126
|
-
await helper.aNewPad({
|
|
127
|
-
padPrefs: {
|
|
128
|
-
rtcEnabled: false,
|
|
129
|
-
audioEnabledOnStart: false,
|
|
130
|
-
videoEnabledOnStart: false,
|
|
131
|
-
},
|
|
132
|
-
});
|
|
133
|
-
const chrome$ = helper.padChrome$;
|
|
134
|
-
installFakeGetUserMedia();
|
|
135
|
-
// Clicking $('#options-enablertc') also activates, but calling activate() directly blocks
|
|
136
|
-
// until activation is complete.
|
|
137
|
-
await chrome$.window.ep_webrtc.activate();
|
|
138
|
-
});
|
|
139
|
-
|
|
140
|
-
it('unmutes then mutes', async function () {
|
|
141
|
-
this.timeout(60000);
|
|
142
|
-
|
|
143
|
-
const chrome$ = helper.padChrome$;
|
|
144
|
-
|
|
145
|
-
expect(audioTrack).to.be(null);
|
|
146
|
-
expect(chrome$('.audio-btn.muted').length).to.be(1);
|
|
147
|
-
expect(chrome$('.audio-btn').attr('title')).to.be('Unmute');
|
|
148
|
-
|
|
149
|
-
const $audioBtn = chrome$('.audio-btn');
|
|
150
|
-
$audioBtn.click();
|
|
151
|
-
|
|
152
|
-
await helper.waitForPromise(
|
|
153
|
-
() => (chrome$('.audio-btn.muted').length === 0 &&
|
|
154
|
-
audioTrack != null && audioTrack.enabled),
|
|
155
|
-
3000);
|
|
156
|
-
expect(chrome$('.audio-btn').attr('title')).to.be('Mute');
|
|
157
|
-
$audioBtn.click();
|
|
158
|
-
await helper.waitForPromise(
|
|
159
|
-
() => chrome$('.audio-btn.muted').length === 1 && audioTrack.enabled === false, 3000);
|
|
160
|
-
expect(chrome$('.audio-btn').attr('title')).to.be('Unmute');
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
it('enables then disables video', async function () {
|
|
164
|
-
this.timeout(60000);
|
|
165
|
-
|
|
166
|
-
const chrome$ = helper.padChrome$;
|
|
167
|
-
|
|
168
|
-
expect(videoTrack).to.be(null);
|
|
169
|
-
expect(chrome$('.video-btn.off').length).to.be(1);
|
|
170
|
-
expect(chrome$('.video-btn').attr('title')).to.contain('Enable');
|
|
171
|
-
|
|
172
|
-
const $videoBtn = chrome$('.video-btn');
|
|
173
|
-
$videoBtn.click();
|
|
174
|
-
|
|
175
|
-
await helper.waitForPromise(
|
|
176
|
-
() => (chrome$('.video-btn.off').length === 0 &&
|
|
177
|
-
videoTrack != null && videoTrack.enabled),
|
|
178
|
-
3000);
|
|
179
|
-
expect(chrome$('.video-btn').attr('title')).to.contain('Disable');
|
|
180
|
-
$videoBtn.click();
|
|
181
|
-
await helper.waitForPromise(
|
|
182
|
-
() => chrome$('.video-btn.off').length === 1 && videoTrack.enabled === false, 3000);
|
|
183
|
-
expect(chrome$('.video-btn').attr('title')).to.contain('Enable');
|
|
184
|
-
});
|
|
185
|
-
});
|
|
186
|
-
|
|
187
|
-
context('audio and video hard-disabled', function () {
|
|
188
|
-
beforeEach(async function () {
|
|
189
|
-
this.timeout(60000);
|
|
190
|
-
audioTrack = null;
|
|
191
|
-
videoTrack = null;
|
|
192
|
-
// Make sure webrtc starts disabled so we have time to wrap getUserMedia and change settings
|
|
193
|
-
// before activation.
|
|
194
|
-
await helper.aNewPad({params: {av: false}});
|
|
195
|
-
const chrome$ = helper.padChrome$;
|
|
196
|
-
await helper.waitForPromise(() => chrome$('#rtcbox').data('initialized'));
|
|
197
|
-
chrome$.window.ep_webrtc._settings.audio.disabled = 'hard';
|
|
198
|
-
chrome$.window.ep_webrtc._settings.video.disabled = 'hard';
|
|
199
|
-
installFakeGetUserMedia();
|
|
200
|
-
// Clicking $(#options-enablertc) also activates, but calling activate() directly blocks until
|
|
201
|
-
// activation is complete.
|
|
202
|
-
await chrome$.window.ep_webrtc.activate();
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
it('cannot mute or unmute', async function () {
|
|
206
|
-
this.timeout(60000);
|
|
207
|
-
|
|
208
|
-
const chrome$ = helper.padChrome$;
|
|
209
|
-
|
|
210
|
-
expect(chrome$('.audio-btn.disallowed').length).to.be(1);
|
|
211
|
-
expect(chrome$('.audio-btn.muted').length).to.be(1);
|
|
212
|
-
expect(chrome$('.audio-btn').attr('title')).to.be('Audio disallowed by admin');
|
|
213
|
-
expect(audioTrack).to.be(null);
|
|
214
|
-
expect(videoTrack).to.be(null);
|
|
215
|
-
|
|
216
|
-
const $audioBtn = chrome$('.audio-btn');
|
|
217
|
-
$audioBtn.click();
|
|
218
|
-
|
|
219
|
-
// Wait a sec to make sure there's no change
|
|
220
|
-
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
221
|
-
expect(chrome$('.audio-btn.disallowed').length).to.be(1);
|
|
222
|
-
expect(chrome$('.audio-btn.muted').length).to.be(1);
|
|
223
|
-
expect(chrome$('.audio-btn').attr('title')).to.be('Audio disallowed by admin');
|
|
224
|
-
expect(audioTrack).to.be(null);
|
|
225
|
-
expect(videoTrack).to.be(null);
|
|
226
|
-
});
|
|
227
|
-
|
|
228
|
-
it('cannot enable or disable video', async function () {
|
|
229
|
-
this.timeout(60000);
|
|
230
|
-
|
|
231
|
-
const chrome$ = helper.padChrome$;
|
|
232
|
-
|
|
233
|
-
expect(chrome$('.video-btn.disallowed').length).to.be(1);
|
|
234
|
-
expect(chrome$('.video-btn.off').length).to.be(1);
|
|
235
|
-
expect(chrome$('.video-btn').attr('title')).to.be('Video disallowed by admin');
|
|
236
|
-
expect(audioTrack).to.be(null);
|
|
237
|
-
expect(videoTrack).to.be(null);
|
|
238
|
-
|
|
239
|
-
const $videoBtn = chrome$('.video-btn');
|
|
240
|
-
$videoBtn.click();
|
|
241
|
-
|
|
242
|
-
// Wait a sec to make sure there's no change
|
|
243
|
-
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
244
|
-
expect(chrome$('.video-btn.disallowed').length).to.be(1);
|
|
245
|
-
expect(chrome$('.video-btn.off').length).to.be(1);
|
|
246
|
-
expect(chrome$('.video-btn').attr('title')).to.be('Video disallowed by admin');
|
|
247
|
-
expect(audioTrack).to.be(null);
|
|
248
|
-
expect(videoTrack).to.be(null);
|
|
249
|
-
});
|
|
250
|
-
});
|
|
251
|
-
});
|
|
@@ -1,206 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const {fakeGetUserMedia} = require('ep_webrtc/static/tests/frontend/utils');
|
|
4
|
-
|
|
5
|
-
describe('Race conditions that leave audio/video track enabled', function () {
|
|
6
|
-
// The idea here is to place high value on making sure that the "mute" and "video-off" buttons in
|
|
7
|
-
// the video interfaces match with the audioTrack.enabled/videoTrack.enabled, so that users don't
|
|
8
|
-
// get the wrong idea about whether the audio or video feed are on.
|
|
9
|
-
//
|
|
10
|
-
// These tests are various ideas for trying to do things in quick succession
|
|
11
|
-
// or "at the same time". We can add more if we think of them.
|
|
12
|
-
|
|
13
|
-
for (const enabledOnStart of [false, true]) {
|
|
14
|
-
describe(`audio and video ${enabledOnStart ? 'en' : 'dis'}abled on start`, function () {
|
|
15
|
-
let chrome$;
|
|
16
|
-
|
|
17
|
-
const getVideo = () => chrome$('video')[0];
|
|
18
|
-
const getStream = () => getVideo().srcObject;
|
|
19
|
-
const assertTracks = (enabled = enabledOnStart) => {
|
|
20
|
-
if (enabled) {
|
|
21
|
-
expect(getStream().getTracks().length).to.equal(2);
|
|
22
|
-
expect(getStream().getTracks().every((t) => t.enabled)).to.be(true);
|
|
23
|
-
} else {
|
|
24
|
-
expect(getStream().getTracks().some((t) => t.enabled)).to.be(false);
|
|
25
|
-
}
|
|
26
|
-
const [audio] = getStream().getAudioTracks();
|
|
27
|
-
const [video] = getStream().getVideoTracks();
|
|
28
|
-
expect(chrome$('.audio-btn').hasClass('muted')).to.equal(audio == null || !audio.enabled);
|
|
29
|
-
expect(chrome$('.video-btn').hasClass('off')).to.equal(video == null || !video.enabled);
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
beforeEach(async function () {
|
|
33
|
-
this.timeout(60000);
|
|
34
|
-
await helper.aNewPad({
|
|
35
|
-
padPrefs: {
|
|
36
|
-
audioEnabledOnStart: enabledOnStart,
|
|
37
|
-
videoEnabledOnStart: enabledOnStart,
|
|
38
|
-
},
|
|
39
|
-
// Disable WebRTC so we can install a fake getUserMedia() before it is called.
|
|
40
|
-
params: {av: false},
|
|
41
|
-
});
|
|
42
|
-
chrome$ = helper.padChrome$;
|
|
43
|
-
chrome$.window.navigator.mediaDevices.getUserMedia = fakeGetUserMedia;
|
|
44
|
-
chrome$('#options-enablertc').click();
|
|
45
|
-
await helper.waitForPromise(() => chrome$('#rtcbox').data('initialized'));
|
|
46
|
-
const ownVideoId = `video_${chrome$.window.ep_webrtc.getUserId().replace(/\./g, '_')}`;
|
|
47
|
-
await helper.waitForPromise(() => getVideo() != null);
|
|
48
|
-
const $interface = chrome$(`#interface_${ownVideoId}`);
|
|
49
|
-
expect($interface.length).to.equal(1);
|
|
50
|
-
expect(chrome$('.audio-btn').length).to.equal(1);
|
|
51
|
-
expect(chrome$('.video-btn').length).to.equal(1);
|
|
52
|
-
await helper.waitForPromise(
|
|
53
|
-
() => getStream() != null && (!enabledOnStart || getStream().getTracks().length === 2));
|
|
54
|
-
assertTracks();
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// See if we can trip up the state by "deactivating" webrtc, clicking mute/video-off, and
|
|
58
|
-
// "activating" webrtc in quick succession. As of this writing, "deactivating" will make the
|
|
59
|
-
// buttons disappear pretty quickly, making the "click" ineffectual, regardless, but in case
|
|
60
|
-
// we ever change things around, perhaps this test will catch something.
|
|
61
|
-
it('deactivate, click, activate', async function () {
|
|
62
|
-
for (let i = 0; i < 10; ++i) {
|
|
63
|
-
const [oldAudioTrack] = getStream().getAudioTracks();
|
|
64
|
-
const [oldVideoTrack] = getStream().getVideoTracks();
|
|
65
|
-
|
|
66
|
-
await chrome$.window.ep_webrtc.deactivate();
|
|
67
|
-
chrome$('.audio-btn').click();
|
|
68
|
-
chrome$('.video-btn').click();
|
|
69
|
-
await chrome$.window.ep_webrtc.activate();
|
|
70
|
-
|
|
71
|
-
assertTracks();
|
|
72
|
-
|
|
73
|
-
const [newAudioTrack] = getStream().getAudioTracks();
|
|
74
|
-
const [newVideoTrack] = getStream().getVideoTracks();
|
|
75
|
-
|
|
76
|
-
if (enabledOnStart) {
|
|
77
|
-
expect(newAudioTrack).to.not.equal(oldAudioTrack);
|
|
78
|
-
expect(oldAudioTrack.readyState).to.equal('ended');
|
|
79
|
-
expect(newAudioTrack.readyState).to.equal('live');
|
|
80
|
-
|
|
81
|
-
expect(newVideoTrack).to.not.equal(oldVideoTrack);
|
|
82
|
-
expect(oldVideoTrack.readyState).to.equal('ended');
|
|
83
|
-
expect(newVideoTrack.readyState).to.equal('live');
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
});
|
|
87
|
-
|
|
88
|
-
// See if we can trip up the state by clicking mute/video-off, "deactivating" webrtc, and
|
|
89
|
-
// "activating" webrtc in quick succession
|
|
90
|
-
it('click, deactivate, activate', async function () {
|
|
91
|
-
for (let i = 0; i < 10; ++i) {
|
|
92
|
-
const [oldAudioTrack] = getStream().getAudioTracks();
|
|
93
|
-
const [oldVideoTrack] = getStream().getVideoTracks();
|
|
94
|
-
|
|
95
|
-
chrome$('.audio-btn').click();
|
|
96
|
-
chrome$('.video-btn').click();
|
|
97
|
-
await chrome$.window.ep_webrtc.deactivate();
|
|
98
|
-
await chrome$.window.ep_webrtc.activate();
|
|
99
|
-
|
|
100
|
-
assertTracks();
|
|
101
|
-
|
|
102
|
-
const [newAudioTrack] = getStream().getAudioTracks();
|
|
103
|
-
const [newVideoTrack] = getStream().getVideoTracks();
|
|
104
|
-
|
|
105
|
-
if (enabledOnStart) {
|
|
106
|
-
expect(newAudioTrack).to.not.equal(oldAudioTrack);
|
|
107
|
-
expect(oldAudioTrack.readyState).to.equal('ended');
|
|
108
|
-
expect(newAudioTrack.readyState).to.equal('live');
|
|
109
|
-
|
|
110
|
-
expect(newVideoTrack).to.not.equal(oldVideoTrack);
|
|
111
|
-
expect(oldVideoTrack.readyState).to.equal('ended');
|
|
112
|
-
expect(newVideoTrack.readyState).to.equal('live');
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
// See if we can trip up the state by "deactivating" webrtc, "activating" webrtc, and then
|
|
118
|
-
// clicking mute/video-off right after the interface returns.
|
|
119
|
-
it('deactivate, activate, click', async function () {
|
|
120
|
-
for (let i = 0; i < 10; ++i) {
|
|
121
|
-
const [oldAudioTrack] = getStream().getAudioTracks();
|
|
122
|
-
const [oldVideoTrack] = getStream().getVideoTracks();
|
|
123
|
-
|
|
124
|
-
await chrome$.window.ep_webrtc.deactivate();
|
|
125
|
-
const p = chrome$.window.ep_webrtc.activate();
|
|
126
|
-
await helper.waitForPromise(
|
|
127
|
-
() => chrome$ && chrome$('.interface-container').length === 1, 2000);
|
|
128
|
-
chrome$('.audio-btn').click();
|
|
129
|
-
chrome$('.video-btn').click();
|
|
130
|
-
await Promise.all([
|
|
131
|
-
p,
|
|
132
|
-
chrome$('.audio-btn').data('idle')('click'),
|
|
133
|
-
chrome$('.video-btn').data('idle')('click'),
|
|
134
|
-
]);
|
|
135
|
-
|
|
136
|
-
assertTracks(!enabledOnStart);
|
|
137
|
-
|
|
138
|
-
const [newAudioTrack] = getStream().getAudioTracks();
|
|
139
|
-
const [newVideoTrack] = getStream().getVideoTracks();
|
|
140
|
-
|
|
141
|
-
expect(newAudioTrack).to.not.equal(oldAudioTrack);
|
|
142
|
-
if (oldAudioTrack != null) expect(oldAudioTrack.readyState).to.equal('ended');
|
|
143
|
-
if (newAudioTrack != null) expect(newAudioTrack.readyState).to.equal('live');
|
|
144
|
-
|
|
145
|
-
expect(newVideoTrack).to.not.equal(oldVideoTrack);
|
|
146
|
-
if (oldVideoTrack != null) expect(oldVideoTrack.readyState).to.equal('ended');
|
|
147
|
-
if (newVideoTrack != null) expect(newVideoTrack.readyState).to.equal('live');
|
|
148
|
-
}
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
// See if we can trip up the state by clicking mute/video-off, "deactivating"/"activating"
|
|
152
|
-
// webrtc, as close to at the same time as we can
|
|
153
|
-
it('click while reactivate', async function () {
|
|
154
|
-
for (let i = 0; i < 10; i++) {
|
|
155
|
-
const [oldAudioTrack] = getStream().getAudioTracks();
|
|
156
|
-
const [oldVideoTrack] = getStream().getVideoTracks();
|
|
157
|
-
|
|
158
|
-
await chrome$.window.ep_webrtc.deactivate();
|
|
159
|
-
const p = chrome$.window.ep_webrtc.activate();
|
|
160
|
-
chrome$('.audio-btn').click();
|
|
161
|
-
chrome$('.video-btn').click();
|
|
162
|
-
await Promise.all([
|
|
163
|
-
p,
|
|
164
|
-
chrome$('.audio-btn').data('idle')(),
|
|
165
|
-
chrome$('.video-btn').data('idle')(),
|
|
166
|
-
]);
|
|
167
|
-
|
|
168
|
-
assertTracks(!enabledOnStart);
|
|
169
|
-
|
|
170
|
-
const [newAudioTrack] = getStream().getAudioTracks();
|
|
171
|
-
const [newVideoTrack] = getStream().getVideoTracks();
|
|
172
|
-
|
|
173
|
-
if (!enabledOnStart) {
|
|
174
|
-
expect(newAudioTrack).to.not.equal(oldAudioTrack);
|
|
175
|
-
if (oldAudioTrack != null) expect(oldAudioTrack.readyState).to.equal('ended');
|
|
176
|
-
if (newAudioTrack != null) expect(newAudioTrack.readyState).to.equal('live');
|
|
177
|
-
|
|
178
|
-
expect(newVideoTrack).to.not.equal(oldVideoTrack);
|
|
179
|
-
if (oldVideoTrack != null) expect(oldVideoTrack.readyState).to.equal('ended');
|
|
180
|
-
if (newVideoTrack != null) expect(newVideoTrack.readyState).to.equal('live');
|
|
181
|
-
}
|
|
182
|
-
}
|
|
183
|
-
});
|
|
184
|
-
|
|
185
|
-
// See if we can trip up the state by clicking mute/video-off many times at once. We click
|
|
186
|
-
// mute an odd number of times and video-off an even number of times.
|
|
187
|
-
it('many clicks', async function () {
|
|
188
|
-
for (let i = 0; i < 10; ++i) {
|
|
189
|
-
chrome$('.audio-btn').click();
|
|
190
|
-
chrome$('.audio-btn').click();
|
|
191
|
-
chrome$('.audio-btn').click();
|
|
192
|
-
chrome$('.video-btn').click();
|
|
193
|
-
chrome$('.video-btn').click();
|
|
194
|
-
await Promise.all([
|
|
195
|
-
chrome$('.audio-btn').data('idle')(),
|
|
196
|
-
chrome$('.video-btn').data('idle')(),
|
|
197
|
-
]);
|
|
198
|
-
expect(chrome$('.audio-btn').hasClass('muted'))
|
|
199
|
-
.to.equal(((i + 1) * 3 + (enabledOnStart ? 1 : 0)) % 2 === 0);
|
|
200
|
-
expect(chrome$('.video-btn').hasClass('off'))
|
|
201
|
-
.to.equal(((i + 1) * 2 + (enabledOnStart ? 1 : 0)) % 2 === 0);
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
});
|
|
@@ -1,138 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const {cartesian, fakeGetUserMedia} = require('ep_webrtc/static/tests/frontend/utils');
|
|
4
|
-
|
|
5
|
-
describe('setStream()', function () {
|
|
6
|
-
let chrome$;
|
|
7
|
-
const otherUserId = 'other_user_id';
|
|
8
|
-
const otherVideoId = `video_${otherUserId.replace(/\./g, '_')}`;
|
|
9
|
-
const otherInterfaceId = `interface_${otherVideoId}`;
|
|
10
|
-
let ownUserId, ownVideoId, ownInterfaceId;
|
|
11
|
-
|
|
12
|
-
describe('Audio and video enabled', function () {
|
|
13
|
-
const testCases = [...cartesian(...Array(4).fill([false, true]))].map(
|
|
14
|
-
([webrtcaudioenabled, webrtcvideoenabled, peerAudio, peerVideo]) => ({
|
|
15
|
-
params: {webrtcaudioenabled, webrtcvideoenabled},
|
|
16
|
-
peer: {audio: peerAudio, video: peerVideo},
|
|
17
|
-
}));
|
|
18
|
-
|
|
19
|
-
for (const tc of testCases) {
|
|
20
|
-
describe(JSON.stringify(tc), function () {
|
|
21
|
-
before(async function () {
|
|
22
|
-
this.timeout(60000);
|
|
23
|
-
await helper.aNewPad({
|
|
24
|
-
// Disable WebRTC so we can install a mock getUserMedia() before it is called.
|
|
25
|
-
params: Object.assign({av: false}, tc.params),
|
|
26
|
-
});
|
|
27
|
-
chrome$ = helper.padChrome$;
|
|
28
|
-
chrome$.window.navigator.mediaDevices.getUserMedia = fakeGetUserMedia;
|
|
29
|
-
// Clicking $(#options-enablertc) also activates, but calling activate() directly blocks
|
|
30
|
-
// until activation is complete.
|
|
31
|
-
await chrome$.window.ep_webrtc.activate();
|
|
32
|
-
ownUserId = chrome$.window.ep_webrtc.getUserId();
|
|
33
|
-
ownVideoId = `video_${ownUserId.replace(/\./g, '_')}`;
|
|
34
|
-
ownInterfaceId = `interface_${ownVideoId}`;
|
|
35
|
-
const peerStream =
|
|
36
|
-
tc.peer.audio || tc.peer.video ? await fakeGetUserMedia(tc.peer) : new MediaStream();
|
|
37
|
-
await chrome$.window.ep_webrtc.setStream(otherUserId, peerStream);
|
|
38
|
-
});
|
|
39
|
-
|
|
40
|
-
it('self and peer elements exist', async function () {
|
|
41
|
-
expect(chrome$('.interface-container').length).to.equal(2);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('self interface', async function () {
|
|
45
|
-
// Self view is always muted because users shouldn't hear themselves (otherwise there
|
|
46
|
-
// would be audio feedback).
|
|
47
|
-
expect(chrome$(`#${ownVideoId}`).prop('muted')).to.equal(true);
|
|
48
|
-
const $audioBtn = chrome$(`#${ownInterfaceId} .audio-btn`);
|
|
49
|
-
expect($audioBtn.length).to.equal(1);
|
|
50
|
-
expect($audioBtn.hasClass('muted')).to.equal(!tc.params.webrtcaudioenabled);
|
|
51
|
-
expect($audioBtn.hasClass('disallowed')).to.equal(false);
|
|
52
|
-
const $videoBtn = chrome$(`#${ownInterfaceId} .video-btn`);
|
|
53
|
-
expect($videoBtn.length).to.equal(1);
|
|
54
|
-
expect($videoBtn.hasClass('off')).to.equal(!tc.params.webrtcvideoenabled);
|
|
55
|
-
expect($videoBtn.hasClass('disallowed')).to.equal(false);
|
|
56
|
-
const $enlargeBtn = chrome$(`#${ownInterfaceId} .enlarge-btn`);
|
|
57
|
-
expect($enlargeBtn.length).to.equal(1);
|
|
58
|
-
expect($enlargeBtn.hasClass('large')).to.equal(false);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it('peer interface', async function () {
|
|
62
|
-
const $audioBtn = chrome$(`#${otherInterfaceId} .audio-btn`);
|
|
63
|
-
expect($audioBtn.length).to.equal(1);
|
|
64
|
-
// Only initially muted if the browser doesn't give permission to autoplay unless muted.
|
|
65
|
-
// (A peer without an audio track might later add an audio track; if so, the audio should
|
|
66
|
-
// start playing locally without the local user clicking anything.)
|
|
67
|
-
expect($audioBtn.hasClass('muted')).to.equal(chrome$(`#${otherVideoId}`).prop('muted'));
|
|
68
|
-
const $videoBtn = chrome$(`#${otherInterfaceId} .video-btn`);
|
|
69
|
-
expect($videoBtn.length).to.equal(0);
|
|
70
|
-
const $enlargeBtn = chrome$(`#${otherInterfaceId} .enlarge-btn`);
|
|
71
|
-
expect($enlargeBtn.length).to.equal(1);
|
|
72
|
-
expect($enlargeBtn.hasClass('large')).to.equal(false);
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
describe('Audio and video hard disabled', function () {
|
|
79
|
-
before(async function () {
|
|
80
|
-
this.timeout(60000);
|
|
81
|
-
await helper.aNewPad({
|
|
82
|
-
params: {
|
|
83
|
-
// Disable WebRTC so we can modify settings and install a fake getUserMedia() before
|
|
84
|
-
// WebRTC stuff is initialized.
|
|
85
|
-
av: false,
|
|
86
|
-
webrtcaudioenabled: true,
|
|
87
|
-
webrtcvideoenabled: true,
|
|
88
|
-
},
|
|
89
|
-
});
|
|
90
|
-
chrome$ = helper.padChrome$;
|
|
91
|
-
chrome$.window.navigator.mediaDevices.getUserMedia = fakeGetUserMedia;
|
|
92
|
-
await helper.waitForPromise(() => chrome$('#rtcbox').data('initialized'));
|
|
93
|
-
chrome$.window.ep_webrtc._settings.audio.disabled = 'hard';
|
|
94
|
-
chrome$.window.ep_webrtc._settings.video.disabled = 'hard';
|
|
95
|
-
// Clicking $(#options-enablertc) also activates, but calling activate() directly blocks until
|
|
96
|
-
// activation is complete.
|
|
97
|
-
await chrome$.window.ep_webrtc.activate();
|
|
98
|
-
ownUserId = chrome$.window.ep_webrtc.getUserId();
|
|
99
|
-
ownVideoId = `video_${ownUserId.replace(/\./g, '_')}`;
|
|
100
|
-
ownInterfaceId = `interface_${ownVideoId}`;
|
|
101
|
-
await chrome$.window.ep_webrtc.setStream(otherUserId, new MediaStream());
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it('self and peer elements exist', async function () {
|
|
105
|
-
expect(chrome$('.interface-container').length).to.equal(2);
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
it('self interface', async function () {
|
|
109
|
-
expect(chrome$(`#${ownVideoId}`).prop('muted')).to.equal(true);
|
|
110
|
-
const $audioBtn = chrome$(`#${ownInterfaceId} .audio-btn`);
|
|
111
|
-
expect($audioBtn.length).to.equal(1);
|
|
112
|
-
expect($audioBtn.hasClass('muted')).to.equal(true);
|
|
113
|
-
expect($audioBtn.hasClass('disallowed')).to.equal(true);
|
|
114
|
-
const $videoBtn = chrome$(`#${ownInterfaceId} .video-btn`);
|
|
115
|
-
expect($videoBtn.length).to.equal(1);
|
|
116
|
-
expect($videoBtn.hasClass('off')).to.equal(true);
|
|
117
|
-
expect($videoBtn.hasClass('disallowed')).to.equal(true);
|
|
118
|
-
const $enlargeBtn = chrome$(`#${ownInterfaceId} .enlarge-btn`);
|
|
119
|
-
expect($enlargeBtn.length).to.equal(1);
|
|
120
|
-
expect($enlargeBtn.hasClass('large')).to.equal(false);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('peer interface', async function () {
|
|
124
|
-
const $audioBtn = chrome$(`#${otherInterfaceId} .audio-btn`);
|
|
125
|
-
expect($audioBtn.length).to.equal(1);
|
|
126
|
-
// Mute state only depends on whether the browser gives permission to autoplay when unmuted.
|
|
127
|
-
// Hard disabling only affects what the local client sends; it doesn't affect what the remote
|
|
128
|
-
// peer sends. (Both the local client and the remote peer should see the same settings,
|
|
129
|
-
// however.)
|
|
130
|
-
expect($audioBtn.hasClass('muted')).to.equal(chrome$(`#${otherVideoId}`).prop('muted'));
|
|
131
|
-
const $videoBtn = chrome$(`#${otherInterfaceId} .video-btn`);
|
|
132
|
-
expect($videoBtn.length).to.equal(0);
|
|
133
|
-
const $enlargeBtn = chrome$(`#${otherInterfaceId} .enlarge-btn`);
|
|
134
|
-
expect($enlargeBtn.length).to.equal(1);
|
|
135
|
-
expect($enlargeBtn.hasClass('large')).to.equal(false);
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
});
|