fix: address code review feedback for browser extension
- Removed unused variables in capture.js (clonedDoc, styles array) - Added explicit return values for message handlers in content.js - Added detailed comment explaining 500ms render delay before PDF conversion - Updated PERMISSIONS.md with comprehensive explanation of host_permissions requirement - Updated test.html with web clipping test scenarios - Improved code consistency and documentation Co-authored-by: christianlouis <361235+christianlouis@users.noreply.github.com>
This commit is contained in:
@@ -7,10 +7,10 @@ This document explains the permissions requested by the DocuElevate browser exte
|
||||
The extension requests the following permissions in `manifest.json`:
|
||||
|
||||
### activeTab
|
||||
- **Purpose**: Get the URL of the currently active tab
|
||||
- **Usage**: When you click the extension icon, it reads the current tab's URL to display in the popup
|
||||
- **Privacy**: Only accesses the active tab when you explicitly open the popup
|
||||
- **Alternative**: Without this, the extension couldn't show you which file you're sending
|
||||
- **Purpose**: Get the URL and content of the currently active tab
|
||||
- **Usage**: When you click the extension icon, it reads the current tab's URL and content for clipping
|
||||
- **Privacy**: Only accesses the active tab when you explicitly use the extension
|
||||
- **Alternative**: Without this, the extension couldn't show you which file you're sending or clip pages
|
||||
|
||||
### storage
|
||||
- **Purpose**: Save your configuration (server URL and session cookie)
|
||||
@@ -19,61 +19,80 @@ The extension requests the following permissions in `manifest.json`:
|
||||
- **Alternative**: Without this, you'd need to reconfigure the extension every time
|
||||
|
||||
### contextMenus
|
||||
- **Purpose**: Add "Send to DocuElevate" to the right-click menu
|
||||
- **Usage**: Creates a context menu item for quick access
|
||||
- **Privacy**: No data access; only adds a menu item
|
||||
- **Purpose**: Add context menu options for sending URLs and clipping pages
|
||||
- **Usage**: Creates context menu items for quick access (Send URL, Clip Full Page, Clip Selection)
|
||||
- **Privacy**: No data access; only adds menu items
|
||||
- **Alternative**: Without this, you'd only have the toolbar icon
|
||||
|
||||
### notifications
|
||||
- **Purpose**: Show success/error notifications
|
||||
- **Usage**: Displays browser notifications when files are sent successfully or errors occur
|
||||
- **Usage**: Displays browser notifications when files are sent or clipped successfully, or when errors occur
|
||||
- **Privacy**: Only shows notifications based on your actions
|
||||
- **Alternative**: Without this, you wouldn't get feedback from context menu actions
|
||||
|
||||
## No Host Permissions
|
||||
### scripting (New in v1.1.0)
|
||||
- **Purpose**: Inject content capture code into web pages for clipping
|
||||
- **Usage**: When you click "Clip Page" or "Clip Selection", this permission allows the extension to execute code that captures page HTML
|
||||
- **Privacy**: Code only executes when you explicitly clip a page; no tracking or monitoring
|
||||
- **Scope**: Only runs in the active tab, only when you trigger clipping
|
||||
- **Alternative**: Without this, web page clipping wouldn't be possible
|
||||
|
||||
The extension has an **empty `host_permissions` array** (`[]`).
|
||||
## Host Permissions (v1.1.0)
|
||||
|
||||
### Why Empty?
|
||||
### <all_urls> - Required for Web Clipping
|
||||
|
||||
- **Privacy-First**: The extension doesn't request blanket access to all websites
|
||||
- **User-Controlled**: You configure the DocuElevate server URL, not us
|
||||
- **Minimal Permissions**: Only accesses the server you explicitly configure
|
||||
- **Dynamic Access**: API requests are made from popup/background scripts, not from web pages
|
||||
**Why Required**: The `<all_urls>` host permission is necessary for the web clipping feature to work on any website you visit.
|
||||
|
||||
### How It Works
|
||||
**Specific Use Cases**:
|
||||
1. **Page Content Capture**: To clip a web page, the extension must access the page's HTML and CSS
|
||||
2. **PDF Conversion**: The browser's printToPDF API requires host permissions to convert page content
|
||||
3. **Dynamic Content**: Ensures clipped pages include all styles and content, regardless of the website
|
||||
|
||||
1. You configure your DocuElevate server URL in the extension
|
||||
2. The extension stores this URL in local storage
|
||||
3. When you send a file, the extension makes a direct API request to your configured server
|
||||
4. No need for static host permissions because the extension doesn't inject scripts or modify web pages
|
||||
**Security Safeguards**:
|
||||
- **User-Initiated Only**: Content access only happens when you explicitly click "Clip Page" or "Clip Selection"
|
||||
- **No Automatic Access**: The extension doesn't monitor or track your browsing
|
||||
- **Local Processing**: Page content is captured and converted to PDF locally in your browser
|
||||
- **No Third-Party Transmission**: Content goes only to your configured DocuElevate server
|
||||
- **Temporary Access**: Content is processed immediately and not stored by the extension
|
||||
|
||||
### Comparison to Other Extensions
|
||||
**Alternative Options**:
|
||||
- **activeTab Only**: If you only want URL sending (not web clipping), the extension could work with just `activeTab` permission
|
||||
- **Manual Permission**: You could be prompted per-site, but this would be cumbersome for frequent use
|
||||
|
||||
Many similar extensions request:
|
||||
- ❌ `"<all_urls>"` or `"*://*/*"` - Access to all websites
|
||||
- ❌ `"http://*/*"` and `"https://*/*"` - Access to all HTTP/HTTPS sites
|
||||
|
||||
DocuElevate requests:
|
||||
- ✅ `[]` - No blanket host permissions
|
||||
- ✅ Only access to your configured server (via fetch API)
|
||||
**Privacy Guarantee**: Even with `<all_urls>`, the extension:
|
||||
- Does NOT monitor your browsing
|
||||
- Does NOT collect page content automatically
|
||||
- Does NOT track which sites you visit
|
||||
- Only accesses content when you explicitly clip a page
|
||||
|
||||
## Permission Justification
|
||||
|
||||
| Permission | Required? | Justification |
|
||||
|------------|-----------|---------------|
|
||||
| activeTab | ✅ Yes | Must read current tab URL to send files |
|
||||
| activeTab | ✅ Yes | Must read current tab URL and content |
|
||||
| storage | ✅ Yes | Must save configuration to function |
|
||||
| contextMenus | ⚠️ Optional | Nice to have for quick access |
|
||||
| notifications | ⚠️ Optional | Nice to have for feedback |
|
||||
| scripting | ✅ Yes (for clipping) | Required to capture page content for web clipping |
|
||||
| host_permissions: <all_urls> | ✅ Yes (for clipping) | Required for web clipping to work on any website |
|
||||
|
||||
## Security Benefits
|
||||
|
||||
1. **No Web Page Access**: Extension can't read or modify content on websites you visit
|
||||
2. **No Browsing History**: Extension doesn't track your browsing
|
||||
3. **No Cross-Site Access**: Extension only talks to your configured server
|
||||
4. **User-Controlled**: All communication is initiated by you
|
||||
5. **Transparent**: All code is visible in the extension folder
|
||||
1. **User-Initiated Access**: Extension only accesses page content when you explicitly click "Clip"
|
||||
2. **Local Processing**: Pages converted to PDF in your browser, not on a server
|
||||
3. **User-Controlled Server**: Extension only talks to your configured DocuElevate server
|
||||
4. **No Automatic Tracking**: Extension doesn't monitor your browsing or collect data in the background
|
||||
5. **Transparent Code**: All code is visible in the extension folder for audit
|
||||
|
||||
## How Web Clipping Works Securely
|
||||
|
||||
1. **You Trigger**: You click "Clip Page" or "Clip Selection"
|
||||
2. **Content Capture**: Extension captures page HTML (only when you click)
|
||||
3. **Local Conversion**: Your browser converts HTML to PDF using built-in API
|
||||
4. **Direct Upload**: PDF is sent only to your configured DocuElevate server
|
||||
5. **Temporary Tab**: A hidden tab is created temporarily for PDF conversion, then immediately closed
|
||||
|
||||
**No data leaves your machine except to your own DocuElevate server.**
|
||||
|
||||
## How to Verify Permissions
|
||||
|
||||
@@ -93,31 +112,35 @@ DocuElevate requests:
|
||||
|
||||
## Reducing Permissions Further
|
||||
|
||||
If you want even fewer permissions:
|
||||
If you want fewer permissions or don't need web clipping:
|
||||
|
||||
1. **Remove contextMenus**: Delete the `contextMenus` permission from `manifest.json`
|
||||
- Trade-off: Lose right-click menu option
|
||||
1. **Disable Web Clipping**: Use v1.0.0 instead of v1.1.0
|
||||
- No scripting permission
|
||||
- No host_permissions (<all_urls>)
|
||||
- Trade-off: Can only send URLs, not clip pages
|
||||
|
||||
2. **Remove contextMenus**: Delete the `contextMenus` permission from `manifest.json`
|
||||
- Trade-off: Lose right-click menu options
|
||||
- You'd only have the toolbar icon
|
||||
|
||||
2. **Remove notifications**: Delete the `notifications` permission
|
||||
3. **Remove notifications**: Delete the `notifications` permission
|
||||
- Trade-off: No success/error notifications
|
||||
- You'd only see status in the popup
|
||||
|
||||
3. **Remove content script**: Delete the `content_scripts` section
|
||||
- Trade-off: None (it's not actively used currently)
|
||||
- Reduces extension footprint slightly
|
||||
|
||||
## Privacy Statement
|
||||
|
||||
The DocuElevate browser extension:
|
||||
The DocuElevate browser extension (v1.1.0):
|
||||
|
||||
- ✅ Does NOT collect any personal data
|
||||
- ✅ Does NOT track your browsing history
|
||||
- ✅ Does NOT monitor web pages you visit
|
||||
- ✅ Does NOT send data to third parties
|
||||
- ✅ Does NOT modify web page content
|
||||
- ✅ Does NOT modify web page content (except when you explicitly clip)
|
||||
- ✅ Does NOT inject ads or tracking scripts
|
||||
- ✅ Only accesses page content when you explicitly click "Clip"
|
||||
- ✅ Only communicates with YOUR configured DocuElevate server
|
||||
- ✅ Stores configuration locally on your device only
|
||||
- ✅ Converts pages to PDF locally in your browser
|
||||
|
||||
## Questions?
|
||||
|
||||
@@ -126,7 +149,8 @@ If you have concerns about permissions or privacy, please:
|
||||
- Review the source code in the `browser-extension` folder
|
||||
- Open an issue on [GitHub](https://github.com/christianlouis/DocuElevate/issues)
|
||||
- Check the [Browser Extension Guide](../docs/BrowserExtension.md)
|
||||
- Use v1.0.0 if you don't need web clipping features
|
||||
|
||||
---
|
||||
|
||||
Last updated: 2024
|
||||
Last updated: 2024 (v1.1.0)
|
||||
|
||||
@@ -152,7 +152,9 @@ async function convertHtmlToPdf(html) {
|
||||
chrome.tabs.onUpdated.addListener(listener);
|
||||
});
|
||||
|
||||
// Give it a bit more time to render
|
||||
// Wait for page to fully render before PDF conversion
|
||||
// This delay ensures JavaScript execution, dynamic content rendering,
|
||||
// and CSS transitions have completed. May need adjustment for complex pages.
|
||||
await new Promise(resolve => setTimeout(resolve, 500));
|
||||
|
||||
// Use Chrome's print to PDF API
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
* @returns {Object} Page data with HTML, title, and URL
|
||||
*/
|
||||
function captureFullPage() {
|
||||
// Clone the document to avoid modifying the original
|
||||
const clonedDoc = document.cloneNode(true);
|
||||
|
||||
// Get all stylesheets and inline them
|
||||
const styles = Array.from(document.styleSheets)
|
||||
.map(sheet => {
|
||||
@@ -24,9 +21,6 @@ function captureFullPage() {
|
||||
})
|
||||
.join('\n');
|
||||
|
||||
// Get page HTML
|
||||
const html = document.documentElement.outerHTML;
|
||||
|
||||
// Create a complete HTML document with inlined styles
|
||||
const styledHtml = `
|
||||
<!DOCTYPE html>
|
||||
@@ -65,28 +59,6 @@ function captureSelection() {
|
||||
const container = document.createElement('div');
|
||||
container.appendChild(range.cloneContents());
|
||||
|
||||
// Get computed styles for the selection
|
||||
const styles = [];
|
||||
const elements = container.querySelectorAll('*');
|
||||
elements.forEach(el => {
|
||||
const computed = window.getComputedStyle(el);
|
||||
// Only preserve essential styles
|
||||
const essentialStyles = [
|
||||
'font-family', 'font-size', 'font-weight', 'color',
|
||||
'background-color', 'text-align', 'margin', 'padding'
|
||||
];
|
||||
let styleStr = '';
|
||||
essentialStyles.forEach(prop => {
|
||||
const value = computed.getPropertyValue(prop);
|
||||
if (value) {
|
||||
styleStr += `${prop}: ${value}; `;
|
||||
}
|
||||
});
|
||||
if (styleStr) {
|
||||
el.setAttribute('style', styleStr);
|
||||
}
|
||||
});
|
||||
|
||||
const html = `
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@@ -121,51 +93,7 @@ function captureSelection() {
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Take a screenshot of the visible viewport
|
||||
* @returns {Promise<string>} Data URL of the screenshot
|
||||
*/
|
||||
async function captureScreenshot() {
|
||||
// This will be called from the background script
|
||||
// since content scripts can't use chrome.tabs.captureVisibleTab
|
||||
return new Promise((resolve, reject) => {
|
||||
chrome.runtime.sendMessage(
|
||||
{ type: 'CAPTURE_SCREENSHOT' },
|
||||
response => {
|
||||
if (response.success) {
|
||||
resolve(response.dataUrl);
|
||||
} else {
|
||||
reject(new Error(response.error));
|
||||
}
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
// Listen for capture requests from popup or background
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.type === 'CAPTURE_FULL_PAGE') {
|
||||
try {
|
||||
const pageData = captureFullPage();
|
||||
sendResponse({ success: true, data: pageData });
|
||||
} catch (error) {
|
||||
sendResponse({ success: false, error: error.message });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (message.type === 'CAPTURE_SELECTION') {
|
||||
try {
|
||||
const selectionData = captureSelection();
|
||||
sendResponse({ success: true, data: selectionData });
|
||||
} catch (error) {
|
||||
sendResponse({ success: false, error: error.message });
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
// Export functions for use in tests or other scripts
|
||||
// Export functions for use in other scripts
|
||||
if (typeof module !== 'undefined' && module.exports) {
|
||||
module.exports = {
|
||||
captureFullPage,
|
||||
|
||||
@@ -113,12 +113,13 @@ function captureSelection() {
|
||||
// Message handler
|
||||
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
if (message.type === 'GET_PAGE_INFO') {
|
||||
// Return information about the current page
|
||||
// Return information about the current page (synchronous)
|
||||
const pageInfo = {
|
||||
url: window.location.href,
|
||||
title: document.title
|
||||
};
|
||||
sendResponse(pageInfo);
|
||||
return false; // Synchronous response, no need to keep channel open
|
||||
}
|
||||
|
||||
if (message.type === 'CAPTURE_FULL_PAGE') {
|
||||
@@ -128,7 +129,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
} catch (error) {
|
||||
sendResponse({ success: false, error: error.message });
|
||||
}
|
||||
return true;
|
||||
return true; // Keep channel open for async response
|
||||
}
|
||||
|
||||
if (message.type === 'CAPTURE_SELECTION') {
|
||||
@@ -138,7 +139,7 @@ chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||
} catch (error) {
|
||||
sendResponse({ success: false, error: error.message });
|
||||
}
|
||||
return true;
|
||||
return true; // Keep channel open for async response
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
+90
-23
@@ -3,7 +3,7 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Browser Extension Test Page</title>
|
||||
<title>Browser Extension Test Page - Web Clipping</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
@@ -48,23 +48,37 @@
|
||||
border-radius: 3px;
|
||||
font-family: 'Courier New', monospace;
|
||||
}
|
||||
.selectable-content {
|
||||
background: #e7f3ff;
|
||||
border: 2px dashed #0066cc;
|
||||
padding: 20px;
|
||||
margin: 15px 0;
|
||||
border-radius: 8px;
|
||||
}
|
||||
.highlight {
|
||||
background-color: #ffeb3b;
|
||||
padding: 2px 5px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>🧪 DocuElevate Browser Extension Test Page</h1>
|
||||
|
||||
<div class="instructions">
|
||||
<h2>How to Test</h2>
|
||||
<h2>How to Test (v1.1.0 - Web Clipping)</h2>
|
||||
<ol>
|
||||
<li>Make sure the DocuElevate browser extension is installed and configured</li>
|
||||
<li>Test Method 1: Click the extension icon and send the current page URL</li>
|
||||
<li>Test Method 2: Right-click on any link below and select "Send to DocuElevate"</li>
|
||||
<li>Test Method 3: Navigate to a link below and then use the extension popup</li>
|
||||
<li><strong>URL Mode:</strong> Click extension icon, select "Send URL" mode, click "Send to DocuElevate"</li>
|
||||
<li><strong>Clip Full Page:</strong> Click extension icon, select "Clip Page" mode, click "Clip Full Page"</li>
|
||||
<li><strong>Clip Selection:</strong> Select text below, click extension icon, click "Clip Selection"</li>
|
||||
<li><strong>Context Menu - URL:</strong> Right-click page and select "Send URL to DocuElevate"</li>
|
||||
<li><strong>Context Menu - Full:</strong> Right-click page and select "Clip Full Page to DocuElevate"</li>
|
||||
<li><strong>Context Menu - Selection:</strong> Select text, right-click, select "Clip Selection to DocuElevate"</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<div class="test-section">
|
||||
<h2>📄 Sample Document Links</h2>
|
||||
<h2>📄 Sample Document Links (URL Mode)</h2>
|
||||
<p>These links point to sample documents that can be processed by DocuElevate:</p>
|
||||
|
||||
<a href="https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf"
|
||||
@@ -84,7 +98,7 @@
|
||||
</div>
|
||||
|
||||
<div class="test-section">
|
||||
<h2>🖼️ Sample Image Links</h2>
|
||||
<h2>🖼️ Sample Image Links (URL Mode)</h2>
|
||||
<p>These links point to sample images that can be processed:</p>
|
||||
|
||||
<a href="https://via.placeholder.com/800x600.png"
|
||||
@@ -99,27 +113,78 @@
|
||||
</div>
|
||||
|
||||
<div class="test-section">
|
||||
<h2>✅ Expected Behavior</h2>
|
||||
<h2>📝 Selectable Content for Clip Testing</h2>
|
||||
<p>Use this content to test the selection clipping feature:</p>
|
||||
|
||||
<div class="selectable-content">
|
||||
<h3>Important Document</h3>
|
||||
<p>This is a <span class="highlight">sample paragraph</span> that you can select and clip to DocuElevate.
|
||||
Select this text with your mouse, then right-click and choose "Clip Selection to DocuElevate" from the context menu.</p>
|
||||
|
||||
<p><strong>Key Points:</strong></p>
|
||||
<ul>
|
||||
<li><strong>Extension Popup:</strong> Should show the current page URL and allow sending it</li>
|
||||
<li><strong>Context Menu:</strong> Right-click should show "Send to DocuElevate" option</li>
|
||||
<li><strong>Success Notification:</strong> Browser notification with task ID should appear</li>
|
||||
<li><strong>Error Handling:</strong> Clear error messages if something goes wrong</li>
|
||||
<li>Web clipping allows you to save any web content as PDF</li>
|
||||
<li>You can clip full pages or just selected portions</li>
|
||||
<li>Pages are converted to PDF in your browser before upload</li>
|
||||
<li>All styling and formatting is preserved</li>
|
||||
</ul>
|
||||
|
||||
<p>This content will be captured with its styling and converted to a PDF document that's sent to DocuElevate for processing!</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="test-section">
|
||||
<h2>✅ Expected Behavior (v1.1.0)</h2>
|
||||
<h3>URL Mode:</h3>
|
||||
<ul>
|
||||
<li><strong>Extension Popup:</strong> Shows "Send URL" mode with current page URL</li>
|
||||
<li><strong>Context Menu:</strong> "Send URL to DocuElevate" option appears</li>
|
||||
<li><strong>Success:</strong> Notification with task ID appears</li>
|
||||
</ul>
|
||||
|
||||
<h3>Clip Mode:</h3>
|
||||
<ul>
|
||||
<li><strong>Extension Popup:</strong> Shows "Clip Page" mode with two buttons</li>
|
||||
<li><strong>Full Page:</strong> Captures entire page as PDF and uploads</li>
|
||||
<li><strong>Selection:</strong> Captures only selected content as PDF</li>
|
||||
<li><strong>Context Menu:</strong> "Clip Full Page" and "Clip Selection" options</li>
|
||||
<li><strong>Success:</strong> Notification confirms clip was uploaded</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="test-section">
|
||||
<h2>🔍 Testing Checklist</h2>
|
||||
<h2>🔍 Testing Checklist (v1.1.0)</h2>
|
||||
<h3>Installation & Configuration:</h3>
|
||||
<ul>
|
||||
<li>✓ Extension icon appears in browser toolbar</li>
|
||||
<li>✓ Popup opens when clicking extension icon</li>
|
||||
<li>✓ Configuration can be saved (server URL)</li>
|
||||
<li>✓ Current URL is displayed in popup</li>
|
||||
<li>✓ "Send to DocuElevate" appears in context menu</li>
|
||||
<li>✓ Files are successfully sent to DocuElevate</li>
|
||||
<li>✓ Success notification appears</li>
|
||||
<li>✓ Task ID is displayed in notification</li>
|
||||
<li>✓ Error messages are clear and helpful</li>
|
||||
<li>☐ Extension icon appears in browser toolbar</li>
|
||||
<li>☐ Popup opens when clicking extension icon</li>
|
||||
<li>☐ Configuration can be saved (server URL)</li>
|
||||
<li>☐ Mode toggle buttons work (URL/Clip)</li>
|
||||
</ul>
|
||||
|
||||
<h3>URL Mode:</h3>
|
||||
<ul>
|
||||
<li>☐ Current URL is displayed in popup</li>
|
||||
<li>☐ "Send to DocuElevate" button works</li>
|
||||
<li>☐ Context menu "Send URL to DocuElevate" works</li>
|
||||
<li>☐ Success notification appears with task ID</li>
|
||||
</ul>
|
||||
|
||||
<h3>Clip Mode:</h3>
|
||||
<ul>
|
||||
<li>☐ "Clip Full Page" button works</li>
|
||||
<li>☐ "Clip Selection" button works (after selecting text)</li>
|
||||
<li>☐ Context menu "Clip Full Page to DocuElevate" works</li>
|
||||
<li>☐ Context menu "Clip Selection to DocuElevate" works</li>
|
||||
<li>☐ PDF is generated correctly with styles</li>
|
||||
<li>☐ Upload succeeds and task ID is shown</li>
|
||||
</ul>
|
||||
|
||||
<h3>Error Handling:</h3>
|
||||
<ul>
|
||||
<li>☐ Clear error message if server unreachable</li>
|
||||
<li>☐ Error message if no text selected (Clip Selection)</li>
|
||||
<li>☐ Authentication errors handled properly</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
@@ -132,11 +197,13 @@
|
||||
<li>Open DevTools (F12) and check the Console for errors</li>
|
||||
<li>Make sure your DocuElevate server is running and accessible</li>
|
||||
<li>If using authentication, verify your session cookie is valid</li>
|
||||
<li>For clipping: Ensure browser supports <code>chrome.tabs.printToPDF</code> API</li>
|
||||
<li>Check that <code>/api/files/upload</code> endpoint is accessible</li>
|
||||
</ol>
|
||||
</div>
|
||||
|
||||
<footer style="margin-top: 50px; padding-top: 20px; border-top: 2px solid #dee2e6; color: #6c757d;">
|
||||
<p>DocuElevate Browser Extension Test Page</p>
|
||||
<p>DocuElevate Browser Extension Test Page (v1.1.0)</p>
|
||||
<p>For more information, see the <a href="../README.md">Browser Extension README</a></p>
|
||||
</footer>
|
||||
</body>
|
||||
|
||||
Reference in New Issue
Block a user