Branch was cut from pre-#901 main, so its avito.py lacked the _browser branch
in _fetch_serp_html → pipeline's scraper._browser was a no-op (reviewer was
right). Merge current main to bring #901's avito.py in; replace the monkeypatch
SERP test with a real _fetch_serp_html call proving browser routing.
Refs #883, #901
Review #916: fix vacuous `or True` assert; hoist _is_firewall_page import to
module level in avito_houses; add test proving _fetch_serp_html routes through
_browser when set (refutes the AssertionError concern — _browser branch precedes
the _cffi assert, per #901). No production-code change to SERP path.
Refs #883, #901
Stage 1 of #915. run_avito_pipeline / run_avito_city_sweep acquire a shared
BrowserFetcher when scraper_fetch_mode==browser (instead of injecting a curl
_cffi session); fetch_detail / fetch_house_catalog gain a browser_fetcher param.
Fixes#901's gap where the pipeline bypassed browser-mode. IMV stays on curl
(Stage 3). Default scraper_fetch_mode unchanged.
Refs #883, #901