Skip to content

The harness browser

The harness controls a local Chromium with Playwright and CDP on port 9222. The window is visible. This is correct and necessary.

┌─────────────────────┐ CDP 9222 ┌──────────────────────────────┐
│ ungoogled-chromium │ ◄──────────► │ playwright connectOverCDP │
│ chromium-profile/ │ │ scripts/inspect-api.ts │
│ (outside the repo) │ │ → .api-dumps/*.json │
│ + the extension │ └──────────────────────────────┘
└─────────────────────┘
  1. Run npm run build. Then run npm run browser:launch. The script does not start a second browser on port 9222. To keep the browser after the shell closes, run nohup npm run browser:launch > /tmp/gopher-launch.log 2>&1 &. Then wait until curl http://localhost:9222/json/version gives an answer.

  2. A person must sign in one time in the visible window. Go to patreon.com, sign in, do the Cloudflare challenge, and go to the home page. The profile is in the directory chromium-profile/ below ${XDG_STATE_HOME:-$HOME/.local/state}/gopher/. It keeps the cookies after a restart. If the session becomes invalid, do this step again. The harness cannot do the Cloudflare challenge and cannot type the password.

  3. npm run api:inspect records each answer to /api/current_user and /api/posts. Read Patreon in the window while the script operates. The files go to .api-dumps/.

  4. npm run api:check calls /api/current_user in the page. Exit code 0 means that the session is correct and that a minimum of one campaign is available. Exit code 1 means that the account is not signed in, that a challenge is open, or that there are no campaigns. The scripts connect with noDefaults: true, because Chromium 152 and later refuse the Browser.setDownloadBehavior call that Playwright usually sends.

  5. To find the cause of exit code 1, look at the page. Each condition has a different mark:

    ConditionMark in the page
    Not signed inh1 is “Where Creator Communities Thrive”. No form and no challenge
    Cloudflare challengeAn iframe for the challenge, or the text “Verify you are human”
    Sign-in formAn input[type="password"] element

    Compare a host pattern with url.hostname, or put a / at the end of the origin. A regular expression with $ at the end never matches a full URL.

  6. To install a new build without a restart of the browser: run npm run build, then open chrome://extensions and click the reload button. You can also do this with Playwright and the developerPrivate API. Then open a patreon.com tab again. If the manifest changed, you must do a full reload. Look at chrome://extensions → Gopher → “Errors” if the extension does not operate.

The examination sequence

  1. npm run compile
  2. npm run build
  3. npm test
  4. npm run api:check
  5. Manual examination of the panel in the harness browser

The “Verified, and not verified” section of memory.md, at the root of the repository, tells you what each step proves.

To do the examination with a session: run npm run build, run npm run browser:launch, sign in in the window, and run npm run api:check. Then open the panel.