news 2026/9/11 9:09:57

PostHog 前端 QA 实战指南:开发堆栈就绪检查(Stack Readiness)与登录(Login)流程

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
PostHog 前端 QA 实战指南:开发堆栈就绪检查(Stack Readiness)与登录(Login)流程

PostHog 前端 QA 实战指南:开发堆栈就绪检查(Stack Readiness)与登录(Login)流程

【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog

本篇技术指南以 PostHog 仓库内qa-frontend技能链的核心参考文档 stack-and-login.md 为骨架,系统讲解在进行浏览器前端 QA(Browser QA)前,如何判断本地 PostHog 开发堆栈是否可用、何时以及如何启动堆栈,以及如何安全地登录测试账号与准备隔离测试工作区。读完本篇,你将掌握一整套可复制的"堆栈复用 → 健康检查 → 审批启动 → 登录鉴权"流程,并理解其背后的仓库源码与安全边界,可直接应用于 PR 模式与本地模式的 PostHog 前端回归验证。

背景:stack-and-login 在 QA 流程中的角色

PostHog 仓库在 .agents/skills/qa-frontend/SKILL.md 中定义了一套完整的仓库内前端 QA 技能(/qa-frontend),它运行在一个有界的前端 QA 循环里,支持两种模式:

  • PR 模式:用户提供 PR 引用(URL、编号或分支),技能检出 PR 后执行 QA,经批准后上传证据并发布 PR 评论,要求工作树干净。
  • 本地模式:针对当前检出内容与未提交改动进行 QA,报告只写本地,不上传、不评论、不推送,允许脏工作树。

无论哪种模式,进入 Checkout、Diff 分析、浏览器执行之前,都必须先通过堆栈就绪与登录这道门。这正是 stack-and-login.md 的职责:它全权负责BASE_URLSTACK_STARTED_BY_AGENT、对仓库内run-posthog技能的委托、phrocs 进程检查、启动审批规则,以及登录/测试工作区的处理。SKILL.md 明确要求:"Do not checkout, edit, upload, comment, or push until it confirms the local PostHog stack is reachable enough for the planned QA target"——未通过就绪检查前,一切后续动作都被禁止。

一、堆栈就绪(Stack Readiness)

1.1 环境变量基线:BASE_URL 与 STACK_STARTED_BY_AGENT

在开始任何检查之前,先设置两个关键环境变量:

BASE_URL="${BASE_URL:-http://localhost:8010}" STACK_STARTED_BY_AGENT=0
  • BASE_URL是浏览器 QA 实际访问的入口。默认值http://localhost:8010是 PostHog 开发堆栈的 Envoy 风格代理地址:它把/static/*反代到 Vite(开发服务器实际运行在:8234),其余流量反代给 Django,因此浏览器始终浏览 8010 端口,直接访问 Vite 的 8234 端口会因无索引路由而 404(详见 .agents/skills/run-posthog/SKILL.md 的 Gotchas 一节)。
  • STACK_STARTED_BY_AGENT是一个归属标记:只有当你(Agent)获得用户批准并实际启动了堆栈时才置为1,其核心约束是只允许停止自己启动的那个堆栈,且只能在清理阶段或获得用户批准后进行。

1.2 核心原则:复用用户现有堆栈

文档强调的第一条原则是:默认复用用户已有的环境,不要因为你要跑 QA 就去启动、重启或替换开发堆栈。动作顺序是:

  1. 先检查BASE_URL处 PostHog 是否已经可达;
  2. 若可达,直接继续,不要启动、重启、替换或等待另一个堆栈;
  3. 若不可达,再考虑启动流程(见 1.5 启动审批)。

这一原则与 .agents/skills/qa-frontend/references/safety-rules.md 中的"Local Stack Control"章节一致:BASE_URL已可达时禁止另起炉灶,且"启动、停止、重启本地 PostHog 开发堆栈"本身属于必须获得当前会话内明确批准(explicit approval)的动作。

1.3 模式差异:PR 模式与本地模式的堆栈要求

堆栈选择还取决于运行模式:

  • PR 模式:优先让 PR 的代码在开发者机器之外执行——例如通过远程 devbox 提供BASE_URL转发端口(仓库的setting-up-devbox技能覆盖了如何配置一个 devbox)。因为 PR 模式会在本地堆栈上执行 PR 作者的代码(Python 与 JavaScript),等于以运行者权限运行他人的代码;若要在开发者自己机器上跑 PR 代码,必须取得 safety-rules.md 中描述的显式批准,并明确告知"这将在你的机器上执行 <作者> 的代码"。
  • 本地模式:测试的是开发者自己的代码,没有上述门槛。

另外,仓库内还存在 git hook 风险:PostHog 跟踪.husky/post-checkoutpre-commitpre-push,且core.hooksPath指向它们。因此 PR 模式检出时必须导出GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=core.hooksPath GIT_CONFIG_VALUE_0=/dev/null,防止检出时执行 PR 控制的 hook(见 SKILL.md 的 Checkout 章节)。

当仓库内存在 .agents/skills/run-posthog/SKILL.md 时,以它的当前就绪检查、phrocs 进程指引和setup_test/登录配方为唯一事实来源(source of truth);stack-and-login 参考文档只额外附加 QA 专属约束:用户堆栈可用就复用、启动/重启 PostHog 前先询问、只停止自己启动的堆栈。

1.4 可达性检查:curl 探测与 phrocs MCP 进程检查

BASE_URL执行两条最小健康检查命令:

curl -sf --max-time 5 "$BASE_URL/_health" curl -sf --max-time 10 -o /dev/null -w '%{http_code}' "$BASE_URL/"
  • 第一条探测/_health端点,-f让 HTTP 错误直接表现为命令失败,--max-time 5限制超时为 5 秒;
  • 第二条对根路径发起请求,只输出 HTTP 状态码(期望 200 或 302)。

若两条检查显示应用可达,就直接继续,不再折腾其他堆栈。若失败,则使用可用的本地健康检查手段,例如当 phrocs 已在运行时调用其 MCP 工具:

  • mcp__phrocs__get_process_status(process="backend")
  • mcp__phrocs__get_process_status(process="frontend")

在 .agents/skills/run-posthog/SKILL.md 中还有更完整的就绪条(readiness bars):backendfrontend是 UI QA 的硬性门槛(hard gates),只有目标路由还需要mcpfeature-flagsnodejscaptureingestion等单元时才追加检查。对于 HogQL 支撑的场景(insights、dashboards、web analytics)以及POST /api/setup_test/...,还额外要求migrate-clickhouse进程显示status:"done" exit_code:0

1.5 目标路由就绪比全栈健康更重要

文档给出了一个关键判断:"可达"不等于"在服务你的检出内容"BASE_URL可能是转发到远程堆栈(如 Coder devbox)的地址,而转发堆栈可能滞后于或偏离本地工作树。因此,在开始针对 diff 的验证或变更状态(登录、主题切换、种子数据)之前,必须确认堆栈确实在运行被测代码:打开一个被改动过的界面、确认改动已呈现,若堆栈同步有延迟则短暂重试。

数据播种(seeding)也必须对准浏览器实际对话的那个堆栈——本地执行manage.py shell写的是本地数据库,当BASE_URL转发到远程堆栈时这显然是错误的目标。播种应在提供BASE_URL的堆栈上进行,否则就记录一个 coverage gap。

对浏览器 QA 而言,目标路由就绪是比"本地全栈绿灯"更强的证据:改动后的 UI 能加载、分支/SHA 或其他 diff 内标记与在测代码一致、路由关键 API 可用。无关的降级单元记入run-notes.md即可,不必为了一个可用目标路由去追逐全栈健康。

1.6 启动流程与审批门槛

当 PostHog 不可达时,顺序如下:

  1. 先查用户记忆/设置与本地偏好,再查仓库指引及AGENTS.md等邻近文档中推荐的启动方式;
  2. 在启动 PostHog 之前询问用户希望如何处理
  3. 若目录与命令都很明确,可以提出具体的启动路径建议(包括是交互式还是后台运行),但要明确标注这是待确认的推断;若目录、命令、BASE_URL或启动方式不明确,则直接询问用户希望在哪里、以何种方式运行堆栈,或是否改用其他BASE_URL
  4. 在聊天中提问并停止等待用户回答。沙箱升级提示、命令批准对话框或已被批准的指令前缀都不等于工作流批准——它们只在你选定 agent 托管启动后才授权某条命令执行。

