Skip to content

refactor(prefs): single-source-of-truth Firefox prefs dict + obsolescence verifier in update.py#1201

Draft
vringar wants to merge 1 commit into
fix/obsolete-firefox-prefsfrom
feat/firefox-prefs-dict
Draft

refactor(prefs): single-source-of-truth Firefox prefs dict + obsolescence verifier in update.py#1201
vringar wants to merge 1 commit into
fix/obsolete-firefox-prefsfrom
feat/firefox-prefs-dict

Conversation

@vringar

@vringar vringar commented Jun 20, 2026

Copy link
Copy Markdown
Contributor

Summary

Makes OpenWPM's default Firefox preferences a single source-of-truth that both
the setter (configure_firefox.py) and the obsolescence verifier read,
so the two are structurally interlocked and cannot drift. Wires the verifier
into scripts/update.py so every dependency/Firefox update auto-checks the
prefs we set for obsolescence.

Stacks on #1140 (fix/obsolete-firefox-prefs). This refactors the
already-cleaned pref set from that PR; merge #1140 first. The diff shown
against master will look larger until #1140 lands.

What changed

1. Prefs consolidated into dicts (single source of truth)

openwpm/deploy_browsers/configure_firefox.py now defines two module-level
dicts:

  • OPTIMIZE_PREFS: dict[str, bool | int | str] — the 54 static
    speed/telemetry/safebrowsing/update prefs, with the original comment grouping
    preserved. optimize_prefs() is now for name, value in OPTIMIZE_PREFS.items(): fo.set_preference(name, value).
  • PRIVACY_PREFS: dict[str, bool | int | str] — the privacy pref names
    (privacy.donottrackheader.enabled, network.cookie.cookieBehavior). These
    prefs' values are dynamic (computed from browser_params), so privacy()
    still sets them inline/conditionally; only the names live in the dict so the
    verifier can probe them.

Behavior is identical — same prefs, same values, same ordering (privacy
then optimize), and browser_params.prefs still override last. Verified by
mock-capturing the new optimize_prefs() output and diffing it against the
pre-refactor source: 54/54 optimize prefs match on name+value, privacy
set_preference calls byte-identical, and PRIVACY_PREFS covers exactly the
privacy pref names.

2. Verifier moved + interlocked

datadir/verify_obsolete_prefs.pyscripts/verify_obsolete_prefs.py. It
now imports PRIVACY_PREFS and OPTIMIZE_PREFS and probes their
.keys() — no hardcoded/copied pref list. It keeps the Firefox
default-branch probe (getDefaultBranch('').getPrefType) and the honest
caveat: a default-branch absence is a strong-but-not-absolute signal, so
INVALID prefs are reported as review candidates, not auto-removed. Takes
FIREFOX_BINARY from the environment.

3. Wired into scripts/update.py

After the Firefox bump step (firefox_version.update_if_needed()),
check_obsolete_firefox_prefs() runs scripts/verify_obsolete_prefs.py
against the installed Firefox (firefox-bin/firefox-bin, or $FIREFOX_BINARY)
and prints a clear WARNING block listing any pref that now probes obsolete.
Fully non-fatal: a missing binary, a launch failure, or obsolete prefs only
warn — the update is never blocked.

Verification

  • from openwpm.deploy_browsers.configure_firefox import PRIVACY_PREFS, OPTIMIZE_PREFS2 54
  • import openwpm.deploy_browsers.deploy_firefox imports cleanly
  • scripts/verify_obsolete_prefs.py imports and builds a 56-pref list (privacy-first, no dupes)
  • Applied pref-set proven unchanged vs. the pre-refactor source (see above)
  • update.py skip path exercised (non-fatal when no binary present)
  • pre-commit (black / isort / mypy) green

A full crawl was not run (browser env-blocked); the static "same prefs" proof
is the key check.

…erifier; run it in update.py

Consolidate OpenWPM's static Firefox default prefs into module-level
PRIVACY_PREFS / OPTIMIZE_PREFS dicts in configure_firefox.py, the single
source of truth. optimize_prefs() now iterates OPTIMIZE_PREFS; privacy()
keeps its dynamic (browser_params-dependent) values inline but its pref
names are tracked in PRIVACY_PREFS.

Move datadir/verify_obsolete_prefs.py -> scripts/verify_obsolete_prefs.py
and refactor it to import those same dicts (no hardcoded pref list) so the
setter and the obsolescence verifier are structurally interlocked and
cannot drift.

Wire the verifier into scripts/update.py: after the Firefox bump it probes
the installed Firefox for any pref OpenWPM sets that is no longer recognized
and prints a non-fatal WARNING block.
@codecov

codecov Bot commented Jun 20, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 61.40%. Comparing base (1986eb2) to head (1b73290).

Additional details and impacted files
@@                      Coverage Diff                       @@
##           fix/obsolete-firefox-prefs    #1201      +/-   ##
==============================================================
- Coverage                       61.87%   61.40%   -0.48%     
==============================================================
  Files                              40       40              
  Lines                            3892     3842      -50     
==============================================================
- Hits                             2408     2359      -49     
+ Misses                           1484     1483       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant