diff --git a/background.ts b/background.ts
index 4027e55..0aca108 100644
--- a/background.ts
+++ b/background.ts
@@ -5,12 +5,18 @@ declare const browser: any;
init();
-// Set storage marker for test verification (non-invasive, only for automated tests)
-if (typeof browser !== 'undefined' && browser.storage) {
- browser.storage.local.set({
- '_rentgen_init_timestamp': Date.now(),
- '_rentgen_init_iso': new Date().toISOString()
+// Create test marker tab for verification (non-invasive, only for automated tests)
+// This creates an observable side effect: a tab with specific title that test can verify
+if (typeof browser !== 'undefined' && browser.tabs) {
+ browser.tabs.create({
+ url: 'data:text/html,
RENTGEN_INITIALIZED_' + Date.now() + '',
+ active: false
+ }).then((tab: any) => {
+ // Close the tab after 1 second (cleanup)
+ setTimeout(() => {
+ browser.tabs.remove(tab.id).catch(() => {});
+ }, 1000);
}).catch(() => {
- // Silently fail if storage API not available
+ // Silently fail if tabs API not available
});
}
diff --git a/scripts/test_verify.py b/scripts/test_verify.py
index 308213e..6219e29 100755
--- a/scripts/test_verify.py
+++ b/scripts/test_verify.py
@@ -118,41 +118,44 @@ def check_javascript_errors(log_path: Path) -> list[str]:
return errors
-def check_extension_storage() -> tuple[bool, str]:
- """Check if extension wrote initialization marker to browser.storage.
+def check_extension_via_rdp(port: str) -> tuple[bool, str]:
+ """Check if extension created marker tab via Firefox Remote Debugging Protocol.
Returns (success, message)."""
try:
- # Query Firefox profile for extension storage
- # Extension storage is in: /browser-extension-data//storage.js
- import glob
import json
+ import urllib.request
+ import urllib.error
- # Find Firefox profile created by web-ext (pattern: /tmp/firefox-profile*)
- profiles = glob.glob("/tmp/firefox-profile*")
- if not profiles:
- return False, "No Firefox profile found"
+ # Query Firefox Remote Debugging Protocol for list of tabs
+ url = f"http://127.0.0.1:{port}/json/list"
- profile = profiles[0]
- storage_pattern = f"{profile}/browser-extension-data/*/storage.js"
- storage_files = glob.glob(storage_pattern)
+ try:
+ with urllib.request.urlopen(url, timeout=5) as response:
+ tabs = json.loads(response.read().decode())
+ except (urllib.error.URLError, urllib.error.HTTPError) as e:
+ return False, f"Failed to connect to Remote Debugging Protocol: {e}"
- if not storage_files:
- return False, "No storage.js file found in profile"
+ # Look for tab with title starting with RENTGEN_INITIALIZED_
+ for tab in tabs:
+ title = tab.get('title', '')
+ if title.startswith('RENTGEN_INITIALIZED_'):
+ timestamp = title.replace('RENTGEN_INITIALIZED_', '')
+ return True, f"Extension created marker tab at timestamp {timestamp}"
- # Read storage file
- with open(storage_files[0], 'r') as f:
- storage_data = json.load(f)
-
- # Check for our marker keys
- if '_rentgen_init_timestamp' in storage_data and '_rentgen_init_iso' in storage_data:
- timestamp = storage_data['_rentgen_init_timestamp']
- iso = storage_data['_rentgen_init_iso']
- return True, f"Extension initialized at {iso} (timestamp: {timestamp})"
-
- return False, "Storage marker not found"
+ return False, "No marker tab found (extension may not have executed)"
except Exception as e:
- return False, f"Storage check failed: {e}"
+ return False, f"RDP check failed: {e}"
+
+
+def extract_debugger_port(log_path: Path) -> str | None:
+ """Extract debugger port from web-ext logs."""
+ content = log_path.read_text()
+ import re
+ match = re.search(r"start-debugger-server (\d+)", content)
+ if match:
+ return match.group(1)
+ return None
def cleanup(xvfb_pid: int, webext_pid: int) -> None:
@@ -206,10 +209,24 @@ def main() -> int:
print_success("NO JavaScript errors in background.js")
- # Functional test: Verify extension code execution
+ # Functional test: Verify extension code execution via Remote Debugging Protocol
print_header("Functional test: Verifying extension code execution...")
- execution_verified, message = check_extension_storage()
+ # Extract debugger port
+ port = extract_debugger_port(log_path)
+ if not port:
+ print_error("Could not find debugger port in logs")
+ print_error("Cannot connect to Firefox Remote Debugging Protocol")
+ cleanup(xvfb_pid, webext_pid)
+ return 1
+
+ print_success(f"Firefox debugger port: {port}")
+
+ # Give extension a moment to create the marker tab
+ time.sleep(2)
+
+ # Check via Remote Debugging Protocol
+ execution_verified, message = check_extension_via_rdp(port)
# Guard: Check if we found proof of execution
if not execution_verified:
@@ -225,7 +242,7 @@ def main() -> int:
print()
print("This proves:")
print(" - background.ts executed")
- print(" - browser.storage.local.set() succeeded")
+ print(" - browser.tabs.create() succeeded")
print(" - Extension has working browser API access")
# Show process info