若用户批准 agent 托管启动,则:

  • 优先使用仓库常规的后台堆栈:对新/已停止的 devbox 用hogli devbox:start --start-app;对服务BASE_URL的检出目录用hogli up -d -yhogli dev:*系列仅用于理解不清晰的路由依赖。
  • 运行已批准的启动路径,并设置STACK_STARTED_BY_AGENT=1
  • 若命令因 shell 缺少仓库依赖或全局命令不在PATH上而失败,遵循仓库对同一启动意图的指引(例如仓库本地包装脚本或flox这类环境包装器),并宣告这一回退
  • 在切换检出、目录、启动模式、删除锁文件或启动不同堆栈之前,再次询问
  • 无头(headless)Agent 会话中避免交互式终端 UI,除非用户明确要求。
  • 只停止自己启动的堆栈,且仅在清理阶段或用户批准后进行。

启动之后,重复run-posthog的应用可达性检查(若该技能不可用,则用 1.4 的最小检查),并查询相关进程状态:backendfrontend,以及与改动表面直接相关的进程(例如测试 MCP 改动时的mcp)。只有应用可达且所需进程集就绪,才允许继续;backend 或 frontend 未就绪时,必须在检出、编辑、上传、评论或推送之前停止。

日志获取的优先级:优先使用 phrocs MCP 日志——mcp__phrocs__get_process_logs(process="backend")mcp__phrocs__get_process_logs(process="frontend");仅当 phrocs MCP 不可用时,回退到仓库本地日志目录.posthog/.generated/logs/

二、登录(Login)

2.1 两条登录路径:setup_test 隔离工作区 vs 种子默认账号

文档给出两条登录路径,按需选择:

路径 A:需要真实数据或隔离工作区时,使用run-posthogPOST /api/setup_test/organization_with_team/配方。在浏览器页面上下文中调用它,然后用返回的user_email与固定密码12345678从页面上下文登录;构造路由时使用返回的team_id/project/{team_id}/...。文档强调这是前端 QA 的准备工作,不是独立的后端/API 测试。

路径 B:不需要专用工作区时,默认使用公开的 PostHog 本地开发种子账号:test@posthog.com/12345678这两个凭据记录在 docs/published/handbook/engineering/manual-dev-setup.md("The first time you run the app, you can log in with a test account: usertest@posthog.compwd12345678"),由bin/start播种。它们只存在于以该方式播种的开发堆栈上(笔记本堆栈或个人 devbox),因此回退到它们是安全的。

2.2 源码佐证:setup_test 端点的实现与门槛

setup_test端点的实现位于 posthog/api/playwright_setup.py:它是一个仅接受POST的 DRF 视图,permission_classes([AllowAny]),通过test_name路由参数从posthog.test.playwright_setup_functions中注册的PLAYWRIGHT_SETUP_FUNCTIONS字典里选取对应的 setup 函数。关键安全门槛在第 20-28 行:

test_modes = ( getattr(settings, "TEST", False), getattr(settings, "DEBUG", False), getattr(settings, "CI", False), getattr(settings, "E2E_TESTING", False), ) if not any(test_modes): raise Http404()

即该端点仅在 TEST / DEBUG / CI / E2E_TESTING 任一模式下可用,本地开发默认满足DEBUG=True,因此可用;生产式配置下会直接 404。请求体经 pydanticinput_model校验后调用 setup 函数,成功返回{"success": True, "test_name": ..., "result": ...},异常则返回 500 与错误描述。这与 .agents/skills/run-posthog/SKILL.md 中"Gated onDEBUG=True | E2E_TESTING | CI | TEST"的描述完全对应。

run-posthog技能给出了完整的浏览器 MCP 配方(.agents/skills/run-posthog/SKILL.md 的 Drive the UI for /verify 一节),此处摘要关键步骤:

