Skip to content

Commit 342c5a5

Browse files
Device enum support (#1806)
* Add PoC support for device enum * debugging * Restore Scriptlets submodule to default master branch * Add typing * Make pass instanceof checks * Use input interface also * Lint fixes * Add test case * Reset submodule * Update remote config * Fix test keys * Add types * Update config * Disable read only check * Fix device info definition * Lint fix * Readonly doens't throw * Remove unnecessary file
1 parent a823caa commit 342c5a5

File tree

11 files changed

+564
-7
lines changed

11 files changed

+564
-7
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { gotoAndWait, testContextForExtension } from './helpers/harness.js';
2+
import { test as base, expect } from '@playwright/test';
3+
4+
const test = testContextForExtension(base);
5+
6+
test.describe('Device Enumeration Feature', () => {
7+
test.describe('disabled feature', () => {
8+
test('should not intercept enumerateDevices when disabled', async ({ page }) => {
9+
await gotoAndWait(page, '/webcompat/pages/device-enumeration.html', {
10+
site: { enabledFeatures: [] },
11+
});
12+
13+
// Should use native implementation
14+
const results = await page.evaluate(() => {
15+
// @ts-expect-error - results is set by renderResults()
16+
return window.results;
17+
});
18+
19+
// The test should pass with native behavior
20+
expect(results).toBeDefined();
21+
});
22+
});
23+
24+
test.describe('enabled feature', () => {
25+
test('should intercept enumerateDevices when enabled', async ({ page }) => {
26+
await gotoAndWait(page, '/webcompat/pages/device-enumeration.html', {
27+
site: {
28+
enabledFeatures: ['webCompat'],
29+
},
30+
featureSettings: {
31+
webCompat: {
32+
enumerateDevices: 'enabled',
33+
},
34+
},
35+
});
36+
37+
// Should use our implementation
38+
const results = await page.evaluate(() => {
39+
// @ts-expect-error - results is set by renderResults()
40+
return window.results;
41+
});
42+
43+
// The test should pass with our implementation
44+
expect(results).toBeDefined();
45+
});
46+
});
47+
});

injected/integration-test/pages.spec.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,15 @@ test.describe('Test integration pages', () => {
127127
);
128128
});
129129

130+
test('enumerateDevices API functionality', async ({ page }, testInfo) => {
131+
await testPage(
132+
page,
133+
testInfo,
134+
'webcompat/pages/enumerate-devices-api-test.html',
135+
'./integration-test/test-pages/webcompat/config/enumerate-devices-api.json',
136+
);
137+
});
138+
130139
test('minSupportedVersion (string)', async ({ page }, testInfo) => {
131140
await testPage(
132141
page,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"readme": "This config is used to test the enumerateDevices API proxy functionality.",
3+
"version": 1,
4+
"unprotectedTemporary": [],
5+
"features": {
6+
"webCompat": {
7+
"state": "enabled",
8+
"exceptions": [],
9+
"settings": {
10+
"enumerateDevices": "enabled"
11+
}
12+
}
13+
}
14+
}

injected/integration-test/test-pages/webcompat/index.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
<li><a href="./pages/message-handlers.html">Message Handlers</a> - <a href="./config/message-handlers.json">Config</a></li>
1313
<li><a href="./pages/shims.html">Shims</a> - <a href="./config/shims.json">Config</a></li>
1414
<li><a href="./pages/modify-localstorage.html">Modify localStorage</a> - <a href="./config/modify-localstorage.json">Config</a></li>
15+
<li><a href="./pages/device-enumeration.html">Device Enumeration</a></li>
16+
<li><a href="./pages/enumerate-devices-api-test.html">Enumerate Devices API Test</a> - <a href="./config/enumerate-devices-api.json">Config</a></li>
1517
</ul>
1618
</body>
1719
</html>
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="utf-8">
5+
<meta name="viewport" content="width=device-width">
6+
<title>Device Enumeration Test</title>
7+
<link rel="stylesheet" href="../../shared/style.css">
8+
</head>
9+
<body>
10+
<script src="../../shared/utils.js"></script>
11+
<p><a href="../index.html">[Webcompat shims]</a></p>
12+
13+
<p>This page tests the device enumeration feature</p>
14+
15+
<script>
16+
test('Device Enumeration', async () => {
17+
if (!navigator.mediaDevices) {
18+
return [
19+
{
20+
name: 'MediaDevices not available',
21+
result: 'MediaDevices API not supported',
22+
expected: 'MediaDevices API not supported'
23+
}
24+
];
25+
}
26+
27+
try {
28+
const devices = await navigator.mediaDevices.enumerateDevices();
29+
30+
// Check if we got a valid response
31+
const hasVideoInput = devices.some(device => device.kind === 'videoinput');
32+
const hasAudioInput = devices.some(device => device.kind === 'audioinput');
33+
const hasAudioOutput = devices.some(device => device.kind === 'audiooutput');
34+
35+
return [
36+
{
37+
name: 'enumerateDevices returns array',
38+
result: Array.isArray(devices),
39+
expected: true
40+
},
41+
{
42+
name: 'devices have correct structure',
43+
result: devices.every(device =>
44+
typeof device.deviceId === 'string' &&
45+
typeof device.kind === 'string' &&
46+
typeof device.label === 'string' &&
47+
typeof device.groupId === 'string'
48+
),
49+
expected: true
50+
},
51+
{
52+
name: 'video input devices present',
53+
result: hasVideoInput,
54+
expected: true
55+
},
56+
{
57+
name: 'audio input devices present',
58+
result: hasAudioInput,
59+
expected: true
60+
},
61+
{
62+
name: 'audio output devices present',
63+
result: hasAudioOutput,
64+
expected: true
65+
}
66+
];
67+
} catch (error) {
68+
return [
69+
{
70+
name: 'enumerateDevices throws error',
71+
result: error.message,
72+
expected: 'Should not throw error'
73+
}
74+
];
75+
}
76+
});
77+
78+
renderResults();
79+
</script>
80+
</body>
81+
</html>

0 commit comments

Comments
 (0)