Skip to content

Releases: feder-cr/invisible_puppeteer

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 19 Oct 08:00
31a6aee

The pin moves to invisible-core 50.48.0, on the same firefox-50 engine.

Changed

  • The user-install job runs on the ledger pull request, not on
    release: published, which never fired: the Release is created with
    GITHUB_TOKEN, and an event that token causes starts no other workflow.
    CI checks the wiring with python -m invisible_core.install_job.
  • The install test keeps out of the venv it builds every variable the core's
    library reads, as invisible_core.install_job.LEAKS lists them: an engine
    folder, a seal file or a GitHub token in the caller's shell no longer
    changes what it measures.
  • The publish workflow checks the version and the ledger against the index
    before it uploads (invisible_core.release check --verify-index), as the
    pre-push hook does: a clone without the hook can no longer skip it.

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 19:28
ef0187f

The pin moves to invisible-core 50.47.0, on the firefox-50 engine. From
firefox-50 every realm, worker and worklet takes the session's zone from the
engine's own override, so the launch no longer writes TZ into the browser's
environment. On Windows no TZ could satisfy both the C runtime and ICU, so
some zones showed the machine's time inside a Worker, and zones outside a
ten-row table were never covered; that is gone with it.

Changed

  • The IANA-to-POSIX conversion is no longer imported or used. Code that took
    IANA_TO_POSIX_TZ from the core has to stop: the core 50.47.0 removes it.

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 18 Oct 02:44
b9a2b4d

The pin moves to invisible-core 49.46.0. The desktop settings a page can read -
scrollbars, text scale, drag threshold, double-click selection, the system
colours in both schemes, the refresh rate, the form-control font and more -
are declared by the persona instead of read from the machine it runs on, and
each of them can be pinned (the keys are the ones invisible_playwright documents in its pinning page).

Changed

  • The way in is uv. The README installs with one complete block per
    system: uv from its own installer, uv init --python ">=3.11" my-project,
    uv add invisible-puppeteer, uv run invisible-puppeteer fetch. CONTRIBUTING teaches the same,
    and CI refuses an install instruction that is not uv
    (python -m invisible_core.way_in, core 49.45.0).
  • A remedy this package prints is the command for your environment. In a
    venv uv made, which has no pip, a broken install was told to run
    pip install --force-reinstall invisible-puppeteer; it is now told the uv command, and
    an environment pip made is still told pip, through its own interpreter.

Fixed

  • CONTRIBUTING.md was a copy of invisible_playwright's: it cloned that
    repository and described its API. It now describes this one.
  • Nothing ran the README's install block. A user-install workflow now runs it
    as written, on Linux and Windows, and starts the browser from the project
    it makes.

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 17 Oct 12:22
dc148e9

The pin moves to invisible-core 49.44.0, on the firefox-49 engine.

