- pyproject.toml: norecursedirs for tests/playwright-upstream/, a vendored
Microsoft Playwright test suite with its own pixelmatch API version
mismatch. We run it explicitly when doing compat audits, not on every
push. Default collection now ignores it so the pre-push hook (which
runs the full default pytest collection) doesn't error out.
- tests/test_service_worker.py: replace em-dash with hyphen inside a
bytes literal at line 91. Python rejects non-ASCII bytes literals
with SyntaxError at collection time. Now collects cleanly.
Both were blocking unrelated pushes (e.g. the issue #18 fix in the
previous commit). Splitting them out so the issue #18 commit stays
focused.
- Add profile_dir= kwarg to InvisiblePlaywright (sync + async).
Maps to firefox.launch_persistent_context(); returns a BrowserContext.
Cookies / localStorage / extensions / cache / prefs all persisted.
- Drop the firefox-4 era workaround that filtered locale + timezone_id
out of the persistent kwargs. firefox-5 ships the C++
docShell.overrideTimezone IDL method (50 LOC patch in
docshell/base/nsIDocShell.idl + nsDocShell.cpp, see patch.md
section 19 in feder-cr/invisible-firefox), so per-realm overrides
land without crashing the launch handshake.
- Bump BINARY_VERSION firefox-4 -> firefox-5.
- Sentinel unit tests added: persistent kwargs MUST include locale +
timezone_id (defends against re-introducing the workaround) and
must NOT include timezone_id when timezone="" is the "host TZ" sentinel.
Validation: smoke test against the local firefox-5 build, persistent
context UP in 21s (was 180s timeout), Intl.timeZone == Europe/London,
hardwareConcurrency / screen / DPR / locale all reflect the PIN.
#15 shipped because unit tests only covered text-mode sha256sum output.
This adds a comprehensive parser test matrix (binary mode `*` prefix,
mixed, CRLF, BOM, indent, trailing whitespace, multiple stars, empty,
comment-only, sha256sum -b coreutils format) plus the integration
sentinel test_ensure_binary_accepts_binary_mode_checksums that
reproduces #15 against the live wire format.
Also covered for the first time:
- _resolve_asset_url public/private branches, auth header propagation,
asset-missing failure, HTTP 4xx propagation
- _download_file 200/404/500, parent mkdir, auth on api.github.com
only (not leaking to CDN URLs)
- cache_root / cache_dir_for_version path shape and version isolation
- _parse_owner_repo malformed inputs and dash/underscore/dot repo names
ARCHIVE_NAME case-matrix (uppercase platform, lowercase machine),
unsupported arch rejection (i386, ppc64le, arm64), unsupported platform
rejection (darwin, freebsd), BINARY_ENTRY_REL <-> ARCHIVE_NAME invariant,
RELEASE_URL_TEMPLATE shape (https, placeholders, owner pointer).
New e2e tests (marker `e2e`, excluded by default):
clean venv install, fetch against live release, binary launch, real-site
Playwright sanity. This is the test suite that would have caught #15
end-to-end before publish.
Stats: 275 -> 327 unit tests (+52), 0 -> 6 e2e tests.
Controprova: rolling back the parser fix makes 9 of the new tests fail
with the exact "no SHA256 for ..." error from #15.
The Juggler JS in upstream Playwright calls win.windowUtils.jugglerSendMouseEvent
at four sites, but when the Juggler was ported FF146 -> FF150 the matching C++
patch to nsIDOMWindowUtils.idl + nsDOMWindowUtils.cpp was dropped. Result: every
page.mouse.*, page.click(selector), locator.click(), page.hover(), mouse.wheel()
threw "win.windowUtils.jugglerSendMouseEvent is not a function" on first call.
The fix is shipped in the patched Firefox source (feder-cr/firefox-stealth):
six call sites in juggler/protocol/PageHandler.js and juggler/content/PageAgent.js
were swapped to win.synthesizeMouseEvent — a Mozilla chrome-scope helper that is
already present in FF150. scrollRectIntoViewIfNeeded was also guarded at the two
PageHandler.js sites where it was called unconditionally on the FF150
_linkedBrowser, which no longer exposes that method.
This invisible_playwright release adds the regression suite in tests/test_mouse.py
(12 cases inspired by microsoft/playwright-python/tests/async/test_click.py),
the CHANGELOG, and the version bump. The patched Firefox archive on GitHub
Releases must be refreshed before users actually receive the fix; the
BINARY_VERSION bump to firefox-2 will land with that asset.
Reporter: @trob9 (issue #9) — provided ready-to-apply JS patches, 4-line minimal
repro, and confirmed reCAPTCHA v3 = 0.90 holds after the swap.
E9-E12 exercise the launcher's Linux code paths without spawning a
real Firefox binary or Xvfb. They monkeypatch ``sys.platform`` and
stub ``make_virtual_display`` / ``_binary_on_path`` so the tests run
on any host:
- E9 ``_build_prefs(headless=True)`` on Linux passes
``virtual_display=False`` to the translator, so the Win32-only
``security.sandbox.gpu.level`` workaround never leaks into Linux
prefs (Xvfb handles window hiding instead).
- E10 ``_resolve_headless`` on Linux + headless=True invokes the
dispatcher and stores the returned object on ``self._virtual_display``.
- E11 ``_teardown`` stops the Linux virtual display, clears the
reference, and is idempotent on a second call.
- E12 With Xvfb missing from PATH, ``_resolve_headless`` raises a
clear ``RuntimeError`` mentioning ``Xvfb`` instead of a cryptic
FileNotFoundError.
Suite on Linux/WSL: 286 passed, 5 skipped (4 binary-gated E2E
lifecycle tests + 1 Win32 ctypes test). Binary-gated E1/E2/E5/E8
remain ready to run on Linux once the patched Firefox tar.gz is
fetched locally.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
IT11–IT13 mirror IT10 on the Linux platform branch, verifying:
- Xvfb workarounds coexist with SOCKS5 proxy mutation
- MSAA pin propagates through prefs translation on Linux
- _LINUX_GENERIC_FONT_FACTORS is prepended to per-font metrics
Tests use monkeypatch on sys.platform so they run on any host OS.
Verified green on Linux/WSL alongside the existing Windows tests.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Cover the Linux branches in prefs.py that previously had no tests
(font metrics, GPU spoofing, MSAA from profile, canvas noise mask
per renderer, WebGL extension preservation, Xvfb workarounds,
virtual_display no-op) and add construction smoke tests for
_LinuxVirtualDisplay. Also fix two host-platform-dependent tests
so the suite stays green on both Windows and Linux.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Final sweep adds unit tests for the modules left at 0% direct coverage
after Phases 1-9:
- launcher._tz_env: 7 tests covering the IANA -> POSIX mapping
including the Phoenix / Honolulu no-DST regression cases
- launcher._humanize_max_seconds, _default_context_kwargs: 11 tests
on the constructor-side helpers (no browser launch)
- _headless.make_virtual_display dispatcher + _WindowsVirtualDesktop
init/teardown: 8 tests (Linux dispatch branch covered without
spawning Xvfb, since __init__ does no I/O)
- async_api.InvisiblePlaywright constructor parity with sync: 8 tests
guarding against drift between the two APIs
Suite: 230 -> 264 passing. Pyramid stays clean: 243 unit / 12
integration / 9 e2e.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five test the constructor only (seed handling, eager profile build,
fail-fast pin validation) and always run. Four spin up the patched
Firefox and exercise the full `with InvisiblePlaywright(...)` lifecycle,
gated on a locally cached binary so CI without the binary skips
cleanly. All 230 tests pass on Windows with the binary fetched.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Covers _accept_language, _font_metrics_for_platform, Windows GPU/MSAA
clearing, Windows canvas noise mask (intel path), Windows WebGL extension
clearing, timezone handling, extra_prefs overlay (add/delete/override/no-op),
dark-theme system colors palette, locale normalization, Xvfb-key absence on
Windows, virtual_display sandbox workaround, and seed-derived LAN IP.
Linux-specific branches are intentionally not covered in this commit per
scoping instruction; they remain available in the plan for a follow-up
pass when running on Linux.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Covers _validate_pin_key (all groups + negatives), _apply_pins_to_raw
(fonts list/tuple/typeerror, multi-pin, no-mutation, unknown-key guard),
and generate_profile (determinism, seed coercion, pin propagation through
to_prefs_dict, frozen-instance, dark_theme bool coercion, fonts list
roundtrip, int31 boundary). Includes a guard test that every dotted pin
key has a _PIN_TO_RAW mapping.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Covers classify_gpu (decision-table over 28 GPU strings inc. boundary
values for AMD Radeon number ranges), _screen_tier resolution
classification, derive_font_prefs / derive_font_whitelist coherence and
determinism, and the public Forge / sample entry points (locked
identity, key set, type correctness, seed determinism).
One plan deviation: the original plan claimed `AMD FirePro W7100` →
`workstation`, but the workstation regex requires a `Radeon` prefix,
so FirePro alone falls through to the `mid_range` fallback. Test
asserts the actual behaviour.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
invisible-playwright: a patched Firefox 150.0.1 for browser-fingerprint
stealth, shipped as a Playwright-compatible Python wrapper.
* Sync + async InvisiblePlaywright launcher (firefox_user_prefs, virtual
desktop on Windows, SOCKS5 auth via patched nsProtocolProxyService)
* fpforge: Bayesian fingerprint sampler over GPU / audio / fonts /
screen / ~400 other navigator fields
* WebRTC stealth: srflx address swap, synthetic srflx fallback,
private-LAN host candidates. No real public IP leak via STUN.
* GPU sandbox fix for FF150 alt-desktop regression
* Bezier-curve mouse motion baked into Juggler
Targets Windows x86_64 + Linux x86_64. Binary fetched on first run from
GitHub Release "firefox-1".