# Simulator Browser RPA Example 这是一个**仿真浏览器 RPA** 的可复制参考实现:在可控 sandbox 页面上,通过 Playwright 完成登录、表单填写、弹窗确认、结果解析。 本示例抽象自已跑通的「批量提交类」浏览器自动化 skill,但已去业务化,不包含真实银行/真实资金语义。 ## 适合什么场景 - 自有 **仿真系统 / sandbox / training 页面** - 需要 **浏览器 RPA** 做端到端演示或回归 - 表单较复杂:多步登录、Tab 切换、动态增行、PIN 弹窗、成功页解析 - 需要 **adapter 分层**:mock(CI)与 simulator_rpa(半集成)可切换 ## 不适合什么场景 - **真实第三方网站 + 高风控 + 人工验证码** → 优先看 [`../real_browser_rpa/README.md`](../real_browser_rpa/README.md) - 目标系统有稳定 **官方 API** → 不要硬写浏览器 RPA,后续参考 `real_api` - **不要把本示例的业务字段、selector、sandbox URL 原样复制**到你的 skill ## 目录结构 ``` simulator_browser_rpa/ ├── README.md ├── sandbox/ │ └── demo_app.html # 本地仿真页面(稳定 data-testid / name) ├── scripts/ │ ├── service/ │ │ ├── browser_session.py # 浏览器启动(URL 仅 page.goto) │ │ ├── account_client.py # 账号来源集中封装 │ │ ├── task_service.py # 编排层 │ │ └── adapter/ │ │ ├── base.py # BatchItem / BatchSubmitResult 契约 │ │ ├── mock.py # mock/unit 档 │ │ ├── simulator_rpa.py │ │ └── __init__.py # select_adapter │ └── util/ │ ├── constants.py │ └── logging.py └── tests/ ├── test_adapter_dispatch.py ├── test_simulator_rpa_unit.py └── test_stop_reason.py ``` ## 文件职责 | 文件 | 职责 | |---|---| | `browser_session.py` | 系统 Chrome/Edge + launch args 规范;支持 profile / 无 profile | | `account_client.py` | 示例从环境变量读账号;真实 skill 可在此集中对接 account-manager | | `adapter/base.py` | 数据契约与 `BatchAdapterBase` | | `adapter/mock.py` | 不启浏览器,供 unit/mock/CI | | `adapter/simulator_rpa.py` | 仿真 RPA 主流程 | | `task_service.py` | 校验输入 → 选 adapter → 提交 → 返回 summary | | `sandbox/demo_app.html` | 可控 DOM,配合 selector 稳定 | | `tests/` | dispatch、URL 不进 launch args、失败转结果 | ## 核心流程 1. `task_service.run_batch_submit(target, items)` 校验参数 2. `select_adapter()` 按 `OPENCLAW_TEST_TARGET` 选择 mock 或 simulator RPA 3. simulator 档:`pick_simulator_account()` → `set_credentials()` → `submit_batch()` 4. RPA:登录两步 → 批量页 → 填表 → 提交 → PIN → 解析 `batch_id` 5. 失败截图(有 `artifacts_dir` 时)→ 返回 `BatchSubmitResult` ## 复制到新 skill 时怎么做 按 copy map **选择性复制**到 `scripts/`;**不要**整包照搬本目录,**不要**把本 README 当作新技能根 README。 ## Copy map(复制到新技能 `scripts/`) | 来源(examples) | 目标(新技能) | 说明 | |---|---|---| | `examples/simulator_browser_rpa/scripts/service/browser_session.py` | `scripts/service/browser_session.py` | URL 仅 `page.goto`,不进 launch args | | `examples/simulator_browser_rpa/scripts/service/account_client.py` | `scripts/service/account_client.py` | 账号来源集中封装 | | `examples/simulator_browser_rpa/scripts/service/task_service.py` | `scripts/service/task_service.py` | 编排层,合并业务逻辑 | | `examples/simulator_browser_rpa/scripts/service/adapter/` | `scripts/service/_adapter/` | **adapter 分层权威参考** | | `examples/simulator_browser_rpa/scripts/util/constants.py` | `scripts/util/constants.py` | 须替换业务常量 | | `examples/simulator_browser_rpa/scripts/util/logging.py` | `scripts/util/logging.py` | 可选 | | `examples/simulator_browser_rpa/tests/` | `tests/` | 可按需复制 dispatch / unit 测试 | | `examples/simulator_browser_rpa/sandbox/demo_app.html` | — | **仅仿真测试用**,不进入生产 skill | | `examples/simulator_browser_rpa/README.md` | — | **只读参考**,不复制为新技能根 README | **边界说明:** - `sandbox/` 只用于仿真测试与本地回归,**不进入**真实生产 skill - `adapter/` 分层(base / mock / simulator_rpa)是仿真浏览器 RPA 的权威参考 - `mock` / `simulator_rpa` 只用于测试与仿真,**不要**混入 `real_browser_rpa` 的真实站点逻辑 - `demo_app.html` 是可运行沙箱页面,**不是**真实业务系统 **保留:** - adapter 分层(base / mock / simulator_rpa / `select_adapter`) - `browser_session.py` 启动规范(**URL 不进 launch args**) - `account_client.py` 集中封装模式 - 关键节点结构化日志 + 失败截图 - 测试:dispatch、launch args、错误转 `BatchSubmitResult` **替换:** - `BatchItem` 字段与校验规则 - `sandbox/demo_app.html` 或 `SIMULATOR_BASE_URL` 指向的页面 - 全部 DOM selector(必须 F12 实测) - `task_service.py` 输入输出与 DB/任务日志 - mock 返回字段、成功页 `batch_id` 解析逻辑 ## 明确禁止 - 不要复制 `__pycache__`、`.pytest_cache`、`artifacts/`、`recordings/` 等生成物 - **不要在技能侧**执行 `playwright install` / `pip install playwright`(Python 包由宿主共享 runtime 提供) - **不要把 URL 放进** `launch_persistent_context(args=[...])` - **不要在** `task_service.py` / RPA 主流程里散落 account-manager subprocess - **不要把真实生产系统**配置到 `simulator_rpa` 档位 - 不要照抄 slug、logger 名、演示账号到生产 skill ## 依赖说明 - Python 3.10+ - Python 包 `playwright`:由**宿主共享 runtime** 提供;技能侧不要写入 `requirements.txt`,不要 `pip install playwright` - 默认使用**系统 Chrome/Edge**,不使用 Playwright 内置 Chromium - 技能侧不要执行 `playwright install` / `playwright install chromium` - 本地独立开发若缺 Playwright Python 包,仅作开发机临时补装;生产由宿主解决 - `jiangchang_skill_core.runtime_env.find_chrome_executable`(可选,用于查找系统浏览器) ## 环境变量(示例) | 变量 | 说明 | |---|---| | `OPENCLAW_TEST_TARGET` | `mock`/`unit` → Mock;默认 → Simulator RPA | | `SIMULATOR_BASE_URL` | 仿真页 URL;默认本地 `sandbox/demo_app.html` 的 file URI | | `SIMULATOR_LOGIN_ID` / `PASSWORD` / `TOKEN_PIN` | 演示账号 | | `SIMULATOR_PROFILE_DIR` | 可选 persistent profile | | `OPENCLAW_BROWSER_HEADLESS` | `0` 默认有头;`1` 无头模式(CI 可用) | ## 运行测试 ```bash cd examples/simulator_browser_rpa python -m pytest tests/ -v ``` 测试为 mock/纯函数,**不需要启动真实浏览器**。 ## 当前状态 - 示例代码与 sandbox 页面已就绪,可作为仿真浏览器 RPA 复制起点。 - 未接入完整 CLI、数据库与 entitlement。