{"id":40135505,"url":"https://github.com/addpipe/webcam-tester","last_synced_at":"2026-02-02T08:23:53.513Z","repository":{"id":320646150,"uuid":"1079820802","full_name":"addpipe/webcam-tester","owner":"addpipe","description":"webcam-tester.js is a comprehensive JavaScript library for testing webcam and microphone functionality in web browsers and priming browser permissions before users reach your main application and diagnosing webcam \u0026 microphone issues.","archived":false,"fork":false,"pushed_at":"2025-10-22T09:08:23.000Z","size":2235,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-25T01:27:47.165Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@addpipe/webcam-tester","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/addpipe.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-10-20T12:44:58.000Z","updated_at":"2025-10-22T09:20:52.000Z","dependencies_parsed_at":"2025-10-25T01:27:49.172Z","dependency_job_id":"8ecc0e76-24f1-495d-8571-22447f346a4d","html_url":"https://github.com/addpipe/webcam-tester","commit_stats":null,"previous_names":["addpipe/webcam-tester"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/addpipe/webcam-tester","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/addpipe%2Fwebcam-tester","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/addpipe%2Fwebcam-tester/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/addpipe%2Fwebcam-tester/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/addpipe%2Fwebcam-tester/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/addpipe","download_url":"https://codeload.github.com/addpipe/webcam-tester/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/addpipe%2Fwebcam-tester/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28571556,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-19T12:50:50.164Z","status":"ssl_error","status_checked_at":"2026-01-19T12:50:42.704Z","response_time":67,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-19T14:00:20.120Z","updated_at":"2026-02-02T08:23:53.465Z","avatar_url":"https://github.com/addpipe.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Webcam Tester Library\n\n[![Author](https://img.shields.io/badge/Author-Addpipe-blue.svg)](https://addpipe.com/)\n[![License: AGPL 3.0](https://img.shields.io/badge/License-AGPL_3.0-brightgreen.svg)](https://opensource.org/license/agpl-v3)\n\n`webcam-tester.js` is a JavaScript library for:\n\n1. testing webcam and microphone functionality in web browsers\n2. priming browser/OS permissions (and default devices) before users reach your main application (read more about [priming](#how-priming-works))\n3. diagnosing webcam \u0026 microphone issues\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"public/media/demo.gif\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nYou can test it [here](https://addpipe.com/webcam-tester/).\n\n## Features\n\n- ✅ **Tests for minimum requirements** - Detects `getUserMedia` (incl. legacy versions), [secure contexts](https://developer.mozilla.org/en-US/docs/Web/Security/Secure_Contexts), [Permissions Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Permissions_Policy), [Permissions API](https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API)\n- 🎥 **Camera Testing** - Complete permission and device functionality checks with device selection\n- 🎤 **Microphone Testing** - Independent microphone permission and device testing with device selection\n- 📺 **Resolution Testing** - Tests multiple resolutions from 144p to 4K with frame rate detection\n- 💡 **Lighting Analysis** - Analyzes camera brightness and provides recommendations\n- 🔧 **Other APIs** - Tests [MediaStream Recording API](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API), [MediaStream Image Capture API](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Image_Capture_API), [Screen Capture API](https://developer.mozilla.org/en-US/docs/Web/API/Screen_Capture_API) and [Web Audio API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API)\n- 🎨 **Dark Mode** - Built-in light and dark themes\n- ⚙️ **Highly Configurable** - Extensive customization options (see config options [below](#configuration-options))\n- 📱 **Device Enumeration** - Lists all available audio/video input and output devices (reacts to `ondevicechange`)\n- 🔒 **Privacy-First** - No data transmission or storage; Library runs locally in the browser\n- 🚀 **Easy Integration** - Insert into any page using a single function call\n- 👻 **UI-less Mode** - Run tests programmatically without UI\n- 📤 **Export Results** - Export test results to Markdown, JSON, CSV, or XML formats with browser and device metadata\n\n## Installation \u0026 Quick Start\n\n### Via NPM\n\n```bash\nnpm install @addpipe/webcam-tester\n```\n\n```javascript\nimport { insertWebcamTestLibrary } from \"@addpipe/webcam-tester\";\n\n// OR\n\nconst { insertWebcamTestLibrary } = require(\"@addpipe/webcam-tester\");\n```\n\n```html\n\u003c!-- This element will be replaced by the library --\u003e\n\u003cdiv id=\"webcam-tester-container\"\u003e\u003c/div\u003e\n```\n\n```javascript\nconst webcamTester = insertWebcamTestLibrary(\"webcam-tester-container\");\n```\n\n### Via CDN\n\nAdding the webcam tests to your web page is as simple as copying and pasting the code below in your page:\n\n```html\n\u003c!-- This element will be replaced by the library --\u003e\n\u003cdiv id=\"webcam-tester-container\"\u003e\u003c/div\u003e\n\n\u003c!-- Minified version (recommended for production) --\u003e\n\u003cscript src=\"https://unpkg.com/@addpipe/webcam-tester@latest/dist/webcam-tester.min.js\"\u003e\u003c/script\u003e\n\n\u003cscript\u003e\n  document.addEventListener(\"DOMContentLoaded\", function () {\n    const webcamTester = insertWebcamTestLibrary(\"webcam-tester-container\");\n  });\n\u003c/script\u003e\n```\n\nThat's it! The library will automatically replace the target element with a complete media testing interface.\n\nYou can also include the library’s source code directly in your page instead of loading it from a CDN. To do this, replace the line `\u003cscript src=\"https://unpkg.com/@addpipe/webcam-tester@latest/dist/webcam-tester.min.js\"\u003e\u003c/script\u003e` with the actual [source code](https://github.com/addpipe/webcam-tester/blob/master/src/webcam-tester.js) of the library inside a script tag.\n\nFor more advanced code examples, check out the [Examples section](#examples).\n\n## Configuration Options\n\nThe library accepts a configuration object with the following options:\n\n```javascript\nconst webcamTester = insertWebcamTestLibrary(\"webcam-tester-container\", {\n  // UI Display Options\n  showResults: true, // Show test result logs (default: true)\n  showCameraPreview: true, // Show camera preview (default: true)\n  showRedoButtons: true, // Show individual redo buttons (default: true)\n  showLoadingText: true, // Show loading animations (default: true)\n  allowRestart: true, // Allow restarting entire test suite (default: true)\n  allowCameraSelection: true, // Allow camera device selection (default: true)\n  allowMicSelection: true, // Allow microphone device selection (default: true)\n\n  // Appearance\n  darkTheme: false, // Use dark theme (default: false)\n  title: \"Webcam Tester\", // Custom title (default: 'Webcam Tester')\n\n  // Execution Mode\n  uiLess: false, // Run without UI (default: false)\n\n  // Test Selection\n  tests: [\n    // Specific tests to run (default: all)\n    \"getUserMedia\",\n    \"secureContext\",\n    \"permissionsPolicy\",\n    \"cameraPermissions\",\n    \"micPermissions\",\n    \"permissionsApi\",\n    \"devices\",\n    \"capture\",\n    \"resolutions\",\n    \"lighting\",\n    \"otherApis\",\n  ],\n\n  // Event Callbacks\n  callbacks: {\n    onTestStart: function () {\n      console.log(\"Testing started\");\n    },\n    onTestComplete: function (result) {\n      console.log(\"Test completed:\", result);\n    },\n    onAllTestsComplete: function (allResults) {\n      console.log(\"All tests finished:\", allResults);\n    },\n    onError: function (testName, error) {\n      console.error(\"Test error:\", testName, error);\n    },\n  },\n});\n```\n\n## Tests\n\nWhat does the library test?\n\n### 1. Checks Browser Support for `getUserMedia()`\n\n- Verifies if the browser supports the getUserMedia API\n- Checks for legacy implementations\n- **Result**: Success if modern API available, warning for legacy, error if unsupported\n\n### 2. Checks for Secure Context\n\n- Ensures the page is running in a secure context (HTTPS, localhost, file:// etc.)\n- **Result**: Success if secure, error if not secure\n\n### 3. Checks Permissions Policy\n- Verifies that Permissions Policy (formerly Feature Policy) allows camera and microphone access\n- **Expandable Info**: Shows detailed policy status for each feature with explanations\n- **Result**: Success if all features allowed, warning if some blocked, info if API not supported\n\n**Why this matters:** In supporting browsers, a Permissions Policy can block camera and microphone access before the user is prompted to give their own permission. This is common in cross-origin iframes or when a restrictive `Permissions-Policy` HTTP response header is set.\n\n### 4. Checks Camera Permissions\n\n- Requests camera permissions from the user\n- Allows selection of specific camera device (if `allowCameraSelection: true`); on Chrome and Firefox, the selection made in the library UI has higher priority\n- Sets up the camera preview if successful\n- **Result**: Success if granted, error with specific reason if denied\n\n### 5. Checks Microphone Permissions\n\n- Requests microphone permissions from the user\n- Allows selection of specific microphone device (if `allowMicSelection: true`); on Chrome and Firefox, the selection made in the library UI has higher priority\n- Works independently from camera permissions\n- **Result**: Success if granted, error with specific reason if denied\n\n### 6. Verifies Permissions API State\n\n- Uses the [Permissions API](https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API) to verify that camera and microphone permissions were successfully granted\n- Runs after the permission request tests to confirm the actual permission state\n- **Expandable Info**: Shows detailed permission state for each device type with explanations of what each state means\n- **Result**: Success if both permissions are granted, warning if permissions are still in \"prompt\" state (something went wrong), error if permissions are denied\n\n**Why this matters:** This test confirms that permissions were actually granted after the user was prompted. If permissions show as \"denied\", the user blocked access and would need to change their browser settings. If permissions show as \"prompt\" after the permission request tests, it indicates an unexpected issue.\n\n**Note:** If the Permissions API is not supported by the browser, a warning is shown instead of a failure, as camera and microphone access may still work through `getUserMedia()`.\n\n### 7. Enumerates Devices\n\n- Lists all available audio inputs, video inputs, and audio outputs\n- Shows which devices are currently selected\n- **Expandable Info**: Shows detailed device lists by category with selection indicators\n- **Result**: Success with device count\n\n### 8. Tests Active Streams and Tracks\n\n- Verifies is active media streams or tracks are working correctly\n- Displays current capture resolution for video\n- Shows status for both audio and video tracks\n- **Result**: Success with resolution info, warning if partial capture\n\n### 9. Tests Resolutions\n\n- Tests 8 standard resolutions: 144p, 240p, 360p, 480p, 720p, 1080p, 1440p, 4K\n- Measures frame rates for each supported resolution\n- **Expandable Info**: Shows all tested resolutions with status and frame rates\n- **Result**: Success with supported count and average FPS\n\n### 10. Tests Lighting\n\n- Analyzes camera brightness using pixel data analysis\n- Provides recommendations for optimal lighting\n- **Expandable Info**: Shows brightness scale (0-255) with explanations\n- **Result**: Success/warning based on lighting conditions with brightness value\n\n### 11. Checks Other APIs\n\n- Tests availability of other web APIs:\n  - [MediaStream Recording API](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Recording_API) (for recording)\n  - [MediaStream Image Capture API](https://developer.mozilla.org/en-US/docs/Web/API/MediaStream_Image_Capture_API) (for photo capture)\n  - [Screen Capture API](https://developer.mozilla.org/en-US/docs/Web/API/Screen_Capture_API) (for screen sharing)\n  - [Web Audio API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Audio_API) (for audio processing)\n- **Expandable Info**: Shows detailed status for each capability\n- **Result**: Success if capabilities available, warning if limited\n\n## API Methods\n\nOnce initialized, the library instance provides these methods:\n\n```javascript\nconst webcamTester = insertWebcamTestLibrary(\"webcam-tester-container\");\n\n// Start tests programmatically (useful in UI-less mode)\nawait webcamTester.start();\n\n// Get all test results\nconst results = webcamTester.getTestResults();\nconsole.log(results);\n// Returns: { testId: { id, icon, message, type, details, timestamp, deviceId, deviceLabel }, ... }\n\n// Check if tests are currently running\nconst isRunning = webcamTester.isRunning();\nconsole.log(\"Tests running:\", isRunning);\n\n// Get the current media stream\nconst stream = webcamTester.getCurrentStream();\nif (stream) {\n  // Use the stream for other purposes\n  console.log(\"Stream available:\", stream);\n}\n\n// Get selected camera information\nconst cameraInfo = webcamTester.getSelectedCameraInfo();\nconsole.log(\"Camera:\", cameraInfo.deviceLabel, cameraInfo.deviceId);\n\n// Get selected microphone information\nconst micInfo = webcamTester.getSelectedMicrophoneInfo();\nconsole.log(\"Microphone:\", micInfo.deviceLabel, micInfo.deviceId);\n\n// Clean up resources and remove from DOM\nwebcamTester.destroy();\n```\n\n## Event Callbacks\n\n### onTestStart()\n\nFired when the user clicks \"Start Test\" or when `webcamTester.start()` is called programmatically.\n\n```javascript\ncallbacks: {\n    onTestStart: function() {\n        console.log('User started testing process');\n    }\n}\n```\n\n### onTestComplete(result)\n\nFired after each individual test completes. Receives a result object:\n\n```javascript\ncallbacks: {\n    onTestComplete: function(result) {\n        console.log(`Test ${result.id} completed:`, result.type);\n        // result = {\n        //   id, icon, message, type, details,\n        //   timestamp, deviceId, deviceLabel\n        // }\n    }\n}\n```\n\n### onAllTestsComplete(allResults)\n\nFired when all tests finish. Receives complete results object:\n\n```javascript\ncallbacks: {\n    onAllTestsComplete: function(allResults) {\n        console.log('Testing complete. Results:', allResults);\n        // Process final results\n        const failedTests = Object.values(allResults)\n            .filter(test =\u003e test.type === 'error');\n        console.log('Failed tests:', failedTests.length);\n    }\n}\n```\n\n### onError(testName, error)\n\nFired when a test encounters an error:\n\n```javascript\ncallbacks: {\n    onError: function(testName, error) {\n        console.error(`Error in ${testName}:`, error);\n        // Handle specific test failures\n    }\n}\n```\n\n## Export Results\n\nAfter all tests complete, an export section appears (when `showResults: true`) allowing users to download test results in various formats:\n\n- **Markdown (.md)** - Human-readable format with tables, ideal for documentation or sharing\n- **JSON (.json)** - Structured data format, ideal for programmatic processing\n- **CSV (.csv)** - Spreadsheet-compatible format, ideal for data analysis\n- **XML (.xml)** - Markup format, ideal for integration with other systems\n\n### Exported Data Includes\n\n- **Timestamp**: When the tests were run\n- **Browser Information**: Name, version, OS, language, user agent\n- **Selected Devices**: Camera and microphone names/IDs\n- **Test Summary**: Total tests, passed, warnings, failed counts\n- **Detailed Results**: Each test's status, message, and details\n\n### Export Filename Format\n\nFiles are automatically named with a timestamp: `webcam-test-results-{timestamp}.{ext}`\n\nExample: `webcam-test-results-Jan-30-2025-14-30-45.md`\n\n## Examples\n\n### Basic Usage NPM\n\n```javascript\nimport { insertWebcamTestLibrary } from \"@addpipe/webcam-tester\";\n\n// Simple initialization with defaults\nconst webcamTester = insertWebcamTestLibrary(\"webcam-tester-container\");\n```\n\n### Basic Usage CDN\n\n```html\n\u003cdiv id=\"webcam-tester-container\"\u003e\u003c/div\u003e\n```\n\n```javascript\n\u003cscript src=\"https://unpkg.com/@addpipe/webcam-tester@latest/dist/webcam-tester.min.js\"\u003e\u003c/script\u003e\n\u003cscript\u003e\n    // Simple initialization with defaults\n    const webcamTester = insertWebcamTestLibrary('webcam-tester-container');\n\u003c/script\u003e\n```\n\n### Custom Configuration\n\n```javascript\n// Customized for a specific use case\nconst webcamTester = insertWebcamTestLibrary(\"webcam-tester-container\", {\n  darkTheme: true,\n  title: \"Camera \u0026 Mic Check\",\n  tests: [\"cameraPermissions\", \"micPermissions\", \"devices\", \"resolutions\"],\n  callbacks: {\n    onAllTestsComplete: function (results) {\n      const cameraOk = results.cameraPermissions?.type === \"success\";\n      const micOk = results.micPermissions?.type === \"success\";\n\n      if (cameraOk \u0026\u0026 micOk) {\n        // Proceed with main application\n        window.location.href = \"/start-recording\";\n      } else {\n        // Show help message\n        alert(\"Camera and microphone access is required for recordings\");\n      }\n    },\n  },\n});\n```\n\n### UI-less Mode (Programmatic Usage)\n\n```javascript\n// Run tests without any UI\nconst webcamTester = insertWebcamTestLibrary(\"webcam-tester-container\", {\n  uiLess: true,\n  allowCameraSelection: false, // Skip device selection UI\n  allowMicSelection: false,\n  tests: [\"getUserMedia\", \"secureContext\", \"cameraPermissions\", \"micPermissions\"],\n  callbacks: {\n    onAllTestsComplete: function (results) {\n      console.log(\"uiLess test results:\", results);\n\n      // Process results programmatically\n      if (results.cameraPermissions?.result \u0026\u0026 results.micPermissions?.result) {\n        startRecording();\n      } else {\n        showPermissionError();\n      }\n    },\n  },\n});\n\n// Start tests programmatically\nawait webcamTester.start();\n\n// Get results at any time\nconst currentResults = webcamTester.getTestResults();\n```\n\n### Integration with React\n\n```javascript\nimport { useEffect, useState } from \"react\";\nimport { insertWebcamTestLibrary } from \"@addpipe/webcam-tester\";\n\nfunction MediaTester() {\n  const [testResults, setTestResults] = useState(null);\n  const [testingComplete, setTestingComplete] = useState(false);\n\n  useEffect(() =\u003e {\n    const webcamTester = insertWebcamTestLibrary(\"webcam-tester-container\", {\n      callbacks: {\n        onAllTestsComplete: (results) =\u003e {\n          setTestResults(results);\n          setTestingComplete(true);\n        },\n      },\n    });\n\n    return () =\u003e webcamTester.destroy(); // Cleanup on unmount\n  }, []);\n\n  return (\n    \u003cdiv\u003e\n      \u003cdiv id=\"webcam-tester-container\"\u003e\u003c/div\u003e\n      {testingComplete \u0026\u0026 (\n        \u003cdiv\u003e\n          \u003ch3\u003eTest Results:\u003c/h3\u003e\n          \u003cpre\u003e{JSON.stringify(testResults, null, 2)}\u003c/pre\u003e\n        \u003c/div\u003e\n      )}\n    \u003c/div\u003e\n  );\n}\n```\n\n### Integration with Vue\n\n```html\n\u003ctemplate\u003e\n    \u003cdiv id=\"webcam-tester-container\"\u003e\u003c/div\u003e\n\u003c/template\u003e\n\n\u003cscript\u003e\nimport { onMounted, onUnmounted } from 'vue';\nimport { insertWebcamTestLibrary } from '@addpipe/webcam-tester';\n\nexport default {\n    name: 'MediaTester',\n    setup() {\n        let webcamTester = null;\n\n        onMounted(() =\u003e {\n            webcamTester = insertWebcamTestLibrary('webcam-tester-container', {\n                callbacks: {\n                    onAllTestsComplete: (results) =\u003e {\n                        console.log('Tests complete:', results);\n                    }\n                }\n            });\n        });\n\n        onUnmounted(() =\u003e {\n            if (webcamTester) {\n                webcamTester.destroy();\n            }\n        });\n    }\n};\n\u003c/script\u003e\n```\n\n### Permission Priming with Device Selection\n\nIn this example, the library first confirms that camera and microphone permissions have been granted. It then redirects the user to a dedicated video recording page, ensuring that all required permissions are in place before starting the recording. The selected devices ID's are also stored within the local storage in this example.\n\n```javascript\n// Use before main video calling interface\nconst webcamTester = insertWebcamTestLibrary(\"webcam-tester-container\", {\n  tests: [\"cameraPermissions\", \"micPermissions\"],\n  allowCameraSelection: true,\n  allowMicSelection: true,\n  callbacks: {\n    onAllTestsComplete: function (results) {\n      const cameraOk = results.cameraPermissions?.type === \"success\";\n      const micOk = results.micPermissions?.type === \"success\";\n\n      if (cameraOk \u0026\u0026 micOk) {\n        // Get selected devices\n        const camera = webcamTester.getSelectedCameraInfo();\n        const mic = webcamTester.getSelectedMicrophoneInfo();\n\n        // Store preferences\n        localStorage.setItem(\"preferredCamera\", camera.deviceId);\n        localStorage.setItem(\"preferredMic\", mic.deviceId);\n\n        // Redirect to main app\n        window.location.href = \"/record-video\";\n      }\n    },\n  },\n});\n```\n\n### Camera-Only or Mic-Only Testing\n\nIn these examples, the library will only test the camera or mic permissions, not both.\n\n```javascript\n// Test only camera\nconst cameraTester = insertWebcamTestLibrary(\"webcam-tester-container\", {\n  tests: [\"cameraPermissions\", \"resolutions\", \"lighting\"],\n  allowMicSelection: false,\n});\n\n// Test only microphone\nconst micTester = insertWebcamTestLibrary(\"webcam-tester-container\", {\n  tests: [\"micPermissions\", \"devices\"],\n  allowCameraSelection: false,\n  showCameraPreview: false,\n});\n```\n\n## How Priming Works:\n\n1. On Chrome on macOS, it primes user permissions and the default devices (at the domain level; closing all tabs with said domain resets the permission)\n2. On Firefox on macOS, it primes user permissions and the default device (at the browser tab x device level; refreshing the tab does not reset permissions)\n3. On Safari on macOS, it primes user permission at the tab level (refreshing the tab resets the permission)\n\nPriming works differently when the library is tested through `file://`.\n\n## Device Selection\n\nThe library supports device selection for both cameras and microphones. It’s especially handy on Safari which has no device selection UI. On Chrome and Firefox, because they offer their own device selector dialog, we prioritize the device chosen through the library (we use the `exact` keyword when requesting device access).\n\n- **Automatic Detection**: If only one device is available, it's selected automatically\n- **Selection UI**: If multiple devices exist, users can choose from a list. On browsers which have their own device selector (Chrome, Firefox, etc.) the device selected through the `webcam-tester.js` UI has higher priority (we use the `exact` keyword)\n- **Skip Selection**: Set `allowCameraSelection: false` or `allowMicSelection: false` to skip\n- **UI-less Mode**: In UI-less mode, the library automatically uses the media device selected by the user through the browser’s permission prompt. If no device selector is available, it defaults to the one provided by `getUserMedia`\n\nDevice selection flow:\n\n1. Camera selection (if enabled and multiple cameras exist)\n2. Microphone selection (if enabled and multiple microphones exist)\n3. Tests execution\n\n## Privacy \u0026 Security\n\n- No data transmission - All processing happens locally\n- No data storage - Results are only kept in memory\n- Stream cleanup - Automatically stops camera/microphone when removed using the `destroy()` method\n\n## Troubleshooting\n\n### Common Issues\n\n**\"getUserMedia not supported\"**\n\n- Use HTTPS (not HTTP)\n- Update to a modern browser\n\n**\"Permission denied\"**\n\n- User must click \"Allow\" in browser prompt\n- Check browser settings for camera/microphone permissions\n- Ensure no other application is using the devices\n\n**\"No devices found\"**\n\n- Check physical camera/microphone connections\n- Verify devices work in other applications\n- Check browser device permissions in settings\n\n**Camera preview shows but tests fail**\n\n- May indicate browser or hardware limitations\n- Check console for specific error messages\n\n**Device selection not showing**\n\n- Check that `allowCameraSelection` or `allowMicSelection` is `true`\n- Ensure multiple devices are actually available\n- Verify browser has permission to enumerate devices\n\n### Debug Mode\n\nPreview detailed logging by opening browser developer tools:\n\n```javascript\nconst webcamTester = insertWebcamTestLibrary(\"webcam-tester-container\", {\n  callbacks: {\n    onError: (testName, error) =\u003e console.error(testName, error),\n    onTestComplete: (result) =\u003e console.log(result),\n    onAllTestsComplete: (results) =\u003e console.table(results),\n  },\n});\n```\n\n## TypeScript Support\n\nTypeScript definitions are included in the package:\n\n```typescript\nimport { insertWebcamTestLibrary, WebcamDeviceTester, TestResult } from \"@addpipe/webcam-tester\";\n\nconst webcamTester: WebcamDeviceTester = insertWebcamTestLibrary(\"webcam-tester-container\", {\n  uiLess: true,\n  callbacks: {\n    onAllTestsComplete: (results: Record\u003cstring, TestResult\u003e) =\u003e {\n      console.log(results);\n    },\n  },\n});\n```\n\n## Contributing\n\nThis library is designed to be extensible. To add new webcam \u0026 microphone tests:\n\n1. Add test configuration to the `tests` array\n2. Implement test method following the pattern `testYourTestName()`\n3. Add test to the `testMap` in `runAllTests()`\n4. Update documentation\n\n## License\n\nThis project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0).\n\nSee [LICENSE](LICENSE) for full details or visit https://www.gnu.org/licenses/agpl-3.0.html\n\n## Changelog\n\n### v1.3.0\n- Added [Permissions API](https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API) test to check actual permission states (granted/prompt/denied) for camera and microphone after requesting access\n- Added export functionality to download test results in Markdown, JSON, CSV, or XML formats\n\n### v1.2.0\n- User is now prompted for cam \u0026 mic permission only after the (3) minimum requirement tests pass\n- Fix: Library no longer throws an alert when a minimum requirement test does not pass\n\n### v1.1.0\n- Added [Permissions Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Permissions_Policy) test to check if camera and microphone access is permitted on the page. Permissions Policy is only supported by some browsers\n- Fixed a bug where sometimes in React the target element was not found\n\n### v1.0.0\n\n- Initial release\n- Core testing functionality\n- Configuration options\n- API methods and callbacks\n\n---\n\n**Built with ❤️ by the [addpipe.com](https://addpipe.com/) team**","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faddpipe%2Fwebcam-tester","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faddpipe%2Fwebcam-tester","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faddpipe%2Fwebcam-tester/lists"}