Safeco Full Flow
Keep in sync: When editing this file, also update
.cursor/skills/safeco-full-flow/SKILL.mdso both describe the same step sequence, URLs, routes, and field values.
Path: .cursor/skills/safeco-full-flow/SKILL.md (canonical executable skill — full MCP tool examples and step-by-step instructions live there)
Category: Browser and Automation
Triggers: running the full Safeco flow, end-to-end bind test, DA-to-Fastlane flow
What It Does
Walks the agent through the complete Safeco Auto quote-to-bind flow using the Playwright MCP (user-playwright-mcp). Supports local, dev, and QA environments. This is a manual end-to-end verification flow — not an automated test — used to validate that the entire pipeline works from DA through Fastlane Portal checkout.
Environments
| Environment | DA URL | Fastlane Portal URL | SSL workaround? | OTP? |
|---|---|---|---|---|
| local | http://localhost:3000 | http://localhost:4202 | Yes | Gateway bypassed, but DA Auth0 OTP may still appear (see fallback) |
| dev | https://dev.quote.goosehead.com | https://dev-fastlane-portal.goosehead.com | No | Yes |
| QA | https://qa.quote.goosehead.com | https://test-fastlane-portal.goosehead.com | No | Yes |
Flow Sequence
Steps
- DA Quote — Start in the DA app for the target environment, fill out customer/driver/vehicle info, submit the quote
- Carrier Selection — Select Liberty Mutual (Safeco) from the quoted carriers list
- Buy Online — Click Buy Online
- Local: DA redirects to
https://localhost:3443but Playwright can't trust the SSL cert — extract sessionId and navigate tohttp://localhost:4202directly - Dev/QA: Redirect goes directly to the real Fastlane Portal URL — follow normally; OTP pause if triggered
- Local: DA redirects to
- Fastlane Portal — Continue through: drivers confirm, excluded drivers, vehicles confirm, policy coverages, vehicle coverages, discounts, summary, and checkout
Pre-Flight Checklist
Local (mandatory every run):
- Docker is running
- VPN is on (required for carrier API calls)
- DA at
http://localhost:3000, Fastlane Portal athttp://localhost:4202 - Clear stale session: run
browser_evaluateto clearlocalStorage/sessionStorage, then navigate tohttp://localhost:3000— stale sessions load mid-quote URLs even without a spinner
Dev / QA:
- VPN is on
- No local services needed
| Symptom | Cause |
|---|---|
| DA loads mid-quote URL (local) | Stale session — mandatory storage clear before Step 1 |
ERR_CONNECTION_REFUSED on :4202 | Docker / Fastlane not running |
| Stuck on carrier loading spinner > 30s | VPN off — re-issue wait (~30s MCP cap per call) |
| Validation errors on confirm pages | Expand accordion first; fill all required comboboxes |
| Knockout at Policy Coverages | Ineligible VIN — use the fixed VIN below |
Test Data
Identity
Randomize the person on every run — never reuse the same name/email/phone, or you'll hit duplicate-quote and OTP-delivery collisions. Generate a fresh person at the start and reuse those values through every step (including the checkout cardholder name).
Randomize per run:
| Field | How to generate |
|---|---|
| First / Last Name | Random plausible given name + surname |
| DOB | Random valid adult, ~25–70 yrs old, MM/DD/YYYY |
| Gender | Random Male / Female |
| Marital Status | Random Single / Married |
| Phone | Random 10-digit US number not 555-prefixed (DA rejects 555 even on local); dev/QA: one you can receive OTP on |
Fresh disposable address per run from temp-mail.org; successhack@test.com only for throwaway non-OTP local checks | |
| DL Number | Random 8-digit number |
| Industry / Occupation | Any valid pair — Business/Sales/Offi + Consultant are safe defaults |
Keep fixed (the flow depends on these):
| Field | Value | Why |
|---|---|---|
| Address | 255 Bowie Ct Allen, TX 75002 | Drives the Excluded Drivers step (public-records household members) and TX rating |
| DL State | Texas | Must match the TX address |
| Vehicle VIN | WVWAR7AN0LE017577 (2020 Volkswagen Arteon) | Clears Safeco local eligibility; old 1HGCM82633A004352 knocks out at Policy Coverages |
Payment Card (Checkout)
| Field | Value |
|---|---|
| Card | 4917 6100 0000 0000 |
| Expiry | 03/2030 |
| CVC | 737 |
| Name | The run's generated First + Last name |
| Zip | 75002 |
Browser MCP
This skill uses user-playwright-mcp (the Playwright MCP server). Full tool call examples: see .cursor/skills/safeco-full-flow/SKILL.md.
Key differences from cursor-ide-browser:
- Use
target(notref) for element targeting in click/type/fill_form - There is no
browser_fill— usebrowser_type(textarg) for one field,browser_fill_form(fieldsarray) for several browser_evaluatetakes afunctionarg (() => { ... }), NOTscriptbrowser_lock/browser_unlockdo not exist;browser_tabsexists but isn't needed herebrowser_run_code_unsafeis available for arbitrary Playwright codebrowser_take_screenshotrequires afilenameargument
Common Quirks
- Snapshot before every interaction — refs change on every re-render; always get a fresh snapshot before clicking or filling
browser_wait_for~30s cap per call —timeoutis milliseconds but each call caps at ~30s; re-issue the wait for long polls (Results, carrier loading)browser_wait_fortimeis seconds — don't mixtimeandtimeout- No
browser_fill—browser_type(single field) replaces the value; useslowly: truefor autocomplete inputs (address, agent search);browser_fill_formsets several fields at once - DA VIN field hidden — click "Or Enter VIN instead" before typing the VIN; accordion may stay "NEW VEHICLE" until submit
- Radix comboboxes are not native selects —
select_optiondoes not work; click to open, then click the option by text - Open dropdowns intercept clicks — press
Escapebetween interactions if the next click is unresponsive - Iframes are inaccessible — the Hydra payment iframe at checkout cannot be automated; the agent pauses and hands off to the user
- SSL redirect workaround — after clicking Buy Online, extract
sessionIdfrom the chrome error page URL and navigate directly tohttp://localhost:4202 - Don't deep-link to a step for visual checks — local Vite paints before CSS settles, faking layout bugs (overlapping / one-word-per-line text). Walk the flow so styles are warm; if you must deep-link, reload and wait before judging layout
- Results wait — wait only on the name-independent
"here are your top"(full heading is "Hi <FirstName>, here are your top auto quotes!"); re-issue every ~25s; intermediate "Gathering…" / "Almost finished" screens are transient and stall a wait
SSL Redirect Workaround (Local Only)
On local, the DA app redirects to https://localhost:3443 after Buy Online, but Playwright cannot trust the local SSL proxy's self-signed certificate. The workaround:
1. Click Buy Online
2. Wait 3s for redirect to fail (chrome-error://chromewebdata/)
3. Read the URL from the snapshot's <strong> element — contains the sessionId
4. Call browser_run_code_unsafe → page.unrouteAll()
5. Navigate to http://localhost:4202/?sessionId=<id>&lob=Auto&carrierId=35&state=TX
OTP can still appear on local. GOOSEHEAD_BYPASS_AUTH=true only bypasses the Fastlane gateway — the DA app runs its own Auth0 passwordless OTP on Buy Online, so you may land on /auth/login?...&step=code instead of the SSL error. Don't guess codes (000000 etc. are real Auth0 codes and fail). The DA already created the Fastlane session before the OTP gate, so read the sessionId from the DTC/CRN session terminal logs (SessionId: <uuid>) and navigate to http://localhost:4202/?sessionId=<id>&lob=Auto&carrierId=35&state=TX to skip the OTP. If it isn't in the logs, fall back to an OTP pause.
Where to read logs: portal-entry SessionId: <uuid> → DTC/CRN session or API-gateway terminal; carrier eligibility / update-quote errors → API-gateway only (Update quote failed for session <id>).
On dev/QA, the redirect goes directly to the real Fastlane Portal (dev-fastlane-portal.goosehead.com / test-fastlane-portal.goosehead.com) — no workaround needed. Just follow the redirect. If an OTP page appears, pause for the user.
Fastlane Step Guide
| Step | URL segment | Key actions |
|---|---|---|
| Drivers Confirm | drivers/confirm | Fill Industry + Occupation (required); no checkbox needed |
| Excluded Drivers | drivers/excluded | Fill exclusion reason + relationship for each excluded person |
| Confirm Vehicles | vehicles/confirm | Expand accordion first; fill Coverage Status = "Covered" + Registered Owner |
| Policy Coverages | coverages/policy | Accept defaults (Essential pre-selected) |
| Vehicle Coverages | coverages/vehicle | Accept defaults |
| Discounts | discounts | No discounts needed; just continue |
| Summary | summary | Check credit consent checkbox; handle "Rate Updated" modal → Proceed to Checkout |
| Checkout | checkout | Credit Card + Full Payment pre-selected; user fills Hydra iframe |
Pause Points
| Pause / Stop | Env | Trigger |
|---|---|---|
| Knockout | all | Redirect to /carriers/liberty-mutual/auto/knockout — screenshot, read page reason, grep API-gateway log, report and stop |
| OTP | dev / QA (and local if the DTC-log session fallback fails) | After Buy Online, if OTP page appears before Fastlane |
| Payment | all | Hydra payment iframe at Checkout (inaccessible to MCP) |
At each pause: screenshot the page, tell the user what to do (or report knockout reason), wait for their signal before continuing — except Knockout, which is a hard stop.
Stop Conditions
The agent reports immediately and stops if:
- Knockout page at
/carriers/liberty-mutual/auto/knockout— capture screenshot + page reason, grep API-gateway forUpdate quote failed for session <id>, report both, do not retry blindly - Stuck on carrier loading spinner > 45s — likely VPN
:4202connection refused (local) — Docker / Fastlane down- Hydra iframe fails to load after 30s — report URL and current page state
Proof Artifacts
When verifying a fix, save screenshots into .agent/proof/<TICKET>/ with numbered, descriptive names:
.agent/proof/<TICKET>/
01-<state-before-action>.png
02-<state-after-action>.png
03-<expected-result>.png
Reference these in the MR description.