Files
rakuten-api/scripts/verify_cart_clear.py
T
q792602257 086ab82614 feat(trading): 清空购物车落步骤证据,补空车/有商品两场景测试
- clear_cart 返回清理后 cart 页最终 HTML(best-effort,抓取失败不掩盖清理结果)
- runner step 0 落 00-cart-clear.{html,meta.json} 并登记 evidence_index,
  证据先于闸门判断落盘(清理未净被拦时这份现场就是排查依据);
  仍是本机卫生步骤:不上报 gateway、不记 order_events
- /api/cart/clear 响应不携带 html(路由显式挑字段,与 cart_add 同风格)
- 单测:fake page 覆盖空车/有商品/HTML 抓取失败;runner 层覆盖证据落盘
  与闸门拦截场景
- 真账号复验 scripts/verify_cart_clear.py:空车 removed=0/count=0;
  加购 1 件后 clear removed=1/count=0,status 复核 101
2026-08-17 08:32:11 +08:00

83 lines
3.7 KiB
Python

"""真账号验证:clear_cart 两个场景——空车返回成功 / 有商品正确清除
场景 1(空车):clear_cart 应 removed_count=0、cart_count=0(status=101 是合法
空车,不是获取失败),并带回清理后的页面 HTML(runner step 0 落证据用)。
场景 2(有商品):先加购 1 件商品,clear_cart 应 removed_count>=1、cart_count=0,
末尾再用 cart_status 独立复核确实是空车。
前置:登录态有效(.auth/ 下有 storage_state);浏览器必须非无头(站点风控要求,
会弹出真实浏览器窗口)。商品 URL 与其他探针(probe_new_card 等)一致。
用法:
.venv/Scripts/python.exe scripts/verify_cart_clear.py
"""
from __future__ import annotations
import asyncio
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
from app.shared.config import get_settings # noqa: E402
from app.trading.services.auth_session import AuthSession # noqa: E402
from app.trading.worker.site_interact import SiteInteractor # noqa: E402
ITEM_URL = "https://item.rakuten.co.jp/moccasin/ds001iwrgesaaa2/"
async def run() -> int:
settings = get_settings()
auth = AuthSession(settings)
await auth.start()
site = SiteInteractor(auth_session=auth, settings=settings)
await site.start()
try:
# 前置:先清一次,保证从空车起步(顺便清掉上次验证可能残留的商品)
pre = await site.clear_cart()
print(f"前置 clear -> removed={pre['removed_count']} cart_count={pre['cart_count']}")
assert pre["cart_count"] == 0, f"前置清理后应为空车,实际 {pre['cart_count']}"
# 场景 1:空车 —— 应直接返回清理成功,不做任何点击
empty = await site.clear_cart()
print(
f"场景1 空车 -> removed={empty['removed_count']} "
f"cart_count={empty['cart_count']} html={len(empty['html'])}B"
)
assert empty["removed_count"] == 0, f"空车不应有点击,实际 {empty['removed_count']}"
assert empty["cart_count"] == 0, f"空车 cart_count 应为 0,实际 {empty['cart_count']}"
assert empty["html"], "空车也应带回页面 HTML(runner 落证据用)"
# 场景 2:有商品 —— 先加购 1 件,再清,应真删掉
added = await site.add_to_cart_payload(item_url=ITEM_URL, quantity=1)
print(f"加购 -> item_id={added['item_id']} cart_count={added['cart_count']}")
assert added["cart_count"] >= 1, "加购后购物车应有商品"
cleared = await site.clear_cart()
print(
f"场景2 有商品 -> removed={cleared['removed_count']} "
f"cart_count={cleared['cart_count']} html={len(cleared['html'])}B"
)
assert cleared["removed_count"] >= 1, (
f"有商品时至少点 1 次「削除」,实际 {cleared['removed_count']}"
)
assert cleared["cart_count"] == 0, f"清理后应为空车,实际 {cleared['cart_count']}"
assert cleared["html"], "清理后应带回页面 HTML"
# 复核:独立的 status 查询确认确实是空车(不只信 clear 末尾的一次校验)
status = await site.cart_status()
print(f"复核 status -> {status}")
assert status["count"] == 0 and status["raw_status"] == "101", (
f"复核应为空车(count=0, raw_status=101),实际 {status}"
)
print("\n验证通过:空车正确返回成功;有商品时正确清除并复核为空车")
return 0
finally:
await site.close()
await auth.close()
if __name__ == "__main__":
raise SystemExit(asyncio.run(run()))