1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
|
const PREF_DELAY_AUTOPLAY = "media.block-autoplay-until-in-foreground";
add_task(async function setPref() {
await SpecialPowers.pushPrefEnv({
set: [[PREF_DELAY_AUTOPLAY, true]],
});
});
add_task(async function muteTabs_usingButton() {
let tab0 = await addMediaTab();
let tab1 = await addMediaTab();
let tab2 = await addMediaTab();
let tab3 = await addMediaTab();
let tab4 = await addMediaTab();
let tabs = [tab0, tab1, tab2, tab3, tab4];
await BrowserTestUtils.switchTab(gBrowser, tab0);
await play(tab0);
await play(tab1, false);
await play(tab2, false);
// Multiselecting tab1, tab2 and tab3
await BrowserTestUtils.switchTab(gBrowser, tab1);
await triggerClickOn(tab3, { shiftKey: true });
is(gBrowser.multiSelectedTabsCount, 3, "Three multiselected tabs");
ok(!tab0.multiselected, "Tab0 is not multiselected");
ok(!tab4.multiselected, "Tab4 is not multiselected");
// tab1,tab2 and tab3 should be multiselected.
for (let i = 1; i <= 3; i++) {
ok(tabs[i].multiselected, "Tab" + i + " is multiselected");
}
// All five tabs are unmuted
for (let i = 0; i < 5; i++) {
ok(!muted(tabs[i]), "Tab" + i + " is not muted");
}
// Mute tab0 which is not multiselected, thus other tabs muted state should not be affected
let tab0MuteAudioBtn = tab0.overlayIcon;
await test_mute_tab(tab0, tab0MuteAudioBtn, true);
ok(muted(tab0), "Tab0 is muted");
for (let i = 1; i <= 4; i++) {
ok(!muted(tabs[i]), "Tab" + i + " is not muted");
}
// Now we multiselect tab0
await triggerClickOn(tab0, { ctrlKey: true });
// tab0, tab1, tab2, tab3 are multiselected
for (let i = 0; i <= 3; i++) {
ok(tabs[i].multiselected, "tab" + i + " is multiselected");
}
ok(!tab4.multiselected, "tab4 is not multiselected");
// Check mute state
ok(muted(tab0), "Tab0 is still muted");
ok(!muted(tab1), "Tab1 is not muted");
ok(!activeMediaBlocked(tab1), "Tab1 is not activemedia-blocked");
ok(activeMediaBlocked(tab2), "Tab2 is media-blocked");
ok(!muted(tab3), "Tab3 is not muted");
ok(!activeMediaBlocked(tab3), "Tab3 is not activemedia-blocked");
ok(!muted(tab4), "Tab4 is not muted");
ok(!activeMediaBlocked(tab4), "Tab4 is not activemedia-blocked");
// Mute tab1 which is multiselected, thus other multiselected tabs should be affected too
// in the following way:
// a) muted tabs (tab0) will remain muted.
// b) unmuted tabs (tab1, tab3) will become muted.
// b) media-blocked tabs (tab2) will remain media-blocked.
// However tab4 (unmuted) which is not multiselected should not be affected.
let tab1MuteAudioBtn = tab1.overlayIcon;
await test_mute_tab(tab1, tab1MuteAudioBtn, true);
// Check mute state
ok(muted(tab0), "Tab0 is still muted");
ok(muted(tab1), "Tab1 is muted");
ok(activeMediaBlocked(tab2), "Tab2 is still media-blocked");
ok(muted(tab3), "Tab3 is now muted");
ok(!muted(tab4), "Tab4 is not muted");
ok(!activeMediaBlocked(tab4), "Tab4 is not activemedia-blocked");
for (let tab of tabs) {
BrowserTestUtils.removeTab(tab);
}
});
add_task(async function unmuteTabs_usingButton() {
let tab0 = await addMediaTab();
let tab1 = await addMediaTab();
let tab2 = await addMediaTab();
let tab3 = await addMediaTab();
let tab4 = await addMediaTab();
let tabs = [tab0, tab1, tab2, tab3, tab4];
await BrowserTestUtils.switchTab(gBrowser, tab0);
await play(tab0);
await play(tab1, false);
await play(tab2, false);
// Mute tab3 and tab4
await toggleMuteAudio(tab3, true);
await toggleMuteAudio(tab4, true);
// Multiselecting tab0, tab1, tab2 and tab3
await triggerClickOn(tab3, { shiftKey: true });
// Check multiselection
for (let i = 0; i <= 3; i++) {
ok(tabs[i].multiselected, "tab" + i + " is multiselected");
}
ok(!tab4.multiselected, "tab4 is not multiselected");
// Check tabs mute state
ok(!muted(tab0), "Tab0 is not muted");
ok(!activeMediaBlocked(tab0), "Tab0 is not activemedia-blocked");
ok(activeMediaBlocked(tab1), "Tab1 is media-blocked");
ok(activeMediaBlocked(tab2), "Tab2 is media-blocked");
ok(muted(tab3), "Tab3 is muted");
ok(muted(tab4), "Tab4 is muted");
is(gBrowser.selectedTab, tab0, "Tab0 is active");
// unmute tab0 which is multiselected, thus other multiselected tabs should be affected too
// in the following way:
// a) muted tabs (tab3) will become unmuted.
// b) unmuted tabs (tab0) will remain unmuted.
// c) media-blocked tabs (tab1, tab2) will remain blocked.
// However tab4 (muted) which is not multiselected should not be affected.
let tab3MuteAudioBtn = tab3.overlayIcon;
await test_mute_tab(tab3, tab3MuteAudioBtn, false);
ok(!muted(tab0), "Tab0 is not muted");
ok(!activeMediaBlocked(tab0), "Tab0 is not activemedia-blocked");
ok(!muted(tab1), "Tab1 is not muted");
ok(activeMediaBlocked(tab1), "Tab1 is activemedia-blocked");
ok(!muted(tab2), "Tab2 is not muted");
ok(activeMediaBlocked(tab2), "Tab2 is activemedia-blocked");
ok(!muted(tab3), "Tab3 is not muted");
ok(!activeMediaBlocked(tab3), "Tab3 is not activemedia-blocked");
ok(muted(tab4), "Tab4 is muted");
is(gBrowser.selectedTab, tab0, "Tab0 is active");
for (let tab of tabs) {
BrowserTestUtils.removeTab(tab);
}
});
add_task(async function muteAndUnmuteTabs_usingKeyboard() {
let tab0 = await addMediaTab();
let tab1 = await addMediaTab();
let tab2 = await addMediaTab();
let tab3 = await addMediaTab();
let tab4 = await addMediaTab();
let tabs = [tab0, tab1, tab2, tab3, tab4];
await BrowserTestUtils.switchTab(gBrowser, tab0);
let mutedPromise = get_wait_for_mute_promise(tab0, true);
EventUtils.synthesizeKey("M", { ctrlKey: true });
await mutedPromise;
ok(muted(tab0), "Tab0 should be muted");
ok(!muted(tab1), "Tab1 should not be muted");
ok(!muted(tab2), "Tab2 should not be muted");
ok(!muted(tab3), "Tab3 should not be muted");
ok(!muted(tab4), "Tab4 should not be muted");
// Multiselecting tab0, tab1, tab2 and tab3
await triggerClickOn(tab3, { shiftKey: true });
// Check multiselection
for (let i = 0; i <= 3; i++) {
ok(tabs[i].multiselected, "tab" + i + " is multiselected");
}
ok(!tab4.multiselected, "tab4 is not multiselected");
mutedPromise = get_wait_for_mute_promise(tab0, false);
EventUtils.synthesizeKey("M", { ctrlKey: true });
await mutedPromise;
ok(!muted(tab0), "Tab0 should not be muted");
ok(!muted(tab1), "Tab1 should not be muted");
ok(!muted(tab2), "Tab2 should not be muted");
ok(!muted(tab3), "Tab3 should not be muted");
ok(!muted(tab4), "Tab4 should not be muted");
mutedPromise = get_wait_for_mute_promise(tab0, true);
EventUtils.synthesizeKey("M", { ctrlKey: true });
await mutedPromise;
ok(muted(tab0), "Tab0 should be muted");
ok(muted(tab1), "Tab1 should be muted");
ok(muted(tab2), "Tab2 should be muted");
ok(muted(tab3), "Tab3 should be muted");
ok(!muted(tab4), "Tab4 should not be muted");
for (let tab of tabs) {
BrowserTestUtils.removeTab(tab);
}
});
add_task(async function playTabs_usingButton() {
let tab0 = await addMediaTab();
let tab1 = await addMediaTab();
let tab2 = await addMediaTab();
let tab3 = await addMediaTab();
let tab4 = await addMediaTab();
let tabs = [tab0, tab1, tab2, tab3, tab4];
await BrowserTestUtils.switchTab(gBrowser, tab0);
await play(tab0);
await play(tab1, false);
await play(tab2, false);
// Multiselecting tab0, tab1, tab2 and tab3.
await triggerClickOn(tab3, { shiftKey: true });
// Mute tab0 and tab4
await toggleMuteAudio(tab0, true);
await toggleMuteAudio(tab4, true);
// Check multiselection
for (let i = 0; i <= 3; i++) {
ok(tabs[i].multiselected, "tab" + i + " is multiselected");
}
ok(!tab4.multiselected, "tab4 is not multiselected");
// Check mute state
ok(muted(tab0), "Tab0 is muted");
ok(activeMediaBlocked(tab1), "Tab1 is media-blocked");
ok(activeMediaBlocked(tab2), "Tab2 is media-blocked");
ok(!muted(tab3), "Tab3 is not muted");
ok(!activeMediaBlocked(tab3), "Tab3 is not activemedia-blocked");
ok(muted(tab4), "Tab4 is muted");
is(gBrowser.selectedTab, tab0, "Tab0 is active");
// play tab2 which is multiselected, thus other multiselected tabs should be affected too
// in the following way:
// a) muted tabs (tab0) will remain muted.
// b) unmuted tabs (tab3) will remain unmuted.
// c) media-blocked tabs (tab1, tab2) will become unblocked.
// However tab4 (muted) which is not multiselected should not be affected.
let tab2MuteAudioBtn = tab2.overlayIcon;
await test_mute_tab(tab2, tab2MuteAudioBtn, false);
ok(muted(tab0), "Tab0 is muted");
ok(!activeMediaBlocked(tab0), "Tab0 is not activemedia-blocked");
ok(!muted(tab1), "Tab1 is not muted");
ok(!activeMediaBlocked(tab1), "Tab1 is not activemedia-blocked");
ok(!muted(tab2), "Tab2 is not muted");
ok(!activeMediaBlocked(tab2), "Tab2 is not activemedia-blocked");
ok(!muted(tab3), "Tab3 is not muted");
ok(!activeMediaBlocked(tab3), "Tab3 is not activemedia-blocked");
ok(muted(tab4), "Tab4 is muted");
is(gBrowser.selectedTab, tab0, "Tab0 is active");
for (let tab of tabs) {
BrowserTestUtils.removeTab(tab);
}
});
add_task(async function checkTabContextMenu() {
let tab0 = await addMediaTab();
let tab1 = await addMediaTab();
let tab2 = await addMediaTab();
let tab3 = await addMediaTab();
let tabs = [tab0, tab1, tab2, tab3];
let menuItemToggleMuteTab = document.getElementById("context_toggleMuteTab");
let menuItemToggleMuteSelectedTabs = document.getElementById(
"context_toggleMuteSelectedTabs"
);
await play(tab0, false);
await toggleMuteAudio(tab0, true);
await play(tab1, false);
await toggleMuteAudio(tab2, true);
// multiselect tab0, tab1, tab2.
await triggerClickOn(tab0, { ctrlKey: true });
await triggerClickOn(tab1, { ctrlKey: true });
await triggerClickOn(tab2, { ctrlKey: true });
// Check multiselected tabs
for (let i = 0; i <= 2; i++) {
ok(tabs[i].multiselected, "Tab" + i + " is multi-selected");
}
ok(!tab3.multiselected, "Tab3 is not multiselected");
// Check mute state for tabs
ok(muted(tab0), "Tab0 is muted");
ok(activeMediaBlocked(tab0), "Tab0 is activemedia-blocked");
ok(activeMediaBlocked(tab1), "Tab1 is activemedia-blocked");
ok(muted(tab2), "Tab2 is muted");
ok(!muted(tab3, "Tab3 is not muted"));
const l10nIds = [
"tabbrowser-context-unmute-selected-tabs",
"tabbrowser-context-mute-selected-tabs",
"tabbrowser-context-unmute-selected-tabs",
];
for (let i = 0; i <= 2; i++) {
updateTabContextMenu(tabs[i]);
ok(
menuItemToggleMuteTab.hidden,
"toggleMuteAudio menu for one tab is hidden - contextTab" + i
);
ok(
!menuItemToggleMuteSelectedTabs.hidden,
"toggleMuteAudio menu for selected tab is not hidden - contextTab" + i
);
is(
menuItemToggleMuteSelectedTabs.dataset.l10nId,
l10nIds[i],
l10nIds[i] + " should be shown"
);
}
updateTabContextMenu(tab3);
ok(
!menuItemToggleMuteTab.hidden,
"toggleMuteAudio menu for one tab is not hidden"
);
ok(
menuItemToggleMuteSelectedTabs.hidden,
"toggleMuteAudio menu for selected tab is hidden"
);
for (let tab of tabs) {
BrowserTestUtils.removeTab(tab);
}
});
|