ep_webrtc 2.5.35 → 2.5.36

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.
@@ -0,0 +1,185 @@
1
+ import {expect, test} from '@playwright/test';
2
+ import {cartesian, goToNewPadWithParams, installFakeGetUserMedia} from '../helper/utils';
3
+
4
+ const otherUserId = 'other_user_id';
5
+ const otherVideoId = `video_${otherUserId.replace(/\./g, '_')}`;
6
+ const otherInterfaceId = `interface_${otherVideoId}`;
7
+
8
+ test.describe('setStream()', () => {
9
+ test.describe('Audio and video enabled', () => {
10
+ const testCases = [...cartesian(...Array(4).fill([false, true]) as boolean[][])].map(
11
+ ([webrtcaudioenabled, webrtcvideoenabled, peerAudio, peerVideo]: boolean[]) => ({
12
+ params: {webrtcaudioenabled, webrtcvideoenabled},
13
+ peer: {audio: peerAudio, video: peerVideo},
14
+ }));
15
+
16
+ for (const tc of testCases) {
17
+ test.describe(JSON.stringify(tc), () => {
18
+ test.describe.configure({mode: 'serial'});
19
+ let sharedPage: import('@playwright/test').Page;
20
+ let ownVideoId: string;
21
+ let ownInterfaceId: string;
22
+
23
+ test.beforeAll(async ({browser}) => {
24
+ sharedPage = await browser.newPage();
25
+ test.setTimeout(60_000);
26
+ await goToNewPadWithParams(sharedPage, {av: false, ...tc.params});
27
+ await installFakeGetUserMedia(sharedPage);
28
+ await sharedPage.evaluate(() => (window as any).ep_webrtc.activate());
29
+ const ids = await sharedPage.evaluate(() => {
30
+ const w = window as any;
31
+ const ownUserId = w.ep_webrtc.getUserId();
32
+ const ownVideoId = `video_${ownUserId.replace(/\./g, '_')}`;
33
+ return {ownVideoId, ownInterfaceId: `interface_${ownVideoId}`};
34
+ });
35
+ ownVideoId = ids.ownVideoId;
36
+ ownInterfaceId = ids.ownInterfaceId;
37
+ await sharedPage.evaluate(async ({peer, otherUserId}) => {
38
+ const w = window as any;
39
+ const peerStream = (peer.audio || peer.video)
40
+ ? await w.__fakeGetUserMedia(peer)
41
+ : new MediaStream();
42
+ await w.ep_webrtc.setStream(otherUserId, peerStream);
43
+ }, {peer: tc.peer, otherUserId});
44
+ });
45
+
46
+ test.afterAll(async () => {
47
+ await sharedPage.close();
48
+ });
49
+
50
+ test('self and peer elements exist', async () => {
51
+ const count = await sharedPage.locator('.interface-container').count();
52
+ expect(count).toBe(2);
53
+ });
54
+
55
+ test('self interface', async () => {
56
+ // Self view is always muted (no audio feedback).
57
+ const muted = await sharedPage.locator(`#${ownVideoId}`)
58
+ .evaluate((el) => (el as HTMLVideoElement).muted);
59
+ expect(muted).toBe(true);
60
+
61
+ const audioBtn = sharedPage.locator(`#${ownInterfaceId} .audio-btn`);
62
+ expect(await audioBtn.count()).toBe(1);
63
+ expect(await audioBtn.evaluate((el) => el.classList.contains('muted')))
64
+ .toBe(!tc.params.webrtcaudioenabled);
65
+ expect(await audioBtn.evaluate((el) => el.classList.contains('disallowed')))
66
+ .toBe(false);
67
+
68
+ const videoBtn = sharedPage.locator(`#${ownInterfaceId} .video-btn`);
69
+ expect(await videoBtn.count()).toBe(1);
70
+ expect(await videoBtn.evaluate((el) => el.classList.contains('off')))
71
+ .toBe(!tc.params.webrtcvideoenabled);
72
+ expect(await videoBtn.evaluate((el) => el.classList.contains('disallowed')))
73
+ .toBe(false);
74
+
75
+ const enlargeBtn = sharedPage.locator(`#${ownInterfaceId} .enlarge-btn`);
76
+ expect(await enlargeBtn.count()).toBe(1);
77
+ expect(await enlargeBtn.evaluate((el) => el.classList.contains('large')))
78
+ .toBe(false);
79
+ });
80
+
81
+ test('peer interface', async () => {
82
+ const audioBtn = sharedPage.locator(`#${otherInterfaceId} .audio-btn`);
83
+ expect(await audioBtn.count()).toBe(1);
84
+ // Only initially muted if browser doesn't permit autoplay unless muted.
85
+ const peerVideoMuted = await sharedPage.locator(`#${otherVideoId}`)
86
+ .evaluate((el) => (el as HTMLVideoElement).muted);
87
+ expect(await audioBtn.evaluate((el) => el.classList.contains('muted')))
88
+ .toBe(peerVideoMuted);
89
+
90
+ const videoBtn = sharedPage.locator(`#${otherInterfaceId} .video-btn`);
91
+ expect(await videoBtn.count()).toBe(0);
92
+
93
+ const enlargeBtn = sharedPage.locator(`#${otherInterfaceId} .enlarge-btn`);
94
+ expect(await enlargeBtn.count()).toBe(1);
95
+ expect(await enlargeBtn.evaluate((el) => el.classList.contains('large')))
96
+ .toBe(false);
97
+ });
98
+ });
99
+ }
100
+ });
101
+
102
+ test.describe('Audio and video hard disabled', () => {
103
+ test.describe.configure({mode: 'serial'});
104
+ let sharedPage: import('@playwright/test').Page;
105
+ let ownVideoId: string;
106
+ let ownInterfaceId: string;
107
+
108
+ test.beforeAll(async ({browser}) => {
109
+ sharedPage = await browser.newPage();
110
+ test.setTimeout(60_000);
111
+ await goToNewPadWithParams(sharedPage, {
112
+ av: false,
113
+ webrtcaudioenabled: true,
114
+ webrtcvideoenabled: true,
115
+ });
116
+ await installFakeGetUserMedia(sharedPage);
117
+ await sharedPage.waitForFunction(
118
+ () => (window as any).$('#rtcbox').data('initialized'));
119
+ await sharedPage.evaluate(() => {
120
+ const w = window as any;
121
+ w.ep_webrtc._settings.audio.disabled = 'hard';
122
+ w.ep_webrtc._settings.video.disabled = 'hard';
123
+ });
124
+ await sharedPage.evaluate(() => (window as any).ep_webrtc.activate());
125
+ const ids = await sharedPage.evaluate(() => {
126
+ const w = window as any;
127
+ const ownUserId = w.ep_webrtc.getUserId();
128
+ const ownVideoId = `video_${ownUserId.replace(/\./g, '_')}`;
129
+ return {ownVideoId, ownInterfaceId: `interface_${ownVideoId}`};
130
+ });
131
+ ownVideoId = ids.ownVideoId;
132
+ ownInterfaceId = ids.ownInterfaceId;
133
+ await sharedPage.evaluate(async (otherUserId) => {
134
+ const w = window as any;
135
+ await w.ep_webrtc.setStream(otherUserId, new MediaStream());
136
+ }, otherUserId);
137
+ });
138
+
139
+ test.afterAll(async () => {
140
+ await sharedPage.close();
141
+ });
142
+
143
+ test('self and peer elements exist', async () => {
144
+ const count = await sharedPage.locator('.interface-container').count();
145
+ expect(count).toBe(2);
146
+ });
147
+
148
+ test('self interface', async () => {
149
+ const muted = await sharedPage.locator(`#${ownVideoId}`)
150
+ .evaluate((el) => (el as HTMLVideoElement).muted);
151
+ expect(muted).toBe(true);
152
+
153
+ const audioBtn = sharedPage.locator(`#${ownInterfaceId} .audio-btn`);
154
+ expect(await audioBtn.count()).toBe(1);
155
+ expect(await audioBtn.evaluate((el) => el.classList.contains('muted'))).toBe(true);
156
+ expect(await audioBtn.evaluate((el) => el.classList.contains('disallowed'))).toBe(true);
157
+
158
+ const videoBtn = sharedPage.locator(`#${ownInterfaceId} .video-btn`);
159
+ expect(await videoBtn.count()).toBe(1);
160
+ expect(await videoBtn.evaluate((el) => el.classList.contains('off'))).toBe(true);
161
+ expect(await videoBtn.evaluate((el) => el.classList.contains('disallowed'))).toBe(true);
162
+
163
+ const enlargeBtn = sharedPage.locator(`#${ownInterfaceId} .enlarge-btn`);
164
+ expect(await enlargeBtn.count()).toBe(1);
165
+ expect(await enlargeBtn.evaluate((el) => el.classList.contains('large'))).toBe(false);
166
+ });
167
+
168
+ test('peer interface', async () => {
169
+ const audioBtn = sharedPage.locator(`#${otherInterfaceId} .audio-btn`);
170
+ expect(await audioBtn.count()).toBe(1);
171
+ // Mute state only depends on browser autoplay-when-unmuted permission.
172
+ const peerVideoMuted = await sharedPage.locator(`#${otherVideoId}`)
173
+ .evaluate((el) => (el as HTMLVideoElement).muted);
174
+ expect(await audioBtn.evaluate((el) => el.classList.contains('muted')))
175
+ .toBe(peerVideoMuted);
176
+
177
+ const videoBtn = sharedPage.locator(`#${otherInterfaceId} .video-btn`);
178
+ expect(await videoBtn.count()).toBe(0);
179
+
180
+ const enlargeBtn = sharedPage.locator(`#${otherInterfaceId} .enlarge-btn`);
181
+ expect(await enlargeBtn.count()).toBe(1);
182
+ expect(await enlargeBtn.evaluate((el) => el.classList.contains('large'))).toBe(false);
183
+ });
184
+ });
185
+ });
@@ -1,35 +0,0 @@
1
- 'use strict';
2
-
3
- const {cartesian, fakeGetUserMedia} = require('ep_webrtc/static/tests/frontend/utils');
4
-
5
- describe('audio/video on/off according to query parameters/cookies', function () {
6
- const testCases = cartesian(['audio', 'video'], [null, false, true], [null, false, true]);
7
-
8
- for (const [avType, cookieVal, queryVal] of testCases) {
9
- it(`${avType} cookie=${cookieVal} query=${queryVal}`, async function () {
10
- this.timeout(60000);
11
- await helper.aNewPad({
12
- padPrefs: cookieVal == null ? {} : {[`${avType}EnabledOnStart`]: cookieVal},
13
- params: Object.assign({
14
- // Disable WebRTC so we can install a fake getUserMedia() before WebRTC stuff is
15
- // initialized.
16
- av: false,
17
- }, queryVal == null ? {} : {[`webrtc${avType}enabled`]: queryVal}),
18
- });
19
- const chrome$ = helper.padChrome$;
20
- chrome$.window.navigator.mediaDevices.getUserMedia = fakeGetUserMedia;
21
- // Clicking $(#options-enablertc) also activates, but calling activate() directly blocks until
22
- // activation is complete.
23
- await chrome$.window.ep_webrtc.activate();
24
- const {disabled} = chrome$.window.ep_webrtc._settings[avType];
25
- const checkbox = chrome$(`#options-${avType}enabledonstart`);
26
- if (disabled === 'hard') {
27
- expect(checkbox.length).to.equal(0); // There shouldn't even be a checkbox.
28
- } else {
29
- const wantChecked = (queryVal || (queryVal == null && cookieVal) ||
30
- (queryVal == null && cookieVal == null && disabled === 'none'));
31
- expect(checkbox.prop('checked')).to.equal(wantChecked);
32
- }
33
- });
34
- }
35
- });
@@ -1,107 +0,0 @@
1
- 'use strict';
2
-
3
- const {cartesian} = require('ep_webrtc/static/tests/frontend/utils');
4
-
5
- describe('settingToCheckbox', function () {
6
- const testCases = [
7
- ...cartesian([false, true], [null, false, true], [null, false, true]),
8
- ].map(([defaultVal, cookieVal, queryVal], i) => ({
9
- name: `default=${defaultVal} cookie=${cookieVal} query=${queryVal}`,
10
- defaultVal,
11
- cookieVal,
12
- queryVal,
13
- i,
14
- id: `checkboxId${i}`,
15
- want: queryVal ||
16
- (queryVal == null && cookieVal) ||
17
- (queryVal == null && cookieVal == null && defaultVal),
18
- }));
19
- let chrome$;
20
- let padcookie;
21
-
22
- before(async function () {
23
- this.timeout(60000);
24
- await helper.aNewPad({
25
- padPrefs: Object.assign({}, ...testCases
26
- .filter(({cookieVal}) => cookieVal != null)
27
- .map(({cookieVal, i}) => ({[`cookie${i}`]: cookieVal}))),
28
- params: Object.assign({av: false}, ...testCases
29
- .filter(({queryVal}) => queryVal != null)
30
- .map(({queryVal, i}) => ({[`urlVar${i}`]: queryVal}))),
31
- });
32
- chrome$ = helper.padChrome$;
33
- padcookie = chrome$.window.require('ep_etherpad-lite/static/js/pad_cookie').padcookie;
34
- for (const {id} of testCases) {
35
- chrome$('#settings').append(chrome$('<input>').attr('type', 'checkbox').attr('id', id));
36
- }
37
- await helper.waitForPromise(() => {
38
- for (const {id} of testCases) {
39
- if (chrome$(`#${id}`).length !== 1) return false;
40
- }
41
- return true;
42
- });
43
- for (const {defaultVal, i, id} of testCases) {
44
- chrome$.window.ep_webrtc.settingToCheckbox({
45
- urlVar: `urlVar${i}`,
46
- cookie: `cookie${i}`,
47
- defaultVal,
48
- checkboxId: `#${id}`,
49
- });
50
- }
51
- });
52
-
53
- describe('initially checked/unchecked', function () {
54
- for (const {name, want, id} of testCases) {
55
- it(name, async function () {
56
- expect(chrome$(`#${id}`).prop('checked')).to.equal(want);
57
- });
58
- }
59
- });
60
-
61
- describe('query parameter sets cookie', function () {
62
- for (const {name, queryVal, i} of testCases.filter(({queryVal}) => queryVal != null)) {
63
- it(name, async function () {
64
- expect(padcookie.getPref(`cookie${i}`)).to.equal(queryVal);
65
- });
66
- }
67
- });
68
-
69
- describe('no query parameter, no cookie -> cookie not set', function () {
70
- for (const {name, queryVal, cookieVal, i} of testCases) {
71
- if (queryVal != null || cookieVal != null) continue;
72
- it(name, async function () {
73
- expect(padcookie.getPref(`cookie${i}`) == null).to.be(true);
74
- });
75
- }
76
- });
77
-
78
- describe('clicking sets cookie', function () {
79
- for (const {name, i, id, want} of testCases) {
80
- it(name, async function () {
81
- const cb = chrome$(`#${id}`);
82
- cb.click();
83
- await helper.waitForPromise(() => cb.prop('checked') === !want);
84
- expect(padcookie.getPref(`cookie${i}`)).to.equal(!want);
85
- });
86
- }
87
- });
88
-
89
- describe('throws errors for missing params', function () {
90
- const params = {
91
- urlVar: 'urlVar',
92
- cookie: 'cookie',
93
- defaultVal: true,
94
- checkboxId: '#checkboxId',
95
- };
96
-
97
- for (const k of Object.keys(params)) {
98
- const badParams = Object.assign({}, params);
99
- delete badParams[k];
100
-
101
- it(k, async function () {
102
- expect(() => chrome$.window.ep_webrtc.settingToCheckbox(badParams))
103
- .to.throwError(new RegExp(k));
104
- });
105
- }
106
- });
107
- });
@@ -1,50 +0,0 @@
1
- 'use strict';
2
-
3
- const {cartesian} = require('ep_webrtc/static/tests/frontend/utils');
4
-
5
- describe('enable/disable', function () {
6
- const testCases = cartesian([null, false, true], [null, false, true, 'NO', 'YES', 'ignored']);
7
-
8
- for (const [cookieVal, queryVal] of testCases) {
9
- describe(`cookie=${cookieVal} query=${queryVal}`, function () {
10
- let chrome$;
11
- let wantChecked;
12
- let checkbox;
13
-
14
- before(async function () {
15
- this.timeout(60000);
16
- await helper.aNewPad({
17
- padPrefs: cookieVal == null ? {} : {rtcEnabled: cookieVal},
18
- params: queryVal == null ? {} : {av: queryVal},
19
- });
20
- chrome$ = helper.padChrome$;
21
- // Normalize queryVal to null/false/true.
22
- const queryNorm =
23
- !!queryVal === queryVal ? queryVal // Already boolean.
24
- : queryVal === 'NO' ? false
25
- : queryVal === 'YES' ? true
26
- : null;
27
- await helper.waitForPromise(() => chrome$('#rtcbox').data('initialized'), 5000);
28
- const defaultChecked = !!chrome$.window.ep_webrtc._settings.enabled;
29
- wantChecked = (queryNorm || (queryNorm == null && cookieVal) ||
30
- (queryNorm == null && cookieVal == null && defaultChecked));
31
- checkbox = chrome$('#options-enablertc');
32
- });
33
-
34
- it('checkbox is checked/unchecked', async function () {
35
- expect(checkbox.prop('checked')).to.equal(wantChecked);
36
- });
37
-
38
- it('self video element', async function () {
39
- expect(chrome$('#rtcbox video').length).to.equal(wantChecked ? 1 : 0);
40
- });
41
-
42
- it('clicking checkbox toggles state', async function () {
43
- checkbox.click();
44
- expect(checkbox.prop('checked')).to.equal(!wantChecked);
45
- await helper.waitForPromise(
46
- () => chrome$('#rtcbox video').length === (wantChecked ? 0 : 1));
47
- });
48
- });
49
- }
50
- });
@@ -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
- });