feat(google): rewrite /search language params pre-request via a DNR redirect rule#249
Open
rejifald wants to merge 2 commits into
Open
feat(google): rewrite /search language params pre-request via a DNR redirect rule#249rejifald wants to merge 2 commits into
rejifald wants to merge 2 commits into
Conversation
…edirect rule The content-script searchParams rewrite acts only after the raw entry request has been served: one wasted page load per entry search, and the raw request — carrying Chrome's opaque gs_lcrp omnibox token — seeds the server-side pinned candidate set that can zero out results under the lr filter (the case #208's detect-and-retry mitigates after the fact). A dynamic declarativeNetRequest redirect rule (id 2) now rewrites the URL inside the network stack before the request leaves the browser: queryTransform adds hl + the pipe-joined lr and removes the strip/scrub token tiers (plus the enumerated gs_* family — removeParams has no prefix matching). Condition mirrors the site-rule gates: GOOGLE_REQUEST_DOMAINS (new @movar/host-match export derived from the isGoogleHost suffix set), an RE2 regexFilter for /search + a real q param, main_frame only, allowlist/snooze excluded; regenerated on every settings/pause/snooze change alongside the Accept-Language rule. The transform is idempotent and browsers skip same-URL redirects, so already-clean SERP-internal navigations are matched-but-skipped no-ops (Firefox documents the skip; Chrome is pinned by e2e). Safari is compile-time excluded (open queryTransform bugs) and keeps the content-script fallback, which stays everywhere as layer 1 — a dnr.test.ts parity test pins both layers to byte-identical URLs. The #208 empty-results retry stays as layer 2 for pins seeded by vectors the rule never sees. DNR rewrites log no CorrectionEvent (like the Accept-Language rule), so the live google fixture drops its correction expectation; store forms, deployment checklist, and docs (google-search-url-params.md "prevention layer" section, pitfalls.md entry #4) updated to match. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Under machine load the serviceWorker fixture flaked in two ways: the `serviceworker` waitForEvent inherited the 5s actionTimeout — too tight for a cold SW boot on a starved host — and the storage clear+seed evaluate ran once against whatever instance Playwright returned first. Chrome tears down and restarts a just-installed MV3 service worker at will, so that evaluate could reject with "Target ... closed" or hang with no error until the 30s test timeout killed the context. waitForServiceWorker now waits with an explicit 15s budget, prefers the newest listed instance, and skips instances already seen to die. The clear+seed is one idempotent evaluate raced against a 5s deadline and retried (3 attempts) against a re-acquired live worker; explicit closed errors blacklist the dead instance, deadline timeouts retry without blacklisting so a healthy-but-starved worker gets another chance. The fixture hands downstream fixtures the worker that actually served the seed. Per-test storage-isolation contract is unchanged. Verified: popup.behavior + options.behavior at --repeat-each=10 --workers=6, 150/150 twice (the flake's home spec, toolbar-icon .behavior, lives on main and isn't on this branch). Metrics regen rides along (LOC badge +102). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Two commits:
1.
feat(google): rewrite/searchlanguage params pre-request via a DNR redirect rule (ef5aab0)The content-script
searchParamsrewrite acts only after the raw entry request has been served: one wasted page load per omnibox/homepage search, and the raw request — carrying Chrome's opaquegs_lcrptoken — seeds the server-side pinned candidate set that can intersect with thelrfilter down to zero organic results (the empty-SERP class #208 mitigates after the fact).A dynamic
declarativeNetRequestredirect rule (id 2) now rewrites the URL inside the network stack before the request leaves the browser:queryTransformaddshl+ the pipe-joinedlrand removes the strip/scrub token tiers plus the enumeratedgs_*family (removeParamshas no prefix matching).GOOGLE_REQUEST_DOMAINS(new@movar/host-matchexport derived from theisGoogleHostsuffix set), an RE2regexFilterfor/searchwith a realq,main_frameonly, allowlist/snooze excluded; regenerated on every settings/pause/snooze change alongside the Accept-Language rule.queryTransformbugs) and keeps the content-script fallback, which stays everywhere as layer 1 — adnr.test.tsparity test pins both layers to byte-identical URLs. The feat(google): empty-SERP detect-and-retry fallback (finding #1) #208 empty-SERP detect-and-retry stays as layer 2 for pins seeded by vectors the rule never sees.DNR rewrites log no CorrectionEvent (same as the Accept-Language rule), so the live google fixture drops its correction expectation. Store privacy forms, deployment checklist, and docs (
google-search-url-params.mdprevention-layer section,pitfalls.md#4) updated. Changeset included (@movar/extensionminor).2.
test(e2e): retry serviceWorker fixture seeding across MV3 SW restarts (269b8d7)Under machine load the
serviceWorkerfixture flaked in two ways:waitForEvent('serviceworker')inherited the 5sactionTimeout(too tight for a cold SW boot on a starved host), and the storage clear+seed evaluate ran once against whatever SW instance came first — Chrome can tear down and restart a just-installed MV3 service worker, leaving that evaluate to reject with "Target … closed" or hang until the 30s test timeout.The fixture now waits with an explicit 15s budget, prefers the newest listed instance, excludes instances already seen to die, and runs the (idempotent) clear+seed raced against a 5s deadline with up to 3 attempts against a re-acquired live worker. Downstream fixtures get the worker that actually served the seed; the per-test storage-isolation contract is unchanged.
Verified:
popup.behavior+options.behaviorat--repeat-each=10 --workers=6, 150/150 twice under 12-concurrent-Chromium load (the flake's home spec,toolbar-icon.behavior, lives on main and isn't on this branch).Reviewer notes
269b8d7(LOC badge +102; health score 81/B unchanged).🤖 Generated with Claude Code