Changed

  • Your code runs in a world of its own, where a page that replaced a
    standard API cannot count your calls.
    evaluate, evaluateHandle,
    waitForFunction, $eval and setContent ran in the page's own
    realm, so a call to document.querySelector went through whatever
    the page had put in its place. They now run in a world with the
    page's principal where a name the standard defines is the native one,
    and every other name is the page's.
    On what the page created (its classes, their instances, its plain objects)
    the page's definitions win, toString and valueOf included, and an
    object your code hands to the page keeps its identity and looks to the
    page like its own (instanceof Array holds, its constructor is the
    page's). What changes, and it is declared rather than accidental: a name
    the standard defines for one of the browser's own objects wins even where
    the page redefined it on that object itself (a setter the page put on one
    input's value does not run; .wrappedJSObject gives the page's own
    view); a bare assignment to an undeclared name creates a global of your
    world, not of the page (window.x = 1 still reaches the page); and your
    code's own eval is not governed by the page's Content-Security-Policy,
    which governs the page's (window.eval) as before. Needs firefox-49.

v0.7.2

Choose a tag to compare

@github-actions github-actions released this 17 Oct 00:06
76498cc

The pin moves to invisible-core 48.43.0, still on the firefox-48 engine.

Fixed

  • The e2e tests that measure time run alone. Nine of them assert an upper
    bound on a wall-clock duration ("refused at once", "returns before the page
    loads"), a bound that four browsers at once can cross with nothing wrong in
    the engine. They carry the new wall_clock marker, and the core's e2e run
    gives them the machine alone after the parallel tests.

v0.7.1

Choose a tag to compare

@github-actions github-actions released this 16 Oct 20:05
08a230e

The pin moves to invisible-core 48.42.0, on the same firefox-48 engine.

Fixed

  • waitForFunction no longer ends on NaN. The predicate's result was
    judged after conversion to Python, where NaN is true; it is now judged as
    JavaScript judges it, with the same rule as invisible-playwright's
    wait_for_function.
  • A GeoIP database being downloaded is never read half-written. Two
    sessions starting together on a cold cache could have one open the database
    while the other was still writing it, and fail with "Is this a valid MaxMind
    DB file?". The core now extracts it outside the cache, checks it with the
    real reader and moves it into place in one step (invisible-core 48.42.0).

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 16 Oct 17:27
435d6a2

The pin moves to invisible-core 48.41.0, on the firefox-48 engine.

Added

  • The branding a page reads is a profile field. pin={"branding": ...}
    takes "official" (the default, the retail Firefox's files), "unofficial",
    or the absolute path of a zip archive of your own with the same 16 files at
    its root. The engine serves the declared files at chrome://branding/content/
    and resource://usercontext-content/branding/ instead of its own, from inside
    the archive as Firefox serves its own branding. Needs firefox-48.

Changed

  • The speechSynthesis voices follow the session's language. An it-IT session
    lists the voices of a Windows with Italian added instead of only the American
    ones; a language without a measured set keeps the English one, and a
    hardware.voices pin still wins.

Fixed

  • A persistent profile stays the same machine across launches. With
    profile_dir and no seed, every launch used to draw a new seed, so the same
    profile came back with another GPU, screen and fonts. The first launch now
    records its seed in the profile and later ones reuse it; an explicit seed
    that differs from the recorded one is refused.

v0.6.4

Choose a tag to compare

@github-actions github-actions released this 15 Oct 11:48
ad0dbbb

The pin moves to invisible-core 47.41.0, on the same firefox-47 engine.

Added

  • The engine can live on a read-only disk. INVISIBLE_PLAYWRIGHT_ENGINE_DIR
    puts the sealed engine trees somewhere of their own, written only by a
    download; INVISIBLE_PLAYWRIGHT_CACHE_DIR keeps the machine's writable state
    (the GeoIP database, the font manifest). Unset, nothing moves. A launch on an
    engine already fetched by the same core writes nothing into the store.

Changed

  • timezone="auto" that cannot be resolved now fails the launch without a
    proxy too.
    It used to fall back to the host's timezone in silence when the
    exit could not be discovered or the GeoIP database could not be obtained,
    which on a server kept in UTC gives a timezone that contradicts its own IP.
    The error names the cause; pass an explicit IANA zone to launch offline.

v0.6.3

Choose a tag to compare

@github-actions github-actions released this 15 Oct 01:06
7729981

The pin moves to invisible-core 47.40.0, on the same firefox-47 engine.

Fixed

  • Closing a browser no longer closes the pipe of another browser in the
    same process.
    The connection closed its two descriptor numbers on
    every call, and a released number goes to the next pipe the process
    opens: a second close, or a write racing the close, could reach another
    browser launched by the same script. The connection now releases each
    end once and never touches the number again.

v0.6.2

Choose a tag to compare

@feder-cr feder-cr released this 14 Oct 22:56
65a5590

The pin moves to invisible-core 47.39.0, which seals the firefox-47 engine.

Fixed

  • A page can no longer tell that the engine carries the automation protocol.
    Every engine until firefox-47 registered the protocol as a chrome package named
    juggler, and a page tells a registered package from an absent one with one
    line, new Worker("chrome://juggler/..."): it returns on our engine and throws
    SecurityError on Firefox. Captcha vendors started probing it in October 2026,
    which is why a challenge solved by hand was still refused. firefox-47 loads the
    protocol from resource://gre/modules/juggler/, a namespace every Firefox has
    and inside which a page cannot tell which files exist; the engine now registers
    exactly the chrome packages and resource substitutions Firefox 151 does.
  • A goto the page stops on its way no longer answers on the old page, nor
    waits out its timeout.
    Stopped with nothing in its place
    (document.open(), window.stop()), it raises PageError
    "NS_BINDING_ABORTED at " at once; replaced by another document, it
    waits on that document, as pyppeteer's NavigatorWatcher does, and answers
    with its response, so the answer always names the page it is on.
  • The wheel is born before the page sees it, as keys and mouse moves are
    since 0.35.7: event.timeStamp was the instant the wheel reached the page,
    0 to 2 ms below performance.now() in the handler where a real wheel is 6
    to 14, and half of the wheel events failed the filter a tracker applies.

Not yet as the original

  • Firefox lets the page being left stop a navigation the browser started
    (document.open, window.stop, location.replace, a form submit, an iframe
    navigating the top); pyppeteer's Chromium lets the browser's navigation win
    over all of them but going back, so there goto lands on the page asked
    for. The engines differ, and this client answers with Firefox's events.