(explicit: str | None)
| 118 | |
| 119 | |
| 120 | def _locate_firefox_profile(explicit: str | None) -> Path: |
| 121 | if explicit and explicit != "auto": |
| 122 | path = Path(explicit).expanduser() |
| 123 | if path.is_file(): |
| 124 | return path |
| 125 | if path.is_dir(): |
| 126 | candidate = path / "cookies.sqlite" |
| 127 | if candidate.is_file(): |
| 128 | return candidate |
| 129 | raise RuntimeError(f"Firefox cookies.sqlite not found at {path}") |
| 130 | # Auto-detect macOS Firefox profile. |
| 131 | base = Path.home() / "Library" / "Application Support" / "Firefox" / "Profiles" |
| 132 | if not base.exists(): |
| 133 | # Linux / other-OS fallbacks. |
| 134 | for guess in (Path.home() / ".mozilla" / "firefox", Path.home() / "snap" / "firefox" / "common" / ".mozilla" / "firefox"): |
| 135 | if guess.exists(): |
| 136 | base = guess |
| 137 | break |
| 138 | if not base.exists(): |
| 139 | raise RuntimeError("Could not locate a Firefox profiles directory.") |
| 140 | candidates = sorted(glob.glob(str(base / "*default*" / "cookies.sqlite"))) or sorted( |
| 141 | glob.glob(str(base / "*" / "cookies.sqlite")) |
| 142 | ) |
| 143 | if not candidates: |
| 144 | raise RuntimeError(f"No cookies.sqlite found under {base}") |
| 145 | # Prefer the most recently modified profile. |
| 146 | return Path(max(candidates, key=lambda p: Path(p).stat().st_mtime)) |
| 147 | |
| 148 | |
| 149 | def _firefox_storage_state(cookies_db: Path, host_glob: str) -> dict: |
no test coverage detected