// 1. 在页面上下文中创建隔离工作区(每次调用使用随机邮箱,密码固定 12345678) const r = await fetch('/api/setup_test/organization_with_team/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ data: { skip_onboarding: true } }), }) const { result } = await r.json() // result: { user_email, team_id, personal_api_key, organization_id, ... } // 2. 仍在页面上下文中执行登录(保证 Django 的 CSRF 中间件拿到正确 cookie) const r = await fetch('/api/login/', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ email: workspace.user_email, password: '12345678' }), }) // 200 = 已登录;403 = 不在页面上下文;400 = 工作区并未真正创建该用户

其中第二步必须在页面上下文中运行——直接curl -X POST /api/login/会因 CSRF 返回 403(run-posthog的 Gotchas 明确记录:会话登录必须在页面内执行,使 cookie 与 CSRF token 正常流转);非浏览器 API 调用则应改用setup_test返回的personal_api_key作为Authorization: Bearer <key>,token 认证无 CSRF 问题。

2.3 凭据来源与优先级

qa-frontend技能在 Preconditions 阶段(.agents/skills/qa-frontend/SKILL.md)从$ARGUMENTS解析--login-username/--username--login-password/--passwordLOGIN_USERNAME/LOGIN_PASSWORD。解析之后若仍未设置,再应用种子默认值:

LOGIN_USERNAME="${LOGIN_USERNAME:-test@posthog.com}" LOGIN_PASSWORD="${LOGIN_PASSWORD:-12345678}"

由此形成三种凭据来源,按优先级排列

  1. chat 参数:调用时显式传入的--login-username/--login-password
  2. 环境变量:shell 中已导出的LOGIN_USERNAME/LOGIN_PASSWORD
  3. 种子默认值test@posthog.com/12345678

文档特别说明,不需要_OVERRIDE/_EFFECTIVE这类间接层;而fork 规则(fork-rule)的运行完全忽略上述优先级,一律只使用一次性(throwaway)凭据,详见 safety-rules.md 的 Fork PRs 章节——因为 fork 的代码可能窃取密码、浏览器会话、CSRF token 或本地数据,任何 fork PR 的浏览器 QA 都应假设"密码与会话可能泄露"。

2.4 密码安全与用户可见输出

两条铁律:

  • 绝不打印密码;对 chat 提供的凭据,在面向用户的输出中只称"login override provided"(已提供登录覆盖)。
  • LOGIN_PASSWORD不得打印、记录或包含进证据与评论(SKILL.md Preconditions 同样重申:"Do not print, log, or includeLOGIN_PASSWORDin evidence or comments")。

2.5 浏览器 MCP 登录的五个步骤

