{"_id":"@addpipe/webcam-tester","_rev":"6-866e1033ae48ea575206302841cd0a1b","name":"@addpipe/webcam-tester","dist-tags":{"latest":"1.3.2"},"versions":{"1.0.0":{"name":"@addpipe/webcam-tester","version":"1.0.0","keywords":["webcam","microphone","camera","media","getUserMedia","webrtc","testing","device","permissions","browser","video","audio"],"author":{"name":"Addpipe"},"license":"AGPL-3.0","_id":"@addpipe/webcam-tester@1.0.0","maintainers":[{"name":"octavn","email":"octavian@addpipe.com"},{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},{"name":"remusn","email":"remusnegrota@gmail.com"}],"homepage":"https://github.com/addpipe/webcam-tester#readme","bugs":{"url":"mailto:contact@addpipe.com"},"dist":{"shasum":"4db4b44f2062d1ac9eab57b289067347e519e159","tarball":"https://registry.npmjs.org/@addpipe/webcam-tester/-/webcam-tester-1.0.0.tgz","fileCount":9,"integrity":"sha512-2Kr031Ms9bgxx7WUNmbXI+0PH0WMNM+THNbvR8GWS3u+JfsFFMx3L7DDrFrEsfsOxbP7HVSI8k+Qlv/vzW4mjg==","signatures":[{"sig":"MEYCIQCljoj87SryhcpVs5aFwK1MEr230cam1kchF20cVMN0QwIhAOkzPcLgBXlYg7ZelFfqJ01aeLSNsk4WZvkR5i2DulV0","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":322291},"main":"dist/webcam-tester.js","types":"dist/index.d.ts","module":"dist/webcam-tester.esm.js","gitHead":"88f062bce2952303ef8aa1ebd74ec785dedb14e6","scripts":{"test":"echo \"No tests yet\" && exit 0","build":"rollup -c","prepublishOnly":"npm run build"},"_npmUser":{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},"repository":{"url":"","type":"git"},"_npmVersion":"11.4.2","description":"A JavaScript library for testing webcam and microphone functionality in web browsers","directories":{},"_nodeVersion":"23.1.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.9.0","@rollup/plugin-terser":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/webcam-tester_1.0.0_1761124795628_0.5886225154601861","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@addpipe/webcam-tester","version":"1.1.0","keywords":["webcam","microphone","camera","media","getUserMedia","webrtc","testing","device","permissions","browser","video","audio"],"author":{"name":"Addpipe"},"license":"AGPL-3.0","_id":"@addpipe/webcam-tester@1.1.0","maintainers":[{"name":"octavn","email":"octavian@addpipe.com"},{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},{"name":"remusn","email":"remusnegrota@gmail.com"}],"homepage":"https://github.com/addpipe/webcam-tester#readme","bugs":{"url":"mailto:contact@addpipe.com"},"dist":{"shasum":"cda51dbffc72db00eb3ad2b3e0334722cf62aa67","tarball":"https://registry.npmjs.org/@addpipe/webcam-tester/-/webcam-tester-1.1.0.tgz","fileCount":9,"integrity":"sha512-WmInWORLgxikCaAhQY3AdDCF6MdDdzK0t9IWH110GXXQND++H7ZTQo1iOmiE6kJfvV5mYAksZQaUTaXi6cI4Ag==","signatures":[{"sig":"MEQCIB2c8NBH+z+Z+7aoKclWNxMV2qVOjXXdAH3+o8186tqhAiBKBusnU18ZcgG7D2Seny3t8ykzASjV4dN7hbIUrhqPDg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":341325},"main":"dist/webcam-tester.js","types":"dist/index.d.ts","module":"dist/webcam-tester.esm.js","gitHead":"28d42bc93f4ddef4a22097bbb64fae5d37b38a3f","scripts":{"test":"echo \"No tests yet\" && exit 0","build":"rollup -c","prepublishOnly":"npm run build"},"_npmUser":{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},"repository":{"url":"","type":"git"},"_npmVersion":"11.4.2","description":"A JavaScript library for testing webcam and microphone functionality in web browsers","directories":{},"_nodeVersion":"23.1.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.9.0","@rollup/plugin-terser":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/webcam-tester_1.1.0_1761730879071_0.6968308191082726","host":"s3://npm-registry-packages-npm-production"}},"1.2.0":{"name":"@addpipe/webcam-tester","version":"1.2.0","keywords":["webcam","microphone","camera","media","getUserMedia","webrtc","testing","device","permissions","browser","video","audio"],"author":{"name":"Addpipe"},"license":"AGPL-3.0","_id":"@addpipe/webcam-tester@1.2.0","maintainers":[{"name":"octavn","email":"octavian@addpipe.com"},{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},{"name":"remusn","email":"remusnegrota@gmail.com"}],"homepage":"https://github.com/addpipe/webcam-tester#readme","bugs":{"url":"mailto:contact@addpipe.com"},"dist":{"shasum":"8a1c605a19a64c1f08b4d584bc6e2e9e20596a95","tarball":"https://registry.npmjs.org/@addpipe/webcam-tester/-/webcam-tester-1.2.0.tgz","fileCount":9,"integrity":"sha512-QOeLp/hN+tZ1d6/iy46dD/BGAhiKJE0taT1ANyC+YToHSRO5tQX5mGVwFpilLMXsMcxv1/cEVz+D/sRCXeXx6g==","signatures":[{"sig":"MEUCIQCRfESit4oiJ6E7PzZ3FyXlliad77MKArHNuIEV74rWUwIgQ2leotv1U19Kh16UVqVzcZEo133f8AU3Dxb/CMqKx/U=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":356842},"main":"dist/webcam-tester.js","types":"dist/index.d.ts","module":"dist/webcam-tester.esm.js","gitHead":"d224ac0121fb3d5ce64a54ff633b6c43d097e521","scripts":{"test":"echo \"No tests yet\" && exit 0","build":"rollup -c","prepublishOnly":"npm run build"},"_npmUser":{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},"repository":{"url":"","type":"git"},"_npmVersion":"11.4.2","description":"A JavaScript library for testing webcam and microphone functionality in web browsers","directories":{},"_nodeVersion":"23.1.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.9.0","@rollup/plugin-terser":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/webcam-tester_1.2.0_1768824341676_0.445514249285649","host":"s3://npm-registry-packages-npm-production"}},"1.3.0":{"name":"@addpipe/webcam-tester","version":"1.3.0","keywords":["webcam","microphone","camera","media","getUserMedia","webrtc","testing","device","permissions","browser","video","audio"],"author":{"name":"Addpipe"},"license":"AGPL-3.0","_id":"@addpipe/webcam-tester@1.3.0","maintainers":[{"name":"octavn","email":"octavian@addpipe.com"},{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},{"name":"remusn","email":"remusnegrota@gmail.com"}],"homepage":"https://github.com/addpipe/webcam-tester#readme","bugs":{"url":"mailto:contact@addpipe.com"},"dist":{"shasum":"bfc314dc0f14d223d9a01304a5895d891ae5b5d0","tarball":"https://registry.npmjs.org/@addpipe/webcam-tester/-/webcam-tester-1.3.0.tgz","fileCount":9,"integrity":"sha512-ctrIhoetG+KvnTYxzuWGdveYtF7EYfWzsYMRBR8T1HubimbqiLtfkUcvod35QaZohCN5ohMmu4g/dX0SHcVO1w==","signatures":[{"sig":"MEUCIQCKg3lkmw+y8yUciFXKTDto/RTPryZNReLNIED4dClJWQIgT/Nbjemf8Ni5V5a64OSxM3P8BnPDNG62mPX1OBmDFCE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":476724},"main":"dist/webcam-tester.js","types":"dist/index.d.ts","module":"dist/webcam-tester.esm.js","gitHead":"bfe81faac467d21e3a98e2873d13c926e20d9384","scripts":{"test":"echo \"No tests yet\" && exit 0","build":"rollup -c","prepublishOnly":"npm run build"},"_npmUser":{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},"repository":{"url":"","type":"git"},"_npmVersion":"11.4.2","description":"A JavaScript library for testing webcam and microphone functionality in web browsers","directories":{},"_nodeVersion":"23.1.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.9.0","@rollup/plugin-terser":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/webcam-tester_1.3.0_1770013111601_0.1085772605657025","host":"s3://npm-registry-packages-npm-production"}},"1.3.1":{"name":"@addpipe/webcam-tester","version":"1.3.1","keywords":["webcam","microphone","camera","media","getUserMedia","webrtc","testing","device","permissions","browser","video","audio"],"author":{"name":"Addpipe"},"license":"AGPL-3.0","_id":"@addpipe/webcam-tester@1.3.1","maintainers":[{"name":"octavn","email":"octavian@addpipe.com"},{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},{"name":"remusn","email":"remusnegrota@gmail.com"}],"homepage":"https://github.com/addpipe/webcam-tester#readme","bugs":{"url":"mailto:contact@addpipe.com"},"dist":{"shasum":"45b9756d379601c1d200de3abb00f1c9ad011438","tarball":"https://registry.npmjs.org/@addpipe/webcam-tester/-/webcam-tester-1.3.1.tgz","fileCount":9,"integrity":"sha512-zvc7Wy3AkqeBF6Re1O9ptzfv2oLfpeXKnpuINCUl2Vlqb8AMiiQzP/2Hx8yYctWoKhLYW6BSDoSSIdeXxlvBxw==","signatures":[{"sig":"MEUCIEFXjXobyHFnOgbVC2maMVm99cSG0j65ps+MDolSiqBZAiEAo8n5HScD7eLNfo04ni+FN+zbTYJeopKzOJ0fK0BYyws=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":477887},"main":"dist/webcam-tester.js","types":"dist/index.d.ts","module":"dist/webcam-tester.esm.js","gitHead":"1a6ea1326cc1fbdf26a0c99949f54d5ef50e6e82","scripts":{"test":"echo \"No tests yet\" && exit 0","build":"rollup -c","prepublishOnly":"npm run build"},"_npmUser":{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},"repository":{"url":"","type":"git"},"_npmVersion":"11.4.2","description":"A JavaScript library for testing webcam and microphone functionality in web browsers","directories":{},"_nodeVersion":"23.1.0","_hasShrinkwrap":false,"devDependencies":{"rollup":"^4.9.0","@rollup/plugin-terser":"^0.4.4"},"_npmOperationalInternal":{"tmp":"tmp/webcam-tester_1.3.1_1770732212834_0.17777090824902952","host":"s3://npm-registry-packages-npm-production"}},"1.3.2":{"name":"@addpipe/webcam-tester","version":"1.3.2","description":"A JavaScript library for testing webcam and microphone functionality in web browsers","main":"dist/webcam-tester.js","module":"dist/webcam-tester.esm.js","types":"dist/index.d.ts","scripts":{"build":"rollup -c","prepublishOnly":"npm run build","test":"echo \"No tests yet\" && exit 0"},"repository":{"type":"git","url":""},"keywords":["webcam","microphone","camera","media","getUserMedia","webrtc","testing","device","permissions","browser","video","audio"],"author":{"name":"Addpipe"},"license":"AGPL-3.0","bugs":{"url":"mailto:contact@addpipe.com"},"homepage":"https://github.com/addpipe/webcam-tester#readme","devDependencies":{"@rollup/plugin-terser":"^0.4.4","rollup":"^4.59.0"},"gitHead":"b6059eaf7f7e828c0ec48cb6f2608432a12ab14b","_id":"@addpipe/webcam-tester@1.3.2","_nodeVersion":"25.6.1","_npmVersion":"11.9.0","dist":{"integrity":"sha512-OAv8rbo6/w6wil6mExd6d3dyCLq1Fs1zZisJo97oNzoIYvoaCnwCil4hIKYDZSi2kUDLEoarqelFx8QQE2caAw==","shasum":"6628034aad6e54ac3b6edbf47e214bf1d27a4099","tarball":"https://registry.npmjs.org/@addpipe/webcam-tester/-/webcam-tester-1.3.2.tgz","fileCount":9,"unpackedSize":477973,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICnvw4vESc99Jq3Yl5+R+wvX+779hCbRz+LZikDi8SRMAiEA8i5j5FMwB0IsMEdiklaCCyGx53KxLy5QN1yCZ+FEubE="}]},"_npmUser":{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},"directories":{},"maintainers":[{"name":"octavn","email":"octavian@addpipe.com"},{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},{"name":"remusn","email":"remusnegrota@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/webcam-tester_1.3.2_1773296206063_0.2604365380755773"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-22T09:19:55.576Z","modified":"2026-03-12T06:16:46.401Z","1.0.0":"2025-10-22T09:19:55.831Z","1.1.0":"2025-10-29T09:41:19.257Z","1.2.0":"2026-01-19T12:05:41.818Z","1.3.0":"2026-02-02T06:18:31.763Z","1.3.1":"2026-02-10T14:03:33.009Z","1.3.2":"2026-03-12T06:16:46.230Z"},"bugs":{"url":"mailto:contact@addpipe.com"},"author":{"name":"Addpipe"},"license":"AGPL-3.0","homepage":"https://github.com/addpipe/webcam-tester#readme","keywords":["webcam","microphone","camera","media","getUserMedia","webrtc","testing","device","permissions","browser","video","audio"],"repository":{"type":"git","url":""},"description":"A JavaScript library for testing webcam and microphone functionality in web browsers","maintainers":[{"name":"octavn","email":"octavian@addpipe.com"},{"name":"alexgarbacea","email":"alexgrb0909@gmail.com"},{"name":"remusn","email":"remusnegrota@gmail.com"}],"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 lightweight JavaScript library for:\n\n1. Verifying minimum requirements (e.g. secure context) before accessing the camera and microphone\n2. Obtaining/priming browser and OS permissions (and default devices) before users reach your main application (read more about [priming](#how-priming-works))\n3. Diagnosing common webcam and microphone issues\n\n<p align=\"center\">\n  <img src=\"public/media/demo.gif\"></a>\n</p>\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), and [Permissions Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/Guides/Permissions_Policy)\n- 🚦 **Permissions API** Checks camera and microphone permissions (before calling `getUserMedia`) using the [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## Use Cases\n\n- Have users go through the process before your main app to test their webcam and prime their permissions\n- Run in UI-less mode behind the scenes to check camera & microphone permissions status\n- Run in UI-less mode behind the scenes to gather debug data\n- Host it on your website for your users to run and send you a report\n- Add it to self hosted apps to check for missing `getUserMedia`, non secure contexts and restrictive permissions policies\n\n## Installation & 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<!-- This element will be replaced by the library -->\n<div id=\"webcam-tester-container\"></div>\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<!-- This element will be replaced by the library -->\n<div id=\"webcam-tester-container\"></div>\n\n<!-- Minified version (recommended for production) -->\n<script src=\"https://unpkg.com/@addpipe/webcam-tester@latest/dist/webcam-tester.min.js\"></script>\n\n<script>\n  document.addEventListener(\"DOMContentLoaded\", function () {\n    const webcamTester = insertWebcamTestLibrary(\"webcam-tester-container\");\n  });\n</script>\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 `<script src=\"https://unpkg.com/@addpipe/webcam-tester@latest/dist/webcam-tester.min.js\"></script>` 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    \"permissionsApi\",\n    \"cameraPermissions\",\n    \"micPermissions\",\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. Verifies Permissions API State\n\n- Uses the [Permissions API](https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API) to query the camera and microphone permissions before requesting access\n- Could be used to skip further checks if permissions are already granted\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 in \"prompt\" state, 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### 5. 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 (we use `exact`)\n- Sets up the camera preview if successful\n- **Result**: Success if granted, error with specific reason if denied\n\n### 6. 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 (we use `exact`)\n- Works independently from camera permissions\n- **Result**: Success if granted, error with specific reason if denied\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 if 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 default 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 => 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<div id=\"webcam-tester-container\"></div>\n```\n\n```javascript\n<script src=\"https://unpkg.com/@addpipe/webcam-tester@latest/dist/webcam-tester.min.js\"></script>\n<script>\n    // Simple initialization with defaults\n    const webcamTester = insertWebcamTestLibrary('webcam-tester-container');\n</script>\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 & 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 && 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 && 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(() => {\n    const webcamTester = insertWebcamTestLibrary(\"webcam-tester-container\", {\n      callbacks: {\n        onAllTestsComplete: (results) => {\n          setTestResults(results);\n          setTestingComplete(true);\n        },\n      },\n    });\n\n    return () => webcamTester.destroy(); // Cleanup on unmount\n  }, []);\n\n  return (\n    <div>\n      <div id=\"webcam-tester-container\"></div>\n      {testingComplete && (\n        <div>\n          <h3>Test Results:</h3>\n          <pre>{JSON.stringify(testResults, null, 2)}</pre>\n        </div>\n      )}\n    </div>\n  );\n}\n```\n\n### Integration with Vue\n\n```html\n<template>\n    <div id=\"webcam-tester-container\"></div>\n</template>\n\n<script>\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(() => {\n            webcamTester = insertWebcamTestLibrary('webcam-tester-container', {\n                callbacks: {\n                    onAllTestsComplete: (results) => {\n                        console.log('Tests complete:', results);\n                    }\n                }\n            });\n        });\n\n        onUnmounted(() => {\n            if (webcamTester) {\n                webcamTester.destroy();\n            }\n        });\n    }\n};\n</script>\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 && 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 & 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) => console.error(testName, error),\n    onTestComplete: (result) => console.log(result),\n    onAllTestsComplete: (results) => 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<string, TestResult>) => {\n      console.log(results);\n    },\n  },\n});\n```\n\n## Contributing\n\nThis library is designed to be extensible. To add new webcam & 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.2\n- Update `rollup` dependency version to `4.59.0`\n\n### v1.3.1\n- Changed [Permissions API](https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API) test location to run before any `getUserMedia` call\n- Removed intrusive alerts that disrupted the test flow\n- Added [use cases](#use-cases) section to README\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 & 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**","readmeFilename":"README.md"}