nixos/tests/test-firefox-config.sh
Julian Sutter 449510c746 Reorganize Firefox configuration and repository documentation
- Configure Firefox with privacy settings and extensions (Bitwarden, Plasma Integration, MetaMask, Kagi Search, uBlock Origin)
- Set Kagi as default/only search engine
- Add MOZ_USE_XINPUT2=1 for smooth scrolling
- Create context/ directory for concise unit documentation
- Create tests/ directory for test scripts
- Move test-firefox-config.sh to tests/
- Update agents.md with documentation workflow guidelines
- Fix syntax errors in desktop.nix and dev.nix
2026-02-16 23:08:48 -08:00

477 lines
14 KiB
Bash
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# Firefox Configuration Test Script
# Tests the Firefox Home Manager configuration for user jsutter
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Test counters
PASSED=0
FAILED=0
SKIPPED=0
TOTAL=0
# Helper functions
print_header() {
echo ""
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
echo -e "${BLUE} $1${NC}"
echo -e "${BLUE}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
}
print_test() {
echo -e "\n${YELLOW}[TEST]${NC} $1"
((TOTAL++))
}
print_pass() {
echo -e "${GREEN} ✓ PASS${NC}: $1"
((PASSED++))
}
print_fail() {
echo -e "${RED} ✗ FAIL${NC}: $1"
((FAILED++))
}
print_skip() {
echo -e "${YELLOW} ⊘ SKIP${NC}: $1"
((SKIPPED++))
}
print_info() {
echo -e " ${NC}$1"
}
print_report() {
local description="$1"
local pass_count="$2"
local fail_count="$3"
if [[ $fail_count -eq 0 ]]; then
print_pass "$description (passed $pass_count/$pass_count)"
else
local total=$((pass_count + fail_count))
print_fail "$description (passed $pass_count/$total)"
fi
}
# Check if a command exists
command_exists() {
command -v "$1" &> /dev/null
}
# Check if a preference matches expected value
check_pref() {
local profile="$1"
local pref="$2"
local expected="$3"
local actual=$(grep "\"${pref}\"" "$profile/prefs.js" 2>/dev/null | head -1 | sed 's/.*user_pref[^,]*,\s*//;s/);.*$//' 2>/dev/null || echo "")
if [[ "$actual" == *"$expected"* ]]; then
print_pass "$pref = $expected"
return 0
else
print_fail "$pref = $expected (got: $actual)"
return 1
fi
}
# Get Firefox profile directory
get_firefox_profile() {
local firefox_dir="$HOME/.mozilla/firefox"
if [[ -d "$firefox_dir" ]]; then
local profile=$(grep -E "Default=1" "$firefox_dir/profiles.ini" 2>/dev/null | head -1 | cut -d= -f2 -s)
if [[ -n "$profile" ]] && [[ -d "$firefox_dir/$profile" ]]; then
echo "$firefox_dir/$profile"
return 0
fi
# Try to find jsutter profile
profile=$(find "$firefox_dir" -maxdepth 1 -type d -name "*jsutter*" 2>/dev/null | head -1)
if [[ -n "$profile" ]]; then
echo "$profile"
return 0
fi
# Get first available profile
profile=$(ls -1 "$firefox_dir"/*.default* 2>/dev/null | head -1)
if [[ -n "$profile" ]]; then
echo "$profile"
return 0
fi
fi
echo ""
return 1
}
# Get Firefox executable
get_firefox_exec() {
if command_exists firefox-esr &>/dev/null; then
echo firefox-esr
elif command_exists firefox &>/dev/null; then
echo firefox
elif [[ -f "/run/current-system/sw/bin/firefox" ]]; then
echo /run/current-system/sw/bin/firefox
else
echo ""
fi
}
print_header "Firefox Configuration Test Script"
echo "Testing configuration for user: $(whoami)"
echo "Date: $(date '+%Y-%m-%d %H:%M:%S')"
# ============================================
# Environment Variables
# ============================================
print_header "1. Environment Variables"
print_test "Check MOZ_USE_XINPUT2 environment variable"
if [[ -z "$MOZ_USE_XINPUT2" ]]; then
print_fail "MOZ_USE_XINPUT2 not set"
print_info "This should be set in Home Manager sessionVariables"
else
if [[ "$MOZ_USE_XINPUT2" == "1" ]]; then
print_pass "MOZ_USE_XINPUT2 = 1"
else
print_fail "MOZ_USE_XINPUT2 = $MOZ_USE_XINPUT2 (expected: 1)"
fi
fi
print_test "Check session variables in shell config"
if [[ -f "$HOME/.zshrc" ]] || [[ -f "$HOME/.bashrc" ]]; then
print_info "Shell config files found"
else
print_skip "No shell config file found"
fi
# ============================================
# Firefox Installation
# ============================================
print_header "2. Firefox Installation"
FIREFOX=$(get_firefox_exec)
if [[ -n "$FIREFOX" ]]; then
print_test "Firefox executable found"
print_pass "Firefox at: $FIREFOX"
print_test "Firefox version"
VERSION=$($FIREFOX --version 2>/dev/null || echo "unknown")
print_pass "Firefox version: $VERSION"
else
print_fail "Firefox executable not found"
print_info "Check if Firefox is installed via nixos-rebuild switch"
fi
# ============================================
# Policy Configuration
# ============================================
print_header "3. Enterprise Policies"
POLICY_FILE="/run/current-system/sw/lib/firefox/distribution/policies.json"
print_test "Check policy file exists"
if [[ -f "$POLICY_FILE" ]]; then
print_pass "Policy file found: $POLICY_FILE"
else
print_fail "Policy file not found"
print_info "Activate the configuration with: nixos-rebuild switch"
fi
if [[ -f "$POLICY_FILE" ]]; then
print_test "Check policy file is valid JSON"
if jq empty "$POLICY_FILE" 2>/dev/null; then
print_pass "Policy file is valid JSON"
else
print_fail "Policy file is not valid JSON"
fi
print_test "Check extension policies"
EXTENSIONS=$(jq -r '.policies.ExtensionSettings | keys[]' "$POLICY_FILE" 2>/dev/null || echo "")
EXPECTED_EXTENSIONS=(
"uBlock0@raymondhill.net"
"{446900e4-71c2-419f-a6a7-df9c2b2dc922}"
"plasma-browser-integration@kde.org"
"webextension@metamask.io"
"kagi-search@kagi.com"
)
all_found=true
for ext in "${EXPECTED_EXTENSIONS[@]}"; do
if echo "$EXTENSIONS" | grep -q "$ext"; then
print_info "Extension policy found: $ext"
else
print_fail "Extension policy missing: $ext"
all_found=false
fi
done
if $all_found; then
print_pass "All extension policies configured"
fi
print_test "Check privacy settings policies"
PRIVACY_OK=true
if jq -e '.policies.OfferToSaveLogins == false' "$POLICY_FILE" &>/dev/null; then
print_info "Password saving disabled"
else
print_fail "Password saving not disabled"
PRIVACY_OK=false
fi
if jq -e '.policies.PasswordManagerEnabled == false' "$POLICY_FILE" &>/dev/null; then
print_info "Password manager disabled"
else
print_fail "Password manager not disabled"
PRIVACY_OK=false
fi
if jq -e '.policies.DisableTelemetry == true' "$POLICY_FILE" &>/dev/null; then
print_info "Telemetry disabled"
else
print_fail "Telemetry not disabled"
PRIVACY_OK=false
fi
if jq -e '.policies.DisableFirefoxStudies == true' "$POLICY_FILE" &>/dev/null; then
print_info "Firefox Studies disabled"
else
print_fail "Firefox Studies not disabled"
PRIVACY_OK=false
fi
if $PRIVACY_OK; then
print_pass "Privacy settings policies configured correctly"
fi
print_test "Check homepage/new tab policies"
HOME_OK=true
if jq -e '.policies.FirefoxHome.Search == false' "$POLICY_FILE" &>/dev/null; then
print_info "Search on home page disabled"
else
print_fail "Search on home page not disabled"
HOME_OK=false
fi
if jq -e '.policies.FirefoxHome.TopSites == false' "$POLICY_FILE" &>/dev/null; then
print_info "Top Sites disabled"
else
print_fail "Top Sites not disabled"
HOME_OK=false
fi
if jq -e '.policies.FirefoxHome.Pocket == false' "$POLICY_FILE" &>/dev/null; then
print_info "Pocket disabled"
else
print_fail "Pocket not disabled"
HOME_OK=false
fi
if $HOME_OK; then
print_pass "Homepage/new tab policies configured correctly"
fi
fi
# ============================================
# User Profile Configuration
# ============================================
print_header "4. Profile Configuration"
PROFILE=$(get_firefox_profile)
if [[ -n "$PROFILE" ]]; then
print_test "Firefox profile directory found"
print_pass "Profile: $PROFILE"
# Check for user.js
USER_JS="$PROFILE/user.js"
if [[ -f "$USER_JS" ]]; then
print_test "user.js file exists"
print_pass "user.js: $USER_JS"
# Check key settings
print_test "Check key user.js preferences"
cat > /tmp/firefox_check.sh << 'EOF'
#!/bin/bash
PROFILE="$1"
check_pref() {
local pref="$1"
local expected="$2"
local actual=$(grep "\"${pref}\"" "$PROFILE/user.js" 2>/dev/null | head -1 | sed 's/.*user_pref[^,]*,\s*//;s/);.*$//' 2>/dev/null || echo "")
if [[ "$actual" == *"$expected"* ]]; then
echo "PASS: $pref"
return 0
else
echo "FAIL: $pref (got: $actual)"
return 1
fi
}
check_pref "browser.ctrlTab.recentlyUsedOrder" "true"
check_pref "browser.tabs.hoverPreview.enabled" "false"
check_pref "browser.link.preview.enabled" "false"
check_pref "browser.newtabpage.enabled" "false"
check_pref "browser.startup.homepage" "about:blank"
check_pref "browser.search.suggest.enabled" "false"
check_pref "signon.rememberSignons" "false"
check_pref "media.videocontrols.picture-in-picture.allow-multiple" "false"
check_pref "browser.contentblocking.category" "strict"
check_pref "extensions.pocket.enabled" "false"
check_pref "privacy.sanitize.sanitizeOnShutdown" "true"
check_pref "toolkit.legacyUserProfileCustomizations.stylesheets" "true"
check_pref "privacy.userContext.enabled" "true"
EOF
chmod +x /tmp/firefox_check.sh
output=$(/tmp/firefox_check.sh "$PROFILE")
pass_count=$(echo "$output" | grep -c "PASS" || true)
fail_count=$(echo "$output" | grep -c "FAIL" || true)
echo "$output" | while read line; do
if [[ "$line" == "PASS:"* ]]; then
print_pass "${line#PASS: }"
else
print_fail "${line#FAIL: }"
fi
done
print_report "user.js key settings" "$pass_count" "$fail_count"
else
print_fail "user.js not found (Firefox needs to be run once to generate)"
fi
# Check for extensions
print_test "Check installed extensions"
INSTALLED_EXTENSIONS=$(ls -1 "$PROFILE/extensions" 2>/dev/null || echo "")
if [[ -n "$INSTALLED_EXTENSIONS" ]]; then
print_info "Found $(echo "$INSTALLED_EXTENSIONS" | wc -l) extension(s):"
echo "$INSTALLED_EXTENSIONS" | while read ext; do
print_info " - $ext"
done
print_pass "Extensions directory exists"
else
print_skip "No extensions installed yet (start Firefox to install via policy)"
fi
else
print_fail "Firefox profile not found"
print_info "Start Firefox once to create a profile"
print_info "Profile location is typically: ~/.mozilla/firefox/*.default*"
fi
# ============================================
# Manual Verification Checklist
# ============================================
print_header "5. Manual Verification Checklist"
cat << 'MANUAL'
The following items require manual verification in Firefox:
[ ] 1. Open Firefox and check all 4 extensions are installed:
- uBlock Origin
- Privacy Badger
- Facebook Container
- Multi-account Containers
[ ] 2. Open about:preferences#privacy and verify:
- Content blocking is set to "Strict"
- "Clear history when Firefox closes" is checked
- "Remember passwords" is unchecked
- "Autoplay" is set to "Block audio and video"
[ ] 3. Open about:policies and verify:
- All policies are "Active"
- Extensions are listed as "Force Installed"
[ ] 4. Test tab behavior:
- Press Ctrl+Tab and verify it cycles through recent tabs
- Hover over a tab and verify no image preview appears
[ ] 5. Test new tab/homepage:
- Open a new tab (Ctrl+T) - should be blank
- Open a new window (Ctrl+N) - should be blank
- No search bar, shortcuts, or widgets should appear
[ ] 6. Test search:
- Type in the address bar and verify no suggestions appear
- Search results should come from Kagi
- No other search engines should be available
- Sign in to Kagi account via Kagi extension for full features
[ ] 7. Test smooth scrolling:
- Scroll on a long page - should feel smooth and responsive
[ ] 8. Test permissions:
- Visit a site that requests location - should auto-block
- Visit a site that requests notifications - should auto-block
- Play a video with audio - should auto-block
MANUAL
print_info "Manual verification above requires user interaction"
# ============================================
# Troubleshooting Information
# ============================================
print_header "6. Troubleshooting Information"
echo "Useful Firefox URLs:"
print_info "about:policies - View active policies"
print_info "about:preferences - Firefox settings"
print_info "about:config - Advanced preferences"
print_info "about:support - Troubleshooting information"
print_info "about:addons - View/manage extensions"
print_info "about:preferences#privacy - Privacy settings"
echo ""
print_info "Configuration files:"
print_info " Policies: $POLICY_FILE"
print_info " Profile: $PROFILE"
print_info " user.js: $USER_JS"
if [[ -n "$PROFILE" ]]; then
print_info " search.json.mozlz4: $PROFILE/search.json.mozlz4"
fi
echo ""
print_info "To rebuild the configuration:"
print_info " nixos-rebuild switch"
echo ""
print_info "To restart Firefox:"
print_info " pkill firefox"
# ============================================
# Summary
# ============================================
print_header "Test Summary"
echo "Total tests: $TOTAL"
echo -e "${GREEN}Passed: $PASSED${NC}"
echo -e "${RED}Failed: $FAILED${NC}"
echo -e "${YELLOW}Skipped: $SKIPPED${NC}"
if [[ $FAILED -eq 0 ]]; then
echo ""
echo -e "${GREEN}✓ All automated tests passed!${NC}"
echo ""
echo "Please run Firefox once to install extensions via policy,"
echo "then complete the manual verification checklist above."
echo ""
echo "Note: Kagi search is the default and only search engine."
echo " Sign in to your Kagi account via the Kagi extension."
exit 0
else
echo ""
echo -e "${RED}✗ Some tests failed. Review the output above for details.${NC}"
exit 1
fi