使用浏览器 MCP/工具时,按如下顺序完成登录:

  1. 导航到$BASE_URL/login
  2. 若使用setup_test:先在页面内执行 run-posthog 的 setup 与登录 fetch,再导航到返回team_id对应的路由;
  3. 否则,用生效的登录值填写邮箱与密码;
  4. 提交表单;
  5. 等待登录后的 URL 匹配**/project/**——这是登录成功的关键信号,因为 PostHog 登录成功后会跳转到项目作用域路由。

2.6 登录失败的处理

若登录失败,或两个生效登录值任一缺失:中止整个流程、恢复原分支、不发布 PR 评论——因为 QA 实际上没有运行,发布评论会给出误导性结论。这与 SKILL.md 中"Never print passwords or include credentials in evidence. If login fails, abort before posting a PR comment because QA did not run"一致。

三、常见故障与排查线索(结合实际堆栈经验)

虽然 stack-and-login 文档本身聚焦就绪与登录,仓库内 .agents/skills/run-posthog/SKILL.md 沉淀了与之直接相关的常见故障,可作为登录/就绪失败时的排查地图:

  • migrate-clickhouse冷启动崩溃hogli up -d时与migrate-postgres并行启动存在竞态,Postgres 未就绪时崩溃。这是POST /api/setup_test/...与 HogQL 场景的硬前置,但不是/run的前置。修复序列:等migrate-postgres显示status:"done"后重启崩溃的迁移单元(mcp__phrocs__toggle_process是外科手术式工具,但在共享堆栈上被 auto-mode 拦截时,回退到phrocs stop && hogli up -d全量重启,或直接python manage.py migrate_clickhouse——需先set -a; source .env.services; set +a使CLICKHOUSE_DATABASE=posthog)。
  • POST /api/login/返回 400invalid_credentials:你登录的用户并非setup_test工作区真正创建的用户(通常是 ClickHouse 崩溃导致)。检查 setup_test 调用的响应,若其 500,先修 ClickHouse。
  • POST /api/setup_test/organization_with_team/返回 404DEBUGE2E_TESTINGCITEST全部为假。本地开发默认DEBUG=True;若未设置,通常是.env.local缺失或DJANGO_SETTINGS_MODULE指向了类生产配置。
  • POST /api/setup_test/organization_with_team/返回 500Table posthog.person does not existmigrate-clickhouse启动时崩溃,见第一条。
  • 页面内fetch('/api/login/')返回 403:调用未发生在页面上下文(例如用了page.request.post而非page.evaluate)。必须用evaluate_script/browser_evaluate使调用源于页面内。
  • hogli up -dAnother instance of bin/start is already running:上一次运行未清理;用 phrocs 状态确认无残留后,删除bin/start.lock重试。
  • 浏览器控制台的 CSP 警告与 401:登录前的正常现象——preflight/login 页面会尝试拉取/api/projects/@current/api/users/@me/与 PostHog.js 远程配置,在注册前均返回 401。

四、流程总结:一张就绪-登录决策表

阶段判定条件动作
设置基线BASE_URL=${BASE_URL:-http://localhost:8010}STACK_STARTED_BY_AGENT=0
复用检查curl/_health/均成功直接继续,不启动/重启/替换堆栈
复用失败curl 失败用 phrocsget_process_status(backend/frontend)补充判断
仍不可达进程检查未就绪查用户偏好 → 查仓库指引/AGENTS.md → 询问用户启动方式并等待答复
获批启动用户批准运行hogli devbox:start --start-apphogli up -d -ySTACK_STARTED_BY_AGENT=1
启动后复检重跑可达性 + 进程检查仅当应用可达且所需进程集就绪才继续;否则在 checkout/编辑/评论/推送前停止
登录路径 A需要隔离数据页面上下文调POST /api/setup_test/organization_with_team/,用返回邮箱 +12345678登录,team_id构造路由
登录路径 B无需隔离数据test@posthog.com/12345678(种子默认)
登录验证地址匹配**/project/**视为成功;失败则中止、恢复分支、不发 PR 评论

这套流程的核心设计思想可以概括为三点:最小干预(能复用就不新建)、显式批准(启动/重启/推送等高影响动作必须对话内确认)、证据优先(目标路由可用的局部证据优于全栈绿灯的粗粒度判断)。对于任何需要在 PostHog 仓库上执行浏览器前端 QA 的开发者或 Agent,先跑通"堆栈就绪 → 登录"这两步,是后续所有测试用例设计、证据采集与报告产出的可靠前提。

【免费下载链接】posthog:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.项目地址: https://gitcode.com/GitHub_Trending/po/posthog

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/11 9:09:06

解决Python子进程Ctrl+C中断问题的信号处理方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/11 9:07:30

ESP32+FPGA+CYW240128异构系统协同调试指南

1. 项目背景与核心问题定位CYW240128 是 Cypress&#xff08;现属英飞凌&#xff09;推出的一款高度集成的 Wi-Fi Bluetooth 双模 SoC&#xff0c;常用于工业物联网网关、边缘智能终端等对无线连接可靠性与实时性要求较高的场景。它本身不具备完整 MCU 功能&#xff0c;需搭配…

作者头像 李华
网站建设 2026/9/11 9:03:09

Shadcn UI + JavaFX WebView:构建现代Java桌面应用的实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/11 9:02:36

YOLOv8+双大模型的工业质检落地实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/11 8:59:46

AI Core多核数据一致性实战指南:SetFlag/WaitFlag与NPU选项调优

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华