sh1pt browser: Playwright recipes for the consoles that have no API - #1008
Merged
Merged
Conversation
Some provider settings have no CLI and no API. Google's OAuth consent screen is the standard case: gcloud covers the rest of Google Cloud, but test users, publishing status and a client's redirect URIs are console pages, and an app left in Testing with no test users answers every sign-in with Error 403: access_denied. packages/automation/browser holds those as typed, reusable recipes on a persistent Chrome profile, so a sign-in is answered once and every later run is unattended. `sh1pt browser list` prints the shelf. Three findings decide whether a sign-in works at all, and all three are in session.ts: - Playwright's headless:true asks for the old headless binary, which sign-in pages recognise and refuse. Drive a real Chrome and pass --headless=new instead. - New headless still reports HeadlessChrome, and Google answers that with a stripped flow that will not accept a password. Send a desktop user agent built from the binary's own version. - With no authenticator a passkey prompt never settles: the page sits on "Verifying it's you…" and even its own "Try another way" button does nothing. Registering Chrome's DevTools virtual authenticator makes the request fail like an empty security key, and the password fallback appears. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WYMJH7N4d2qRct5Q5q2YWQ
vu1nz Security Review0 finding(s) in PR #? No security issues found. |
ThreatCrush Security Scan49 finding(s) HIGH/CRITICAL: 1 | MEDIUM: 14 | LOW: 34
Snippets are redacted; ThreatCrush never prints matched credential material. |
The cli now depends on @profullstack/sh1pt-automation-browser, and pnpm rewrites workspace: to a real range at publish time. Without this the release would ship a cli whose dependency does not exist on npm, and every npm i @profullstack/sh1pt would 404 on it. Added to PACKAGES in scripts/version.mjs and to the build + publish steps in release.yml, in dependency order, and kept the test file out of the published dist. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WYMJH7N4d2qRct5Q5q2YWQ
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.
Why
Some provider settings have no CLI and no API. Google's OAuth consent screen is the standard case:
gcloudcovers the rest of Google Cloud, but test users, publishing status and a client's redirect URIs are console pages. An app left in Testing with no test users answers every sign-in withError 403: access_denied, and nothing on the command line can change that.What
packages/automation/browser(@profullstack/sh1pt-automation-browser): typed, reusable Playwright recipes on a persistent Chrome profile, so a sign-in is answered once and every later run is unattended. When only a person can answer (a 2FA code, a captcha),session.ask()writes a screenshot and question into the run's artifacts and waits for an answer file, so an unattended box parks instead of failing.google-cloud-oauth:status,add-test-users,publish,add-redirect-uri.sh1pt browsercommand:listplus<recipe> <action>. Playwright is an optional peer dependency, loaded lazily, so machines without it run every other command fine.CLI_INTEGRATIONS.mdand a package README.Three things that decide whether a sign-in works
Learned the hard way against Google, all in
session.ts:headless: trueasks for the old headless binary, which sign-in pages recognise and refuse. Drive a real Chrome and pass--headless=new.HeadlessChrome; Google answers that with a stripped flow (flowName=WebLiteSignIn) that will not take a password at all. Send a desktop user agent built from the binary's own version.Verified
pnpm test): 719 files, 3,642 tests, 0 failures. Without that build step 670 files fail to collect on@profullstack/sh1pt-core/testing; that is the known unbuilt-worktree behaviour, not this change.tsc --noEmitclean for the new package and the CLI.add-test-users/publishare therefore not yet exercised end to end; the page objects are written from the live DOM but wait on a working credential.🤖 Generated with Claude Code
https://claude.ai/code/session_01WYMJH7N4d2qRct5Q5q2YWQ