Skip to content

Device enum support #1806

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 18 commits into from
Jul 11, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions injected/integration-test/device-enumeration.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { gotoAndWait, testContextForExtension } from './helpers/harness.js';
import { test as base, expect } from '@playwright/test';

const test = testContextForExtension(base);

test.describe('Device Enumeration Feature', () => {
test.describe('disabled feature', () => {
test('should not intercept enumerateDevices when disabled', async ({ page }) => {
await gotoAndWait(page, '/webcompat/pages/device-enumeration.html', {
site: { enabledFeatures: [] },
});

// Should use native implementation
const results = await page.evaluate(() => {
// @ts-expect-error - results is set by renderResults()
return window.results;
});

// The test should pass with native behavior
expect(results).toBeDefined();
});
});

test.describe('enabled feature', () => {
test('should intercept enumerateDevices when enabled', async ({ page }) => {
await gotoAndWait(page, '/webcompat/pages/device-enumeration.html', {
site: {
enabledFeatures: ['webCompat'],
},
featureSettings: {
webCompat: {
enumerateDevices: 'enabled',
},
},
});

// Should use our implementation
const results = await page.evaluate(() => {
// @ts-expect-error - results is set by renderResults()
return window.results;
});

// The test should pass with our implementation
expect(results).toBeDefined();
});
});
});
9 changes: 9 additions & 0 deletions injected/integration-test/pages.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,15 @@ test.describe('Test integration pages', () => {
);
});

test('enumerateDevices API functionality', async ({ page }, testInfo) => {
await testPage(
page,
testInfo,
'webcompat/pages/enumerate-devices-api-test.html',
'./integration-test/test-pages/webcompat/config/enumerate-devices-api.json',
);
});

test('minSupportedVersion (string)', async ({ page }, testInfo) => {
await testPage(
page,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"readme": "This config is used to test the enumerateDevices API proxy functionality.",
"version": 1,
"unprotectedTemporary": [],
"features": {
"webCompat": {
"state": "enabled",
"exceptions": [],
"settings": {
"enumerateDevices": "enabled"
}
}
}
}
2 changes: 2 additions & 0 deletions injected/integration-test/test-pages/webcompat/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
<li><a href="./pages/message-handlers.html">Message Handlers</a> - <a href="./config/message-handlers.json">Config</a></li>
<li><a href="./pages/shims.html">Shims</a> - <a href="./config/shims.json">Config</a></li>
<li><a href="./pages/modify-localstorage.html">Modify localStorage</a> - <a href="./config/modify-localstorage.json">Config</a></li>
<li><a href="./pages/device-enumeration.html">Device Enumeration</a></li>
<li><a href="./pages/enumerate-devices-api-test.html">Enumerate Devices API Test</a> - <a href="./config/enumerate-devices-api.json">Config</a></li>
</ul>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Device Enumeration Test</title>
<link rel="stylesheet" href="../../shared/style.css">
</head>
<body>
<script src="../../shared/utils.js"></script>
<p><a href="../index.html">[Webcompat shims]</a></p>

<p>This page tests the device enumeration feature</p>

<script>
test('Device Enumeration', async () => {
if (!navigator.mediaDevices) {
return [
{
name: 'MediaDevices not available',
result: 'MediaDevices API not supported',
expected: 'MediaDevices API not supported'
}
];
}

try {
const devices = await navigator.mediaDevices.enumerateDevices();

// Check if we got a valid response
const hasVideoInput = devices.some(device => device.kind === 'videoinput');
const hasAudioInput = devices.some(device => device.kind === 'audioinput');
const hasAudioOutput = devices.some(device => device.kind === 'audiooutput');

return [
{
name: 'enumerateDevices returns array',
result: Array.isArray(devices),
expected: true
},
{
name: 'devices have correct structure',
result: devices.every(device =>
typeof device.deviceId === 'string' &&
typeof device.kind === 'string' &&
typeof device.label === 'string' &&
typeof device.groupId === 'string'
),
expected: true
},
{
name: 'video input devices present',
result: hasVideoInput,
expected: true
},
{
name: 'audio input devices present',
result: hasAudioInput,
expected: true
},
{
name: 'audio output devices present',
result: hasAudioOutput,
expected: true
}
];
} catch (error) {
return [
{
name: 'enumerateDevices throws error',
result: error.message,
expected: 'Should not throw error'
}
];
}
});

renderResults();
</script>
</body>
</html>
Loading
Loading