from fastcore.test import test_eq, expect_failBrowser setup
The connect and extension transports drive your everyday browser, but sometimes that’s exactly what you don’t want: an agent filling forms shouldn’t see your banking session. fastcdp-setup creates an OS launcher (“CDP Chrome”) that starts your installed Chrome with --remote-debugging-port and its own profile directory, so you get a separate Chrome that’s only logged in to the things you want automated, ready for CDP.remote(). On macOS it’s a real app bundle in ~/Applications, on Linux a .desktop entry, on Windows a Start Menu shortcut.
Each platform builder takes explicit chrome, port, profile, and dest paths, so they can be exercised anywhere; main picks the right one and the conventional destination for the OS.
The bundle is three files: a plist, a one-line launcher script, and the icon. Building one into a temp dir shows the structure:
app = _mac_app(Path('/usr/bin/true'), 'CDP Chrome', 9223, Path('/tmp/prof'), Path('/tmp/fastcdp-test-apps'))
print((app/'Contents/MacOS/launch').read_text())
test_eq((app/'Contents/Resources/icon.icns').exists(), True)A .desktop entry plus a hicolor icon is the whole story on Linux:
desk = _linux_app(Path('/usr/bin/true'), 'CDP Chrome', 9223, Path('/tmp/prof'), Path('/tmp/fastcdp-test-share'))
print(desk.read_text())
test_eq(desk.name, 'cdp-chrome.desktop')Windows gets a Start Menu shortcut built by PowerShell’s WScript.Shell COM object; the icon is copied next to the profile so the .lnk has a stable path to point at.
Chrome for Testing
Disposable sessions use a separately downloaded Chrome for Testing, not the installed Chrome above. Run fastcdp-setup --install stable once, then use async with CDP.testing(); add headless=True to run without a window. Installation never creates or rewrites a desktop launcher, changes normal Chrome discovery, or touches a browser profile.
Google’s download manifests provide native builds by release channel and exact version. Downloads are cached by platform and version under ~/.cache/fastcdp/chrome-for-testing. The last successfully installed version is selected for testing; CDP.testing(version='...') selects an exact installed version instead. Runtime lookup is offline and does not consult FASTCDP_CHROME.
Install paths are keyed by exact version. _chrome_version rejects anything else, channel names included:
test_eq(_chrome_version('139.0.7258.66'), '139.0.7258.66')
with expect_fail(ValueError, contains='exact Chrome version'): _chrome_version('stable')testing_chrome
def testing_chrome(
version:str=None
):Executable for an installed Chrome for Testing; never falls back to the user’s Chrome or downloads
install_chrome
def install_chrome(
version:str='stable', # Release channel or exact four-part version
with_deps:bool=False, # Also install Linux system dependencies using apt-get (and sudo if needed)
):Download and select Chrome for Testing, without changing desktop launchers or profiles
On macOS, ditto preserves the complete app bundle, including framework symlinks and executable permissions. No system installation or sudo is needed. On Debian/Ubuntu, --with-deps explicitly opts into apt installation using the archive’s deb.deps manifest; without it, setup only downloads the browser. Other Linux distributions must provide their browser dependencies themselves.
Install Stable once, then address that cached version directly. The second installation reuses the download, and testing_chrome only reads local files:
test_chrome = install_chrome()
test_version = (_testing_root()/'current').read_text()
test_eq(install_chrome(test_version), test_chrome)
test_eq(testing_chrome(), test_chrome)
test_chromemain
def main(
port:int=9223, # Debug port (`CDP.remote`'s default; 9222 would clash with the everyday browser's built-in debugging)
profile:str=None, # Chrome profile dir (default: `~/.cache/fastcdp/cdp-chrome`)
name:str='CDP Chrome', # Launcher name
install:str=None, # Install Chrome for Testing instead of a launcher: stable, beta, dev, canary, or exact version
with_deps:bool=False, # Also install Linux dependencies (requires --install; may invoke sudo)
):Create the CDP Chrome launcher, or use –install to provision a separate Chrome for Testing
fastcdp-setup is registered as a console script, so after pip install fastcdp it’s one command with sensible defaults. It shares CDP.remote’s default port 9223, so the pair works with no arguments on either side; 9222 is avoided because a main browser with built-in remote debugging enabled already holds it.